1c0b746e5SOllivier Robert /* 29c2daa00SOllivier Robert * ntpdc_ops.c - subroutines which are called to perform operations by xntpdc 3c0b746e5SOllivier Robert */ 4c0b746e5SOllivier Robert 5c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H 6c0b746e5SOllivier Robert # include <config.h> 7c0b746e5SOllivier Robert #endif 8c0b746e5SOllivier Robert 9c0b746e5SOllivier Robert #include <stdio.h> 109c2daa00SOllivier Robert #include <stddef.h> 11224ba2bdSOllivier Robert 12224ba2bdSOllivier Robert #include "ntpdc.h" 13224ba2bdSOllivier Robert #include "ntp_control.h" 14224ba2bdSOllivier Robert #include "ntp_refclock.h" 15224ba2bdSOllivier Robert #include "ntp_stdlib.h" 16224ba2bdSOllivier Robert 17c0b746e5SOllivier Robert #include <ctype.h> 18c0b746e5SOllivier Robert #ifdef HAVE_SYS_TIMEX_H 19c0b746e5SOllivier Robert # include <sys/timex.h> 20c0b746e5SOllivier Robert #endif 21c0b746e5SOllivier Robert #include <netdb.h> 22c0b746e5SOllivier Robert #if !defined(__bsdi__) && !defined(apollo) 23c0b746e5SOllivier Robert #include <netinet/in.h> 24c0b746e5SOllivier Robert #endif 25c0b746e5SOllivier Robert 26c0b746e5SOllivier Robert #include <arpa/inet.h> 27c0b746e5SOllivier Robert 28c0b746e5SOllivier Robert /* 29c0b746e5SOllivier Robert * Declarations for command handlers in here 30c0b746e5SOllivier Robert */ 31c0b746e5SOllivier Robert static int checkitems P((int, FILE *)); 32c0b746e5SOllivier Robert static int checkitemsize P((int, int)); 33c0b746e5SOllivier Robert static int check1item P((int, FILE *)); 34c0b746e5SOllivier Robert static void peerlist P((struct parse *, FILE *)); 35c0b746e5SOllivier Robert static void peers P((struct parse *, FILE *)); 36c0b746e5SOllivier Robert static void doconfig P((struct parse *pcmd, FILE *fp, int mode, int refc)); 37c0b746e5SOllivier Robert static void dmpeers P((struct parse *, FILE *)); 38c0b746e5SOllivier Robert static void dopeers P((struct parse *, FILE *, int)); 39c0b746e5SOllivier Robert static void printpeer P((struct info_peer *, FILE *)); 40c0b746e5SOllivier Robert static void showpeer P((struct parse *, FILE *)); 41c0b746e5SOllivier Robert static void peerstats P((struct parse *, FILE *)); 42c0b746e5SOllivier Robert static void loopinfo P((struct parse *, FILE *)); 43c0b746e5SOllivier Robert static void sysinfo P((struct parse *, FILE *)); 44c0b746e5SOllivier Robert static void sysstats P((struct parse *, FILE *)); 45c0b746e5SOllivier Robert static void iostats P((struct parse *, FILE *)); 46c0b746e5SOllivier Robert static void memstats P((struct parse *, FILE *)); 47c0b746e5SOllivier Robert static void timerstats P((struct parse *, FILE *)); 48c0b746e5SOllivier Robert static void addpeer P((struct parse *, FILE *)); 49c0b746e5SOllivier Robert static void addserver P((struct parse *, FILE *)); 50c0b746e5SOllivier Robert static void addrefclock P((struct parse *, FILE *)); 51c0b746e5SOllivier Robert static void broadcast P((struct parse *, FILE *)); 52c0b746e5SOllivier Robert static void doconfig P((struct parse *, FILE *, int, int)); 53c0b746e5SOllivier Robert static void unconfig P((struct parse *, FILE *)); 54c0b746e5SOllivier Robert static void set P((struct parse *, FILE *)); 55c0b746e5SOllivier Robert static void sys_clear P((struct parse *, FILE *)); 56c0b746e5SOllivier Robert static void doset P((struct parse *, FILE *, int)); 57c0b746e5SOllivier Robert static void reslist P((struct parse *, FILE *)); 58c0b746e5SOllivier Robert static void new_restrict P((struct parse *, FILE *)); 59c0b746e5SOllivier Robert static void unrestrict P((struct parse *, FILE *)); 60c0b746e5SOllivier Robert static void delrestrict P((struct parse *, FILE *)); 61c0b746e5SOllivier Robert static void do_restrict P((struct parse *, FILE *, int)); 62c0b746e5SOllivier Robert static void monlist P((struct parse *, FILE *)); 63c0b746e5SOllivier Robert static void reset P((struct parse *, FILE *)); 64c0b746e5SOllivier Robert static void preset P((struct parse *, FILE *)); 65c0b746e5SOllivier Robert static void readkeys P((struct parse *, FILE *)); 66c0b746e5SOllivier Robert static void trustkey P((struct parse *, FILE *)); 67c0b746e5SOllivier Robert static void untrustkey P((struct parse *, FILE *)); 68c0b746e5SOllivier Robert static void do_trustkey P((struct parse *, FILE *, int)); 69c0b746e5SOllivier Robert static void authinfo P((struct parse *, FILE *)); 70c0b746e5SOllivier Robert static void traps P((struct parse *, FILE *)); 71c0b746e5SOllivier Robert static void addtrap P((struct parse *, FILE *)); 72c0b746e5SOllivier Robert static void clrtrap P((struct parse *, FILE *)); 73c0b746e5SOllivier Robert static void do_addclr_trap P((struct parse *, FILE *, int)); 74c0b746e5SOllivier Robert static void requestkey P((struct parse *, FILE *)); 75c0b746e5SOllivier Robert static void controlkey P((struct parse *, FILE *)); 76c0b746e5SOllivier Robert static void do_changekey P((struct parse *, FILE *, int)); 77c0b746e5SOllivier Robert static void ctlstats P((struct parse *, FILE *)); 78c0b746e5SOllivier Robert static void clockstat P((struct parse *, FILE *)); 79c0b746e5SOllivier Robert static void fudge P((struct parse *, FILE *)); 80c0b746e5SOllivier Robert static void clkbug P((struct parse *, FILE *)); 81c0b746e5SOllivier Robert static void kerninfo P((struct parse *, FILE *)); 82c0b746e5SOllivier Robert 83c0b746e5SOllivier Robert /* 84c0b746e5SOllivier Robert * Commands we understand. Ntpdc imports this. 85c0b746e5SOllivier Robert */ 86c0b746e5SOllivier Robert struct xcmd opcmds[] = { 879c2daa00SOllivier Robert { "listpeers", peerlist, { OPT|IP_VERSION, NO, NO, NO }, 889c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 899c2daa00SOllivier Robert "display list of peers the server knows about [IP Version]" }, 909c2daa00SOllivier Robert { "peers", peers, { OPT|IP_VERSION, NO, NO, NO }, 919c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 929c2daa00SOllivier Robert "display peer summary information [IP Version]" }, 939c2daa00SOllivier Robert { "dmpeers", dmpeers, { OPT|IP_VERSION, NO, NO, NO }, 949c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 959c2daa00SOllivier Robert "display peer summary info the way Dave Mills likes it (IP Version)" }, 96c0b746e5SOllivier Robert { "showpeer", showpeer, { ADD, OPT|ADD, OPT|ADD, OPT|ADD}, 97c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 98c0b746e5SOllivier Robert "display detailed information for one or more peers" }, 99c0b746e5SOllivier Robert { "pstats", peerstats, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 100c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 101c0b746e5SOllivier Robert "display statistical information for one or more peers" }, 102c0b746e5SOllivier Robert { "loopinfo", loopinfo, { OPT|NTP_STR, NO, NO, NO }, 103c0b746e5SOllivier Robert { "oneline|multiline", "", "", "" }, 104c0b746e5SOllivier Robert "display loop filter information" }, 105c0b746e5SOllivier Robert { "sysinfo", sysinfo, { NO, NO, NO, NO }, 106c0b746e5SOllivier Robert { "", "", "", "" }, 107c0b746e5SOllivier Robert "display local server information" }, 108c0b746e5SOllivier Robert { "sysstats", sysstats, { NO, NO, NO, NO }, 109c0b746e5SOllivier Robert { "", "", "", "" }, 110c0b746e5SOllivier Robert "display local server statistics" }, 111c0b746e5SOllivier Robert { "memstats", memstats, { NO, NO, NO, NO }, 112c0b746e5SOllivier Robert { "", "", "", "" }, 113c0b746e5SOllivier Robert "display peer memory usage statistics" }, 114c0b746e5SOllivier Robert { "iostats", iostats, { NO, NO, NO, NO }, 115c0b746e5SOllivier Robert { "", "", "", "" }, 116c0b746e5SOllivier Robert "display I/O subsystem statistics" }, 117c0b746e5SOllivier Robert { "timerstats", timerstats, { NO, NO, NO, NO }, 118c0b746e5SOllivier Robert { "", "", "", "" }, 119c0b746e5SOllivier Robert "display event timer subsystem statistics" }, 120c0b746e5SOllivier Robert { "addpeer", addpeer, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR }, 121c0b746e5SOllivier Robert { "addr", "keyid", "version", "minpoll|prefer" }, 122c0b746e5SOllivier Robert "configure a new peer association" }, 123c0b746e5SOllivier Robert { "addserver", addserver, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR }, 124c0b746e5SOllivier Robert { "addr", "keyid", "version", "minpoll|prefer" }, 125c0b746e5SOllivier Robert "configure a new server" }, 126c0b746e5SOllivier Robert { "addrefclock",addrefclock, { ADD, OPT|UINT, OPT|NTP_STR, OPT|NTP_STR }, 127c0b746e5SOllivier Robert { "addr", "mode", "minpoll|prefer", "minpoll|prefer" }, 128c0b746e5SOllivier Robert "configure a new server" }, 129c0b746e5SOllivier Robert { "broadcast", broadcast, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR }, 130c0b746e5SOllivier Robert { "addr", "keyid", "version", "minpoll" }, 131c0b746e5SOllivier Robert "configure broadcasting time service" }, 132c0b746e5SOllivier Robert { "unconfig", unconfig, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 133c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 134c0b746e5SOllivier Robert "unconfigure existing peer assocations" }, 135c0b746e5SOllivier Robert { "enable", set, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 136c0b746e5SOllivier Robert { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 137c0b746e5SOllivier Robert "set a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 138c0b746e5SOllivier Robert { "disable", sys_clear, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 139c0b746e5SOllivier Robert { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 140c0b746e5SOllivier Robert "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 1419c2daa00SOllivier Robert { "reslist", reslist, {OPT|IP_VERSION, NO, NO, NO }, 1429c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 143c0b746e5SOllivier Robert "display the server's restrict list" }, 144c0b746e5SOllivier Robert { "restrict", new_restrict, { ADD, ADD, NTP_STR, OPT|NTP_STR }, 145c0b746e5SOllivier Robert { "address", "mask", 146224ba2bdSOllivier Robert "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 147c0b746e5SOllivier Robert "..." }, 148c0b746e5SOllivier Robert "create restrict entry/add flags to entry" }, 149c0b746e5SOllivier Robert { "unrestrict", unrestrict, { ADD, ADD, NTP_STR, OPT|NTP_STR }, 150c0b746e5SOllivier Robert { "address", "mask", 151224ba2bdSOllivier Robert "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 152c0b746e5SOllivier Robert "..." }, 153c0b746e5SOllivier Robert "remove flags from a restrict entry" }, 154c0b746e5SOllivier Robert { "delrestrict", delrestrict, { ADD, ADD, OPT|NTP_STR, NO }, 155c0b746e5SOllivier Robert { "address", "mask", "ntpport", "" }, 156c0b746e5SOllivier Robert "delete a restrict entry" }, 157c0b746e5SOllivier Robert { "monlist", monlist, { OPT|INT, NO, NO, NO }, 158c0b746e5SOllivier Robert { "version", "", "", "" }, 159c0b746e5SOllivier Robert "display data the server's monitor routines have collected" }, 160c0b746e5SOllivier Robert { "reset", reset, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 161c0b746e5SOllivier Robert { "io|sys|mem|timer|auth|allpeers", "...", "...", "..." }, 162c0b746e5SOllivier Robert "reset various subsystem statistics counters" }, 163c0b746e5SOllivier Robert { "preset", preset, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 164c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 165c0b746e5SOllivier Robert "reset stat counters associated with particular peer(s)" }, 166c0b746e5SOllivier Robert { "readkeys", readkeys, { NO, NO, NO, NO }, 167c0b746e5SOllivier Robert { "", "", "", "" }, 168c0b746e5SOllivier Robert "request a reread of the keys file and re-init of system keys" }, 169c0b746e5SOllivier Robert { "trustedkey", trustkey, { UINT, OPT|UINT, OPT|UINT, OPT|UINT }, 170c0b746e5SOllivier Robert { "keyid", "keyid", "keyid", "keyid" }, 171c0b746e5SOllivier Robert "add one or more key ID's to the trusted list" }, 172c0b746e5SOllivier Robert { "untrustedkey", untrustkey, { UINT, OPT|UINT, OPT|UINT, OPT|UINT }, 173c0b746e5SOllivier Robert { "keyid", "keyid", "keyid", "keyid" }, 174c0b746e5SOllivier Robert "remove one or more key ID's from the trusted list" }, 175c0b746e5SOllivier Robert { "authinfo", authinfo, { NO, NO, NO, NO }, 176c0b746e5SOllivier Robert { "", "", "", "" }, 177c0b746e5SOllivier Robert "display the state of the authentication code" }, 178c0b746e5SOllivier Robert { "traps", traps, { NO, NO, NO, NO }, 179c0b746e5SOllivier Robert { "", "", "", "" }, 180c0b746e5SOllivier Robert "display the traps set in the server" }, 181c0b746e5SOllivier Robert { "addtrap", addtrap, { ADD, OPT|UINT, OPT|ADD, NO }, 182c0b746e5SOllivier Robert { "address", "port", "interface", "" }, 183c0b746e5SOllivier Robert "configure a trap in the server" }, 184c0b746e5SOllivier Robert { "clrtrap", clrtrap, { ADD, OPT|UINT, OPT|ADD, NO }, 185c0b746e5SOllivier Robert { "address", "port", "interface", "" }, 186c0b746e5SOllivier Robert "remove a trap (configured or otherwise) from the server" }, 187c0b746e5SOllivier Robert { "requestkey", requestkey, { UINT, NO, NO, NO }, 188c0b746e5SOllivier Robert { "keyid", "", "", "" }, 189c0b746e5SOllivier Robert "change the keyid the server uses to authenticate requests" }, 190c0b746e5SOllivier Robert { "controlkey", controlkey, { UINT, NO, NO, NO }, 191c0b746e5SOllivier Robert { "keyid", "", "", "" }, 192c0b746e5SOllivier Robert "change the keyid the server uses to authenticate control messages" }, 193c0b746e5SOllivier Robert { "ctlstats", ctlstats, { NO, NO, NO, NO }, 194c0b746e5SOllivier Robert { "", "", "", "" }, 195c0b746e5SOllivier Robert "display packet count statistics from the control module" }, 196c0b746e5SOllivier Robert { "clockstat", clockstat, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 197c0b746e5SOllivier Robert { "address", "address", "address", "address" }, 198c0b746e5SOllivier Robert "display clock status information" }, 199c0b746e5SOllivier Robert { "fudge", fudge, { ADD, NTP_STR, NTP_STR, NO }, 200c0b746e5SOllivier Robert { "address", "time1|time2|val1|val2|flags", "value", "" }, 201c0b746e5SOllivier Robert "set/change one of a clock's fudge factors" }, 202c0b746e5SOllivier Robert { "clkbug", clkbug, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 203c0b746e5SOllivier Robert { "address", "address", "address", "address" }, 204c0b746e5SOllivier Robert "display clock debugging information" }, 205c0b746e5SOllivier Robert { "kerninfo", kerninfo, { NO, NO, NO, NO }, 206c0b746e5SOllivier Robert { "", "", "", "" }, 207c0b746e5SOllivier Robert "display the kernel pll/pps variables" }, 208c0b746e5SOllivier Robert 209c0b746e5SOllivier Robert { 0, 0, { NO, NO, NO, NO }, 210c0b746e5SOllivier Robert { "", "", "", "" }, "" } 211c0b746e5SOllivier Robert }; 212c0b746e5SOllivier Robert 213c0b746e5SOllivier Robert /* 214c0b746e5SOllivier Robert * For quick string comparisons 215c0b746e5SOllivier Robert */ 216c0b746e5SOllivier Robert #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 217c0b746e5SOllivier Robert 218c0b746e5SOllivier Robert 219c0b746e5SOllivier Robert /* 220c0b746e5SOllivier Robert * checkitems - utility to print a message if no items were returned 221c0b746e5SOllivier Robert */ 222c0b746e5SOllivier Robert static int 223c0b746e5SOllivier Robert checkitems( 224c0b746e5SOllivier Robert int items, 225c0b746e5SOllivier Robert FILE *fp 226c0b746e5SOllivier Robert ) 227c0b746e5SOllivier Robert { 228c0b746e5SOllivier Robert if (items == 0) { 229c0b746e5SOllivier Robert (void) fprintf(fp, "No data returned in response to query\n"); 230c0b746e5SOllivier Robert return 0; 231c0b746e5SOllivier Robert } 232c0b746e5SOllivier Robert return 1; 233c0b746e5SOllivier Robert } 234c0b746e5SOllivier Robert 235c0b746e5SOllivier Robert 236c0b746e5SOllivier Robert /* 237c0b746e5SOllivier Robert * checkitemsize - utility to print a message if the item size is wrong 238c0b746e5SOllivier Robert */ 239c0b746e5SOllivier Robert static int 240c0b746e5SOllivier Robert checkitemsize( 241c0b746e5SOllivier Robert int itemsize, 242c0b746e5SOllivier Robert int expected 243c0b746e5SOllivier Robert ) 244c0b746e5SOllivier Robert { 245c0b746e5SOllivier Robert if (itemsize != expected) { 246c0b746e5SOllivier Robert (void) fprintf(stderr, 247c0b746e5SOllivier Robert "***Incorrect item size returned by remote host (%d should be %d)\n", 248c0b746e5SOllivier Robert itemsize, expected); 249c0b746e5SOllivier Robert return 0; 250c0b746e5SOllivier Robert } 251c0b746e5SOllivier Robert return 1; 252c0b746e5SOllivier Robert } 253c0b746e5SOllivier Robert 254c0b746e5SOllivier Robert 255c0b746e5SOllivier Robert /* 256c0b746e5SOllivier Robert * check1item - check to make sure we have exactly one item 257c0b746e5SOllivier Robert */ 258c0b746e5SOllivier Robert static int 259c0b746e5SOllivier Robert check1item( 260c0b746e5SOllivier Robert int items, 261c0b746e5SOllivier Robert FILE *fp 262c0b746e5SOllivier Robert ) 263c0b746e5SOllivier Robert { 264c0b746e5SOllivier Robert if (items == 0) { 265c0b746e5SOllivier Robert (void) fprintf(fp, "No data returned in response to query\n"); 266c0b746e5SOllivier Robert return 0; 267c0b746e5SOllivier Robert } 268c0b746e5SOllivier Robert if (items > 1) { 269c0b746e5SOllivier Robert (void) fprintf(fp, "Expected one item in response, got %d\n", 270c0b746e5SOllivier Robert items); 271c0b746e5SOllivier Robert return 0; 272c0b746e5SOllivier Robert } 273c0b746e5SOllivier Robert return 1; 274c0b746e5SOllivier Robert } 275c0b746e5SOllivier Robert 276c0b746e5SOllivier Robert 277c0b746e5SOllivier Robert 278c0b746e5SOllivier Robert /* 279c0b746e5SOllivier Robert * peerlist - get a short list of peers 280c0b746e5SOllivier Robert */ 281c0b746e5SOllivier Robert /*ARGSUSED*/ 282c0b746e5SOllivier Robert static void 283c0b746e5SOllivier Robert peerlist( 284c0b746e5SOllivier Robert struct parse *pcmd, 285c0b746e5SOllivier Robert FILE *fp 286c0b746e5SOllivier Robert ) 287c0b746e5SOllivier Robert { 288c0b746e5SOllivier Robert struct info_peer_list *plist; 2899c2daa00SOllivier Robert struct sockaddr_storage paddr; 290c0b746e5SOllivier Robert int items; 291c0b746e5SOllivier Robert int itemsize; 292c0b746e5SOllivier Robert int res; 293c0b746e5SOllivier Robert 2949c2daa00SOllivier Robert again: 2959c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items, 2969c2daa00SOllivier Robert &itemsize, (void *)&plist, 0, 2979c2daa00SOllivier Robert sizeof(struct info_peer_list)); 2989c2daa00SOllivier Robert 2999c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 3009c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 3019c2daa00SOllivier Robert goto again; 3029c2daa00SOllivier Robert } 303c0b746e5SOllivier Robert 304c0b746e5SOllivier Robert if (res != 0 && items == 0) 305c0b746e5SOllivier Robert return; 306c0b746e5SOllivier Robert 307c0b746e5SOllivier Robert if (!checkitems(items, fp)) 308c0b746e5SOllivier Robert return; 309c0b746e5SOllivier Robert 3109c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_list)) && 3119c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_list))) 312c0b746e5SOllivier Robert return; 313c0b746e5SOllivier Robert 314c0b746e5SOllivier Robert while (items > 0) { 3159c2daa00SOllivier Robert memset((char *)&paddr, 0, sizeof(paddr)); 3169c2daa00SOllivier Robert if (plist->v6_flag != 0) { 3179c2daa00SOllivier Robert GET_INADDR6(paddr) = plist->addr6; 3189c2daa00SOllivier Robert paddr.ss_family = AF_INET6; 3199c2daa00SOllivier Robert } else { 3209c2daa00SOllivier Robert GET_INADDR(paddr) = plist->addr; 3219c2daa00SOllivier Robert paddr.ss_family = AF_INET; 3229c2daa00SOllivier Robert } 3239c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 3249c2daa00SOllivier Robert paddr.ss_len = SOCKLEN(&paddr); 3259c2daa00SOllivier Robert #endif 3269c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 3279c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 3289c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 3299c2daa00SOllivier Robert (void) fprintf(fp, "%-9s %s\n", 3309c2daa00SOllivier Robert modetoa(plist->hmode), 3319c2daa00SOllivier Robert nntohost(&paddr)); 332c0b746e5SOllivier Robert plist++; 333c0b746e5SOllivier Robert items--; 334c0b746e5SOllivier Robert } 335c0b746e5SOllivier Robert } 336c0b746e5SOllivier Robert 337c0b746e5SOllivier Robert 338c0b746e5SOllivier Robert /* 339c0b746e5SOllivier Robert * peers - show peer summary 340c0b746e5SOllivier Robert */ 341c0b746e5SOllivier Robert static void 342c0b746e5SOllivier Robert peers( 343c0b746e5SOllivier Robert struct parse *pcmd, 344c0b746e5SOllivier Robert FILE *fp 345c0b746e5SOllivier Robert ) 346c0b746e5SOllivier Robert { 347c0b746e5SOllivier Robert dopeers(pcmd, fp, 0); 348c0b746e5SOllivier Robert } 349c0b746e5SOllivier Robert 350c0b746e5SOllivier Robert /* 351c0b746e5SOllivier Robert * dmpeers - show peer summary, Dave Mills style 352c0b746e5SOllivier Robert */ 353c0b746e5SOllivier Robert static void 354c0b746e5SOllivier Robert dmpeers( 355c0b746e5SOllivier Robert struct parse *pcmd, 356c0b746e5SOllivier Robert FILE *fp 357c0b746e5SOllivier Robert ) 358c0b746e5SOllivier Robert { 359c0b746e5SOllivier Robert dopeers(pcmd, fp, 1); 360c0b746e5SOllivier Robert } 361c0b746e5SOllivier Robert 362c0b746e5SOllivier Robert 363c0b746e5SOllivier Robert /* 364c0b746e5SOllivier Robert * peers - show peer summary 365c0b746e5SOllivier Robert */ 366c0b746e5SOllivier Robert /*ARGSUSED*/ 367c0b746e5SOllivier Robert static void 368c0b746e5SOllivier Robert dopeers( 369c0b746e5SOllivier Robert struct parse *pcmd, 370c0b746e5SOllivier Robert FILE *fp, 371c0b746e5SOllivier Robert int dmstyle 372c0b746e5SOllivier Robert ) 373c0b746e5SOllivier Robert { 374c0b746e5SOllivier Robert struct info_peer_summary *plist; 3759c2daa00SOllivier Robert struct sockaddr_storage dstadr; 3769c2daa00SOllivier Robert struct sockaddr_storage srcadr; 377c0b746e5SOllivier Robert int items; 378c0b746e5SOllivier Robert int itemsize; 379c0b746e5SOllivier Robert int ntp_poll; 380c0b746e5SOllivier Robert int res; 381c0b746e5SOllivier Robert int c; 382c0b746e5SOllivier Robert l_fp tempts; 383c0b746e5SOllivier Robert 3849c2daa00SOllivier Robert again: 3859c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL, 3869c2daa00SOllivier Robert &items, &itemsize, (void *)&plist, 0, 3879c2daa00SOllivier Robert sizeof(struct info_peer_summary)); 3889c2daa00SOllivier Robert 3899c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 3909c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 3919c2daa00SOllivier Robert goto again; 3929c2daa00SOllivier Robert } 393c0b746e5SOllivier Robert 394c0b746e5SOllivier Robert if (res != 0 && items == 0) 395c0b746e5SOllivier Robert return; 396c0b746e5SOllivier Robert 397c0b746e5SOllivier Robert if (!checkitems(items, fp)) 398c0b746e5SOllivier Robert return; 399c0b746e5SOllivier Robert 4009c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) && 4019c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_summary))) 402c0b746e5SOllivier Robert return; 403c0b746e5SOllivier Robert 404c0b746e5SOllivier Robert (void) fprintf(fp, 405c0b746e5SOllivier Robert " remote local st poll reach delay offset disp\n"); 406c0b746e5SOllivier Robert (void) fprintf(fp, 407c0b746e5SOllivier Robert "=======================================================================\n"); 408c0b746e5SOllivier Robert while (items > 0) { 409c0b746e5SOllivier Robert if (!dmstyle) { 410c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 411c0b746e5SOllivier Robert c = '*'; 412c0b746e5SOllivier Robert else if (plist->hmode == MODE_ACTIVE) 413c0b746e5SOllivier Robert c = '+'; 414c0b746e5SOllivier Robert else if (plist->hmode == MODE_PASSIVE) 415c0b746e5SOllivier Robert c = '-'; 416c0b746e5SOllivier Robert else if (plist->hmode == MODE_CLIENT) 417c0b746e5SOllivier Robert c = '='; 418c0b746e5SOllivier Robert else if (plist->hmode == MODE_BROADCAST) 419c0b746e5SOllivier Robert c = '^'; 420c0b746e5SOllivier Robert else if (plist->hmode == MODE_BCLIENT) 421c0b746e5SOllivier Robert c = '~'; 422c0b746e5SOllivier Robert else 423c0b746e5SOllivier Robert c = ' '; 424c0b746e5SOllivier Robert } else { 425c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 426c0b746e5SOllivier Robert c = '*'; 427c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SHORTLIST) 428c0b746e5SOllivier Robert c = '+'; 429c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SEL_CANDIDATE) 430c0b746e5SOllivier Robert c = '.'; 431c0b746e5SOllivier Robert else 432c0b746e5SOllivier Robert c = ' '; 433c0b746e5SOllivier Robert } 434c0b746e5SOllivier Robert NTOHL_FP(&(plist->offset), &tempts); 435c0b746e5SOllivier Robert ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL), 436c0b746e5SOllivier Robert NTP_MINPOLL); 4379c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 4389c2daa00SOllivier Robert memset((char *)&srcadr, 0, sizeof(srcadr)); 4399c2daa00SOllivier Robert if (plist->v6_flag != 0) { 4409c2daa00SOllivier Robert GET_INADDR6(dstadr) = plist->dstadr6; 4419c2daa00SOllivier Robert GET_INADDR6(srcadr) = plist->srcadr6; 4429c2daa00SOllivier Robert srcadr.ss_family = AF_INET6; 4439c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 4449c2daa00SOllivier Robert } else { 4459c2daa00SOllivier Robert GET_INADDR(dstadr) = plist->dstadr; 4469c2daa00SOllivier Robert GET_INADDR(srcadr) = plist->srcadr; 4479c2daa00SOllivier Robert srcadr.ss_family = AF_INET; 4489c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 4499c2daa00SOllivier Robert } 4509c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 4519c2daa00SOllivier Robert srcadr.ss_len = SOCKLEN(&srcadr); 4529c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 4539c2daa00SOllivier Robert #endif 4549c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 4559c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 4569c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 457c0b746e5SOllivier Robert (void) fprintf(fp, 458c0b746e5SOllivier Robert "%c%-15.15s %-15.15s %2d %4d %3o %7.7s %9.9s %7.7s\n", 4599c2daa00SOllivier Robert c, nntohost(&srcadr), stoa(&dstadr), 460c0b746e5SOllivier Robert plist->stratum, ntp_poll, plist->reach, 461c0b746e5SOllivier Robert fptoa(NTOHS_FP(plist->delay), 5), 462c0b746e5SOllivier Robert lfptoa(&tempts, 6), 463c0b746e5SOllivier Robert ufptoa(NTOHS_FP(plist->dispersion), 5)); 464c0b746e5SOllivier Robert plist++; 465c0b746e5SOllivier Robert items--; 466c0b746e5SOllivier Robert } 467c0b746e5SOllivier Robert } 468c0b746e5SOllivier Robert 469c0b746e5SOllivier Robert /* Convert a refid & stratum (in host order) to a string */ 470c0b746e5SOllivier Robert static char* 471c0b746e5SOllivier Robert refid_string( 472c0b746e5SOllivier Robert u_int32 refid, 473c0b746e5SOllivier Robert int stratum 474c0b746e5SOllivier Robert ) 475c0b746e5SOllivier Robert { 476c0b746e5SOllivier Robert if (stratum <= 1) { 477c0b746e5SOllivier Robert static char junk[5]; 478c0b746e5SOllivier Robert junk[4] = 0; 479c0b746e5SOllivier Robert memmove(junk, (char *)&refid, 4); 480c0b746e5SOllivier Robert return junk; 481c0b746e5SOllivier Robert } 482c0b746e5SOllivier Robert 483c0b746e5SOllivier Robert return numtoa(refid); 484c0b746e5SOllivier Robert } 485c0b746e5SOllivier Robert 486c0b746e5SOllivier Robert /* 487c0b746e5SOllivier Robert * printpeer - print detail information for a peer 488c0b746e5SOllivier Robert */ 489c0b746e5SOllivier Robert static void 490c0b746e5SOllivier Robert printpeer( 491c0b746e5SOllivier Robert register struct info_peer *pp, 492c0b746e5SOllivier Robert FILE *fp 493c0b746e5SOllivier Robert ) 494c0b746e5SOllivier Robert { 495c0b746e5SOllivier Robert register int i; 496c0b746e5SOllivier Robert const char *str; 497c0b746e5SOllivier Robert l_fp tempts; 4989c2daa00SOllivier Robert struct sockaddr_storage srcadr, dstadr; 499c0b746e5SOllivier Robert 5009c2daa00SOllivier Robert memset((char *)&srcadr, 0, sizeof(srcadr)); 5019c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 5029c2daa00SOllivier Robert if (pp->v6_flag != 0) { 5039c2daa00SOllivier Robert srcadr.ss_family = AF_INET6; 5049c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 5059c2daa00SOllivier Robert GET_INADDR6(srcadr) = pp->srcadr6; 5069c2daa00SOllivier Robert GET_INADDR6(dstadr) = pp->dstadr6; 5079c2daa00SOllivier Robert } else { 5089c2daa00SOllivier Robert srcadr.ss_family = AF_INET; 5099c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 5109c2daa00SOllivier Robert GET_INADDR(srcadr) = pp->srcadr; 5119c2daa00SOllivier Robert GET_INADDR(dstadr) = pp->dstadr; 5129c2daa00SOllivier Robert } 5139c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 5149c2daa00SOllivier Robert srcadr.ss_len = SOCKLEN(&srcadr); 5159c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 5169c2daa00SOllivier Robert #endif 517c0b746e5SOllivier Robert (void) fprintf(fp, "remote %s, local %s\n", 5189c2daa00SOllivier Robert stoa(&srcadr), stoa(&dstadr)); 519c0b746e5SOllivier Robert (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n", 520c0b746e5SOllivier Robert modetoa(pp->hmode), modetoa(pp->pmode), 521c0b746e5SOllivier Robert pp->stratum, pp->precision); 522c0b746e5SOllivier Robert 523c0b746e5SOllivier Robert (void) fprintf(fp, 524c0b746e5SOllivier Robert "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n", 525c0b746e5SOllivier Robert pp->leap & 0x2 ? '1' : '0', 526c0b746e5SOllivier Robert pp->leap & 0x1 ? '1' : '0', 527c0b746e5SOllivier Robert refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5), 528c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->rootdispersion), 5)); 529c0b746e5SOllivier Robert 530c0b746e5SOllivier Robert (void) fprintf(fp, 531c0b746e5SOllivier Robert "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n", 532c0b746e5SOllivier Robert pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd)); 533c0b746e5SOllivier Robert 534c0b746e5SOllivier Robert (void) fprintf(fp, 535224ba2bdSOllivier Robert "reach %03o, unreach %d, flash 0x%04x, ", 536224ba2bdSOllivier Robert pp->reach, pp->unreach, pp->flash2); 537c0b746e5SOllivier Robert 538c0b746e5SOllivier Robert (void) fprintf(fp, "boffset %s, ttl/mode %d\n", 539c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl); 540c0b746e5SOllivier Robert 541c0b746e5SOllivier Robert (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer)); 542c0b746e5SOllivier Robert if (pp->flags == 0) { 543c0b746e5SOllivier Robert (void) fprintf(fp, " none\n"); 544c0b746e5SOllivier Robert } else { 545c0b746e5SOllivier Robert str = ""; 546c0b746e5SOllivier Robert if (pp->flags & INFO_FLAG_SYSPEER) { 547c0b746e5SOllivier Robert (void) fprintf(fp, " system_peer"); 548c0b746e5SOllivier Robert str = ","; 549c0b746e5SOllivier Robert } 550c0b746e5SOllivier Robert if (pp->flags & INFO_FLAG_CONFIG) { 551c0b746e5SOllivier Robert (void) fprintf(fp, "%s config", str); 552c0b746e5SOllivier Robert str = ","; 553c0b746e5SOllivier Robert } 554c0b746e5SOllivier Robert if (pp->flags & INFO_FLAG_REFCLOCK) { 555c0b746e5SOllivier Robert (void) fprintf(fp, "%s refclock", str); 556c0b746e5SOllivier Robert str = ","; 557c0b746e5SOllivier Robert } 558c0b746e5SOllivier Robert if (pp->flags & INFO_FLAG_AUTHENABLE) { 559c0b746e5SOllivier Robert (void) fprintf(fp, "%s auth", str); 560c0b746e5SOllivier Robert str = ","; 561c0b746e5SOllivier Robert } 562c0b746e5SOllivier Robert if (pp->flags & INFO_FLAG_BCLIENT) { 563c0b746e5SOllivier Robert (void) fprintf(fp, "%s bclient", str); 564c0b746e5SOllivier Robert str = ","; 565c0b746e5SOllivier Robert } 566c0b746e5SOllivier Robert if (pp->flags & INFO_FLAG_PREFER) { 567c0b746e5SOllivier Robert (void) fprintf(fp, "%s prefer", str); 568c0b746e5SOllivier Robert str = ","; 569c0b746e5SOllivier Robert } 570c0b746e5SOllivier Robert if (pp->flags & INFO_FLAG_BURST) { 571c0b746e5SOllivier Robert (void) fprintf(fp, "%s burst", str); 572c0b746e5SOllivier Robert } 573c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 574c0b746e5SOllivier Robert } 575c0b746e5SOllivier Robert 576c0b746e5SOllivier Robert NTOHL_FP(&pp->reftime, &tempts); 577c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", 578c0b746e5SOllivier Robert prettydate(&tempts)); 579c0b746e5SOllivier Robert NTOHL_FP(&pp->org, &tempts); 580c0b746e5SOllivier Robert (void) fprintf(fp, "originate timestamp: %s\n", 581c0b746e5SOllivier Robert prettydate(&tempts)); 582c0b746e5SOllivier Robert NTOHL_FP(&pp->rec, &tempts); 583c0b746e5SOllivier Robert (void) fprintf(fp, "receive timestamp: %s\n", 584c0b746e5SOllivier Robert prettydate(&tempts)); 585c0b746e5SOllivier Robert NTOHL_FP(&pp->xmt, &tempts); 586c0b746e5SOllivier Robert (void) fprintf(fp, "transmit timestamp: %s\n", 587c0b746e5SOllivier Robert prettydate(&tempts)); 588c0b746e5SOllivier Robert 589c0b746e5SOllivier Robert (void) fprintf(fp, "filter delay: "); 590c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 591c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", 592c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->filtdelay[i]), 5)); 593c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 594c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 595c0b746e5SOllivier Robert } 596c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 597c0b746e5SOllivier Robert 598c0b746e5SOllivier Robert (void) fprintf(fp, "filter offset:"); 599c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 600c0b746e5SOllivier Robert NTOHL_FP(&pp->filtoffset[i], &tempts); 601c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6)); 602c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 603c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 604c0b746e5SOllivier Robert } 605c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 606c0b746e5SOllivier Robert 607c0b746e5SOllivier Robert (void) fprintf(fp, "filter order: "); 608c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 609c0b746e5SOllivier Robert (void) fprintf(fp, " %-8d", pp->order[i]); 610c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 611c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 612c0b746e5SOllivier Robert } 613c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 614c0b746e5SOllivier Robert 615c0b746e5SOllivier Robert 616c0b746e5SOllivier Robert NTOHL_FP(&pp->offset, &tempts); 617c0b746e5SOllivier Robert (void) fprintf(fp, 618c0b746e5SOllivier Robert "offset %s, delay %s, error bound %s, filter error %s\n", 619c0b746e5SOllivier Robert lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5), 620c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->dispersion), 5), 621c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->selectdisp), 5)); 622c0b746e5SOllivier Robert } 623c0b746e5SOllivier Robert 624c0b746e5SOllivier Robert 625c0b746e5SOllivier Robert /* 626c0b746e5SOllivier Robert * showpeer - show detailed information for a peer 627c0b746e5SOllivier Robert */ 628c0b746e5SOllivier Robert static void 629c0b746e5SOllivier Robert showpeer( 630c0b746e5SOllivier Robert struct parse *pcmd, 631c0b746e5SOllivier Robert FILE *fp 632c0b746e5SOllivier Robert ) 633c0b746e5SOllivier Robert { 634c0b746e5SOllivier Robert struct info_peer *pp; 635c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 6369c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 637c0b746e5SOllivier Robert int qitems; 638c0b746e5SOllivier Robert int items; 639c0b746e5SOllivier Robert int itemsize; 640c0b746e5SOllivier Robert int res; 6419c2daa00SOllivier Robert int sendsize; 642c0b746e5SOllivier Robert 6439c2daa00SOllivier Robert again: 6449c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 6459c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 6469c2daa00SOllivier Robert else 6479c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 6489c2daa00SOllivier Robert 6499c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 4); qitems++) { 6509c2daa00SOllivier Robert if (pcmd->argval[qitems].netnum.ss_family == AF_INET) { 6519c2daa00SOllivier Robert pl->addr = GET_INADDR(pcmd->argval[qitems].netnum); 6529c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 6539c2daa00SOllivier Robert pl->v6_flag = 0; 6549c2daa00SOllivier Robert } else { 6559c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 6569c2daa00SOllivier Robert fprintf(stderr, 6579c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 6589c2daa00SOllivier Robert return; 6599c2daa00SOllivier Robert } 6609c2daa00SOllivier Robert pl->addr6 = GET_INADDR6(pcmd->argval[qitems].netnum); 6619c2daa00SOllivier Robert pl->v6_flag = 1; 6629c2daa00SOllivier Robert } 6639c2daa00SOllivier Robert pl->port = (u_short)s_port; 6649c2daa00SOllivier Robert pl->hmode = pl->flags = 0; 6659c2daa00SOllivier Robert pl = (struct info_peer_list *)((char *)pl + sendsize); 666c0b746e5SOllivier Robert } 667c0b746e5SOllivier Robert 6689c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems, 6699c2daa00SOllivier Robert sendsize, (char *)plist, &items, 6709c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, sizeof(struct info_peer)); 6719c2daa00SOllivier Robert 6729c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 6739c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 6749c2daa00SOllivier Robert goto again; 6759c2daa00SOllivier Robert } 676c0b746e5SOllivier Robert 677c0b746e5SOllivier Robert if (res != 0 && items == 0) 678c0b746e5SOllivier Robert return; 679c0b746e5SOllivier Robert 680c0b746e5SOllivier Robert if (!checkitems(items, fp)) 681c0b746e5SOllivier Robert return; 682c0b746e5SOllivier Robert 6839c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer)) && 6849c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer))) 685c0b746e5SOllivier Robert return; 686c0b746e5SOllivier Robert 687c0b746e5SOllivier Robert while (items-- > 0) { 688c0b746e5SOllivier Robert printpeer(pp, fp); 689c0b746e5SOllivier Robert if (items > 0) 690c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 691c0b746e5SOllivier Robert pp++; 692c0b746e5SOllivier Robert } 693c0b746e5SOllivier Robert } 694c0b746e5SOllivier Robert 695c0b746e5SOllivier Robert 696c0b746e5SOllivier Robert /* 697c0b746e5SOllivier Robert * peerstats - return statistics for a peer 698c0b746e5SOllivier Robert */ 699c0b746e5SOllivier Robert static void 700c0b746e5SOllivier Robert peerstats( 701c0b746e5SOllivier Robert struct parse *pcmd, 702c0b746e5SOllivier Robert FILE *fp 703c0b746e5SOllivier Robert ) 704c0b746e5SOllivier Robert { 705c0b746e5SOllivier Robert struct info_peer_stats *pp; 706c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 7079c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 7089c2daa00SOllivier Robert struct sockaddr_storage src, dst; 709c0b746e5SOllivier Robert int qitems; 710c0b746e5SOllivier Robert int items; 711c0b746e5SOllivier Robert int itemsize; 712c0b746e5SOllivier Robert int res; 7139c2daa00SOllivier Robert int sendsize; 714c0b746e5SOllivier Robert 7159c2daa00SOllivier Robert again: 7169c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7179c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 7189c2daa00SOllivier Robert else 7199c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 7209c2daa00SOllivier Robert 7219c2daa00SOllivier Robert memset((char *)plist, 0, sizeof(struct info_peer_list) * min(MAXARGS, 4)); 7229c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 4); qitems++) { 7239c2daa00SOllivier Robert if (pcmd->argval[qitems].netnum.ss_family == AF_INET) { 7249c2daa00SOllivier Robert pl->addr = GET_INADDR(pcmd->argval[qitems].netnum); 7259c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7269c2daa00SOllivier Robert pl->v6_flag = 0; 7279c2daa00SOllivier Robert } else { 7289c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 7299c2daa00SOllivier Robert fprintf(stderr, 7309c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 7319c2daa00SOllivier Robert return; 7329c2daa00SOllivier Robert } 7339c2daa00SOllivier Robert pl->addr6 = GET_INADDR6(pcmd->argval[qitems].netnum); 7349c2daa00SOllivier Robert pl->v6_flag = 1; 7359c2daa00SOllivier Robert } 7369c2daa00SOllivier Robert pl->port = (u_short)s_port; 7379c2daa00SOllivier Robert pl->hmode = plist[qitems].flags = 0; 7389c2daa00SOllivier Robert pl = (struct info_peer_list *)((char *)pl + sendsize); 739c0b746e5SOllivier Robert } 740c0b746e5SOllivier Robert 7419c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems, 7429c2daa00SOllivier Robert sendsize, (char *)plist, &items, 7439c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, 7449c2daa00SOllivier Robert sizeof(struct info_peer_stats)); 7459c2daa00SOllivier Robert 7469c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 7479c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 7489c2daa00SOllivier Robert goto again; 7499c2daa00SOllivier Robert } 750c0b746e5SOllivier Robert 751c0b746e5SOllivier Robert if (res != 0 && items == 0) 752c0b746e5SOllivier Robert return; 753c0b746e5SOllivier Robert 754c0b746e5SOllivier Robert if (!checkitems(items, fp)) 755c0b746e5SOllivier Robert return; 756c0b746e5SOllivier Robert 7579c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) && 7589c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_stats))) 759c0b746e5SOllivier Robert return; 760c0b746e5SOllivier Robert 761c0b746e5SOllivier Robert while (items-- > 0) { 7629c2daa00SOllivier Robert memset((char *)&src, 0, sizeof(src)); 7639c2daa00SOllivier Robert memset((char *)&dst, 0, sizeof(dst)); 7649c2daa00SOllivier Robert if (pp->v6_flag != 0) { 7659c2daa00SOllivier Robert GET_INADDR6(src) = pp->srcadr6; 7669c2daa00SOllivier Robert GET_INADDR6(dst) = pp->dstadr6; 7679c2daa00SOllivier Robert src.ss_family = AF_INET6; 7689c2daa00SOllivier Robert dst.ss_family = AF_INET6; 7699c2daa00SOllivier Robert } else { 7709c2daa00SOllivier Robert GET_INADDR(src) = pp->srcadr; 7719c2daa00SOllivier Robert GET_INADDR(dst) = pp->dstadr; 7729c2daa00SOllivier Robert src.ss_family = AF_INET; 7739c2daa00SOllivier Robert dst.ss_family = AF_INET; 7749c2daa00SOllivier Robert } 7759c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 7769c2daa00SOllivier Robert src.ss_len = SOCKLEN(&src); 7779c2daa00SOllivier Robert dst.ss_len = SOCKLEN(&dst); 7789c2daa00SOllivier Robert #endif 779c0b746e5SOllivier Robert (void) fprintf(fp, "remote host: %s\n", 7809c2daa00SOllivier Robert nntohost(&src)); 781c0b746e5SOllivier Robert (void) fprintf(fp, "local interface: %s\n", 7829c2daa00SOllivier Robert stoa(&dst)); 783c0b746e5SOllivier Robert (void) fprintf(fp, "time last received: %lds\n", 784c0b746e5SOllivier Robert (long)ntohl(pp->timereceived)); 785c0b746e5SOllivier Robert (void) fprintf(fp, "time until next send: %lds\n", 786c0b746e5SOllivier Robert (long)ntohl(pp->timetosend)); 787c0b746e5SOllivier Robert (void) fprintf(fp, "reachability change: %lds\n", 788c0b746e5SOllivier Robert (long)ntohl(pp->timereachable)); 789c0b746e5SOllivier Robert (void) fprintf(fp, "packets sent: %ld\n", 790c0b746e5SOllivier Robert (long)ntohl(pp->sent)); 791c0b746e5SOllivier Robert (void) fprintf(fp, "packets received: %ld\n", 792c0b746e5SOllivier Robert (long)ntohl(pp->processed)); 793c0b746e5SOllivier Robert (void) fprintf(fp, "bad authentication: %ld\n", 794c0b746e5SOllivier Robert (long)ntohl(pp->badauth)); 795c0b746e5SOllivier Robert (void) fprintf(fp, "bogus origin: %ld\n", 796c0b746e5SOllivier Robert (long)ntohl(pp->bogusorg)); 797c0b746e5SOllivier Robert (void) fprintf(fp, "duplicate: %ld\n", 798c0b746e5SOllivier Robert (long)ntohl(pp->oldpkt)); 799c0b746e5SOllivier Robert (void) fprintf(fp, "bad dispersion: %ld\n", 800c0b746e5SOllivier Robert (long)ntohl(pp->seldisp)); 801c0b746e5SOllivier Robert (void) fprintf(fp, "bad reference time: %ld\n", 802c0b746e5SOllivier Robert (long)ntohl(pp->selbroken)); 803c0b746e5SOllivier Robert (void) fprintf(fp, "candidate order: %d\n", 804c0b746e5SOllivier Robert (int)pp->candidate); 805c0b746e5SOllivier Robert if (items > 0) 806c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 807c0b746e5SOllivier Robert pp++; 808c0b746e5SOllivier Robert } 809c0b746e5SOllivier Robert } 810c0b746e5SOllivier Robert 811c0b746e5SOllivier Robert 812c0b746e5SOllivier Robert /* 813c0b746e5SOllivier Robert * loopinfo - show loop filter information 814c0b746e5SOllivier Robert */ 815c0b746e5SOllivier Robert static void 816c0b746e5SOllivier Robert loopinfo( 817c0b746e5SOllivier Robert struct parse *pcmd, 818c0b746e5SOllivier Robert FILE *fp 819c0b746e5SOllivier Robert ) 820c0b746e5SOllivier Robert { 821c0b746e5SOllivier Robert struct info_loop *il; 822c0b746e5SOllivier Robert int items; 823c0b746e5SOllivier Robert int itemsize; 824c0b746e5SOllivier Robert int oneline = 0; 825c0b746e5SOllivier Robert int res; 826c0b746e5SOllivier Robert l_fp tempts; 827c0b746e5SOllivier Robert 828c0b746e5SOllivier Robert if (pcmd->nargs > 0) { 829c0b746e5SOllivier Robert if (STREQ(pcmd->argval[0].string, "oneline")) 830c0b746e5SOllivier Robert oneline = 1; 831c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[0].string, "multiline")) 832c0b746e5SOllivier Robert oneline = 0; 833c0b746e5SOllivier Robert else { 834c0b746e5SOllivier Robert (void) fprintf(stderr, "How many lines?\n"); 835c0b746e5SOllivier Robert return; 836c0b746e5SOllivier Robert } 837c0b746e5SOllivier Robert } 838c0b746e5SOllivier Robert 8399c2daa00SOllivier Robert again: 8409c2daa00SOllivier Robert res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL, 8419c2daa00SOllivier Robert &items, &itemsize, (void *)&il, 0, 8429c2daa00SOllivier Robert sizeof(struct info_loop)); 8439c2daa00SOllivier Robert 8449c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 8459c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 8469c2daa00SOllivier Robert goto again; 8479c2daa00SOllivier Robert } 848c0b746e5SOllivier Robert 849c0b746e5SOllivier Robert if (res != 0 && items == 0) 850c0b746e5SOllivier Robert return; 851c0b746e5SOllivier Robert 852c0b746e5SOllivier Robert if (!check1item(items, fp)) 853c0b746e5SOllivier Robert return; 854c0b746e5SOllivier Robert 855c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_loop))) 856c0b746e5SOllivier Robert return; 857c0b746e5SOllivier Robert 858c0b746e5SOllivier Robert if (oneline) { 859c0b746e5SOllivier Robert l_fp temp2ts; 860c0b746e5SOllivier Robert 861c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 862c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &temp2ts); 863c0b746e5SOllivier Robert 864c0b746e5SOllivier Robert (void) fprintf(fp, 865c0b746e5SOllivier Robert "offset %s, frequency %s, time_const %ld, watchdog %ld\n", 866c0b746e5SOllivier Robert lfptoa(&tempts, 6), 867c0b746e5SOllivier Robert lfptoa(&temp2ts, 3), 868c0b746e5SOllivier Robert (u_long)ntohl(il->compliance), 869c0b746e5SOllivier Robert (u_long)ntohl(il->watchdog_timer)); 870c0b746e5SOllivier Robert } else { 871c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 872c0b746e5SOllivier Robert (void) fprintf(fp, "offset: %s s\n", 873c0b746e5SOllivier Robert lfptoa(&tempts, 6)); 874c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &tempts); 875c0b746e5SOllivier Robert (void) fprintf(fp, "frequency: %s ppm\n", 876c0b746e5SOllivier Robert lfptoa(&tempts, 3)); 877c0b746e5SOllivier Robert (void) fprintf(fp, "poll adjust: %ld\n", 878c0b746e5SOllivier Robert (u_long)ntohl(il->compliance)); 879c0b746e5SOllivier Robert (void) fprintf(fp, "watchdog timer: %ld s\n", 880c0b746e5SOllivier Robert (u_long)ntohl(il->watchdog_timer)); 881c0b746e5SOllivier Robert } 882c0b746e5SOllivier Robert } 883c0b746e5SOllivier Robert 884c0b746e5SOllivier Robert 885c0b746e5SOllivier Robert /* 886c0b746e5SOllivier Robert * sysinfo - show current system state 887c0b746e5SOllivier Robert */ 888c0b746e5SOllivier Robert /*ARGSUSED*/ 889c0b746e5SOllivier Robert static void 890c0b746e5SOllivier Robert sysinfo( 891c0b746e5SOllivier Robert struct parse *pcmd, 892c0b746e5SOllivier Robert FILE *fp 893c0b746e5SOllivier Robert ) 894c0b746e5SOllivier Robert { 895c0b746e5SOllivier Robert struct info_sys *is; 8969c2daa00SOllivier Robert struct sockaddr_storage peeraddr; 897c0b746e5SOllivier Robert int items; 898c0b746e5SOllivier Robert int itemsize; 899c0b746e5SOllivier Robert int res; 900c0b746e5SOllivier Robert l_fp tempts; 901c0b746e5SOllivier Robert 9029c2daa00SOllivier Robert again: 9039c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL, 9049c2daa00SOllivier Robert &items, &itemsize, (void *)&is, 0, 9059c2daa00SOllivier Robert sizeof(struct info_sys)); 9069c2daa00SOllivier Robert 9079c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 9089c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 9099c2daa00SOllivier Robert goto again; 9109c2daa00SOllivier Robert } 911c0b746e5SOllivier Robert 912c0b746e5SOllivier Robert if (res != 0 && items == 0) 913c0b746e5SOllivier Robert return; 914c0b746e5SOllivier Robert 915c0b746e5SOllivier Robert if (!check1item(items, fp)) 916c0b746e5SOllivier Robert return; 917c0b746e5SOllivier Robert 9189c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_sys)) && 9199c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_sys))) 920c0b746e5SOllivier Robert return; 921c0b746e5SOllivier Robert 9229c2daa00SOllivier Robert memset((char *)&peeraddr, 0, sizeof(peeraddr)); 9239c2daa00SOllivier Robert if (is->v6_flag != 0) { 9249c2daa00SOllivier Robert GET_INADDR6(peeraddr) = is->peer6; 9259c2daa00SOllivier Robert peeraddr.ss_family = AF_INET6; 9269c2daa00SOllivier Robert } else { 9279c2daa00SOllivier Robert GET_INADDR(peeraddr) = is->peer; 9289c2daa00SOllivier Robert peeraddr.ss_family = AF_INET; 9299c2daa00SOllivier Robert } 9309c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 9319c2daa00SOllivier Robert peeraddr.ss_len = SOCKLEN(&peeraddr); 9329c2daa00SOllivier Robert #endif 9339c2daa00SOllivier Robert (void) fprintf(fp, "system peer: %s\n", nntohost(&peeraddr)); 934c0b746e5SOllivier Robert (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode)); 935c0b746e5SOllivier Robert (void) fprintf(fp, "leap indicator: %c%c\n", 936c0b746e5SOllivier Robert is->leap & 0x2 ? '1' : '0', 937c0b746e5SOllivier Robert is->leap & 0x1 ? '1' : '0'); 938c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %d\n", (int)is->stratum); 939c0b746e5SOllivier Robert (void) fprintf(fp, "precision: %d\n", (int)is->precision); 940c0b746e5SOllivier Robert (void) fprintf(fp, "root distance: %s s\n", 941c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->rootdelay), 5)); 942c0b746e5SOllivier Robert (void) fprintf(fp, "root dispersion: %s s\n", 943c0b746e5SOllivier Robert ufptoa(NTOHS_FP(is->rootdispersion), 5)); 944c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: [%s]\n", 945c0b746e5SOllivier Robert refid_string(is->refid, is->stratum)); 946c0b746e5SOllivier Robert NTOHL_FP(&is->reftime, &tempts); 947c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts)); 948c0b746e5SOllivier Robert 949c0b746e5SOllivier Robert (void) fprintf(fp, "system flags: "); 950c0b746e5SOllivier Robert if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE | 951ce265a54SOllivier Robert INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL | 952c0b746e5SOllivier Robert INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) { 953c0b746e5SOllivier Robert (void) fprintf(fp, "none\n"); 954c0b746e5SOllivier Robert } else { 955c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_BCLIENT) 956c0b746e5SOllivier Robert (void) fprintf(fp, "bclient "); 957c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_AUTHENTICATE) 958c0b746e5SOllivier Robert (void) fprintf(fp, "auth "); 959c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_MONITOR) 960c0b746e5SOllivier Robert (void) fprintf(fp, "monitor "); 961c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_NTP) 962c0b746e5SOllivier Robert (void) fprintf(fp, "ntp "); 963c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_KERNEL) 964c0b746e5SOllivier Robert (void) fprintf(fp, "kernel "); 965c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_FILEGEN) 966c0b746e5SOllivier Robert (void) fprintf(fp, "stats "); 967ce265a54SOllivier Robert if (is->flags & INFO_FLAG_CAL) 968ce265a54SOllivier Robert (void) fprintf(fp, "calibrate "); 969c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_PPS_SYNC) 970ce265a54SOllivier Robert (void) fprintf(fp, "pps "); 971c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 972c0b746e5SOllivier Robert } 973c0b746e5SOllivier Robert (void) fprintf(fp, "jitter: %s s\n", 974c0b746e5SOllivier Robert fptoa(ntohl(is->frequency), 6)); 975c0b746e5SOllivier Robert (void) fprintf(fp, "stability: %s ppm\n", 976c0b746e5SOllivier Robert ufptoa(ntohl(is->stability), 3)); 977c0b746e5SOllivier Robert (void) fprintf(fp, "broadcastdelay: %s s\n", 978c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->bdelay), 6)); 979c0b746e5SOllivier Robert NTOHL_FP(&is->authdelay, &tempts); 980c0b746e5SOllivier Robert (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6)); 981c0b746e5SOllivier Robert } 982c0b746e5SOllivier Robert 983c0b746e5SOllivier Robert 984c0b746e5SOllivier Robert /* 985c0b746e5SOllivier Robert * sysstats - print system statistics 986c0b746e5SOllivier Robert */ 987c0b746e5SOllivier Robert /*ARGSUSED*/ 988c0b746e5SOllivier Robert static void 989c0b746e5SOllivier Robert sysstats( 990c0b746e5SOllivier Robert struct parse *pcmd, 991c0b746e5SOllivier Robert FILE *fp 992c0b746e5SOllivier Robert ) 993c0b746e5SOllivier Robert { 994c0b746e5SOllivier Robert struct info_sys_stats *ss; 995c0b746e5SOllivier Robert int items; 996c0b746e5SOllivier Robert int itemsize; 997c0b746e5SOllivier Robert int res; 998c0b746e5SOllivier Robert 9999c2daa00SOllivier Robert again: 10009c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL, 10019c2daa00SOllivier Robert &items, &itemsize, (void *)&ss, 0, 10029c2daa00SOllivier Robert sizeof(struct info_sys_stats)); 10039c2daa00SOllivier Robert 10049c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 10059c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 10069c2daa00SOllivier Robert goto again; 10079c2daa00SOllivier Robert } 1008c0b746e5SOllivier Robert 1009c0b746e5SOllivier Robert if (res != 0 && items == 0) 1010c0b746e5SOllivier Robert return; 1011c0b746e5SOllivier Robert 1012c0b746e5SOllivier Robert if (!check1item(items, fp)) 1013c0b746e5SOllivier Robert return; 1014c0b746e5SOllivier Robert 1015c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats) && 1016c0b746e5SOllivier Robert itemsize != sizeof(struct old_info_sys_stats)) { 1017c0b746e5SOllivier Robert /* issue warning according to new structure size */ 1018c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_sys_stats)); 1019c0b746e5SOllivier Robert return; 1020c0b746e5SOllivier Robert } 10219c2daa00SOllivier Robert fprintf(fp, "time since restart: %ld\n", 1022c0b746e5SOllivier Robert (u_long)ntohl(ss->timeup)); 10239c2daa00SOllivier Robert fprintf(fp, "time since reset: %ld\n", 1024c0b746e5SOllivier Robert (u_long)ntohl(ss->timereset)); 10259c2daa00SOllivier Robert fprintf(fp, "packets received: %ld\n", 10269c2daa00SOllivier Robert (u_long)ntohl(ss->received)); 10279c2daa00SOllivier Robert fprintf(fp, "packets processed: %ld\n", 1028c0b746e5SOllivier Robert (u_long)ntohl(ss->processed)); 10299c2daa00SOllivier Robert fprintf(fp, "current version: %ld\n", 10309c2daa00SOllivier Robert (u_long)ntohl(ss->newversionpkt)); 10319c2daa00SOllivier Robert fprintf(fp, "previous version: %ld\n", 10329c2daa00SOllivier Robert (u_long)ntohl(ss->oldversionpkt)); 10339c2daa00SOllivier Robert fprintf(fp, "bad version: %ld\n", 10349c2daa00SOllivier Robert (u_long)ntohl(ss->unknownversion)); 10359c2daa00SOllivier Robert fprintf(fp, "access denied: %ld\n", 10369c2daa00SOllivier Robert (u_long)ntohl(ss->denied)); 10379c2daa00SOllivier Robert fprintf(fp, "bad length or format: %ld\n", 10389c2daa00SOllivier Robert (u_long)ntohl(ss->badlength)); 10399c2daa00SOllivier Robert fprintf(fp, "bad authentication: %ld\n", 1040c0b746e5SOllivier Robert (u_long)ntohl(ss->badauth)); 1041c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats)) 1042c0b746e5SOllivier Robert return; 1043c0b746e5SOllivier Robert 10449c2daa00SOllivier Robert fprintf(fp, "rate exceeded: %ld\n", 1045c0b746e5SOllivier Robert (u_long)ntohl(ss->limitrejected)); 1046c0b746e5SOllivier Robert } 1047c0b746e5SOllivier Robert 1048c0b746e5SOllivier Robert 1049c0b746e5SOllivier Robert 1050c0b746e5SOllivier Robert /* 1051c0b746e5SOllivier Robert * iostats - print I/O statistics 1052c0b746e5SOllivier Robert */ 1053c0b746e5SOllivier Robert /*ARGSUSED*/ 1054c0b746e5SOllivier Robert static void 1055c0b746e5SOllivier Robert iostats( 1056c0b746e5SOllivier Robert struct parse *pcmd, 1057c0b746e5SOllivier Robert FILE *fp 1058c0b746e5SOllivier Robert ) 1059c0b746e5SOllivier Robert { 1060c0b746e5SOllivier Robert struct info_io_stats *io; 1061c0b746e5SOllivier Robert int items; 1062c0b746e5SOllivier Robert int itemsize; 1063c0b746e5SOllivier Robert int res; 1064c0b746e5SOllivier Robert 10659c2daa00SOllivier Robert again: 10669c2daa00SOllivier Robert res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, (char *)NULL, 10679c2daa00SOllivier Robert &items, &itemsize, (void *)&io, 0, 10689c2daa00SOllivier Robert sizeof(struct info_io_stats)); 10699c2daa00SOllivier Robert 10709c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 10719c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 10729c2daa00SOllivier Robert goto again; 10739c2daa00SOllivier Robert } 1074c0b746e5SOllivier Robert 1075c0b746e5SOllivier Robert if (res != 0 && items == 0) 1076c0b746e5SOllivier Robert return; 1077c0b746e5SOllivier Robert 1078c0b746e5SOllivier Robert if (!check1item(items, fp)) 1079c0b746e5SOllivier Robert return; 1080c0b746e5SOllivier Robert 1081c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_io_stats))) 1082c0b746e5SOllivier Robert return; 1083c0b746e5SOllivier Robert 1084c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 1085c0b746e5SOllivier Robert (u_long)ntohl(io->timereset)); 1086c0b746e5SOllivier Robert (void) fprintf(fp, "receive buffers: %d\n", 1087c0b746e5SOllivier Robert ntohs(io->totalrecvbufs)); 1088c0b746e5SOllivier Robert (void) fprintf(fp, "free receive buffers: %d\n", 1089c0b746e5SOllivier Robert ntohs(io->freerecvbufs)); 1090c0b746e5SOllivier Robert (void) fprintf(fp, "used receive buffers: %d\n", 1091c0b746e5SOllivier Robert ntohs(io->fullrecvbufs)); 1092c0b746e5SOllivier Robert (void) fprintf(fp, "low water refills: %d\n", 1093c0b746e5SOllivier Robert ntohs(io->lowwater)); 1094c0b746e5SOllivier Robert (void) fprintf(fp, "dropped packets: %ld\n", 1095c0b746e5SOllivier Robert (u_long)ntohl(io->dropped)); 1096c0b746e5SOllivier Robert (void) fprintf(fp, "ignored packets: %ld\n", 1097c0b746e5SOllivier Robert (u_long)ntohl(io->ignored)); 1098c0b746e5SOllivier Robert (void) fprintf(fp, "received packets: %ld\n", 1099c0b746e5SOllivier Robert (u_long)ntohl(io->received)); 1100c0b746e5SOllivier Robert (void) fprintf(fp, "packets sent: %ld\n", 1101c0b746e5SOllivier Robert (u_long)ntohl(io->sent)); 1102c0b746e5SOllivier Robert (void) fprintf(fp, "packets not sent: %ld\n", 1103c0b746e5SOllivier Robert (u_long)ntohl(io->notsent)); 1104c0b746e5SOllivier Robert (void) fprintf(fp, "interrupts handled: %ld\n", 1105c0b746e5SOllivier Robert (u_long)ntohl(io->interrupts)); 1106c0b746e5SOllivier Robert (void) fprintf(fp, "received by int: %ld\n", 1107c0b746e5SOllivier Robert (u_long)ntohl(io->int_received)); 1108c0b746e5SOllivier Robert } 1109c0b746e5SOllivier Robert 1110c0b746e5SOllivier Robert 1111c0b746e5SOllivier Robert /* 1112c0b746e5SOllivier Robert * memstats - print peer memory statistics 1113c0b746e5SOllivier Robert */ 1114c0b746e5SOllivier Robert /*ARGSUSED*/ 1115c0b746e5SOllivier Robert static void 1116c0b746e5SOllivier Robert memstats( 1117c0b746e5SOllivier Robert struct parse *pcmd, 1118c0b746e5SOllivier Robert FILE *fp 1119c0b746e5SOllivier Robert ) 1120c0b746e5SOllivier Robert { 1121c0b746e5SOllivier Robert struct info_mem_stats *mem; 1122c0b746e5SOllivier Robert int i; 1123c0b746e5SOllivier Robert int items; 1124c0b746e5SOllivier Robert int itemsize; 1125c0b746e5SOllivier Robert int res; 1126c0b746e5SOllivier Robert 11279c2daa00SOllivier Robert again: 11289c2daa00SOllivier Robert res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, (char *)NULL, 11299c2daa00SOllivier Robert &items, &itemsize, (void *)&mem, 0, 11309c2daa00SOllivier Robert sizeof(struct info_mem_stats)); 11319c2daa00SOllivier Robert 11329c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 11339c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 11349c2daa00SOllivier Robert goto again; 11359c2daa00SOllivier Robert } 1136c0b746e5SOllivier Robert 1137c0b746e5SOllivier Robert if (res != 0 && items == 0) 1138c0b746e5SOllivier Robert return; 1139c0b746e5SOllivier Robert 1140c0b746e5SOllivier Robert if (!check1item(items, fp)) 1141c0b746e5SOllivier Robert return; 1142c0b746e5SOllivier Robert 1143c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_mem_stats))) 1144c0b746e5SOllivier Robert return; 1145c0b746e5SOllivier Robert 1146c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 1147c0b746e5SOllivier Robert (u_long)ntohl(mem->timereset)); 1148c0b746e5SOllivier Robert (void) fprintf(fp, "total peer memory: %d\n", 1149c0b746e5SOllivier Robert ntohs(mem->totalpeermem)); 1150c0b746e5SOllivier Robert (void) fprintf(fp, "free peer memory: %d\n", 1151c0b746e5SOllivier Robert ntohs(mem->freepeermem)); 1152c0b746e5SOllivier Robert (void) fprintf(fp, "calls to findpeer: %ld\n", 1153c0b746e5SOllivier Robert (u_long)ntohl(mem->findpeer_calls)); 1154c0b746e5SOllivier Robert (void) fprintf(fp, "new peer allocations: %ld\n", 1155c0b746e5SOllivier Robert (u_long)ntohl(mem->allocations)); 1156c0b746e5SOllivier Robert (void) fprintf(fp, "peer demobilizations: %ld\n", 1157c0b746e5SOllivier Robert (u_long)ntohl(mem->demobilizations)); 1158c0b746e5SOllivier Robert 1159c0b746e5SOllivier Robert (void) fprintf(fp, "hash table counts: "); 1160c0b746e5SOllivier Robert for (i = 0; i < HASH_SIZE; i++) { 1161c0b746e5SOllivier Robert (void) fprintf(fp, "%4d", (int)mem->hashcount[i]); 1162c0b746e5SOllivier Robert if ((i % 8) == 7 && i != (HASH_SIZE-1)) { 1163c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 1164c0b746e5SOllivier Robert } 1165c0b746e5SOllivier Robert } 1166c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 1167c0b746e5SOllivier Robert } 1168c0b746e5SOllivier Robert 1169c0b746e5SOllivier Robert 1170c0b746e5SOllivier Robert 1171c0b746e5SOllivier Robert /* 1172c0b746e5SOllivier Robert * timerstats - print timer statistics 1173c0b746e5SOllivier Robert */ 1174c0b746e5SOllivier Robert /*ARGSUSED*/ 1175c0b746e5SOllivier Robert static void 1176c0b746e5SOllivier Robert timerstats( 1177c0b746e5SOllivier Robert struct parse *pcmd, 1178c0b746e5SOllivier Robert FILE *fp 1179c0b746e5SOllivier Robert ) 1180c0b746e5SOllivier Robert { 1181c0b746e5SOllivier Robert struct info_timer_stats *tim; 1182c0b746e5SOllivier Robert int items; 1183c0b746e5SOllivier Robert int itemsize; 1184c0b746e5SOllivier Robert int res; 1185c0b746e5SOllivier Robert 11869c2daa00SOllivier Robert again: 11879c2daa00SOllivier Robert res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, (char *)NULL, 11889c2daa00SOllivier Robert &items, &itemsize, (void *)&tim, 0, 11899c2daa00SOllivier Robert sizeof(struct info_timer_stats)); 11909c2daa00SOllivier Robert 11919c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 11929c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 11939c2daa00SOllivier Robert goto again; 11949c2daa00SOllivier Robert } 1195c0b746e5SOllivier Robert 1196c0b746e5SOllivier Robert if (res != 0 && items == 0) 1197c0b746e5SOllivier Robert return; 1198c0b746e5SOllivier Robert 1199c0b746e5SOllivier Robert if (!check1item(items, fp)) 1200c0b746e5SOllivier Robert return; 1201c0b746e5SOllivier Robert 1202c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_timer_stats))) 1203c0b746e5SOllivier Robert return; 1204c0b746e5SOllivier Robert 1205c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 1206c0b746e5SOllivier Robert (u_long)ntohl(tim->timereset)); 1207c0b746e5SOllivier Robert (void) fprintf(fp, "alarms handled: %ld\n", 1208c0b746e5SOllivier Robert (u_long)ntohl(tim->alarms)); 1209c0b746e5SOllivier Robert (void) fprintf(fp, "alarm overruns: %ld\n", 1210c0b746e5SOllivier Robert (u_long)ntohl(tim->overflows)); 1211c0b746e5SOllivier Robert (void) fprintf(fp, "calls to transmit: %ld\n", 1212c0b746e5SOllivier Robert (u_long)ntohl(tim->xmtcalls)); 1213c0b746e5SOllivier Robert } 1214c0b746e5SOllivier Robert 1215c0b746e5SOllivier Robert 1216c0b746e5SOllivier Robert /* 1217c0b746e5SOllivier Robert * addpeer - configure an active mode association 1218c0b746e5SOllivier Robert */ 1219c0b746e5SOllivier Robert static void 1220c0b746e5SOllivier Robert addpeer( 1221c0b746e5SOllivier Robert struct parse *pcmd, 1222c0b746e5SOllivier Robert FILE *fp 1223c0b746e5SOllivier Robert ) 1224c0b746e5SOllivier Robert { 1225c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_ACTIVE, 0); 1226c0b746e5SOllivier Robert } 1227c0b746e5SOllivier Robert 1228c0b746e5SOllivier Robert 1229c0b746e5SOllivier Robert /* 1230c0b746e5SOllivier Robert * addserver - configure a client mode association 1231c0b746e5SOllivier Robert */ 1232c0b746e5SOllivier Robert static void 1233c0b746e5SOllivier Robert addserver( 1234c0b746e5SOllivier Robert struct parse *pcmd, 1235c0b746e5SOllivier Robert FILE *fp 1236c0b746e5SOllivier Robert ) 1237c0b746e5SOllivier Robert { 1238c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 0); 1239c0b746e5SOllivier Robert } 1240c0b746e5SOllivier Robert 1241c0b746e5SOllivier Robert /* 1242c0b746e5SOllivier Robert * addrefclock - configure a reference clock association 1243c0b746e5SOllivier Robert */ 1244c0b746e5SOllivier Robert static void 1245c0b746e5SOllivier Robert addrefclock( 1246c0b746e5SOllivier Robert struct parse *pcmd, 1247c0b746e5SOllivier Robert FILE *fp 1248c0b746e5SOllivier Robert ) 1249c0b746e5SOllivier Robert { 1250c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 1); 1251c0b746e5SOllivier Robert } 1252c0b746e5SOllivier Robert 1253c0b746e5SOllivier Robert /* 1254c0b746e5SOllivier Robert * broadcast - configure a broadcast mode association 1255c0b746e5SOllivier Robert */ 1256c0b746e5SOllivier Robert static void 1257c0b746e5SOllivier Robert broadcast( 1258c0b746e5SOllivier Robert struct parse *pcmd, 1259c0b746e5SOllivier Robert FILE *fp 1260c0b746e5SOllivier Robert ) 1261c0b746e5SOllivier Robert { 1262c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_BROADCAST, 0); 1263c0b746e5SOllivier Robert } 1264c0b746e5SOllivier Robert 1265c0b746e5SOllivier Robert 1266c0b746e5SOllivier Robert /* 1267c0b746e5SOllivier Robert * config - configure a new peer association 1268c0b746e5SOllivier Robert */ 1269c0b746e5SOllivier Robert static void 1270c0b746e5SOllivier Robert doconfig( 1271c0b746e5SOllivier Robert struct parse *pcmd, 1272c0b746e5SOllivier Robert FILE *fp, 1273c0b746e5SOllivier Robert int mode, 1274c0b746e5SOllivier Robert int refc 1275c0b746e5SOllivier Robert ) 1276c0b746e5SOllivier Robert { 1277c0b746e5SOllivier Robert struct conf_peer cpeer; 1278c0b746e5SOllivier Robert int items; 1279c0b746e5SOllivier Robert int itemsize; 1280c0b746e5SOllivier Robert char *dummy; 1281c0b746e5SOllivier Robert u_long keyid; 1282c0b746e5SOllivier Robert u_int version; 1283c0b746e5SOllivier Robert u_char minpoll; 1284c0b746e5SOllivier Robert u_int flags; 1285c0b746e5SOllivier Robert u_char cmode; 1286c0b746e5SOllivier Robert int res; 12879c2daa00SOllivier Robert int sendsize; 1288c0b746e5SOllivier Robert 12899c2daa00SOllivier Robert again: 1290c0b746e5SOllivier Robert keyid = 0; 1291c0b746e5SOllivier Robert version = NTP_OLDVERSION + 1; 1292c0b746e5SOllivier Robert flags = 0; 1293c0b746e5SOllivier Robert res = 0; 1294c0b746e5SOllivier Robert cmode = 0; 1295c0b746e5SOllivier Robert minpoll = NTP_MINDPOLL; 1296c0b746e5SOllivier Robert 12979c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 12989c2daa00SOllivier Robert sendsize = sizeof(struct conf_peer); 12999c2daa00SOllivier Robert else 13009c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_peer); 13019c2daa00SOllivier Robert 1302c0b746e5SOllivier Robert items = pcmd->nargs; 1303c0b746e5SOllivier Robert 1304c0b746e5SOllivier Robert if (refc) { 1305c0b746e5SOllivier Robert if (pcmd->nargs > 1) { 1306c0b746e5SOllivier Robert cmode = (u_char) pcmd->argval[1].uval; 1307c0b746e5SOllivier Robert items = 2; 1308c0b746e5SOllivier Robert } 1309c0b746e5SOllivier Robert } else { 1310c0b746e5SOllivier Robert if (pcmd->nargs > 1) { 1311c0b746e5SOllivier Robert keyid = pcmd->argval[1].uval; 1312c0b746e5SOllivier Robert if (keyid > 0) { 1313c0b746e5SOllivier Robert flags |= CONF_FLAG_AUTHENABLE; 1314c0b746e5SOllivier Robert } 1315c0b746e5SOllivier Robert if (pcmd->nargs > 2) { 1316c0b746e5SOllivier Robert version = (u_int)pcmd->argval[2].uval; 1317c0b746e5SOllivier Robert if (version > NTP_VERSION || 1318c0b746e5SOllivier Robert version < NTP_OLDVERSION) { 1319c0b746e5SOllivier Robert (void)fprintf(fp, 1320c0b746e5SOllivier Robert "invalid version number %u\n", 1321c0b746e5SOllivier Robert version); 1322c0b746e5SOllivier Robert res++; 1323c0b746e5SOllivier Robert } 1324c0b746e5SOllivier Robert items = 3; 1325c0b746e5SOllivier Robert } 1326c0b746e5SOllivier Robert } 1327c0b746e5SOllivier Robert } 1328c0b746e5SOllivier Robert 1329c0b746e5SOllivier Robert while (pcmd->nargs > items) { 1330c0b746e5SOllivier Robert if (STREQ(pcmd->argval[items].string, "prefer")) 1331c0b746e5SOllivier Robert flags |= CONF_FLAG_PREFER; 1332c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "burst")) 1333c0b746e5SOllivier Robert flags |= CONF_FLAG_BURST; 1334c0b746e5SOllivier Robert else { 1335c0b746e5SOllivier Robert long val; 1336c0b746e5SOllivier Robert if (!atoint(pcmd->argval[items].string, &val)) { 1337c0b746e5SOllivier Robert (void) fprintf(fp, 1338c0b746e5SOllivier Robert "%s not understood\n", 1339c0b746e5SOllivier Robert pcmd->argval[items].string); 1340c0b746e5SOllivier Robert res++; 1341c0b746e5SOllivier Robert break; 1342c0b746e5SOllivier Robert } else { 1343c0b746e5SOllivier Robert if (val >= NTP_MINPOLL && val <= NTP_MAXPOLL) { 1344c0b746e5SOllivier Robert minpoll = (u_char)val; 1345c0b746e5SOllivier Robert } else { 1346c0b746e5SOllivier Robert (void) fprintf(fp, 1347c0b746e5SOllivier Robert "minpol must be within %d..%d\n", 1348c0b746e5SOllivier Robert NTP_MINPOLL, NTP_MAXPOLL); 1349c0b746e5SOllivier Robert res++; 1350c0b746e5SOllivier Robert break; 1351c0b746e5SOllivier Robert } 1352c0b746e5SOllivier Robert } 1353c0b746e5SOllivier Robert } 1354c0b746e5SOllivier Robert items++; 1355c0b746e5SOllivier Robert } 1356c0b746e5SOllivier Robert 1357c0b746e5SOllivier Robert if (res) 1358c0b746e5SOllivier Robert return; 1359c0b746e5SOllivier Robert 13609c2daa00SOllivier Robert memset((void *)&cpeer, 0, sizeof(cpeer)); 1361c0b746e5SOllivier Robert 13629c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 13639c2daa00SOllivier Robert cpeer.peeraddr = GET_INADDR(pcmd->argval[0].netnum); 13649c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 13659c2daa00SOllivier Robert cpeer.v6_flag = 0; 13669c2daa00SOllivier Robert } else { 13679c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 13689c2daa00SOllivier Robert fprintf(stderr, 13699c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 13709c2daa00SOllivier Robert return; 13719c2daa00SOllivier Robert } 13729c2daa00SOllivier Robert cpeer.peeraddr6 = GET_INADDR6(pcmd->argval[0].netnum); 13739c2daa00SOllivier Robert cpeer.v6_flag = 1; 13749c2daa00SOllivier Robert } 1375c0b746e5SOllivier Robert cpeer.hmode = (u_char) mode; 1376c0b746e5SOllivier Robert cpeer.keyid = keyid; 1377c0b746e5SOllivier Robert cpeer.version = (u_char) version; 1378c0b746e5SOllivier Robert cpeer.minpoll = minpoll; 1379c0b746e5SOllivier Robert cpeer.maxpoll = NTP_MAXDPOLL; 1380c0b746e5SOllivier Robert cpeer.flags = (u_char)flags; 1381c0b746e5SOllivier Robert cpeer.ttl = cmode; 1382c0b746e5SOllivier Robert 13839c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 13849c2daa00SOllivier Robert sendsize, (char *)&cpeer, &items, 13859c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_peer)); 13869c2daa00SOllivier Robert 13879c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 13889c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 13899c2daa00SOllivier Robert goto again; 13909c2daa00SOllivier Robert } 1391c0b746e5SOllivier Robert 1392ce265a54SOllivier Robert if (res == INFO_ERR_FMT) { 1393ce265a54SOllivier Robert (void) fprintf(fp, 1394ce265a54SOllivier Robert "***Retrying command with old conf_peer size\n"); 13959c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 1396ce265a54SOllivier Robert sizeof(struct old_conf_peer), (char *)&cpeer, 13979c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, 13989c2daa00SOllivier Robert sizeof(struct conf_peer)); 1399ce265a54SOllivier Robert } 1400c0b746e5SOllivier Robert if (res == 0) 1401c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1402c0b746e5SOllivier Robert return; 1403c0b746e5SOllivier Robert } 1404c0b746e5SOllivier Robert 1405c0b746e5SOllivier Robert 1406c0b746e5SOllivier Robert /* 1407c0b746e5SOllivier Robert * unconfig - unconfigure some associations 1408c0b746e5SOllivier Robert */ 1409c0b746e5SOllivier Robert static void 1410c0b746e5SOllivier Robert unconfig( 1411c0b746e5SOllivier Robert struct parse *pcmd, 1412c0b746e5SOllivier Robert FILE *fp 1413c0b746e5SOllivier Robert ) 1414c0b746e5SOllivier Robert { 1415c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 14169c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 1417c0b746e5SOllivier Robert int qitems; 1418c0b746e5SOllivier Robert int items; 1419c0b746e5SOllivier Robert int itemsize; 1420c0b746e5SOllivier Robert char *dummy; 1421c0b746e5SOllivier Robert int res; 14229c2daa00SOllivier Robert int sendsize; 1423c0b746e5SOllivier Robert 14249c2daa00SOllivier Robert again: 14259c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14269c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 14279c2daa00SOllivier Robert else 14289c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 14299c2daa00SOllivier Robert 14309c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 8); qitems++) { 14319c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 14329c2daa00SOllivier Robert pl->peeraddr = GET_INADDR(pcmd->argval[qitems].netnum); 14339c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14349c2daa00SOllivier Robert pl->v6_flag = 0; 14359c2daa00SOllivier Robert } else { 14369c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 14379c2daa00SOllivier Robert fprintf(stderr, 14389c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 14399c2daa00SOllivier Robert return; 14409c2daa00SOllivier Robert } 14419c2daa00SOllivier Robert pl->peeraddr6 = 14429c2daa00SOllivier Robert GET_INADDR6(pcmd->argval[qitems].netnum); 14439c2daa00SOllivier Robert pl->v6_flag = 1; 14449c2daa00SOllivier Robert } 14459c2daa00SOllivier Robert pl = (struct conf_unpeer *)((char *)pl + sendsize); 1446c0b746e5SOllivier Robert } 1447c0b746e5SOllivier Robert 14489c2daa00SOllivier Robert res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems, 14499c2daa00SOllivier Robert sendsize, (char *)plist, &items, 14509c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 14519c2daa00SOllivier Robert 14529c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 14539c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 14549c2daa00SOllivier Robert goto again; 14559c2daa00SOllivier Robert } 1456c0b746e5SOllivier Robert 1457c0b746e5SOllivier Robert if (res == 0) 1458c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1459c0b746e5SOllivier Robert } 1460c0b746e5SOllivier Robert 1461c0b746e5SOllivier Robert 1462c0b746e5SOllivier Robert /* 1463c0b746e5SOllivier Robert * set - set some system flags 1464c0b746e5SOllivier Robert */ 1465c0b746e5SOllivier Robert static void 1466c0b746e5SOllivier Robert set( 1467c0b746e5SOllivier Robert struct parse *pcmd, 1468c0b746e5SOllivier Robert FILE *fp 1469c0b746e5SOllivier Robert ) 1470c0b746e5SOllivier Robert { 1471c0b746e5SOllivier Robert doset(pcmd, fp, REQ_SET_SYS_FLAG); 1472c0b746e5SOllivier Robert } 1473c0b746e5SOllivier Robert 1474c0b746e5SOllivier Robert 1475c0b746e5SOllivier Robert /* 1476c0b746e5SOllivier Robert * clear - clear some system flags 1477c0b746e5SOllivier Robert */ 1478c0b746e5SOllivier Robert static void 1479c0b746e5SOllivier Robert sys_clear( 1480c0b746e5SOllivier Robert struct parse *pcmd, 1481c0b746e5SOllivier Robert FILE *fp 1482c0b746e5SOllivier Robert ) 1483c0b746e5SOllivier Robert { 1484c0b746e5SOllivier Robert doset(pcmd, fp, REQ_CLR_SYS_FLAG); 1485c0b746e5SOllivier Robert } 1486c0b746e5SOllivier Robert 1487c0b746e5SOllivier Robert 1488c0b746e5SOllivier Robert /* 1489c0b746e5SOllivier Robert * doset - set/clear system flags 1490c0b746e5SOllivier Robert */ 1491c0b746e5SOllivier Robert static void 1492c0b746e5SOllivier Robert doset( 1493c0b746e5SOllivier Robert struct parse *pcmd, 1494c0b746e5SOllivier Robert FILE *fp, 1495c0b746e5SOllivier Robert int req 1496c0b746e5SOllivier Robert ) 1497c0b746e5SOllivier Robert { 1498c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 1499c0b746e5SOllivier Robert struct conf_sys_flags sys; 1500c0b746e5SOllivier Robert int items; 1501c0b746e5SOllivier Robert int itemsize; 1502c0b746e5SOllivier Robert char *dummy; 1503c0b746e5SOllivier Robert int res; 1504c0b746e5SOllivier Robert 1505c0b746e5SOllivier Robert sys.flags = 0; 1506c0b746e5SOllivier Robert res = 0; 1507c0b746e5SOllivier Robert for (items = 0; items < pcmd->nargs; items++) { 1508ce265a54SOllivier Robert if (STREQ(pcmd->argval[items].string, "auth")) 1509ce265a54SOllivier Robert sys.flags |= SYS_FLAG_AUTH; 1510c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "bclient")) 1511c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_BCLIENT; 1512ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "calibrate")) 1513ce265a54SOllivier Robert sys.flags |= SYS_FLAG_CAL; 1514ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "kernel")) 1515ce265a54SOllivier Robert sys.flags |= SYS_FLAG_KERNEL; 1516c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "monitor")) 1517c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_MONITOR; 1518c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "ntp")) 1519c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_NTP; 1520ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "pps")) 1521ce265a54SOllivier Robert sys.flags |= SYS_FLAG_PPS; 1522c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "stats")) 1523c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_FILEGEN; 1524c0b746e5SOllivier Robert else { 1525c0b746e5SOllivier Robert (void) fprintf(fp, "Unknown flag %s\n", 1526c0b746e5SOllivier Robert pcmd->argval[items].string); 1527c0b746e5SOllivier Robert res = 1; 1528c0b746e5SOllivier Robert } 1529c0b746e5SOllivier Robert } 1530c0b746e5SOllivier Robert 1531c0b746e5SOllivier Robert if (res || sys.flags == 0) 1532c0b746e5SOllivier Robert return; 1533c0b746e5SOllivier Robert 15349c2daa00SOllivier Robert again: 15359c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, 1536c0b746e5SOllivier Robert sizeof(struct conf_sys_flags), (char *)&sys, &items, 15379c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_sys_flags)); 15389c2daa00SOllivier Robert 15399c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 15409c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 15419c2daa00SOllivier Robert goto again; 15429c2daa00SOllivier Robert } 1543c0b746e5SOllivier Robert 1544c0b746e5SOllivier Robert if (res == 0) 1545c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1546c0b746e5SOllivier Robert } 1547c0b746e5SOllivier Robert 1548c0b746e5SOllivier Robert 1549c0b746e5SOllivier Robert /* 1550c0b746e5SOllivier Robert * data for printing/interrpreting the restrict flags 1551c0b746e5SOllivier Robert */ 1552c0b746e5SOllivier Robert struct resflags { 1553c0b746e5SOllivier Robert const char *str; 1554c0b746e5SOllivier Robert int bit; 1555c0b746e5SOllivier Robert }; 1556c0b746e5SOllivier Robert 1557c0b746e5SOllivier Robert static struct resflags resflags[] = { 1558c0b746e5SOllivier Robert { "ignore", RES_IGNORE }, 1559c0b746e5SOllivier Robert { "noserve", RES_DONTSERVE }, 1560c0b746e5SOllivier Robert { "notrust", RES_DONTTRUST }, 1561c0b746e5SOllivier Robert { "noquery", RES_NOQUERY }, 1562c0b746e5SOllivier Robert { "nomodify", RES_NOMODIFY }, 1563c0b746e5SOllivier Robert { "nopeer", RES_NOPEER }, 1564c0b746e5SOllivier Robert { "notrap", RES_NOTRAP }, 1565c0b746e5SOllivier Robert { "lptrap", RES_LPTRAP }, 1566c0b746e5SOllivier Robert { "limited", RES_LIMITED }, 1567224ba2bdSOllivier Robert { "version", RES_VERSION }, 1568224ba2bdSOllivier Robert { "kod", RES_DEMOBILIZE }, 15699c2daa00SOllivier Robert { "timeout", RES_TIMEOUT }, 1570224ba2bdSOllivier Robert 1571c0b746e5SOllivier Robert { "", 0 } 1572c0b746e5SOllivier Robert }; 1573c0b746e5SOllivier Robert 1574c0b746e5SOllivier Robert static struct resflags resmflags[] = { 1575c0b746e5SOllivier Robert { "ntpport", RESM_NTPONLY }, 1576c0b746e5SOllivier Robert { "interface", RESM_INTERFACE }, 1577c0b746e5SOllivier Robert { "", 0 } 1578c0b746e5SOllivier Robert }; 1579c0b746e5SOllivier Robert 1580c0b746e5SOllivier Robert 1581c0b746e5SOllivier Robert /* 1582c0b746e5SOllivier Robert * reslist - obtain and print the server's restrict list 1583c0b746e5SOllivier Robert */ 1584c0b746e5SOllivier Robert /*ARGSUSED*/ 1585c0b746e5SOllivier Robert static void 1586c0b746e5SOllivier Robert reslist( 1587c0b746e5SOllivier Robert struct parse *pcmd, 1588c0b746e5SOllivier Robert FILE *fp 1589c0b746e5SOllivier Robert ) 1590c0b746e5SOllivier Robert { 1591c0b746e5SOllivier Robert struct info_restrict *rl; 15929c2daa00SOllivier Robert struct sockaddr_storage resaddr; 15939c2daa00SOllivier Robert struct sockaddr_storage maskaddr; 1594c0b746e5SOllivier Robert int items; 1595c0b746e5SOllivier Robert int itemsize; 1596c0b746e5SOllivier Robert int res; 15979c2daa00SOllivier Robert int skip; 1598c0b746e5SOllivier Robert char *addr; 1599c0b746e5SOllivier Robert char *mask; 1600c0b746e5SOllivier Robert struct resflags *rf; 1601c0b746e5SOllivier Robert u_int32 count; 1602c0b746e5SOllivier Robert u_short flags; 1603c0b746e5SOllivier Robert u_short mflags; 1604c0b746e5SOllivier Robert char flagstr[300]; 1605c0b746e5SOllivier Robert static const char *comma = ", "; 1606c0b746e5SOllivier Robert 16079c2daa00SOllivier Robert again: 16089c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL, 16099c2daa00SOllivier Robert &items, &itemsize, (void *)&rl, 0, 16109c2daa00SOllivier Robert sizeof(struct info_restrict)); 16119c2daa00SOllivier Robert 16129c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 16139c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 16149c2daa00SOllivier Robert goto again; 16159c2daa00SOllivier Robert } 1616c0b746e5SOllivier Robert 1617c0b746e5SOllivier Robert if (res != 0 && items == 0) 1618c0b746e5SOllivier Robert return; 1619c0b746e5SOllivier Robert 1620c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1621c0b746e5SOllivier Robert return; 1622c0b746e5SOllivier Robert 16239c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_restrict)) && 16249c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_restrict))) 1625c0b746e5SOllivier Robert return; 1626c0b746e5SOllivier Robert 1627c0b746e5SOllivier Robert (void) fprintf(fp, 1628c0b746e5SOllivier Robert " address mask count flags\n"); 1629c0b746e5SOllivier Robert (void) fprintf(fp, 1630c0b746e5SOllivier Robert "=====================================================================\n"); 16319c2daa00SOllivier Robert 1632c0b746e5SOllivier Robert while (items > 0) { 16339c2daa00SOllivier Robert memset((char *)&resaddr, 0, sizeof(resaddr)); 16349c2daa00SOllivier Robert memset((char *)&maskaddr, 0, sizeof(maskaddr)); 16359c2daa00SOllivier Robert if (rl->v6_flag != 0) { 16369c2daa00SOllivier Robert GET_INADDR6(resaddr) = rl->addr6; 16379c2daa00SOllivier Robert GET_INADDR6(maskaddr) = rl->mask6; 16389c2daa00SOllivier Robert resaddr.ss_family = AF_INET6; 16399c2daa00SOllivier Robert maskaddr.ss_family = AF_INET6; 16409c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 16419c2daa00SOllivier Robert resaddr.ss_len = SOCKLEN(&resaddr); 16429c2daa00SOllivier Robert #endif 16439c2daa00SOllivier Robert addr = nntohost(&resaddr); 16449c2daa00SOllivier Robert } else { 16459c2daa00SOllivier Robert GET_INADDR(resaddr) = rl->addr; 16469c2daa00SOllivier Robert GET_INADDR(maskaddr) = rl->mask; 16479c2daa00SOllivier Robert resaddr.ss_family = AF_INET; 16489c2daa00SOllivier Robert maskaddr.ss_family = AF_INET; 16499c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 16509c2daa00SOllivier Robert resaddr.ss_len = SOCKLEN(&resaddr); 16519c2daa00SOllivier Robert #endif 1652c0b746e5SOllivier Robert if ((rl->mask == (u_int32)0xffffffff)) 16539c2daa00SOllivier Robert addr = nntohost(&resaddr); 1654c0b746e5SOllivier Robert else 16559c2daa00SOllivier Robert addr = stoa(&resaddr); 16569c2daa00SOllivier Robert } 16579c2daa00SOllivier Robert mask = stoa(&maskaddr); 16589c2daa00SOllivier Robert skip = 1; 16599c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 16609c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) || 16619c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (rl->v6_flag == 0))) 16629c2daa00SOllivier Robert skip = 0; 1663c0b746e5SOllivier Robert count = ntohl(rl->count); 1664c0b746e5SOllivier Robert flags = ntohs(rl->flags); 1665c0b746e5SOllivier Robert mflags = ntohs(rl->mflags); 1666c0b746e5SOllivier Robert flagstr[0] = '\0'; 1667c0b746e5SOllivier Robert 1668c0b746e5SOllivier Robert res = 1; 1669c0b746e5SOllivier Robert rf = &resmflags[0]; 1670c0b746e5SOllivier Robert while (rf->bit != 0) { 1671c0b746e5SOllivier Robert if (mflags & rf->bit) { 1672c0b746e5SOllivier Robert if (!res) 1673c0b746e5SOllivier Robert (void) strcat(flagstr, comma); 1674c0b746e5SOllivier Robert res = 0; 1675c0b746e5SOllivier Robert (void) strcat(flagstr, rf->str); 1676c0b746e5SOllivier Robert } 1677c0b746e5SOllivier Robert rf++; 1678c0b746e5SOllivier Robert } 1679c0b746e5SOllivier Robert 1680c0b746e5SOllivier Robert rf = &resflags[0]; 1681c0b746e5SOllivier Robert while (rf->bit != 0) { 1682c0b746e5SOllivier Robert if (flags & rf->bit) { 1683c0b746e5SOllivier Robert if (!res) 1684c0b746e5SOllivier Robert (void) strcat(flagstr, comma); 1685c0b746e5SOllivier Robert res = 0; 1686c0b746e5SOllivier Robert (void) strcat(flagstr, rf->str); 1687c0b746e5SOllivier Robert } 1688c0b746e5SOllivier Robert rf++; 1689c0b746e5SOllivier Robert } 1690c0b746e5SOllivier Robert 1691c0b746e5SOllivier Robert if (flagstr[0] == '\0') 1692c0b746e5SOllivier Robert (void) strcpy(flagstr, "none"); 1693c0b746e5SOllivier Robert 16949c2daa00SOllivier Robert if (!skip) 1695c0b746e5SOllivier Robert (void) fprintf(fp, "%-15.15s %-15.15s %9ld %s\n", 1696c0b746e5SOllivier Robert addr, mask, (u_long)count, flagstr); 1697c0b746e5SOllivier Robert rl++; 1698c0b746e5SOllivier Robert items--; 1699c0b746e5SOllivier Robert } 1700c0b746e5SOllivier Robert } 1701c0b746e5SOllivier Robert 1702c0b746e5SOllivier Robert 1703c0b746e5SOllivier Robert 1704c0b746e5SOllivier Robert /* 1705c0b746e5SOllivier Robert * new_restrict - create/add a set of restrictions 1706c0b746e5SOllivier Robert */ 1707c0b746e5SOllivier Robert static void 1708c0b746e5SOllivier Robert new_restrict( 1709c0b746e5SOllivier Robert struct parse *pcmd, 1710c0b746e5SOllivier Robert FILE *fp 1711c0b746e5SOllivier Robert ) 1712c0b746e5SOllivier Robert { 1713c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESADDFLAGS); 1714c0b746e5SOllivier Robert } 1715c0b746e5SOllivier Robert 1716c0b746e5SOllivier Robert 1717c0b746e5SOllivier Robert /* 1718c0b746e5SOllivier Robert * unrestrict - remove restriction flags from existing entry 1719c0b746e5SOllivier Robert */ 1720c0b746e5SOllivier Robert static void 1721c0b746e5SOllivier Robert unrestrict( 1722c0b746e5SOllivier Robert struct parse *pcmd, 1723c0b746e5SOllivier Robert FILE *fp 1724c0b746e5SOllivier Robert ) 1725c0b746e5SOllivier Robert { 1726c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESSUBFLAGS); 1727c0b746e5SOllivier Robert } 1728c0b746e5SOllivier Robert 1729c0b746e5SOllivier Robert 1730c0b746e5SOllivier Robert /* 1731c0b746e5SOllivier Robert * delrestrict - delete an existing restriction 1732c0b746e5SOllivier Robert */ 1733c0b746e5SOllivier Robert static void 1734c0b746e5SOllivier Robert delrestrict( 1735c0b746e5SOllivier Robert struct parse *pcmd, 1736c0b746e5SOllivier Robert FILE *fp 1737c0b746e5SOllivier Robert ) 1738c0b746e5SOllivier Robert { 1739c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_UNRESTRICT); 1740c0b746e5SOllivier Robert } 1741c0b746e5SOllivier Robert 1742c0b746e5SOllivier Robert 1743c0b746e5SOllivier Robert /* 1744c0b746e5SOllivier Robert * do_restrict - decode commandline restrictions and make the request 1745c0b746e5SOllivier Robert */ 1746c0b746e5SOllivier Robert static void 1747c0b746e5SOllivier Robert do_restrict( 1748c0b746e5SOllivier Robert struct parse *pcmd, 1749c0b746e5SOllivier Robert FILE *fp, 1750c0b746e5SOllivier Robert int req_code 1751c0b746e5SOllivier Robert ) 1752c0b746e5SOllivier Robert { 1753c0b746e5SOllivier Robert struct conf_restrict cres; 1754c0b746e5SOllivier Robert int items; 1755c0b746e5SOllivier Robert int itemsize; 1756c0b746e5SOllivier Robert char *dummy; 1757c0b746e5SOllivier Robert u_int32 num; 1758c0b746e5SOllivier Robert u_long bit; 1759c0b746e5SOllivier Robert int i; 1760c0b746e5SOllivier Robert int res; 1761c0b746e5SOllivier Robert int err; 17629c2daa00SOllivier Robert int sendsize; 1763c0b746e5SOllivier Robert 17649c2daa00SOllivier Robert /* Initialize cres */ 17659c2daa00SOllivier Robert cres.addr = 0; 17669c2daa00SOllivier Robert cres.mask = 0; 17679c2daa00SOllivier Robert cres.flags = 0; 17689c2daa00SOllivier Robert cres.mflags = 0; 17699c2daa00SOllivier Robert cres.v6_flag = 0; 17709c2daa00SOllivier Robert 17719c2daa00SOllivier Robert again: 17729c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 17739c2daa00SOllivier Robert sendsize = sizeof(struct conf_restrict); 17749c2daa00SOllivier Robert else 17759c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_restrict); 17769c2daa00SOllivier Robert 17779c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 17789c2daa00SOllivier Robert cres.addr = GET_INADDR(pcmd->argval[0].netnum); 17799c2daa00SOllivier Robert cres.mask = GET_INADDR(pcmd->argval[1].netnum); 17809c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 17819c2daa00SOllivier Robert cres.v6_flag = 0; 17829c2daa00SOllivier Robert } else { 17839c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 17849c2daa00SOllivier Robert fprintf(stderr, 17859c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 17869c2daa00SOllivier Robert return; 17879c2daa00SOllivier Robert } 17889c2daa00SOllivier Robert cres.addr6 = GET_INADDR6(pcmd->argval[0].netnum); 17899c2daa00SOllivier Robert cres.v6_flag = 1; 17909c2daa00SOllivier Robert } 1791c0b746e5SOllivier Robert cres.flags = 0; 1792c0b746e5SOllivier Robert cres.mflags = 0; 1793c0b746e5SOllivier Robert err = 0; 1794c0b746e5SOllivier Robert for (res = 2; res < pcmd->nargs; res++) { 1795c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, "ntpport")) { 1796c0b746e5SOllivier Robert cres.mflags |= RESM_NTPONLY; 1797c0b746e5SOllivier Robert } else { 1798c0b746e5SOllivier Robert for (i = 0; resflags[i].bit != 0; i++) { 1799c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, 1800c0b746e5SOllivier Robert resflags[i].str)) 1801c0b746e5SOllivier Robert break; 1802c0b746e5SOllivier Robert } 1803c0b746e5SOllivier Robert if (resflags[i].bit != 0) { 1804c0b746e5SOllivier Robert cres.flags |= resflags[i].bit; 1805c0b746e5SOllivier Robert if (req_code == REQ_UNRESTRICT) { 1806c0b746e5SOllivier Robert (void) fprintf(fp, 1807c0b746e5SOllivier Robert "Flag %s inappropriate\n", 1808c0b746e5SOllivier Robert resflags[i].str); 1809c0b746e5SOllivier Robert err++; 1810c0b746e5SOllivier Robert } 1811c0b746e5SOllivier Robert } else { 1812c0b746e5SOllivier Robert (void) fprintf(fp, "Unknown flag %s\n", 1813c0b746e5SOllivier Robert pcmd->argval[res].string); 1814c0b746e5SOllivier Robert err++; 1815c0b746e5SOllivier Robert } 1816c0b746e5SOllivier Robert } 1817c0b746e5SOllivier Robert } 1818c0b746e5SOllivier Robert 1819c0b746e5SOllivier Robert /* 1820c0b746e5SOllivier Robert * Make sure mask for default address is zero. Otherwise, 1821c0b746e5SOllivier Robert * make sure mask bits are contiguous. 1822c0b746e5SOllivier Robert */ 18239c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 1824c0b746e5SOllivier Robert if (cres.addr == 0) { 1825c0b746e5SOllivier Robert cres.mask = 0; 1826c0b746e5SOllivier Robert } else { 1827c0b746e5SOllivier Robert num = ntohl(cres.mask); 1828c0b746e5SOllivier Robert for (bit = 0x80000000; bit != 0; bit >>= 1) 1829c0b746e5SOllivier Robert if ((num & bit) == 0) 1830c0b746e5SOllivier Robert break; 1831c0b746e5SOllivier Robert for ( ; bit != 0; bit >>= 1) 1832c0b746e5SOllivier Robert if ((num & bit) != 0) 1833c0b746e5SOllivier Robert break; 1834c0b746e5SOllivier Robert if (bit != 0) { 1835c0b746e5SOllivier Robert (void) fprintf(fp, "Invalid mask %s\n", 1836c0b746e5SOllivier Robert numtoa(cres.mask)); 1837c0b746e5SOllivier Robert err++; 1838c0b746e5SOllivier Robert } 1839c0b746e5SOllivier Robert } 18409c2daa00SOllivier Robert } else { 18419c2daa00SOllivier Robert /* XXX IPv6 sanity checking stuff */ 18429c2daa00SOllivier Robert } 1843c0b746e5SOllivier Robert 1844c0b746e5SOllivier Robert if (err) 1845c0b746e5SOllivier Robert return; 1846c0b746e5SOllivier Robert 18479c2daa00SOllivier Robert res = doquery(impl_ver, req_code, 1, 1, 18489c2daa00SOllivier Robert sendsize, (char *)&cres, &items, 18499c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_restrict)); 18509c2daa00SOllivier Robert 18519c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 18529c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 18539c2daa00SOllivier Robert goto again; 18549c2daa00SOllivier Robert } 1855c0b746e5SOllivier Robert 1856c0b746e5SOllivier Robert if (res == 0) 1857c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1858c0b746e5SOllivier Robert return; 1859c0b746e5SOllivier Robert } 1860c0b746e5SOllivier Robert 1861c0b746e5SOllivier Robert 1862c0b746e5SOllivier Robert /* 1863c0b746e5SOllivier Robert * monlist - obtain and print the server's monitor data 1864c0b746e5SOllivier Robert */ 1865c0b746e5SOllivier Robert /*ARGSUSED*/ 1866c0b746e5SOllivier Robert static void 1867c0b746e5SOllivier Robert monlist( 1868c0b746e5SOllivier Robert struct parse *pcmd, 1869c0b746e5SOllivier Robert FILE *fp 1870c0b746e5SOllivier Robert ) 1871c0b746e5SOllivier Robert { 1872c0b746e5SOllivier Robert char *struct_star; 18739c2daa00SOllivier Robert struct sockaddr_storage addr; 18749c2daa00SOllivier Robert struct sockaddr_storage dstadr; 1875c0b746e5SOllivier Robert int items; 1876c0b746e5SOllivier Robert int itemsize; 1877c0b746e5SOllivier Robert int res; 1878c0b746e5SOllivier Robert int version = -1; 1879c0b746e5SOllivier Robert 1880c0b746e5SOllivier Robert if (pcmd->nargs > 0) { 1881c0b746e5SOllivier Robert version = pcmd->argval[0].ival; 1882c0b746e5SOllivier Robert } 1883c0b746e5SOllivier Robert 18849c2daa00SOllivier Robert again: 18859c2daa00SOllivier Robert res = doquery(impl_ver, 1886c0b746e5SOllivier Robert (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : 1887c0b746e5SOllivier Robert REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 1888c0b746e5SOllivier Robert &items, &itemsize, &struct_star, 18899c2daa00SOllivier Robert (version < 0) ? (1 << INFO_ERR_REQ) : 0, 18909c2daa00SOllivier Robert sizeof(struct info_monitor_1)); 18919c2daa00SOllivier Robert 18929c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 18939c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 18949c2daa00SOllivier Robert goto again; 18959c2daa00SOllivier Robert } 1896c0b746e5SOllivier Robert 1897c0b746e5SOllivier Robert if (res == INFO_ERR_REQ && version < 0) 18989c2daa00SOllivier Robert res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 18999c2daa00SOllivier Robert &items, &itemsize, &struct_star, 0, 19009c2daa00SOllivier Robert sizeof(struct info_monitor)); 1901c0b746e5SOllivier Robert 1902c0b746e5SOllivier Robert if (res != 0 && items == 0) 1903c0b746e5SOllivier Robert return; 1904c0b746e5SOllivier Robert 1905c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1906c0b746e5SOllivier Robert return; 1907c0b746e5SOllivier Robert 19089c2daa00SOllivier Robert if (itemsize == sizeof(struct info_monitor_1) || 19099c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor_1)) { 1910c0b746e5SOllivier Robert struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star; 1911c0b746e5SOllivier Robert 1912c0b746e5SOllivier Robert (void) fprintf(fp, 19139c2daa00SOllivier Robert "remote address port local address count m ver code avgint lstint\n"); 1914c0b746e5SOllivier Robert (void) fprintf(fp, 1915c0b746e5SOllivier Robert "===============================================================================\n"); 1916c0b746e5SOllivier Robert while (items > 0) { 19179c2daa00SOllivier Robert memset((char *)&addr, 0, sizeof(addr)); 19189c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 19199c2daa00SOllivier Robert if (ml->v6_flag != 0) { 19209c2daa00SOllivier Robert GET_INADDR6(addr) = ml->addr6; 19219c2daa00SOllivier Robert addr.ss_family = AF_INET6; 19229c2daa00SOllivier Robert GET_INADDR6(dstadr) = ml->daddr6; 19239c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 19249c2daa00SOllivier Robert } else { 19259c2daa00SOllivier Robert GET_INADDR(addr) = ml->addr; 19269c2daa00SOllivier Robert addr.ss_family = AF_INET; 19279c2daa00SOllivier Robert GET_INADDR(dstadr) = ml->daddr; 19289c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 19299c2daa00SOllivier Robert } 19309c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 19319c2daa00SOllivier Robert addr.ss_len = SOCKLEN(&addr); 19329c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 19339c2daa00SOllivier Robert #endif 19349c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 19359c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || 19369c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) 1937c0b746e5SOllivier Robert (void) fprintf(fp, 19389c2daa00SOllivier Robert "%-22.22s %5d %-15s %8ld %1d %1d %6lx %6lu %7lu\n", 19399c2daa00SOllivier Robert nntohost(&addr), 1940c0b746e5SOllivier Robert ntohs(ml->port), 19419c2daa00SOllivier Robert stoa(&dstadr), 1942c0b746e5SOllivier Robert (u_long)ntohl(ml->count), 1943c0b746e5SOllivier Robert ml->mode, 1944c0b746e5SOllivier Robert ml->version, 1945c0b746e5SOllivier Robert (u_long)ntohl(ml->lastdrop), 1946c0b746e5SOllivier Robert (u_long)ntohl(ml->lasttime), 1947c0b746e5SOllivier Robert (u_long)ntohl(ml->firsttime)); 1948c0b746e5SOllivier Robert ml++; 1949c0b746e5SOllivier Robert items--; 1950c0b746e5SOllivier Robert } 19519c2daa00SOllivier Robert } else if (itemsize == sizeof(struct info_monitor) || 19529c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor)) { 1953c0b746e5SOllivier Robert struct info_monitor *ml = (struct info_monitor *) struct_star; 1954c0b746e5SOllivier Robert 1955c0b746e5SOllivier Robert (void) fprintf(fp, 19569c2daa00SOllivier Robert " address port count mode ver code avgint lstint\n"); 1957c0b746e5SOllivier Robert (void) fprintf(fp, 1958c0b746e5SOllivier Robert "===============================================================================\n"); 1959c0b746e5SOllivier Robert while (items > 0) { 19609c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 19619c2daa00SOllivier Robert if (ml->v6_flag != 0) { 19629c2daa00SOllivier Robert GET_INADDR6(dstadr) = ml->addr6; 19639c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 19649c2daa00SOllivier Robert } else { 19659c2daa00SOllivier Robert GET_INADDR(dstadr) = ml->addr; 19669c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 19679c2daa00SOllivier Robert } 19689c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 19699c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 19709c2daa00SOllivier Robert #endif 19719c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 19729c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || 19739c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) 1974c0b746e5SOllivier Robert (void) fprintf(fp, 19759c2daa00SOllivier Robert "%-25.25s %5d %9ld %4d %2d %9lx %9lu %9lu\n", 19769c2daa00SOllivier Robert nntohost(&dstadr), 1977c0b746e5SOllivier Robert ntohs(ml->port), 1978c0b746e5SOllivier Robert (u_long)ntohl(ml->count), 1979c0b746e5SOllivier Robert ml->mode, 1980c0b746e5SOllivier Robert ml->version, 1981c0b746e5SOllivier Robert (u_long)ntohl(ml->lastdrop), 1982c0b746e5SOllivier Robert (u_long)ntohl(ml->lasttime), 1983c0b746e5SOllivier Robert (u_long)ntohl(ml->firsttime)); 1984c0b746e5SOllivier Robert ml++; 1985c0b746e5SOllivier Robert items--; 1986c0b746e5SOllivier Robert } 1987c0b746e5SOllivier Robert } else if (itemsize == sizeof(struct old_info_monitor)) { 1988c0b746e5SOllivier Robert struct old_info_monitor *oml = (struct old_info_monitor *)struct_star; 1989c0b746e5SOllivier Robert (void) fprintf(fp, 1990c0b746e5SOllivier Robert " address port count mode version lasttime firsttime\n"); 1991c0b746e5SOllivier Robert (void) fprintf(fp, 1992c0b746e5SOllivier Robert "======================================================================\n"); 1993c0b746e5SOllivier Robert while (items > 0) { 19949c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 19959c2daa00SOllivier Robert if (oml->v6_flag != 0) { 19969c2daa00SOllivier Robert GET_INADDR6(dstadr) = oml->addr6; 19979c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 19989c2daa00SOllivier Robert } else { 19999c2daa00SOllivier Robert GET_INADDR(dstadr) = oml->addr; 20009c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 20019c2daa00SOllivier Robert } 20029c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 20039c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 20049c2daa00SOllivier Robert #endif 2005c0b746e5SOllivier Robert (void) fprintf(fp, "%-20.20s %5d %9ld %4d %3d %9lu %9lu\n", 20069c2daa00SOllivier Robert nntohost(&dstadr), 2007c0b746e5SOllivier Robert ntohs(oml->port), 2008c0b746e5SOllivier Robert (u_long)ntohl(oml->count), 2009c0b746e5SOllivier Robert oml->mode, 2010c0b746e5SOllivier Robert oml->version, 2011c0b746e5SOllivier Robert (u_long)ntohl(oml->lasttime), 2012c0b746e5SOllivier Robert (u_long)ntohl(oml->firsttime)); 2013c0b746e5SOllivier Robert oml++; 2014c0b746e5SOllivier Robert items--; 2015c0b746e5SOllivier Robert } 2016c0b746e5SOllivier Robert } else { 2017c0b746e5SOllivier Robert /* issue warning according to new info_monitor size */ 2018c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_monitor)); 2019c0b746e5SOllivier Robert } 2020c0b746e5SOllivier Robert } 2021c0b746e5SOllivier Robert 2022c0b746e5SOllivier Robert 2023c0b746e5SOllivier Robert /* 2024c0b746e5SOllivier Robert * Mapping between command line strings and stat reset flags 2025c0b746e5SOllivier Robert */ 2026c0b746e5SOllivier Robert struct statreset { 2027c0b746e5SOllivier Robert const char *str; 2028c0b746e5SOllivier Robert int flag; 2029c0b746e5SOllivier Robert } sreset[] = { 2030c0b746e5SOllivier Robert { "io", RESET_FLAG_IO }, 2031c0b746e5SOllivier Robert { "sys", RESET_FLAG_SYS }, 2032c0b746e5SOllivier Robert { "mem", RESET_FLAG_MEM }, 2033c0b746e5SOllivier Robert { "timer", RESET_FLAG_TIMER }, 2034c0b746e5SOllivier Robert { "auth", RESET_FLAG_AUTH }, 2035c0b746e5SOllivier Robert { "allpeers", RESET_FLAG_ALLPEERS }, 2036c0b746e5SOllivier Robert { "", 0 } 2037c0b746e5SOllivier Robert }; 2038c0b746e5SOllivier Robert 2039c0b746e5SOllivier Robert /* 2040c0b746e5SOllivier Robert * reset - reset statistic counters 2041c0b746e5SOllivier Robert */ 2042c0b746e5SOllivier Robert static void 2043c0b746e5SOllivier Robert reset( 2044c0b746e5SOllivier Robert struct parse *pcmd, 2045c0b746e5SOllivier Robert FILE *fp 2046c0b746e5SOllivier Robert ) 2047c0b746e5SOllivier Robert { 2048c0b746e5SOllivier Robert struct reset_flags rflags; 2049c0b746e5SOllivier Robert int items; 2050c0b746e5SOllivier Robert int itemsize; 2051c0b746e5SOllivier Robert char *dummy; 2052c0b746e5SOllivier Robert int i; 2053c0b746e5SOllivier Robert int res; 2054c0b746e5SOllivier Robert int err; 2055c0b746e5SOllivier Robert 2056c0b746e5SOllivier Robert err = 0; 2057c0b746e5SOllivier Robert rflags.flags = 0; 2058c0b746e5SOllivier Robert for (res = 0; res < pcmd->nargs; res++) { 2059c0b746e5SOllivier Robert for (i = 0; sreset[i].flag != 0; i++) { 2060c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, sreset[i].str)) 2061c0b746e5SOllivier Robert break; 2062c0b746e5SOllivier Robert } 2063c0b746e5SOllivier Robert if (sreset[i].flag == 0) { 2064c0b746e5SOllivier Robert (void) fprintf(fp, "Flag %s unknown\n", 2065c0b746e5SOllivier Robert pcmd->argval[res].string); 2066c0b746e5SOllivier Robert err++; 2067c0b746e5SOllivier Robert } else { 2068c0b746e5SOllivier Robert rflags.flags |= sreset[i].flag; 2069c0b746e5SOllivier Robert } 2070c0b746e5SOllivier Robert } 2071c0b746e5SOllivier Robert 2072c0b746e5SOllivier Robert if (err) { 2073c0b746e5SOllivier Robert (void) fprintf(fp, "Not done due to errors\n"); 2074c0b746e5SOllivier Robert return; 2075c0b746e5SOllivier Robert } 2076c0b746e5SOllivier Robert 20779c2daa00SOllivier Robert again: 20789c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_STATS, 1, 1, 2079c0b746e5SOllivier Robert sizeof(struct reset_flags), (char *)&rflags, &items, 20809c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct reset_flags)); 20819c2daa00SOllivier Robert 20829c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 20839c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 20849c2daa00SOllivier Robert goto again; 20859c2daa00SOllivier Robert } 2086c0b746e5SOllivier Robert 2087c0b746e5SOllivier Robert if (res == 0) 2088c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2089c0b746e5SOllivier Robert return; 2090c0b746e5SOllivier Robert } 2091c0b746e5SOllivier Robert 2092c0b746e5SOllivier Robert 2093c0b746e5SOllivier Robert 2094c0b746e5SOllivier Robert /* 2095c0b746e5SOllivier Robert * preset - reset stat counters for particular peers 2096c0b746e5SOllivier Robert */ 2097c0b746e5SOllivier Robert static void 2098c0b746e5SOllivier Robert preset( 2099c0b746e5SOllivier Robert struct parse *pcmd, 2100c0b746e5SOllivier Robert FILE *fp 2101c0b746e5SOllivier Robert ) 2102c0b746e5SOllivier Robert { 2103c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 21049c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 2105c0b746e5SOllivier Robert int qitems; 2106c0b746e5SOllivier Robert int items; 2107c0b746e5SOllivier Robert int itemsize; 2108c0b746e5SOllivier Robert char *dummy; 2109c0b746e5SOllivier Robert int res; 21109c2daa00SOllivier Robert int sendsize; 2111c0b746e5SOllivier Robert 21129c2daa00SOllivier Robert again: 21139c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21149c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 21159c2daa00SOllivier Robert else 21169c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 21179c2daa00SOllivier Robert 21189c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 8); qitems++) { 21199c2daa00SOllivier Robert if (pcmd->argval[qitems].netnum.ss_family == AF_INET) { 21209c2daa00SOllivier Robert pl->peeraddr = GET_INADDR(pcmd->argval[qitems].netnum); 21219c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21229c2daa00SOllivier Robert pl->v6_flag = 0; 21239c2daa00SOllivier Robert } else { 21249c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 21259c2daa00SOllivier Robert fprintf(stderr, 21269c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 21279c2daa00SOllivier Robert return; 21289c2daa00SOllivier Robert } 21299c2daa00SOllivier Robert pl->peeraddr6 = 21309c2daa00SOllivier Robert GET_INADDR6(pcmd->argval[qitems].netnum); 21319c2daa00SOllivier Robert pl->v6_flag = 1; 21329c2daa00SOllivier Robert } 21339c2daa00SOllivier Robert pl = (struct conf_unpeer *)((char *)pl + sendsize); 2134c0b746e5SOllivier Robert } 2135c0b746e5SOllivier Robert 21369c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems, 21379c2daa00SOllivier Robert sendsize, (char *)plist, &items, 21389c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 21399c2daa00SOllivier Robert 21409c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 21419c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 21429c2daa00SOllivier Robert goto again; 21439c2daa00SOllivier Robert } 2144c0b746e5SOllivier Robert 2145c0b746e5SOllivier Robert if (res == 0) 2146c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2147c0b746e5SOllivier Robert } 2148c0b746e5SOllivier Robert 2149c0b746e5SOllivier Robert 2150c0b746e5SOllivier Robert /* 2151c0b746e5SOllivier Robert * readkeys - request the server to reread the keys file 2152c0b746e5SOllivier Robert */ 2153c0b746e5SOllivier Robert /*ARGSUSED*/ 2154c0b746e5SOllivier Robert static void 2155c0b746e5SOllivier Robert readkeys( 2156c0b746e5SOllivier Robert struct parse *pcmd, 2157c0b746e5SOllivier Robert FILE *fp 2158c0b746e5SOllivier Robert ) 2159c0b746e5SOllivier Robert { 2160c0b746e5SOllivier Robert int items; 2161c0b746e5SOllivier Robert int itemsize; 2162c0b746e5SOllivier Robert char *dummy; 2163c0b746e5SOllivier Robert int res; 2164c0b746e5SOllivier Robert 21659c2daa00SOllivier Robert again: 21669c2daa00SOllivier Robert res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0, 21679c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, sizeof(dummy)); 21689c2daa00SOllivier Robert 21699c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 21709c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 21719c2daa00SOllivier Robert goto again; 21729c2daa00SOllivier Robert } 2173c0b746e5SOllivier Robert 2174c0b746e5SOllivier Robert if (res == 0) 2175c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2176c0b746e5SOllivier Robert return; 2177c0b746e5SOllivier Robert } 2178c0b746e5SOllivier Robert 2179c0b746e5SOllivier Robert 2180c0b746e5SOllivier Robert /* 2181c0b746e5SOllivier Robert * trustkey - add some keys to the trusted key list 2182c0b746e5SOllivier Robert */ 2183c0b746e5SOllivier Robert static void 2184c0b746e5SOllivier Robert trustkey( 2185c0b746e5SOllivier Robert struct parse *pcmd, 2186c0b746e5SOllivier Robert FILE *fp 2187c0b746e5SOllivier Robert ) 2188c0b746e5SOllivier Robert { 2189c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_TRUSTKEY); 2190c0b746e5SOllivier Robert } 2191c0b746e5SOllivier Robert 2192c0b746e5SOllivier Robert 2193c0b746e5SOllivier Robert /* 2194c0b746e5SOllivier Robert * untrustkey - remove some keys from the trusted key list 2195c0b746e5SOllivier Robert */ 2196c0b746e5SOllivier Robert static void 2197c0b746e5SOllivier Robert untrustkey( 2198c0b746e5SOllivier Robert struct parse *pcmd, 2199c0b746e5SOllivier Robert FILE *fp 2200c0b746e5SOllivier Robert ) 2201c0b746e5SOllivier Robert { 2202c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_UNTRUSTKEY); 2203c0b746e5SOllivier Robert } 2204c0b746e5SOllivier Robert 2205c0b746e5SOllivier Robert 2206c0b746e5SOllivier Robert /* 2207c0b746e5SOllivier Robert * do_trustkey - do grunge work of adding/deleting keys 2208c0b746e5SOllivier Robert */ 2209c0b746e5SOllivier Robert static void 2210c0b746e5SOllivier Robert do_trustkey( 2211c0b746e5SOllivier Robert struct parse *pcmd, 2212c0b746e5SOllivier Robert FILE *fp, 2213c0b746e5SOllivier Robert int req 2214c0b746e5SOllivier Robert ) 2215c0b746e5SOllivier Robert { 2216c0b746e5SOllivier Robert u_long keyids[MAXARGS]; 2217c0b746e5SOllivier Robert int i; 2218c0b746e5SOllivier Robert int items; 2219c0b746e5SOllivier Robert int itemsize; 2220c0b746e5SOllivier Robert char *dummy; 2221c0b746e5SOllivier Robert int ritems; 2222c0b746e5SOllivier Robert int res; 2223c0b746e5SOllivier Robert 2224c0b746e5SOllivier Robert ritems = 0; 2225c0b746e5SOllivier Robert for (i = 0; i < pcmd->nargs; i++) { 2226c0b746e5SOllivier Robert keyids[ritems++] = pcmd->argval[i].uval; 2227c0b746e5SOllivier Robert } 2228c0b746e5SOllivier Robert 22299c2daa00SOllivier Robert again: 22309c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, ritems, sizeof(u_long), 22319c2daa00SOllivier Robert (char *)keyids, &items, &itemsize, &dummy, 0, 22329c2daa00SOllivier Robert sizeof(dummy)); 22339c2daa00SOllivier Robert 22349c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22359c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22369c2daa00SOllivier Robert goto again; 22379c2daa00SOllivier Robert } 2238c0b746e5SOllivier Robert 2239c0b746e5SOllivier Robert if (res == 0) 2240c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2241c0b746e5SOllivier Robert return; 2242c0b746e5SOllivier Robert } 2243c0b746e5SOllivier Robert 2244c0b746e5SOllivier Robert 2245c0b746e5SOllivier Robert 2246c0b746e5SOllivier Robert /* 2247c0b746e5SOllivier Robert * authinfo - obtain and print info about authentication 2248c0b746e5SOllivier Robert */ 2249c0b746e5SOllivier Robert /*ARGSUSED*/ 2250c0b746e5SOllivier Robert static void 2251c0b746e5SOllivier Robert authinfo( 2252c0b746e5SOllivier Robert struct parse *pcmd, 2253c0b746e5SOllivier Robert FILE *fp 2254c0b746e5SOllivier Robert ) 2255c0b746e5SOllivier Robert { 2256c0b746e5SOllivier Robert struct info_auth *ia; 2257c0b746e5SOllivier Robert int items; 2258c0b746e5SOllivier Robert int itemsize; 2259c0b746e5SOllivier Robert int res; 2260c0b746e5SOllivier Robert 22619c2daa00SOllivier Robert again: 22629c2daa00SOllivier Robert res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, (char *)NULL, 22639c2daa00SOllivier Robert &items, &itemsize, (void *)&ia, 0, 22649c2daa00SOllivier Robert sizeof(struct info_auth)); 22659c2daa00SOllivier Robert 22669c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22679c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22689c2daa00SOllivier Robert goto again; 22699c2daa00SOllivier Robert } 2270c0b746e5SOllivier Robert 2271c0b746e5SOllivier Robert if (res != 0 && items == 0) 2272c0b746e5SOllivier Robert return; 2273c0b746e5SOllivier Robert 2274c0b746e5SOllivier Robert if (!check1item(items, fp)) 2275c0b746e5SOllivier Robert return; 2276c0b746e5SOllivier Robert 2277c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_auth))) 2278c0b746e5SOllivier Robert return; 2279c0b746e5SOllivier Robert 2280c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 2281c0b746e5SOllivier Robert (u_long)ntohl(ia->timereset)); 2282c0b746e5SOllivier Robert (void) fprintf(fp, "stored keys: %ld\n", 2283c0b746e5SOllivier Robert (u_long)ntohl(ia->numkeys)); 2284c0b746e5SOllivier Robert (void) fprintf(fp, "free keys: %ld\n", 2285c0b746e5SOllivier Robert (u_long)ntohl(ia->numfreekeys)); 2286c0b746e5SOllivier Robert (void) fprintf(fp, "key lookups: %ld\n", 2287c0b746e5SOllivier Robert (u_long)ntohl(ia->keylookups)); 2288c0b746e5SOllivier Robert (void) fprintf(fp, "keys not found: %ld\n", 2289c0b746e5SOllivier Robert (u_long)ntohl(ia->keynotfound)); 2290c0b746e5SOllivier Robert (void) fprintf(fp, "uncached keys: %ld\n", 2291c0b746e5SOllivier Robert (u_long)ntohl(ia->keyuncached)); 2292c0b746e5SOllivier Robert (void) fprintf(fp, "encryptions: %ld\n", 2293c0b746e5SOllivier Robert (u_long)ntohl(ia->encryptions)); 2294c0b746e5SOllivier Robert (void) fprintf(fp, "decryptions: %ld\n", 2295c0b746e5SOllivier Robert (u_long)ntohl(ia->decryptions)); 2296c0b746e5SOllivier Robert (void) fprintf(fp, "expired keys: %ld\n", 2297c0b746e5SOllivier Robert (u_long)ntohl(ia->expired)); 2298c0b746e5SOllivier Robert } 2299c0b746e5SOllivier Robert 2300c0b746e5SOllivier Robert 2301c0b746e5SOllivier Robert 2302c0b746e5SOllivier Robert /* 2303c0b746e5SOllivier Robert * traps - obtain and print a list of traps 2304c0b746e5SOllivier Robert */ 2305c0b746e5SOllivier Robert /*ARGSUSED*/ 2306c0b746e5SOllivier Robert static void 2307c0b746e5SOllivier Robert traps( 2308c0b746e5SOllivier Robert struct parse *pcmd, 2309c0b746e5SOllivier Robert FILE *fp 2310c0b746e5SOllivier Robert ) 2311c0b746e5SOllivier Robert { 2312c0b746e5SOllivier Robert int i; 2313c0b746e5SOllivier Robert struct info_trap *it; 23149c2daa00SOllivier Robert struct sockaddr_storage trap_addr, local_addr; 2315c0b746e5SOllivier Robert int items; 2316c0b746e5SOllivier Robert int itemsize; 2317c0b746e5SOllivier Robert int res; 2318c0b746e5SOllivier Robert 23199c2daa00SOllivier Robert again: 23209c2daa00SOllivier Robert res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, (char *)NULL, 23219c2daa00SOllivier Robert &items, &itemsize, (void *)&it, 0, 23229c2daa00SOllivier Robert sizeof(struct info_trap)); 23239c2daa00SOllivier Robert 23249c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23259c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23269c2daa00SOllivier Robert goto again; 23279c2daa00SOllivier Robert } 2328c0b746e5SOllivier Robert 2329c0b746e5SOllivier Robert if (res != 0 && items == 0) 2330c0b746e5SOllivier Robert return; 2331c0b746e5SOllivier Robert 2332c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2333c0b746e5SOllivier Robert return; 2334c0b746e5SOllivier Robert 23359c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_trap)) && 23369c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_trap))) 2337c0b746e5SOllivier Robert return; 2338c0b746e5SOllivier Robert 2339c0b746e5SOllivier Robert for (i = 0; i < items; i++ ) { 2340c0b746e5SOllivier Robert if (i != 0) 2341c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 23429c2daa00SOllivier Robert memset((char *)&trap_addr, 0, sizeof(trap_addr)); 23439c2daa00SOllivier Robert memset((char *)&local_addr, 0, sizeof(local_addr)); 23449c2daa00SOllivier Robert if (it->v6_flag != 0) { 23459c2daa00SOllivier Robert GET_INADDR6(trap_addr) = it->trap_address6; 23469c2daa00SOllivier Robert GET_INADDR6(local_addr) = it->local_address6; 23479c2daa00SOllivier Robert trap_addr.ss_family = AF_INET6; 23489c2daa00SOllivier Robert local_addr.ss_family = AF_INET6; 23499c2daa00SOllivier Robert } else { 23509c2daa00SOllivier Robert GET_INADDR(trap_addr) = it->trap_address; 23519c2daa00SOllivier Robert GET_INADDR(local_addr) = it->local_address; 23529c2daa00SOllivier Robert trap_addr.ss_family = AF_INET; 23539c2daa00SOllivier Robert local_addr.ss_family = AF_INET; 23549c2daa00SOllivier Robert } 23559c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 23569c2daa00SOllivier Robert trap_addr.ss_len = SOCKLEN(&trap_addr); 23579c2daa00SOllivier Robert local_addr.ss_len = SOCKLEN(&local_addr); 23589c2daa00SOllivier Robert #endif 2359c0b746e5SOllivier Robert (void) fprintf(fp, "address %s, port %d\n", 23609c2daa00SOllivier Robert stoa(&trap_addr), 23619c2daa00SOllivier Robert ntohs(it->trap_port)); 2362c0b746e5SOllivier Robert (void) fprintf(fp, "interface: %s, ", 2363c0b746e5SOllivier Robert (it->local_address == 0) 2364c0b746e5SOllivier Robert ? "wildcard" 23659c2daa00SOllivier Robert : stoa(&local_addr)); 2366c0b746e5SOllivier Robert if (ntohl(it->flags) & TRAP_CONFIGURED) 2367c0b746e5SOllivier Robert (void) fprintf(fp, "configured\n"); 2368c0b746e5SOllivier Robert else if (ntohl(it->flags) & TRAP_NONPRIO) 2369c0b746e5SOllivier Robert (void) fprintf(fp, "low priority\n"); 2370c0b746e5SOllivier Robert else 2371c0b746e5SOllivier Robert (void) fprintf(fp, "normal priority\n"); 2372c0b746e5SOllivier Robert 2373c0b746e5SOllivier Robert (void) fprintf(fp, "set for %ld secs, last set %ld secs ago\n", 2374c0b746e5SOllivier Robert (long)ntohl(it->origtime), 2375c0b746e5SOllivier Robert (long)ntohl(it->settime)); 2376c0b746e5SOllivier Robert (void) fprintf(fp, "sequence %d, number of resets %ld\n", 2377c0b746e5SOllivier Robert ntohs(it->sequence), 2378c0b746e5SOllivier Robert (long)ntohl(it->resets)); 2379c0b746e5SOllivier Robert } 2380c0b746e5SOllivier Robert } 2381c0b746e5SOllivier Robert 2382c0b746e5SOllivier Robert 2383c0b746e5SOllivier Robert /* 2384c0b746e5SOllivier Robert * addtrap - configure a trap 2385c0b746e5SOllivier Robert */ 2386c0b746e5SOllivier Robert static void 2387c0b746e5SOllivier Robert addtrap( 2388c0b746e5SOllivier Robert struct parse *pcmd, 2389c0b746e5SOllivier Robert FILE *fp 2390c0b746e5SOllivier Robert ) 2391c0b746e5SOllivier Robert { 2392c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_ADD_TRAP); 2393c0b746e5SOllivier Robert } 2394c0b746e5SOllivier Robert 2395c0b746e5SOllivier Robert 2396c0b746e5SOllivier Robert /* 2397c0b746e5SOllivier Robert * clrtrap - clear a trap from the server 2398c0b746e5SOllivier Robert */ 2399c0b746e5SOllivier Robert static void 2400c0b746e5SOllivier Robert clrtrap( 2401c0b746e5SOllivier Robert struct parse *pcmd, 2402c0b746e5SOllivier Robert FILE *fp 2403c0b746e5SOllivier Robert ) 2404c0b746e5SOllivier Robert { 2405c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_CLR_TRAP); 2406c0b746e5SOllivier Robert } 2407c0b746e5SOllivier Robert 2408c0b746e5SOllivier Robert 2409c0b746e5SOllivier Robert /* 2410c0b746e5SOllivier Robert * do_addclr_trap - do grunge work of adding/deleting traps 2411c0b746e5SOllivier Robert */ 2412c0b746e5SOllivier Robert static void 2413c0b746e5SOllivier Robert do_addclr_trap( 2414c0b746e5SOllivier Robert struct parse *pcmd, 2415c0b746e5SOllivier Robert FILE *fp, 2416c0b746e5SOllivier Robert int req 2417c0b746e5SOllivier Robert ) 2418c0b746e5SOllivier Robert { 2419c0b746e5SOllivier Robert struct conf_trap ctrap; 2420c0b746e5SOllivier Robert int items; 2421c0b746e5SOllivier Robert int itemsize; 2422c0b746e5SOllivier Robert char *dummy; 2423c0b746e5SOllivier Robert int res; 24249c2daa00SOllivier Robert int sendsize; 2425c0b746e5SOllivier Robert 24269c2daa00SOllivier Robert again: 24279c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 24289c2daa00SOllivier Robert sendsize = sizeof(struct conf_trap); 24299c2daa00SOllivier Robert else 24309c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_trap); 24319c2daa00SOllivier Robert 24329c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 24339c2daa00SOllivier Robert ctrap.trap_address = GET_INADDR(pcmd->argval[0].netnum); 24349c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 24359c2daa00SOllivier Robert ctrap.v6_flag = 0; 24369c2daa00SOllivier Robert } else { 24379c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 24389c2daa00SOllivier Robert fprintf(stderr, 24399c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 24409c2daa00SOllivier Robert return; 24419c2daa00SOllivier Robert } 24429c2daa00SOllivier Robert ctrap.trap_address6 = GET_INADDR6(pcmd->argval[0].netnum); 24439c2daa00SOllivier Robert ctrap.v6_flag = 1; 24449c2daa00SOllivier Robert } 2445c0b746e5SOllivier Robert ctrap.local_address = 0; 2446c0b746e5SOllivier Robert ctrap.trap_port = htons(TRAPPORT); 2447c0b746e5SOllivier Robert ctrap.unused = 0; 2448c0b746e5SOllivier Robert 2449c0b746e5SOllivier Robert if (pcmd->nargs > 1) { 2450c0b746e5SOllivier Robert ctrap.trap_port 2451c0b746e5SOllivier Robert = htons((u_short)(pcmd->argval[1].uval & 0xffff)); 24529c2daa00SOllivier Robert if (pcmd->nargs > 2) { 24539c2daa00SOllivier Robert if (pcmd->argval[2].netnum.ss_family != 24549c2daa00SOllivier Robert pcmd->argval[0].netnum.ss_family) { 24559c2daa00SOllivier Robert fprintf(stderr, 24569c2daa00SOllivier Robert "***Cannot mix IPv4 and IPv6 addresses\n"); 24579c2daa00SOllivier Robert return; 24589c2daa00SOllivier Robert } 24599c2daa00SOllivier Robert if (pcmd->argval[2].netnum.ss_family == AF_INET) 24609c2daa00SOllivier Robert ctrap.local_address = GET_INADDR(pcmd->argval[2].netnum); 24619c2daa00SOllivier Robert else 24629c2daa00SOllivier Robert ctrap.local_address6 = GET_INADDR6(pcmd->argval[2].netnum); 24639c2daa00SOllivier Robert } 2464c0b746e5SOllivier Robert } 2465c0b746e5SOllivier Robert 24669c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sendsize, 24679c2daa00SOllivier Robert (char *)&ctrap, &items, &itemsize, &dummy, 0, 24689c2daa00SOllivier Robert sizeof(struct conf_trap)); 24699c2daa00SOllivier Robert 24709c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 24719c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 24729c2daa00SOllivier Robert goto again; 24739c2daa00SOllivier Robert } 2474c0b746e5SOllivier Robert 2475c0b746e5SOllivier Robert if (res == 0) 2476c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2477c0b746e5SOllivier Robert return; 2478c0b746e5SOllivier Robert } 2479c0b746e5SOllivier Robert 2480c0b746e5SOllivier Robert 2481c0b746e5SOllivier Robert 2482c0b746e5SOllivier Robert /* 2483c0b746e5SOllivier Robert * requestkey - change the server's request key (a dangerous request) 2484c0b746e5SOllivier Robert */ 2485c0b746e5SOllivier Robert static void 2486c0b746e5SOllivier Robert requestkey( 2487c0b746e5SOllivier Robert struct parse *pcmd, 2488c0b746e5SOllivier Robert FILE *fp 2489c0b746e5SOllivier Robert ) 2490c0b746e5SOllivier Robert { 2491c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_REQUEST_KEY); 2492c0b746e5SOllivier Robert } 2493c0b746e5SOllivier Robert 2494c0b746e5SOllivier Robert 2495c0b746e5SOllivier Robert /* 2496c0b746e5SOllivier Robert * controlkey - change the server's control key 2497c0b746e5SOllivier Robert */ 2498c0b746e5SOllivier Robert static void 2499c0b746e5SOllivier Robert controlkey( 2500c0b746e5SOllivier Robert struct parse *pcmd, 2501c0b746e5SOllivier Robert FILE *fp 2502c0b746e5SOllivier Robert ) 2503c0b746e5SOllivier Robert { 2504c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_CONTROL_KEY); 2505c0b746e5SOllivier Robert } 2506c0b746e5SOllivier Robert 2507c0b746e5SOllivier Robert 2508c0b746e5SOllivier Robert 2509c0b746e5SOllivier Robert /* 2510c0b746e5SOllivier Robert * do_changekey - do grunge work of changing keys 2511c0b746e5SOllivier Robert */ 2512c0b746e5SOllivier Robert static void 2513c0b746e5SOllivier Robert do_changekey( 2514c0b746e5SOllivier Robert struct parse *pcmd, 2515c0b746e5SOllivier Robert FILE *fp, 2516c0b746e5SOllivier Robert int req 2517c0b746e5SOllivier Robert ) 2518c0b746e5SOllivier Robert { 2519c0b746e5SOllivier Robert u_long key; 2520c0b746e5SOllivier Robert int items; 2521c0b746e5SOllivier Robert int itemsize; 2522c0b746e5SOllivier Robert char *dummy; 2523c0b746e5SOllivier Robert int res; 2524c0b746e5SOllivier Robert 2525c0b746e5SOllivier Robert 2526c0b746e5SOllivier Robert key = htonl((u_int32)pcmd->argval[0].uval); 2527c0b746e5SOllivier Robert 25289c2daa00SOllivier Robert again: 25299c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sizeof(u_int32), 25309c2daa00SOllivier Robert (char *)&key, &items, &itemsize, &dummy, 0, 25319c2daa00SOllivier Robert sizeof(dummy)); 25329c2daa00SOllivier Robert 25339c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 25349c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25359c2daa00SOllivier Robert goto again; 25369c2daa00SOllivier Robert } 2537c0b746e5SOllivier Robert 2538c0b746e5SOllivier Robert if (res == 0) 2539c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2540c0b746e5SOllivier Robert return; 2541c0b746e5SOllivier Robert } 2542c0b746e5SOllivier Robert 2543c0b746e5SOllivier Robert 2544c0b746e5SOllivier Robert 2545c0b746e5SOllivier Robert /* 2546c0b746e5SOllivier Robert * ctlstats - obtain and print info about authentication 2547c0b746e5SOllivier Robert */ 2548c0b746e5SOllivier Robert /*ARGSUSED*/ 2549c0b746e5SOllivier Robert static void 2550c0b746e5SOllivier Robert ctlstats( 2551c0b746e5SOllivier Robert struct parse *pcmd, 2552c0b746e5SOllivier Robert FILE *fp 2553c0b746e5SOllivier Robert ) 2554c0b746e5SOllivier Robert { 2555c0b746e5SOllivier Robert struct info_control *ic; 2556c0b746e5SOllivier Robert int items; 2557c0b746e5SOllivier Robert int itemsize; 2558c0b746e5SOllivier Robert int res; 2559c0b746e5SOllivier Robert 25609c2daa00SOllivier Robert again: 25619c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, (char *)NULL, 25629c2daa00SOllivier Robert &items, &itemsize, (void *)&ic, 0, 25639c2daa00SOllivier Robert sizeof(struct info_control)); 25649c2daa00SOllivier Robert 25659c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 25669c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25679c2daa00SOllivier Robert goto again; 25689c2daa00SOllivier Robert } 2569c0b746e5SOllivier Robert 2570c0b746e5SOllivier Robert if (res != 0 && items == 0) 2571c0b746e5SOllivier Robert return; 2572c0b746e5SOllivier Robert 2573c0b746e5SOllivier Robert if (!check1item(items, fp)) 2574c0b746e5SOllivier Robert return; 2575c0b746e5SOllivier Robert 2576c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_control))) 2577c0b746e5SOllivier Robert return; 2578c0b746e5SOllivier Robert 2579c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 2580c0b746e5SOllivier Robert (u_long)ntohl(ic->ctltimereset)); 2581c0b746e5SOllivier Robert (void) fprintf(fp, "requests received: %ld\n", 2582c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlreq)); 2583c0b746e5SOllivier Robert (void) fprintf(fp, "responses sent: %ld\n", 2584c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlresponses)); 2585c0b746e5SOllivier Robert (void) fprintf(fp, "fragments sent: %ld\n", 2586c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlfrags)); 2587c0b746e5SOllivier Robert (void) fprintf(fp, "async messages sent: %ld\n", 2588c0b746e5SOllivier Robert (u_long)ntohl(ic->numasyncmsgs)); 2589c0b746e5SOllivier Robert (void) fprintf(fp, "error msgs sent: %ld\n", 2590c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlerrors)); 2591c0b746e5SOllivier Robert (void) fprintf(fp, "total bad pkts: %ld\n", 2592c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadpkts)); 2593c0b746e5SOllivier Robert (void) fprintf(fp, "packet too short: %ld\n", 2594c0b746e5SOllivier Robert (u_long)ntohl(ic->numctltooshort)); 2595c0b746e5SOllivier Robert (void) fprintf(fp, "response on input: %ld\n", 2596c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputresp)); 2597c0b746e5SOllivier Robert (void) fprintf(fp, "fragment on input: %ld\n", 2598c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputfrag)); 2599c0b746e5SOllivier Robert (void) fprintf(fp, "error set on input: %ld\n", 2600c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputerr)); 2601c0b746e5SOllivier Robert (void) fprintf(fp, "bad offset on input: %ld\n", 2602c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadoffset)); 2603c0b746e5SOllivier Robert (void) fprintf(fp, "bad version packets: %ld\n", 2604c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadversion)); 2605c0b746e5SOllivier Robert (void) fprintf(fp, "data in pkt too short: %ld\n", 2606c0b746e5SOllivier Robert (u_long)ntohl(ic->numctldatatooshort)); 2607c0b746e5SOllivier Robert (void) fprintf(fp, "unknown op codes: %ld\n", 2608c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadop)); 2609c0b746e5SOllivier Robert } 2610c0b746e5SOllivier Robert 2611c0b746e5SOllivier Robert 2612c0b746e5SOllivier Robert /* 2613c0b746e5SOllivier Robert * clockstat - get and print clock status information 2614c0b746e5SOllivier Robert */ 2615c0b746e5SOllivier Robert static void 2616c0b746e5SOllivier Robert clockstat( 2617c0b746e5SOllivier Robert struct parse *pcmd, 2618c0b746e5SOllivier Robert FILE *fp 2619c0b746e5SOllivier Robert ) 2620c0b746e5SOllivier Robert { 2621c0b746e5SOllivier Robert struct info_clock *cl; 2622c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2623c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 2624c0b746e5SOllivier Robert int qitems; 2625c0b746e5SOllivier Robert int items; 2626c0b746e5SOllivier Robert int itemsize; 2627c0b746e5SOllivier Robert int res; 2628c0b746e5SOllivier Robert l_fp ts; 2629c0b746e5SOllivier Robert struct clktype *clk; 2630c0b746e5SOllivier Robert u_long ltemp; 2631c0b746e5SOllivier Robert 2632c0b746e5SOllivier Robert for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 26339c2daa00SOllivier Robert clist[qitems] = GET_INADDR(pcmd->argval[qitems].netnum); 2634c0b746e5SOllivier Robert 26359c2daa00SOllivier Robert again: 26369c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems, 2637c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 26389c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clock)); 26399c2daa00SOllivier Robert 26409c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 26419c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 26429c2daa00SOllivier Robert goto again; 26439c2daa00SOllivier Robert } 2644c0b746e5SOllivier Robert 2645c0b746e5SOllivier Robert if (res != 0 && items == 0) 2646c0b746e5SOllivier Robert return; 2647c0b746e5SOllivier Robert 2648c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2649c0b746e5SOllivier Robert return; 2650c0b746e5SOllivier Robert 2651c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clock))) 2652c0b746e5SOllivier Robert return; 2653c0b746e5SOllivier Robert 2654c0b746e5SOllivier Robert while (items-- > 0) { 2655c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2656c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2657c0b746e5SOllivier Robert for (clk = clktypes; clk->code >= 0; clk++) 2658c0b746e5SOllivier Robert if (clk->code == cl->type) 2659c0b746e5SOllivier Robert break; 2660c0b746e5SOllivier Robert if (clk->code >= 0) 2661c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: %s\n", 2662c0b746e5SOllivier Robert clk->clocktype); 2663c0b746e5SOllivier Robert else 2664c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: unknown type (%d)\n", 2665c0b746e5SOllivier Robert cl->type); 2666c0b746e5SOllivier Robert (void) fprintf(fp, "last event: %d\n", 2667c0b746e5SOllivier Robert cl->lastevent); 2668c0b746e5SOllivier Robert (void) fprintf(fp, "current status: %d\n", 2669c0b746e5SOllivier Robert cl->currentstatus); 2670c0b746e5SOllivier Robert (void) fprintf(fp, "number of polls: %lu\n", 2671c0b746e5SOllivier Robert (u_long)ntohl(cl->polls)); 2672c0b746e5SOllivier Robert (void) fprintf(fp, "no response to poll: %lu\n", 2673c0b746e5SOllivier Robert (u_long)ntohl(cl->noresponse)); 2674c0b746e5SOllivier Robert (void) fprintf(fp, "bad format responses: %lu\n", 2675c0b746e5SOllivier Robert (u_long)ntohl(cl->badformat)); 2676c0b746e5SOllivier Robert (void) fprintf(fp, "bad data responses: %lu\n", 2677c0b746e5SOllivier Robert (u_long)ntohl(cl->baddata)); 2678c0b746e5SOllivier Robert (void) fprintf(fp, "running time: %lu\n", 2679c0b746e5SOllivier Robert (u_long)ntohl(cl->timestarted)); 2680c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime1, &ts); 2681c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 1: %s\n", 2682c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2683c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime2, &ts); 2684c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 2: %s\n", 2685c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2686c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %ld\n", 2687c0b746e5SOllivier Robert (u_long)ntohl(cl->fudgeval1)); 2688c0b746e5SOllivier Robert ltemp = ntohl(cl->fudgeval2); 2689c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: %s\n", 2690c0b746e5SOllivier Robert (char *)<emp); 2691c0b746e5SOllivier Robert (void) fprintf(fp, "fudge flags: 0x%x\n", 2692c0b746e5SOllivier Robert cl->flags); 2693c0b746e5SOllivier Robert 2694c0b746e5SOllivier Robert if (items > 0) 2695c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2696c0b746e5SOllivier Robert cl++; 2697c0b746e5SOllivier Robert } 2698c0b746e5SOllivier Robert } 2699c0b746e5SOllivier Robert 2700c0b746e5SOllivier Robert 2701c0b746e5SOllivier Robert /* 2702c0b746e5SOllivier Robert * fudge - set clock fudge factors 2703c0b746e5SOllivier Robert */ 2704c0b746e5SOllivier Robert static void 2705c0b746e5SOllivier Robert fudge( 2706c0b746e5SOllivier Robert struct parse *pcmd, 2707c0b746e5SOllivier Robert FILE *fp 2708c0b746e5SOllivier Robert ) 2709c0b746e5SOllivier Robert { 2710c0b746e5SOllivier Robert struct conf_fudge fudgedata; 2711c0b746e5SOllivier Robert int items; 2712c0b746e5SOllivier Robert int itemsize; 2713c0b746e5SOllivier Robert char *dummy; 2714c0b746e5SOllivier Robert l_fp ts; 2715c0b746e5SOllivier Robert int res; 2716c0b746e5SOllivier Robert long val; 2717c0b746e5SOllivier Robert u_long u_val; 2718c0b746e5SOllivier Robert int err; 2719c0b746e5SOllivier Robert 2720c0b746e5SOllivier Robert 2721c0b746e5SOllivier Robert err = 0; 2722c0b746e5SOllivier Robert memset((char *)&fudgedata, 0, sizeof fudgedata); 27239c2daa00SOllivier Robert fudgedata.clockadr = GET_INADDR(pcmd->argval[0].netnum); 2724c0b746e5SOllivier Robert 2725c0b746e5SOllivier Robert if (STREQ(pcmd->argval[1].string, "time1")) { 2726c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME1); 2727c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2728c0b746e5SOllivier Robert err = 1; 2729c0b746e5SOllivier Robert else 2730c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2731c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "time2")) { 2732c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME2); 2733c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2734c0b746e5SOllivier Robert err = 1; 2735c0b746e5SOllivier Robert else 2736c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2737c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val1")) { 2738c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL1); 2739c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2740c0b746e5SOllivier Robert err = 1; 2741c0b746e5SOllivier Robert else 2742c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl(val); 2743c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val2")) { 2744c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL2); 2745c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2746c0b746e5SOllivier Robert err = 1; 2747c0b746e5SOllivier Robert else 2748c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)val); 2749c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "flags")) { 2750c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_FLAGS); 2751c0b746e5SOllivier Robert if (!hextoint(pcmd->argval[2].string, &u_val)) 2752c0b746e5SOllivier Robert err = 1; 2753c0b746e5SOllivier Robert else 2754c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf)); 2755c0b746e5SOllivier Robert } else { 2756c0b746e5SOllivier Robert (void) fprintf(stderr, "What fudge is %s?\n", 2757c0b746e5SOllivier Robert pcmd->argval[1].string); 2758c0b746e5SOllivier Robert return; 2759c0b746e5SOllivier Robert } 2760c0b746e5SOllivier Robert 2761c0b746e5SOllivier Robert if (err) { 2762c0b746e5SOllivier Robert (void) fprintf(stderr, "Unknown fudge parameter %s\n", 2763c0b746e5SOllivier Robert pcmd->argval[2].string); 2764c0b746e5SOllivier Robert return; 2765c0b746e5SOllivier Robert } 2766c0b746e5SOllivier Robert 27679c2daa00SOllivier Robert again: 27689c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1, 2769c0b746e5SOllivier Robert sizeof(struct conf_fudge), (char *)&fudgedata, &items, 27709c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(dummy)); 27719c2daa00SOllivier Robert 27729c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 27739c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 27749c2daa00SOllivier Robert goto again; 27759c2daa00SOllivier Robert } 2776c0b746e5SOllivier Robert 2777c0b746e5SOllivier Robert if (res == 0) 2778c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2779c0b746e5SOllivier Robert return; 2780c0b746e5SOllivier Robert } 2781c0b746e5SOllivier Robert 2782c0b746e5SOllivier Robert /* 2783c0b746e5SOllivier Robert * clkbug - get and print clock debugging information 2784c0b746e5SOllivier Robert */ 2785c0b746e5SOllivier Robert static void 2786c0b746e5SOllivier Robert clkbug( 2787c0b746e5SOllivier Robert struct parse *pcmd, 2788c0b746e5SOllivier Robert FILE *fp 2789c0b746e5SOllivier Robert ) 2790c0b746e5SOllivier Robert { 2791c0b746e5SOllivier Robert register int i; 2792c0b746e5SOllivier Robert register int n; 2793c0b746e5SOllivier Robert register u_int32 s; 2794c0b746e5SOllivier Robert struct info_clkbug *cl; 2795c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2796c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 2797c0b746e5SOllivier Robert u_int32 ltemp; 2798c0b746e5SOllivier Robert int qitems; 2799c0b746e5SOllivier Robert int items; 2800c0b746e5SOllivier Robert int itemsize; 2801c0b746e5SOllivier Robert int res; 2802c0b746e5SOllivier Robert int needsp; 2803c0b746e5SOllivier Robert l_fp ts; 2804c0b746e5SOllivier Robert 2805c0b746e5SOllivier Robert for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 28069c2daa00SOllivier Robert clist[qitems] = GET_INADDR(pcmd->argval[qitems].netnum); 2807c0b746e5SOllivier Robert 28089c2daa00SOllivier Robert again: 28099c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems, 2810c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 28119c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug)); 28129c2daa00SOllivier Robert 28139c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 28149c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 28159c2daa00SOllivier Robert goto again; 28169c2daa00SOllivier Robert } 2817c0b746e5SOllivier Robert 2818c0b746e5SOllivier Robert if (res != 0 && items == 0) 2819c0b746e5SOllivier Robert return; 2820c0b746e5SOllivier Robert 2821c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2822c0b746e5SOllivier Robert return; 2823c0b746e5SOllivier Robert 2824c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clkbug))) 2825c0b746e5SOllivier Robert return; 2826c0b746e5SOllivier Robert 2827c0b746e5SOllivier Robert while (items-- > 0) { 2828c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2829c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2830c0b746e5SOllivier Robert n = (int)cl->nvalues; 2831c0b746e5SOllivier Robert (void) fprintf(fp, "values: %d", n); 2832c0b746e5SOllivier Robert s = ntohs(cl->svalues); 2833c0b746e5SOllivier Robert if (n > NUMCBUGVALUES) 2834c0b746e5SOllivier Robert n = NUMCBUGVALUES; 2835c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2836c0b746e5SOllivier Robert ltemp = ntohl(cl->values[i]); 2837c0b746e5SOllivier Robert ltemp &= 0xffffffff; /* HMS: This does nothing now */ 2838c0b746e5SOllivier Robert if ((i & 0x3) == 0) 2839c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2840c0b746e5SOllivier Robert if (s & (1 << i)) 2841c0b746e5SOllivier Robert (void) fprintf(fp, "%12ld", (u_long)ltemp); 2842c0b746e5SOllivier Robert else 2843c0b746e5SOllivier Robert (void) fprintf(fp, "%12lu", (u_long)ltemp); 2844c0b746e5SOllivier Robert } 2845c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2846c0b746e5SOllivier Robert 2847c0b746e5SOllivier Robert n = (int)cl->ntimes; 2848c0b746e5SOllivier Robert (void) fprintf(fp, "times: %d", n); 2849c0b746e5SOllivier Robert s = ntohl(cl->stimes); 2850c0b746e5SOllivier Robert if (n > NUMCBUGTIMES) 2851c0b746e5SOllivier Robert n = NUMCBUGTIMES; 2852c0b746e5SOllivier Robert needsp = 0; 2853c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2854c0b746e5SOllivier Robert if ((i & 0x1) == 0) { 2855c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2856c0b746e5SOllivier Robert } else { 2857c0b746e5SOllivier Robert for (;needsp > 0; needsp--) 2858c0b746e5SOllivier Robert putc(' ', fp); 2859c0b746e5SOllivier Robert } 2860c0b746e5SOllivier Robert NTOHL_FP(&cl->times[i], &ts); 2861c0b746e5SOllivier Robert if (s & (1 << i)) { 2862c0b746e5SOllivier Robert (void) fprintf(fp, "%17s", 2863c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2864c0b746e5SOllivier Robert needsp = 22; 2865c0b746e5SOllivier Robert } else { 2866c0b746e5SOllivier Robert (void) fprintf(fp, "%37s", 2867c0b746e5SOllivier Robert uglydate(&ts)); 2868c0b746e5SOllivier Robert needsp = 2; 2869c0b746e5SOllivier Robert } 2870c0b746e5SOllivier Robert } 2871c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2872c0b746e5SOllivier Robert if (items > 0) { 2873c0b746e5SOllivier Robert cl++; 2874c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2875c0b746e5SOllivier Robert } 2876c0b746e5SOllivier Robert } 2877c0b746e5SOllivier Robert } 2878c0b746e5SOllivier Robert 2879c0b746e5SOllivier Robert 2880c0b746e5SOllivier Robert /* 2881c0b746e5SOllivier Robert * kerninfo - display the kernel pll/pps variables 2882c0b746e5SOllivier Robert */ 2883c0b746e5SOllivier Robert static void 2884c0b746e5SOllivier Robert kerninfo( 2885c0b746e5SOllivier Robert struct parse *pcmd, 2886c0b746e5SOllivier Robert FILE *fp 2887c0b746e5SOllivier Robert ) 2888c0b746e5SOllivier Robert { 2889c0b746e5SOllivier Robert struct info_kernel *ik; 2890c0b746e5SOllivier Robert int items; 2891c0b746e5SOllivier Robert int itemsize; 2892c0b746e5SOllivier Robert int res; 2893c0b746e5SOllivier Robert unsigned status; 2894c0b746e5SOllivier Robert double tscale = 1e-6; 2895c0b746e5SOllivier Robert 28969c2daa00SOllivier Robert again: 28979c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL, 28989c2daa00SOllivier Robert &items, &itemsize, (void *)&ik, 0, 28999c2daa00SOllivier Robert sizeof(struct info_kernel)); 29009c2daa00SOllivier Robert 29019c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 29029c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 29039c2daa00SOllivier Robert goto again; 29049c2daa00SOllivier Robert } 29059c2daa00SOllivier Robert 2906c0b746e5SOllivier Robert if (res != 0 && items == 0) 2907c0b746e5SOllivier Robert return; 2908c0b746e5SOllivier Robert if (!check1item(items, fp)) 2909c0b746e5SOllivier Robert return; 2910c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_kernel))) 2911c0b746e5SOllivier Robert return; 2912c0b746e5SOllivier Robert 2913c0b746e5SOllivier Robert status = ntohs(ik->status) & 0xffff; 2914c0b746e5SOllivier Robert /* 2915c0b746e5SOllivier Robert * pll variables. We know more than we should about the NANO bit. 2916c0b746e5SOllivier Robert */ 2917c0b746e5SOllivier Robert #ifdef STA_NANO 2918c0b746e5SOllivier Robert if (status & STA_NANO) 2919c0b746e5SOllivier Robert tscale = 1e-9; 2920c0b746e5SOllivier Robert #endif 2921c0b746e5SOllivier Robert (void)fprintf(fp, "pll offset: %g s\n", 2922c0b746e5SOllivier Robert (long)ntohl(ik->offset) * tscale); 2923c0b746e5SOllivier Robert (void)fprintf(fp, "pll frequency: %s ppm\n", 2924c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->freq), 3)); 2925c0b746e5SOllivier Robert (void)fprintf(fp, "maximum error: %g s\n", 2926c0b746e5SOllivier Robert (u_long)ntohl(ik->maxerror) * 1e-6); 2927c0b746e5SOllivier Robert (void)fprintf(fp, "estimated error: %g s\n", 2928c0b746e5SOllivier Robert (u_long)ntohl(ik->esterror) * 1e-6); 2929c0b746e5SOllivier Robert (void)fprintf(fp, "status: %04x ", status); 2930c0b746e5SOllivier Robert #ifdef STA_PLL 2931c0b746e5SOllivier Robert if (status & STA_PLL) (void)fprintf(fp, " pll"); 2932c0b746e5SOllivier Robert #endif 2933c0b746e5SOllivier Robert #ifdef STA_PPSFREQ 2934c0b746e5SOllivier Robert if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq"); 2935c0b746e5SOllivier Robert #endif 2936c0b746e5SOllivier Robert #ifdef STA_PPSTIME 2937c0b746e5SOllivier Robert if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime"); 2938c0b746e5SOllivier Robert #endif 2939c0b746e5SOllivier Robert #ifdef STA_FLL 2940c0b746e5SOllivier Robert if (status & STA_FLL) (void)fprintf(fp, " fll"); 2941c0b746e5SOllivier Robert #endif 2942c0b746e5SOllivier Robert #ifdef STA_INS 2943c0b746e5SOllivier Robert if (status & STA_INS) (void)fprintf(fp, " ins"); 2944c0b746e5SOllivier Robert #endif 2945c0b746e5SOllivier Robert #ifdef STA_DEL 2946c0b746e5SOllivier Robert if (status & STA_DEL) (void)fprintf(fp, " del"); 2947c0b746e5SOllivier Robert #endif 2948c0b746e5SOllivier Robert #ifdef STA_UNSYNC 2949c0b746e5SOllivier Robert if (status & STA_UNSYNC) (void)fprintf(fp, " unsync"); 2950c0b746e5SOllivier Robert #endif 2951c0b746e5SOllivier Robert #ifdef STA_FREQHOLD 2952c0b746e5SOllivier Robert if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold"); 2953c0b746e5SOllivier Robert #endif 2954c0b746e5SOllivier Robert #ifdef STA_PPSSIGNAL 2955c0b746e5SOllivier Robert if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal"); 2956c0b746e5SOllivier Robert #endif 2957c0b746e5SOllivier Robert #ifdef STA_PPSJITTER 2958c0b746e5SOllivier Robert if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter"); 2959c0b746e5SOllivier Robert #endif 2960c0b746e5SOllivier Robert #ifdef STA_PPSWANDER 2961c0b746e5SOllivier Robert if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander"); 2962c0b746e5SOllivier Robert #endif 2963c0b746e5SOllivier Robert #ifdef STA_PPSERROR 2964c0b746e5SOllivier Robert if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror"); 2965c0b746e5SOllivier Robert #endif 2966c0b746e5SOllivier Robert #ifdef STA_CLOCKERR 2967c0b746e5SOllivier Robert if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr"); 2968c0b746e5SOllivier Robert #endif 2969c0b746e5SOllivier Robert #ifdef STA_NANO 2970c0b746e5SOllivier Robert if (status & STA_NANO) (void)fprintf(fp, " nano"); 2971c0b746e5SOllivier Robert #endif 2972c0b746e5SOllivier Robert #ifdef STA_MODE 2973c0b746e5SOllivier Robert if (status & STA_MODE) (void)fprintf(fp, " mode=fll"); 2974c0b746e5SOllivier Robert #endif 2975c0b746e5SOllivier Robert #ifdef STA_CLK 2976c0b746e5SOllivier Robert if (status & STA_CLK) (void)fprintf(fp, " src=B"); 2977c0b746e5SOllivier Robert #endif 2978c0b746e5SOllivier Robert (void)fprintf(fp, "\n"); 2979c0b746e5SOllivier Robert (void)fprintf(fp, "pll time constant: %ld\n", 2980c0b746e5SOllivier Robert (u_long)ntohl(ik->constant)); 2981c0b746e5SOllivier Robert (void)fprintf(fp, "precision: %g s\n", 2982c0b746e5SOllivier Robert (u_long)ntohl(ik->precision) * tscale); 2983c0b746e5SOllivier Robert (void)fprintf(fp, "frequency tolerance: %s ppm\n", 2984c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->tolerance), 0)); 2985c0b746e5SOllivier Robert 2986c0b746e5SOllivier Robert /* 2987c0b746e5SOllivier Robert * For backwards compatibility (ugh), we find the pps variables 2988c0b746e5SOllivier Robert * only if the shift member is nonzero. 2989c0b746e5SOllivier Robert */ 2990c0b746e5SOllivier Robert if (!ik->shift) 2991c0b746e5SOllivier Robert return; 2992c0b746e5SOllivier Robert 2993c0b746e5SOllivier Robert /* 2994c0b746e5SOllivier Robert * pps variables 2995c0b746e5SOllivier Robert */ 2996c0b746e5SOllivier Robert (void)fprintf(fp, "pps frequency: %s ppm\n", 2997c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->ppsfreq), 3)); 2998c0b746e5SOllivier Robert (void)fprintf(fp, "pps stability: %s ppm\n", 2999c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->stabil), 3)); 3000c0b746e5SOllivier Robert (void)fprintf(fp, "pps jitter: %g s\n", 3001c0b746e5SOllivier Robert (u_long)ntohl(ik->jitter) * tscale); 3002c0b746e5SOllivier Robert (void)fprintf(fp, "calibration interval: %d s\n", 3003c0b746e5SOllivier Robert 1 << ntohs(ik->shift)); 3004c0b746e5SOllivier Robert (void)fprintf(fp, "calibration cycles: %ld\n", 3005c0b746e5SOllivier Robert (u_long)ntohl(ik->calcnt)); 3006c0b746e5SOllivier Robert (void)fprintf(fp, "jitter exceeded: %ld\n", 3007c0b746e5SOllivier Robert (u_long)ntohl(ik->jitcnt)); 3008c0b746e5SOllivier Robert (void)fprintf(fp, "stability exceeded: %ld\n", 3009c0b746e5SOllivier Robert (u_long)ntohl(ik->stbcnt)); 3010c0b746e5SOllivier Robert (void)fprintf(fp, "calibration errors: %ld\n", 3011c0b746e5SOllivier Robert (u_long)ntohl(ik->errcnt)); 3012c0b746e5SOllivier Robert } 3013