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 #if !defined(__bsdi__) && !defined(apollo) 22c0b746e5SOllivier Robert #include <netinet/in.h> 23c0b746e5SOllivier Robert #endif 24c0b746e5SOllivier Robert 25c0b746e5SOllivier Robert #include <arpa/inet.h> 26c0b746e5SOllivier Robert 27c0b746e5SOllivier Robert /* 28c0b746e5SOllivier Robert * Declarations for command handlers in here 29c0b746e5SOllivier Robert */ 30c0b746e5SOllivier Robert static int checkitems P((int, FILE *)); 31c0b746e5SOllivier Robert static int checkitemsize P((int, int)); 32c0b746e5SOllivier Robert static int check1item P((int, FILE *)); 33c0b746e5SOllivier Robert static void peerlist P((struct parse *, FILE *)); 34c0b746e5SOllivier Robert static void peers P((struct parse *, FILE *)); 35c0b746e5SOllivier Robert static void doconfig P((struct parse *pcmd, FILE *fp, int mode, int refc)); 36c0b746e5SOllivier Robert static void dmpeers P((struct parse *, FILE *)); 37c0b746e5SOllivier Robert static void dopeers P((struct parse *, FILE *, int)); 38c0b746e5SOllivier Robert static void printpeer P((struct info_peer *, FILE *)); 39c0b746e5SOllivier Robert static void showpeer P((struct parse *, FILE *)); 40c0b746e5SOllivier Robert static void peerstats P((struct parse *, FILE *)); 41c0b746e5SOllivier Robert static void loopinfo P((struct parse *, FILE *)); 42c0b746e5SOllivier Robert static void sysinfo P((struct parse *, FILE *)); 43c0b746e5SOllivier Robert static void sysstats P((struct parse *, FILE *)); 44c0b746e5SOllivier Robert static void iostats P((struct parse *, FILE *)); 45c0b746e5SOllivier Robert static void memstats P((struct parse *, FILE *)); 46c0b746e5SOllivier Robert static void timerstats P((struct parse *, FILE *)); 47c0b746e5SOllivier Robert static void addpeer P((struct parse *, FILE *)); 48c0b746e5SOllivier Robert static void addserver P((struct parse *, FILE *)); 49c0b746e5SOllivier Robert static void addrefclock P((struct parse *, FILE *)); 50c0b746e5SOllivier Robert static void broadcast P((struct parse *, FILE *)); 51c0b746e5SOllivier Robert static void doconfig P((struct parse *, FILE *, int, int)); 52c0b746e5SOllivier Robert static void unconfig P((struct parse *, FILE *)); 53c0b746e5SOllivier Robert static void set P((struct parse *, FILE *)); 54c0b746e5SOllivier Robert static void sys_clear P((struct parse *, FILE *)); 55c0b746e5SOllivier Robert static void doset P((struct parse *, FILE *, int)); 56c0b746e5SOllivier Robert static void reslist P((struct parse *, FILE *)); 57c0b746e5SOllivier Robert static void new_restrict P((struct parse *, FILE *)); 58c0b746e5SOllivier Robert static void unrestrict P((struct parse *, FILE *)); 59c0b746e5SOllivier Robert static void delrestrict P((struct parse *, FILE *)); 60c0b746e5SOllivier Robert static void do_restrict P((struct parse *, FILE *, int)); 61c0b746e5SOllivier Robert static void monlist P((struct parse *, FILE *)); 62c0b746e5SOllivier Robert static void reset P((struct parse *, FILE *)); 63c0b746e5SOllivier Robert static void preset P((struct parse *, FILE *)); 64c0b746e5SOllivier Robert static void readkeys P((struct parse *, FILE *)); 65c0b746e5SOllivier Robert static void trustkey P((struct parse *, FILE *)); 66c0b746e5SOllivier Robert static void untrustkey P((struct parse *, FILE *)); 67c0b746e5SOllivier Robert static void do_trustkey P((struct parse *, FILE *, int)); 68c0b746e5SOllivier Robert static void authinfo P((struct parse *, FILE *)); 69c0b746e5SOllivier Robert static void traps P((struct parse *, FILE *)); 70c0b746e5SOllivier Robert static void addtrap P((struct parse *, FILE *)); 71c0b746e5SOllivier Robert static void clrtrap P((struct parse *, FILE *)); 72c0b746e5SOllivier Robert static void do_addclr_trap P((struct parse *, FILE *, int)); 73c0b746e5SOllivier Robert static void requestkey P((struct parse *, FILE *)); 74c0b746e5SOllivier Robert static void controlkey P((struct parse *, FILE *)); 75c0b746e5SOllivier Robert static void do_changekey P((struct parse *, FILE *, int)); 76c0b746e5SOllivier Robert static void ctlstats P((struct parse *, FILE *)); 77c0b746e5SOllivier Robert static void clockstat P((struct parse *, FILE *)); 78c0b746e5SOllivier Robert static void fudge P((struct parse *, FILE *)); 79c0b746e5SOllivier Robert static void clkbug P((struct parse *, FILE *)); 80c0b746e5SOllivier Robert static void kerninfo P((struct parse *, FILE *)); 81ea906c41SOllivier Robert static void get_if_stats P((struct parse *, FILE *)); 82ea906c41SOllivier Robert static void do_if_reload P((struct parse *, FILE *)); 83c0b746e5SOllivier Robert 84c0b746e5SOllivier Robert /* 85c0b746e5SOllivier Robert * Commands we understand. Ntpdc imports this. 86c0b746e5SOllivier Robert */ 87c0b746e5SOllivier Robert struct xcmd opcmds[] = { 889c2daa00SOllivier Robert { "listpeers", peerlist, { OPT|IP_VERSION, NO, NO, NO }, 899c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 909c2daa00SOllivier Robert "display list of peers the server knows about [IP Version]" }, 919c2daa00SOllivier Robert { "peers", peers, { OPT|IP_VERSION, NO, NO, NO }, 929c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 939c2daa00SOllivier Robert "display peer summary information [IP Version]" }, 949c2daa00SOllivier Robert { "dmpeers", dmpeers, { OPT|IP_VERSION, NO, NO, NO }, 959c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 969c2daa00SOllivier Robert "display peer summary info the way Dave Mills likes it (IP Version)" }, 97ea906c41SOllivier Robert { "showpeer", showpeer, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD}, 98c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 99c0b746e5SOllivier Robert "display detailed information for one or more peers" }, 100ea906c41SOllivier Robert { "pstats", peerstats, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 101c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 102c0b746e5SOllivier Robert "display statistical information for one or more peers" }, 103c0b746e5SOllivier Robert { "loopinfo", loopinfo, { OPT|NTP_STR, NO, NO, NO }, 104c0b746e5SOllivier Robert { "oneline|multiline", "", "", "" }, 105c0b746e5SOllivier Robert "display loop filter information" }, 106c0b746e5SOllivier Robert { "sysinfo", sysinfo, { NO, NO, NO, NO }, 107c0b746e5SOllivier Robert { "", "", "", "" }, 108c0b746e5SOllivier Robert "display local server information" }, 109c0b746e5SOllivier Robert { "sysstats", sysstats, { NO, NO, NO, NO }, 110c0b746e5SOllivier Robert { "", "", "", "" }, 111c0b746e5SOllivier Robert "display local server statistics" }, 112c0b746e5SOllivier Robert { "memstats", memstats, { NO, NO, NO, NO }, 113c0b746e5SOllivier Robert { "", "", "", "" }, 114c0b746e5SOllivier Robert "display peer memory usage statistics" }, 115c0b746e5SOllivier Robert { "iostats", iostats, { NO, NO, NO, NO }, 116c0b746e5SOllivier Robert { "", "", "", "" }, 117c0b746e5SOllivier Robert "display I/O subsystem statistics" }, 118c0b746e5SOllivier Robert { "timerstats", timerstats, { NO, NO, NO, NO }, 119c0b746e5SOllivier Robert { "", "", "", "" }, 120c0b746e5SOllivier Robert "display event timer subsystem statistics" }, 121ea906c41SOllivier Robert { "addpeer", addpeer, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 122ea906c41SOllivier Robert { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." }, 123c0b746e5SOllivier Robert "configure a new peer association" }, 124ea906c41SOllivier Robert { "addserver", addserver, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 125ea906c41SOllivier Robert { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." }, 126c0b746e5SOllivier Robert "configure a new server" }, 127ea906c41SOllivier Robert { "addrefclock",addrefclock, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_STR, OPT|NTP_STR }, 128c0b746e5SOllivier Robert { "addr", "mode", "minpoll|prefer", "minpoll|prefer" }, 129c0b746e5SOllivier Robert "configure a new server" }, 130ea906c41SOllivier Robert { "broadcast", broadcast, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 131c0b746e5SOllivier Robert { "addr", "keyid", "version", "minpoll" }, 132c0b746e5SOllivier Robert "configure broadcasting time service" }, 133ea906c41SOllivier Robert { "unconfig", unconfig, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 134c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 135c0b746e5SOllivier Robert "unconfigure existing peer assocations" }, 136c0b746e5SOllivier Robert { "enable", set, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 137c0b746e5SOllivier Robert { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 138c0b746e5SOllivier Robert "set a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 139c0b746e5SOllivier Robert { "disable", sys_clear, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 140c0b746e5SOllivier Robert { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 141c0b746e5SOllivier Robert "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 1429c2daa00SOllivier Robert { "reslist", reslist, {OPT|IP_VERSION, NO, NO, NO }, 1439c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 144c0b746e5SOllivier Robert "display the server's restrict list" }, 145ea906c41SOllivier Robert { "restrict", new_restrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR }, 146c0b746e5SOllivier Robert { "address", "mask", 147224ba2bdSOllivier Robert "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 148c0b746e5SOllivier Robert "..." }, 149c0b746e5SOllivier Robert "create restrict entry/add flags to entry" }, 150ea906c41SOllivier Robert { "unrestrict", unrestrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR }, 151c0b746e5SOllivier Robert { "address", "mask", 152224ba2bdSOllivier Robert "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 153c0b746e5SOllivier Robert "..." }, 154c0b746e5SOllivier Robert "remove flags from a restrict entry" }, 155ea906c41SOllivier Robert { "delrestrict", delrestrict, { NTP_ADD, NTP_ADD, OPT|NTP_STR, NO }, 156c0b746e5SOllivier Robert { "address", "mask", "ntpport", "" }, 157c0b746e5SOllivier Robert "delete a restrict entry" }, 158ea906c41SOllivier Robert { "monlist", monlist, { OPT|NTP_INT, NO, NO, NO }, 159c0b746e5SOllivier Robert { "version", "", "", "" }, 160c0b746e5SOllivier Robert "display data the server's monitor routines have collected" }, 161c0b746e5SOllivier Robert { "reset", reset, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 162c0b746e5SOllivier Robert { "io|sys|mem|timer|auth|allpeers", "...", "...", "..." }, 163c0b746e5SOllivier Robert "reset various subsystem statistics counters" }, 164ea906c41SOllivier Robert { "preset", preset, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 165c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 166c0b746e5SOllivier Robert "reset stat counters associated with particular peer(s)" }, 167c0b746e5SOllivier Robert { "readkeys", readkeys, { NO, NO, NO, NO }, 168c0b746e5SOllivier Robert { "", "", "", "" }, 169c0b746e5SOllivier Robert "request a reread of the keys file and re-init of system keys" }, 170ea906c41SOllivier Robert { "trustedkey", trustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT }, 171c0b746e5SOllivier Robert { "keyid", "keyid", "keyid", "keyid" }, 172c0b746e5SOllivier Robert "add one or more key ID's to the trusted list" }, 173ea906c41SOllivier Robert { "untrustedkey", untrustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT }, 174c0b746e5SOllivier Robert { "keyid", "keyid", "keyid", "keyid" }, 175c0b746e5SOllivier Robert "remove one or more key ID's from the trusted list" }, 176c0b746e5SOllivier Robert { "authinfo", authinfo, { NO, NO, NO, NO }, 177c0b746e5SOllivier Robert { "", "", "", "" }, 178c0b746e5SOllivier Robert "display the state of the authentication code" }, 179c0b746e5SOllivier Robert { "traps", traps, { NO, NO, NO, NO }, 180c0b746e5SOllivier Robert { "", "", "", "" }, 181c0b746e5SOllivier Robert "display the traps set in the server" }, 182ea906c41SOllivier Robert { "addtrap", addtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO }, 183c0b746e5SOllivier Robert { "address", "port", "interface", "" }, 184c0b746e5SOllivier Robert "configure a trap in the server" }, 185ea906c41SOllivier Robert { "clrtrap", clrtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO }, 186c0b746e5SOllivier Robert { "address", "port", "interface", "" }, 187c0b746e5SOllivier Robert "remove a trap (configured or otherwise) from the server" }, 188ea906c41SOllivier Robert { "requestkey", requestkey, { NTP_UINT, NO, NO, NO }, 189c0b746e5SOllivier Robert { "keyid", "", "", "" }, 190c0b746e5SOllivier Robert "change the keyid the server uses to authenticate requests" }, 191ea906c41SOllivier Robert { "controlkey", controlkey, { NTP_UINT, NO, NO, NO }, 192c0b746e5SOllivier Robert { "keyid", "", "", "" }, 193c0b746e5SOllivier Robert "change the keyid the server uses to authenticate control messages" }, 194c0b746e5SOllivier Robert { "ctlstats", ctlstats, { NO, NO, NO, NO }, 195c0b746e5SOllivier Robert { "", "", "", "" }, 196c0b746e5SOllivier Robert "display packet count statistics from the control module" }, 197ea906c41SOllivier Robert { "clockstat", clockstat, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 198c0b746e5SOllivier Robert { "address", "address", "address", "address" }, 199c0b746e5SOllivier Robert "display clock status information" }, 200ea906c41SOllivier Robert { "fudge", fudge, { NTP_ADD, NTP_STR, NTP_STR, NO }, 201c0b746e5SOllivier Robert { "address", "time1|time2|val1|val2|flags", "value", "" }, 202c0b746e5SOllivier Robert "set/change one of a clock's fudge factors" }, 203ea906c41SOllivier Robert { "clkbug", clkbug, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 204c0b746e5SOllivier Robert { "address", "address", "address", "address" }, 205c0b746e5SOllivier Robert "display clock debugging information" }, 206c0b746e5SOllivier Robert { "kerninfo", kerninfo, { NO, NO, NO, NO }, 207c0b746e5SOllivier Robert { "", "", "", "" }, 208c0b746e5SOllivier Robert "display the kernel pll/pps variables" }, 209ea906c41SOllivier Robert { "ifstats", get_if_stats, { NO, NO, NO, NO }, 210ea906c41SOllivier Robert { "", "", "", "" }, 211ea906c41SOllivier Robert "list interface statistics" }, 212ea906c41SOllivier Robert { "ifreload", do_if_reload, { NO, NO, NO, NO }, 213ea906c41SOllivier Robert { "", "", "", "" }, 214ea906c41SOllivier Robert "reload interface configuration" }, 215c0b746e5SOllivier Robert { 0, 0, { NO, NO, NO, NO }, 216c0b746e5SOllivier Robert { "", "", "", "" }, "" } 217c0b746e5SOllivier Robert }; 218c0b746e5SOllivier Robert 219c0b746e5SOllivier Robert /* 220c0b746e5SOllivier Robert * For quick string comparisons 221c0b746e5SOllivier Robert */ 222c0b746e5SOllivier Robert #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 223c0b746e5SOllivier Robert 224c0b746e5SOllivier Robert 225c0b746e5SOllivier Robert /* 226c0b746e5SOllivier Robert * checkitems - utility to print a message if no items were returned 227c0b746e5SOllivier Robert */ 228c0b746e5SOllivier Robert static int 229c0b746e5SOllivier Robert checkitems( 230c0b746e5SOllivier Robert int items, 231c0b746e5SOllivier Robert FILE *fp 232c0b746e5SOllivier Robert ) 233c0b746e5SOllivier Robert { 234c0b746e5SOllivier Robert if (items == 0) { 235c0b746e5SOllivier Robert (void) fprintf(fp, "No data returned in response to query\n"); 236c0b746e5SOllivier Robert return 0; 237c0b746e5SOllivier Robert } 238c0b746e5SOllivier Robert return 1; 239c0b746e5SOllivier Robert } 240c0b746e5SOllivier Robert 241c0b746e5SOllivier Robert 242c0b746e5SOllivier Robert /* 243c0b746e5SOllivier Robert * checkitemsize - utility to print a message if the item size is wrong 244c0b746e5SOllivier Robert */ 245c0b746e5SOllivier Robert static int 246c0b746e5SOllivier Robert checkitemsize( 247c0b746e5SOllivier Robert int itemsize, 248c0b746e5SOllivier Robert int expected 249c0b746e5SOllivier Robert ) 250c0b746e5SOllivier Robert { 251c0b746e5SOllivier Robert if (itemsize != expected) { 252c0b746e5SOllivier Robert (void) fprintf(stderr, 253c0b746e5SOllivier Robert "***Incorrect item size returned by remote host (%d should be %d)\n", 254c0b746e5SOllivier Robert itemsize, expected); 255c0b746e5SOllivier Robert return 0; 256c0b746e5SOllivier Robert } 257c0b746e5SOllivier Robert return 1; 258c0b746e5SOllivier Robert } 259c0b746e5SOllivier Robert 260c0b746e5SOllivier Robert 261c0b746e5SOllivier Robert /* 262c0b746e5SOllivier Robert * check1item - check to make sure we have exactly one item 263c0b746e5SOllivier Robert */ 264c0b746e5SOllivier Robert static int 265c0b746e5SOllivier Robert check1item( 266c0b746e5SOllivier Robert int items, 267c0b746e5SOllivier Robert FILE *fp 268c0b746e5SOllivier Robert ) 269c0b746e5SOllivier Robert { 270c0b746e5SOllivier Robert if (items == 0) { 271c0b746e5SOllivier Robert (void) fprintf(fp, "No data returned in response to query\n"); 272c0b746e5SOllivier Robert return 0; 273c0b746e5SOllivier Robert } 274c0b746e5SOllivier Robert if (items > 1) { 275c0b746e5SOllivier Robert (void) fprintf(fp, "Expected one item in response, got %d\n", 276c0b746e5SOllivier Robert items); 277c0b746e5SOllivier Robert return 0; 278c0b746e5SOllivier Robert } 279c0b746e5SOllivier Robert return 1; 280c0b746e5SOllivier Robert } 281c0b746e5SOllivier Robert 282c0b746e5SOllivier Robert 283c0b746e5SOllivier Robert 284c0b746e5SOllivier Robert /* 285c0b746e5SOllivier Robert * peerlist - get a short list of peers 286c0b746e5SOllivier Robert */ 287c0b746e5SOllivier Robert /*ARGSUSED*/ 288c0b746e5SOllivier Robert static void 289c0b746e5SOllivier Robert peerlist( 290c0b746e5SOllivier Robert struct parse *pcmd, 291c0b746e5SOllivier Robert FILE *fp 292c0b746e5SOllivier Robert ) 293c0b746e5SOllivier Robert { 294c0b746e5SOllivier Robert struct info_peer_list *plist; 2959c2daa00SOllivier Robert struct sockaddr_storage paddr; 296c0b746e5SOllivier Robert int items; 297c0b746e5SOllivier Robert int itemsize; 298c0b746e5SOllivier Robert int res; 299c0b746e5SOllivier Robert 3009c2daa00SOllivier Robert again: 3019c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items, 3029c2daa00SOllivier Robert &itemsize, (void *)&plist, 0, 3039c2daa00SOllivier Robert sizeof(struct info_peer_list)); 3049c2daa00SOllivier Robert 3059c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 3069c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 3079c2daa00SOllivier Robert goto again; 3089c2daa00SOllivier Robert } 309c0b746e5SOllivier Robert 310ea906c41SOllivier Robert if (res != 0) 311c0b746e5SOllivier Robert return; 312c0b746e5SOllivier Robert 313c0b746e5SOllivier Robert if (!checkitems(items, fp)) 314c0b746e5SOllivier Robert return; 315c0b746e5SOllivier Robert 3169c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_list)) && 3179c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_list))) 318c0b746e5SOllivier Robert return; 319c0b746e5SOllivier Robert 320c0b746e5SOllivier Robert while (items > 0) { 3219c2daa00SOllivier Robert memset((char *)&paddr, 0, sizeof(paddr)); 3229c2daa00SOllivier Robert if (plist->v6_flag != 0) { 3239c2daa00SOllivier Robert GET_INADDR6(paddr) = plist->addr6; 3249c2daa00SOllivier Robert paddr.ss_family = AF_INET6; 3259c2daa00SOllivier Robert } else { 3269c2daa00SOllivier Robert GET_INADDR(paddr) = plist->addr; 3279c2daa00SOllivier Robert paddr.ss_family = AF_INET; 3289c2daa00SOllivier Robert } 3299c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 3309c2daa00SOllivier Robert paddr.ss_len = SOCKLEN(&paddr); 3319c2daa00SOllivier Robert #endif 3329c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 3339c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 3349c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 3359c2daa00SOllivier Robert (void) fprintf(fp, "%-9s %s\n", 3369c2daa00SOllivier Robert modetoa(plist->hmode), 3379c2daa00SOllivier Robert nntohost(&paddr)); 338c0b746e5SOllivier Robert plist++; 339c0b746e5SOllivier Robert items--; 340c0b746e5SOllivier Robert } 341c0b746e5SOllivier Robert } 342c0b746e5SOllivier Robert 343c0b746e5SOllivier Robert 344c0b746e5SOllivier Robert /* 345c0b746e5SOllivier Robert * peers - show peer summary 346c0b746e5SOllivier Robert */ 347c0b746e5SOllivier Robert static void 348c0b746e5SOllivier Robert peers( 349c0b746e5SOllivier Robert struct parse *pcmd, 350c0b746e5SOllivier Robert FILE *fp 351c0b746e5SOllivier Robert ) 352c0b746e5SOllivier Robert { 353c0b746e5SOllivier Robert dopeers(pcmd, fp, 0); 354c0b746e5SOllivier Robert } 355c0b746e5SOllivier Robert 356c0b746e5SOllivier Robert /* 357c0b746e5SOllivier Robert * dmpeers - show peer summary, Dave Mills style 358c0b746e5SOllivier Robert */ 359c0b746e5SOllivier Robert static void 360c0b746e5SOllivier Robert dmpeers( 361c0b746e5SOllivier Robert struct parse *pcmd, 362c0b746e5SOllivier Robert FILE *fp 363c0b746e5SOllivier Robert ) 364c0b746e5SOllivier Robert { 365c0b746e5SOllivier Robert dopeers(pcmd, fp, 1); 366c0b746e5SOllivier Robert } 367c0b746e5SOllivier Robert 368c0b746e5SOllivier Robert 369c0b746e5SOllivier Robert /* 370c0b746e5SOllivier Robert * peers - show peer summary 371c0b746e5SOllivier Robert */ 372c0b746e5SOllivier Robert /*ARGSUSED*/ 373c0b746e5SOllivier Robert static void 374c0b746e5SOllivier Robert dopeers( 375c0b746e5SOllivier Robert struct parse *pcmd, 376c0b746e5SOllivier Robert FILE *fp, 377c0b746e5SOllivier Robert int dmstyle 378c0b746e5SOllivier Robert ) 379c0b746e5SOllivier Robert { 380c0b746e5SOllivier Robert struct info_peer_summary *plist; 3819c2daa00SOllivier Robert struct sockaddr_storage dstadr; 3829c2daa00SOllivier Robert struct sockaddr_storage srcadr; 383c0b746e5SOllivier Robert int items; 384c0b746e5SOllivier Robert int itemsize; 385c0b746e5SOllivier Robert int ntp_poll; 386c0b746e5SOllivier Robert int res; 387c0b746e5SOllivier Robert int c; 388c0b746e5SOllivier Robert l_fp tempts; 389c0b746e5SOllivier Robert 3909c2daa00SOllivier Robert again: 3919c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL, 3929c2daa00SOllivier Robert &items, &itemsize, (void *)&plist, 0, 3939c2daa00SOllivier Robert sizeof(struct info_peer_summary)); 3949c2daa00SOllivier Robert 3959c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 3969c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 3979c2daa00SOllivier Robert goto again; 3989c2daa00SOllivier Robert } 399c0b746e5SOllivier Robert 400ea906c41SOllivier Robert if (res != 0) 401c0b746e5SOllivier Robert return; 402c0b746e5SOllivier Robert 403c0b746e5SOllivier Robert if (!checkitems(items, fp)) 404c0b746e5SOllivier Robert return; 405c0b746e5SOllivier Robert 4069c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) && 4079c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_summary))) 408c0b746e5SOllivier Robert return; 409c0b746e5SOllivier Robert 410c0b746e5SOllivier Robert (void) fprintf(fp, 411c0b746e5SOllivier Robert " remote local st poll reach delay offset disp\n"); 412c0b746e5SOllivier Robert (void) fprintf(fp, 413c0b746e5SOllivier Robert "=======================================================================\n"); 414c0b746e5SOllivier Robert while (items > 0) { 415c0b746e5SOllivier Robert if (!dmstyle) { 416c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 417c0b746e5SOllivier Robert c = '*'; 418c0b746e5SOllivier Robert else if (plist->hmode == MODE_ACTIVE) 419c0b746e5SOllivier Robert c = '+'; 420c0b746e5SOllivier Robert else if (plist->hmode == MODE_PASSIVE) 421c0b746e5SOllivier Robert c = '-'; 422c0b746e5SOllivier Robert else if (plist->hmode == MODE_CLIENT) 423c0b746e5SOllivier Robert c = '='; 424c0b746e5SOllivier Robert else if (plist->hmode == MODE_BROADCAST) 425c0b746e5SOllivier Robert c = '^'; 426c0b746e5SOllivier Robert else if (plist->hmode == MODE_BCLIENT) 427c0b746e5SOllivier Robert c = '~'; 428c0b746e5SOllivier Robert else 429c0b746e5SOllivier Robert c = ' '; 430c0b746e5SOllivier Robert } else { 431c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 432c0b746e5SOllivier Robert c = '*'; 433c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SHORTLIST) 434c0b746e5SOllivier Robert c = '+'; 435c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SEL_CANDIDATE) 436c0b746e5SOllivier Robert c = '.'; 437c0b746e5SOllivier Robert else 438c0b746e5SOllivier Robert c = ' '; 439c0b746e5SOllivier Robert } 440c0b746e5SOllivier Robert NTOHL_FP(&(plist->offset), &tempts); 441c0b746e5SOllivier Robert ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL), 442c0b746e5SOllivier Robert NTP_MINPOLL); 4439c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 4449c2daa00SOllivier Robert memset((char *)&srcadr, 0, sizeof(srcadr)); 4459c2daa00SOllivier Robert if (plist->v6_flag != 0) { 4469c2daa00SOllivier Robert GET_INADDR6(dstadr) = plist->dstadr6; 4479c2daa00SOllivier Robert GET_INADDR6(srcadr) = plist->srcadr6; 4489c2daa00SOllivier Robert srcadr.ss_family = AF_INET6; 4499c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 4509c2daa00SOllivier Robert } else { 4519c2daa00SOllivier Robert GET_INADDR(dstadr) = plist->dstadr; 4529c2daa00SOllivier Robert GET_INADDR(srcadr) = plist->srcadr; 4539c2daa00SOllivier Robert srcadr.ss_family = AF_INET; 4549c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 4559c2daa00SOllivier Robert } 4569c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 4579c2daa00SOllivier Robert srcadr.ss_len = SOCKLEN(&srcadr); 4589c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 4599c2daa00SOllivier Robert #endif 4609c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 4619c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 4629c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 463c0b746e5SOllivier Robert (void) fprintf(fp, 464c0b746e5SOllivier Robert "%c%-15.15s %-15.15s %2d %4d %3o %7.7s %9.9s %7.7s\n", 4659c2daa00SOllivier Robert c, nntohost(&srcadr), stoa(&dstadr), 466c0b746e5SOllivier Robert plist->stratum, ntp_poll, plist->reach, 467c0b746e5SOllivier Robert fptoa(NTOHS_FP(plist->delay), 5), 468c0b746e5SOllivier Robert lfptoa(&tempts, 6), 469c0b746e5SOllivier Robert ufptoa(NTOHS_FP(plist->dispersion), 5)); 470c0b746e5SOllivier Robert plist++; 471c0b746e5SOllivier Robert items--; 472c0b746e5SOllivier Robert } 473c0b746e5SOllivier Robert } 474c0b746e5SOllivier Robert 475c0b746e5SOllivier Robert /* Convert a refid & stratum (in host order) to a string */ 476c0b746e5SOllivier Robert static char* 477c0b746e5SOllivier Robert refid_string( 478c0b746e5SOllivier Robert u_int32 refid, 479c0b746e5SOllivier Robert int stratum 480c0b746e5SOllivier Robert ) 481c0b746e5SOllivier Robert { 482c0b746e5SOllivier Robert if (stratum <= 1) { 483c0b746e5SOllivier Robert static char junk[5]; 484c0b746e5SOllivier Robert junk[4] = 0; 485c0b746e5SOllivier Robert memmove(junk, (char *)&refid, 4); 486c0b746e5SOllivier Robert return junk; 487c0b746e5SOllivier Robert } 488c0b746e5SOllivier Robert 489c0b746e5SOllivier Robert return numtoa(refid); 490c0b746e5SOllivier Robert } 491c0b746e5SOllivier Robert 492ea906c41SOllivier Robert static void 493ea906c41SOllivier Robert print_pflag( 494ea906c41SOllivier Robert FILE *fp, 495ea906c41SOllivier Robert u_int32 flags 496ea906c41SOllivier Robert ) 497ea906c41SOllivier Robert { 498ea906c41SOllivier Robert const char *str; 499ea906c41SOllivier Robert 500ea906c41SOllivier Robert if (flags == 0) { 501ea906c41SOllivier Robert (void) fprintf(fp, " none\n"); 502ea906c41SOllivier Robert } else { 503ea906c41SOllivier Robert str = ""; 504ea906c41SOllivier Robert if (flags & INFO_FLAG_SYSPEER) { 505ea906c41SOllivier Robert (void) fprintf(fp, " system_peer"); 506ea906c41SOllivier Robert str = ","; 507ea906c41SOllivier Robert } 508ea906c41SOllivier Robert if (flags & INFO_FLAG_CONFIG) { 509ea906c41SOllivier Robert (void) fprintf(fp, "%s config", str); 510ea906c41SOllivier Robert str = ","; 511ea906c41SOllivier Robert } 512ea906c41SOllivier Robert if (flags & INFO_FLAG_REFCLOCK) { 513ea906c41SOllivier Robert (void) fprintf(fp, "%s refclock", str); 514ea906c41SOllivier Robert str = ","; 515ea906c41SOllivier Robert } 516ea906c41SOllivier Robert if (flags & INFO_FLAG_AUTHENABLE) { 517ea906c41SOllivier Robert (void) fprintf(fp, "%s auth", str); 518ea906c41SOllivier Robert str = ","; 519ea906c41SOllivier Robert } 520ea906c41SOllivier Robert if (flags & INFO_FLAG_BCLIENT) { 521ea906c41SOllivier Robert (void) fprintf(fp, "%s bclient", str); 522ea906c41SOllivier Robert str = ","; 523ea906c41SOllivier Robert } 524ea906c41SOllivier Robert if (flags & INFO_FLAG_PREFER) { 525ea906c41SOllivier Robert (void) fprintf(fp, "%s prefer", str); 526ea906c41SOllivier Robert str = ","; 527ea906c41SOllivier Robert } 528ea906c41SOllivier Robert if (flags & INFO_FLAG_IBURST) { 529ea906c41SOllivier Robert (void) fprintf(fp, "%s iburst", str); 530ea906c41SOllivier Robert str = ","; 531ea906c41SOllivier Robert } 532ea906c41SOllivier Robert if (flags & INFO_FLAG_BURST) { 533ea906c41SOllivier Robert (void) fprintf(fp, "%s burst", str); 534ea906c41SOllivier Robert } 535ea906c41SOllivier Robert (void) fprintf(fp, "\n"); 536ea906c41SOllivier Robert } 537ea906c41SOllivier Robert } 538c0b746e5SOllivier Robert /* 539c0b746e5SOllivier Robert * printpeer - print detail information for a peer 540c0b746e5SOllivier Robert */ 541c0b746e5SOllivier Robert static void 542c0b746e5SOllivier Robert printpeer( 543c0b746e5SOllivier Robert register struct info_peer *pp, 544c0b746e5SOllivier Robert FILE *fp 545c0b746e5SOllivier Robert ) 546c0b746e5SOllivier Robert { 547c0b746e5SOllivier Robert register int i; 548c0b746e5SOllivier Robert l_fp tempts; 5499c2daa00SOllivier Robert struct sockaddr_storage srcadr, dstadr; 550c0b746e5SOllivier Robert 5519c2daa00SOllivier Robert memset((char *)&srcadr, 0, sizeof(srcadr)); 5529c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 5539c2daa00SOllivier Robert if (pp->v6_flag != 0) { 5549c2daa00SOllivier Robert srcadr.ss_family = AF_INET6; 5559c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 5569c2daa00SOllivier Robert GET_INADDR6(srcadr) = pp->srcadr6; 5579c2daa00SOllivier Robert GET_INADDR6(dstadr) = pp->dstadr6; 5589c2daa00SOllivier Robert } else { 5599c2daa00SOllivier Robert srcadr.ss_family = AF_INET; 5609c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 5619c2daa00SOllivier Robert GET_INADDR(srcadr) = pp->srcadr; 5629c2daa00SOllivier Robert GET_INADDR(dstadr) = pp->dstadr; 5639c2daa00SOllivier Robert } 5649c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 5659c2daa00SOllivier Robert srcadr.ss_len = SOCKLEN(&srcadr); 5669c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 5679c2daa00SOllivier Robert #endif 568c0b746e5SOllivier Robert (void) fprintf(fp, "remote %s, local %s\n", 5699c2daa00SOllivier Robert stoa(&srcadr), stoa(&dstadr)); 570c0b746e5SOllivier Robert (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n", 571c0b746e5SOllivier Robert modetoa(pp->hmode), modetoa(pp->pmode), 572c0b746e5SOllivier Robert pp->stratum, pp->precision); 573c0b746e5SOllivier Robert 574c0b746e5SOllivier Robert (void) fprintf(fp, 575c0b746e5SOllivier Robert "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n", 576c0b746e5SOllivier Robert pp->leap & 0x2 ? '1' : '0', 577c0b746e5SOllivier Robert pp->leap & 0x1 ? '1' : '0', 578c0b746e5SOllivier Robert refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5), 579c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->rootdispersion), 5)); 580c0b746e5SOllivier Robert 581c0b746e5SOllivier Robert (void) fprintf(fp, 582c0b746e5SOllivier Robert "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n", 583c0b746e5SOllivier Robert pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd)); 584c0b746e5SOllivier Robert 585c0b746e5SOllivier Robert (void) fprintf(fp, 586224ba2bdSOllivier Robert "reach %03o, unreach %d, flash 0x%04x, ", 587224ba2bdSOllivier Robert pp->reach, pp->unreach, pp->flash2); 588c0b746e5SOllivier Robert 589c0b746e5SOllivier Robert (void) fprintf(fp, "boffset %s, ttl/mode %d\n", 590c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl); 591c0b746e5SOllivier Robert 592c0b746e5SOllivier Robert (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer)); 593ea906c41SOllivier Robert print_pflag(fp, pp->flags); 594c0b746e5SOllivier Robert 595c0b746e5SOllivier Robert NTOHL_FP(&pp->reftime, &tempts); 596c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", 597c0b746e5SOllivier Robert prettydate(&tempts)); 598c0b746e5SOllivier Robert NTOHL_FP(&pp->org, &tempts); 599c0b746e5SOllivier Robert (void) fprintf(fp, "originate timestamp: %s\n", 600c0b746e5SOllivier Robert prettydate(&tempts)); 601c0b746e5SOllivier Robert NTOHL_FP(&pp->rec, &tempts); 602c0b746e5SOllivier Robert (void) fprintf(fp, "receive timestamp: %s\n", 603c0b746e5SOllivier Robert prettydate(&tempts)); 604c0b746e5SOllivier Robert NTOHL_FP(&pp->xmt, &tempts); 605c0b746e5SOllivier Robert (void) fprintf(fp, "transmit timestamp: %s\n", 606c0b746e5SOllivier Robert prettydate(&tempts)); 607c0b746e5SOllivier Robert 608c0b746e5SOllivier Robert (void) fprintf(fp, "filter delay: "); 609c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 610c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", 611c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->filtdelay[i]), 5)); 612c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 613c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 614c0b746e5SOllivier Robert } 615c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 616c0b746e5SOllivier Robert 617c0b746e5SOllivier Robert (void) fprintf(fp, "filter offset:"); 618c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 619c0b746e5SOllivier Robert NTOHL_FP(&pp->filtoffset[i], &tempts); 620c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6)); 621c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 622c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 623c0b746e5SOllivier Robert } 624c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 625c0b746e5SOllivier Robert 626c0b746e5SOllivier Robert (void) fprintf(fp, "filter order: "); 627c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 628c0b746e5SOllivier Robert (void) fprintf(fp, " %-8d", pp->order[i]); 629c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 630c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 631c0b746e5SOllivier Robert } 632c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 633c0b746e5SOllivier Robert 634c0b746e5SOllivier Robert 635c0b746e5SOllivier Robert NTOHL_FP(&pp->offset, &tempts); 636c0b746e5SOllivier Robert (void) fprintf(fp, 637c0b746e5SOllivier Robert "offset %s, delay %s, error bound %s, filter error %s\n", 638c0b746e5SOllivier Robert lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5), 639c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->dispersion), 5), 640c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->selectdisp), 5)); 641c0b746e5SOllivier Robert } 642c0b746e5SOllivier Robert 643c0b746e5SOllivier Robert 644c0b746e5SOllivier Robert /* 645c0b746e5SOllivier Robert * showpeer - show detailed information for a peer 646c0b746e5SOllivier Robert */ 647c0b746e5SOllivier Robert static void 648c0b746e5SOllivier Robert showpeer( 649c0b746e5SOllivier Robert struct parse *pcmd, 650c0b746e5SOllivier Robert FILE *fp 651c0b746e5SOllivier Robert ) 652c0b746e5SOllivier Robert { 653c0b746e5SOllivier Robert struct info_peer *pp; 654c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 6559c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 656c0b746e5SOllivier Robert int qitems; 657c0b746e5SOllivier Robert int items; 658c0b746e5SOllivier Robert int itemsize; 659c0b746e5SOllivier Robert int res; 6609c2daa00SOllivier Robert int sendsize; 661c0b746e5SOllivier Robert 6629c2daa00SOllivier Robert again: 6639c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 6649c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 6659c2daa00SOllivier Robert else 6669c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 6679c2daa00SOllivier Robert 6689c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 4); qitems++) { 6699c2daa00SOllivier Robert if (pcmd->argval[qitems].netnum.ss_family == AF_INET) { 6709c2daa00SOllivier Robert pl->addr = GET_INADDR(pcmd->argval[qitems].netnum); 6719c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 6729c2daa00SOllivier Robert pl->v6_flag = 0; 6739c2daa00SOllivier Robert } else { 6749c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 6759c2daa00SOllivier Robert fprintf(stderr, 6769c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 6779c2daa00SOllivier Robert return; 6789c2daa00SOllivier Robert } 6799c2daa00SOllivier Robert pl->addr6 = GET_INADDR6(pcmd->argval[qitems].netnum); 6809c2daa00SOllivier Robert pl->v6_flag = 1; 6819c2daa00SOllivier Robert } 6829c2daa00SOllivier Robert pl->port = (u_short)s_port; 6839c2daa00SOllivier Robert pl->hmode = pl->flags = 0; 6849c2daa00SOllivier Robert pl = (struct info_peer_list *)((char *)pl + sendsize); 685c0b746e5SOllivier Robert } 686c0b746e5SOllivier Robert 6879c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems, 6889c2daa00SOllivier Robert sendsize, (char *)plist, &items, 6899c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, sizeof(struct info_peer)); 6909c2daa00SOllivier Robert 6919c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 6929c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 6939c2daa00SOllivier Robert goto again; 6949c2daa00SOllivier Robert } 695c0b746e5SOllivier Robert 696ea906c41SOllivier Robert if (res != 0) 697c0b746e5SOllivier Robert return; 698c0b746e5SOllivier Robert 699c0b746e5SOllivier Robert if (!checkitems(items, fp)) 700c0b746e5SOllivier Robert return; 701c0b746e5SOllivier Robert 7029c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer)) && 7039c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer))) 704c0b746e5SOllivier Robert return; 705c0b746e5SOllivier Robert 706c0b746e5SOllivier Robert while (items-- > 0) { 707c0b746e5SOllivier Robert printpeer(pp, fp); 708c0b746e5SOllivier Robert if (items > 0) 709c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 710c0b746e5SOllivier Robert pp++; 711c0b746e5SOllivier Robert } 712c0b746e5SOllivier Robert } 713c0b746e5SOllivier Robert 714c0b746e5SOllivier Robert 715c0b746e5SOllivier Robert /* 716c0b746e5SOllivier Robert * peerstats - return statistics for a peer 717c0b746e5SOllivier Robert */ 718c0b746e5SOllivier Robert static void 719c0b746e5SOllivier Robert peerstats( 720c0b746e5SOllivier Robert struct parse *pcmd, 721c0b746e5SOllivier Robert FILE *fp 722c0b746e5SOllivier Robert ) 723c0b746e5SOllivier Robert { 724c0b746e5SOllivier Robert struct info_peer_stats *pp; 725c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 7269c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 7279c2daa00SOllivier Robert struct sockaddr_storage src, dst; 728c0b746e5SOllivier Robert int qitems; 729c0b746e5SOllivier Robert int items; 730c0b746e5SOllivier Robert int itemsize; 731c0b746e5SOllivier Robert int res; 7329c2daa00SOllivier Robert int sendsize; 733c0b746e5SOllivier Robert 7349c2daa00SOllivier Robert again: 7359c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7369c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 7379c2daa00SOllivier Robert else 7389c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 7399c2daa00SOllivier Robert 7409c2daa00SOllivier Robert memset((char *)plist, 0, sizeof(struct info_peer_list) * min(MAXARGS, 4)); 7419c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 4); qitems++) { 7429c2daa00SOllivier Robert if (pcmd->argval[qitems].netnum.ss_family == AF_INET) { 7439c2daa00SOllivier Robert pl->addr = GET_INADDR(pcmd->argval[qitems].netnum); 7449c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7459c2daa00SOllivier Robert pl->v6_flag = 0; 7469c2daa00SOllivier Robert } else { 7479c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 7489c2daa00SOllivier Robert fprintf(stderr, 7499c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 7509c2daa00SOllivier Robert return; 7519c2daa00SOllivier Robert } 7529c2daa00SOllivier Robert pl->addr6 = GET_INADDR6(pcmd->argval[qitems].netnum); 7539c2daa00SOllivier Robert pl->v6_flag = 1; 7549c2daa00SOllivier Robert } 7559c2daa00SOllivier Robert pl->port = (u_short)s_port; 7569c2daa00SOllivier Robert pl->hmode = plist[qitems].flags = 0; 7579c2daa00SOllivier Robert pl = (struct info_peer_list *)((char *)pl + sendsize); 758c0b746e5SOllivier Robert } 759c0b746e5SOllivier Robert 7609c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems, 7619c2daa00SOllivier Robert sendsize, (char *)plist, &items, 7629c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, 7639c2daa00SOllivier Robert sizeof(struct info_peer_stats)); 7649c2daa00SOllivier Robert 7659c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 7669c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 7679c2daa00SOllivier Robert goto again; 7689c2daa00SOllivier Robert } 769c0b746e5SOllivier Robert 770ea906c41SOllivier Robert if (res != 0) 771c0b746e5SOllivier Robert return; 772c0b746e5SOllivier Robert 773c0b746e5SOllivier Robert if (!checkitems(items, fp)) 774c0b746e5SOllivier Robert return; 775c0b746e5SOllivier Robert 7769c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) && 7779c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_stats))) 778c0b746e5SOllivier Robert return; 779c0b746e5SOllivier Robert 780c0b746e5SOllivier Robert while (items-- > 0) { 7819c2daa00SOllivier Robert memset((char *)&src, 0, sizeof(src)); 7829c2daa00SOllivier Robert memset((char *)&dst, 0, sizeof(dst)); 7839c2daa00SOllivier Robert if (pp->v6_flag != 0) { 7849c2daa00SOllivier Robert GET_INADDR6(src) = pp->srcadr6; 7859c2daa00SOllivier Robert GET_INADDR6(dst) = pp->dstadr6; 7869c2daa00SOllivier Robert src.ss_family = AF_INET6; 7879c2daa00SOllivier Robert dst.ss_family = AF_INET6; 7889c2daa00SOllivier Robert } else { 7899c2daa00SOllivier Robert GET_INADDR(src) = pp->srcadr; 7909c2daa00SOllivier Robert GET_INADDR(dst) = pp->dstadr; 7919c2daa00SOllivier Robert src.ss_family = AF_INET; 7929c2daa00SOllivier Robert dst.ss_family = AF_INET; 7939c2daa00SOllivier Robert } 7949c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 7959c2daa00SOllivier Robert src.ss_len = SOCKLEN(&src); 7969c2daa00SOllivier Robert dst.ss_len = SOCKLEN(&dst); 7979c2daa00SOllivier Robert #endif 798c0b746e5SOllivier Robert (void) fprintf(fp, "remote host: %s\n", 7999c2daa00SOllivier Robert nntohost(&src)); 800c0b746e5SOllivier Robert (void) fprintf(fp, "local interface: %s\n", 8019c2daa00SOllivier Robert stoa(&dst)); 802c0b746e5SOllivier Robert (void) fprintf(fp, "time last received: %lds\n", 803c0b746e5SOllivier Robert (long)ntohl(pp->timereceived)); 804c0b746e5SOllivier Robert (void) fprintf(fp, "time until next send: %lds\n", 805c0b746e5SOllivier Robert (long)ntohl(pp->timetosend)); 806c0b746e5SOllivier Robert (void) fprintf(fp, "reachability change: %lds\n", 807c0b746e5SOllivier Robert (long)ntohl(pp->timereachable)); 808c0b746e5SOllivier Robert (void) fprintf(fp, "packets sent: %ld\n", 809c0b746e5SOllivier Robert (long)ntohl(pp->sent)); 810c0b746e5SOllivier Robert (void) fprintf(fp, "packets received: %ld\n", 811c0b746e5SOllivier Robert (long)ntohl(pp->processed)); 812c0b746e5SOllivier Robert (void) fprintf(fp, "bad authentication: %ld\n", 813c0b746e5SOllivier Robert (long)ntohl(pp->badauth)); 814c0b746e5SOllivier Robert (void) fprintf(fp, "bogus origin: %ld\n", 815c0b746e5SOllivier Robert (long)ntohl(pp->bogusorg)); 816c0b746e5SOllivier Robert (void) fprintf(fp, "duplicate: %ld\n", 817c0b746e5SOllivier Robert (long)ntohl(pp->oldpkt)); 818c0b746e5SOllivier Robert (void) fprintf(fp, "bad dispersion: %ld\n", 819c0b746e5SOllivier Robert (long)ntohl(pp->seldisp)); 820c0b746e5SOllivier Robert (void) fprintf(fp, "bad reference time: %ld\n", 821c0b746e5SOllivier Robert (long)ntohl(pp->selbroken)); 822c0b746e5SOllivier Robert (void) fprintf(fp, "candidate order: %d\n", 823c0b746e5SOllivier Robert (int)pp->candidate); 824c0b746e5SOllivier Robert if (items > 0) 825c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 826ea906c41SOllivier Robert (void) fprintf(fp, "flags: "); 827ea906c41SOllivier Robert print_pflag(fp, ntohs(pp->flags)); 828c0b746e5SOllivier Robert pp++; 829c0b746e5SOllivier Robert } 830c0b746e5SOllivier Robert } 831c0b746e5SOllivier Robert 832c0b746e5SOllivier Robert 833c0b746e5SOllivier Robert /* 834c0b746e5SOllivier Robert * loopinfo - show loop filter information 835c0b746e5SOllivier Robert */ 836c0b746e5SOllivier Robert static void 837c0b746e5SOllivier Robert loopinfo( 838c0b746e5SOllivier Robert struct parse *pcmd, 839c0b746e5SOllivier Robert FILE *fp 840c0b746e5SOllivier Robert ) 841c0b746e5SOllivier Robert { 842c0b746e5SOllivier Robert struct info_loop *il; 843c0b746e5SOllivier Robert int items; 844c0b746e5SOllivier Robert int itemsize; 845c0b746e5SOllivier Robert int oneline = 0; 846c0b746e5SOllivier Robert int res; 847c0b746e5SOllivier Robert l_fp tempts; 848c0b746e5SOllivier Robert 849c0b746e5SOllivier Robert if (pcmd->nargs > 0) { 850c0b746e5SOllivier Robert if (STREQ(pcmd->argval[0].string, "oneline")) 851c0b746e5SOllivier Robert oneline = 1; 852c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[0].string, "multiline")) 853c0b746e5SOllivier Robert oneline = 0; 854c0b746e5SOllivier Robert else { 855c0b746e5SOllivier Robert (void) fprintf(stderr, "How many lines?\n"); 856c0b746e5SOllivier Robert return; 857c0b746e5SOllivier Robert } 858c0b746e5SOllivier Robert } 859c0b746e5SOllivier Robert 8609c2daa00SOllivier Robert again: 8619c2daa00SOllivier Robert res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL, 8629c2daa00SOllivier Robert &items, &itemsize, (void *)&il, 0, 8639c2daa00SOllivier Robert sizeof(struct info_loop)); 8649c2daa00SOllivier Robert 8659c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 8669c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 8679c2daa00SOllivier Robert goto again; 8689c2daa00SOllivier Robert } 869c0b746e5SOllivier Robert 870ea906c41SOllivier Robert if (res != 0) 871c0b746e5SOllivier Robert return; 872c0b746e5SOllivier Robert 873c0b746e5SOllivier Robert if (!check1item(items, fp)) 874c0b746e5SOllivier Robert return; 875c0b746e5SOllivier Robert 876c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_loop))) 877c0b746e5SOllivier Robert return; 878c0b746e5SOllivier Robert 879c0b746e5SOllivier Robert if (oneline) { 880c0b746e5SOllivier Robert l_fp temp2ts; 881c0b746e5SOllivier Robert 882c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 883c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &temp2ts); 884c0b746e5SOllivier Robert 885c0b746e5SOllivier Robert (void) fprintf(fp, 886c0b746e5SOllivier Robert "offset %s, frequency %s, time_const %ld, watchdog %ld\n", 887c0b746e5SOllivier Robert lfptoa(&tempts, 6), 888c0b746e5SOllivier Robert lfptoa(&temp2ts, 3), 889ea906c41SOllivier Robert (long)(int32_t)ntohl((u_long)il->compliance), 890ea906c41SOllivier Robert (u_long)ntohl((u_long)il->watchdog_timer)); 891c0b746e5SOllivier Robert } else { 892c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 893c0b746e5SOllivier Robert (void) fprintf(fp, "offset: %s s\n", 894c0b746e5SOllivier Robert lfptoa(&tempts, 6)); 895c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &tempts); 896c0b746e5SOllivier Robert (void) fprintf(fp, "frequency: %s ppm\n", 897c0b746e5SOllivier Robert lfptoa(&tempts, 3)); 898c0b746e5SOllivier Robert (void) fprintf(fp, "poll adjust: %ld\n", 899ea906c41SOllivier Robert (long)(int32_t)ntohl(il->compliance)); 900c0b746e5SOllivier Robert (void) fprintf(fp, "watchdog timer: %ld s\n", 901c0b746e5SOllivier Robert (u_long)ntohl(il->watchdog_timer)); 902c0b746e5SOllivier Robert } 903c0b746e5SOllivier Robert } 904c0b746e5SOllivier Robert 905c0b746e5SOllivier Robert 906c0b746e5SOllivier Robert /* 907c0b746e5SOllivier Robert * sysinfo - show current system state 908c0b746e5SOllivier Robert */ 909c0b746e5SOllivier Robert /*ARGSUSED*/ 910c0b746e5SOllivier Robert static void 911c0b746e5SOllivier Robert sysinfo( 912c0b746e5SOllivier Robert struct parse *pcmd, 913c0b746e5SOllivier Robert FILE *fp 914c0b746e5SOllivier Robert ) 915c0b746e5SOllivier Robert { 916c0b746e5SOllivier Robert struct info_sys *is; 9179c2daa00SOllivier Robert struct sockaddr_storage peeraddr; 918c0b746e5SOllivier Robert int items; 919c0b746e5SOllivier Robert int itemsize; 920c0b746e5SOllivier Robert int res; 921c0b746e5SOllivier Robert l_fp tempts; 922c0b746e5SOllivier Robert 9239c2daa00SOllivier Robert again: 9249c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL, 9259c2daa00SOllivier Robert &items, &itemsize, (void *)&is, 0, 9269c2daa00SOllivier Robert sizeof(struct info_sys)); 9279c2daa00SOllivier Robert 9289c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 9299c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 9309c2daa00SOllivier Robert goto again; 9319c2daa00SOllivier Robert } 932c0b746e5SOllivier Robert 933ea906c41SOllivier Robert if (res != 0) 934c0b746e5SOllivier Robert return; 935c0b746e5SOllivier Robert 936c0b746e5SOllivier Robert if (!check1item(items, fp)) 937c0b746e5SOllivier Robert return; 938c0b746e5SOllivier Robert 9399c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_sys)) && 9409c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_sys))) 941c0b746e5SOllivier Robert return; 942c0b746e5SOllivier Robert 9439c2daa00SOllivier Robert memset((char *)&peeraddr, 0, sizeof(peeraddr)); 9449c2daa00SOllivier Robert if (is->v6_flag != 0) { 9459c2daa00SOllivier Robert GET_INADDR6(peeraddr) = is->peer6; 9469c2daa00SOllivier Robert peeraddr.ss_family = AF_INET6; 9479c2daa00SOllivier Robert } else { 9489c2daa00SOllivier Robert GET_INADDR(peeraddr) = is->peer; 9499c2daa00SOllivier Robert peeraddr.ss_family = AF_INET; 9509c2daa00SOllivier Robert } 9519c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 9529c2daa00SOllivier Robert peeraddr.ss_len = SOCKLEN(&peeraddr); 9539c2daa00SOllivier Robert #endif 9549c2daa00SOllivier Robert (void) fprintf(fp, "system peer: %s\n", nntohost(&peeraddr)); 955c0b746e5SOllivier Robert (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode)); 956c0b746e5SOllivier Robert (void) fprintf(fp, "leap indicator: %c%c\n", 957c0b746e5SOllivier Robert is->leap & 0x2 ? '1' : '0', 958c0b746e5SOllivier Robert is->leap & 0x1 ? '1' : '0'); 959c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %d\n", (int)is->stratum); 960c0b746e5SOllivier Robert (void) fprintf(fp, "precision: %d\n", (int)is->precision); 961c0b746e5SOllivier Robert (void) fprintf(fp, "root distance: %s s\n", 962c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->rootdelay), 5)); 963c0b746e5SOllivier Robert (void) fprintf(fp, "root dispersion: %s s\n", 964c0b746e5SOllivier Robert ufptoa(NTOHS_FP(is->rootdispersion), 5)); 965c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: [%s]\n", 966c0b746e5SOllivier Robert refid_string(is->refid, is->stratum)); 967c0b746e5SOllivier Robert NTOHL_FP(&is->reftime, &tempts); 968c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts)); 969c0b746e5SOllivier Robert 970c0b746e5SOllivier Robert (void) fprintf(fp, "system flags: "); 971c0b746e5SOllivier Robert if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE | 972ce265a54SOllivier Robert INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL | 973c0b746e5SOllivier Robert INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) { 974c0b746e5SOllivier Robert (void) fprintf(fp, "none\n"); 975c0b746e5SOllivier Robert } else { 976c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_BCLIENT) 977c0b746e5SOllivier Robert (void) fprintf(fp, "bclient "); 978c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_AUTHENTICATE) 979c0b746e5SOllivier Robert (void) fprintf(fp, "auth "); 980c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_MONITOR) 981c0b746e5SOllivier Robert (void) fprintf(fp, "monitor "); 982c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_NTP) 983c0b746e5SOllivier Robert (void) fprintf(fp, "ntp "); 984c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_KERNEL) 985c0b746e5SOllivier Robert (void) fprintf(fp, "kernel "); 986c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_FILEGEN) 987c0b746e5SOllivier Robert (void) fprintf(fp, "stats "); 988ce265a54SOllivier Robert if (is->flags & INFO_FLAG_CAL) 989ce265a54SOllivier Robert (void) fprintf(fp, "calibrate "); 990c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_PPS_SYNC) 991ce265a54SOllivier Robert (void) fprintf(fp, "pps "); 992c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 993c0b746e5SOllivier Robert } 994c0b746e5SOllivier Robert (void) fprintf(fp, "jitter: %s s\n", 995c0b746e5SOllivier Robert fptoa(ntohl(is->frequency), 6)); 996c0b746e5SOllivier Robert (void) fprintf(fp, "stability: %s ppm\n", 997c0b746e5SOllivier Robert ufptoa(ntohl(is->stability), 3)); 998c0b746e5SOllivier Robert (void) fprintf(fp, "broadcastdelay: %s s\n", 999c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->bdelay), 6)); 1000c0b746e5SOllivier Robert NTOHL_FP(&is->authdelay, &tempts); 1001c0b746e5SOllivier Robert (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6)); 1002c0b746e5SOllivier Robert } 1003c0b746e5SOllivier Robert 1004c0b746e5SOllivier Robert 1005c0b746e5SOllivier Robert /* 1006c0b746e5SOllivier Robert * sysstats - print system statistics 1007c0b746e5SOllivier Robert */ 1008c0b746e5SOllivier Robert /*ARGSUSED*/ 1009c0b746e5SOllivier Robert static void 1010c0b746e5SOllivier Robert sysstats( 1011c0b746e5SOllivier Robert struct parse *pcmd, 1012c0b746e5SOllivier Robert FILE *fp 1013c0b746e5SOllivier Robert ) 1014c0b746e5SOllivier Robert { 1015c0b746e5SOllivier Robert struct info_sys_stats *ss; 1016c0b746e5SOllivier Robert int items; 1017c0b746e5SOllivier Robert int itemsize; 1018c0b746e5SOllivier Robert int res; 1019c0b746e5SOllivier Robert 10209c2daa00SOllivier Robert again: 10219c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL, 10229c2daa00SOllivier Robert &items, &itemsize, (void *)&ss, 0, 10239c2daa00SOllivier Robert sizeof(struct info_sys_stats)); 10249c2daa00SOllivier Robert 10259c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 10269c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 10279c2daa00SOllivier Robert goto again; 10289c2daa00SOllivier Robert } 1029c0b746e5SOllivier Robert 1030ea906c41SOllivier Robert if (res != 0) 1031c0b746e5SOllivier Robert return; 1032c0b746e5SOllivier Robert 1033c0b746e5SOllivier Robert if (!check1item(items, fp)) 1034c0b746e5SOllivier Robert return; 1035c0b746e5SOllivier Robert 1036c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats) && 1037c0b746e5SOllivier Robert itemsize != sizeof(struct old_info_sys_stats)) { 1038c0b746e5SOllivier Robert /* issue warning according to new structure size */ 1039c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_sys_stats)); 1040c0b746e5SOllivier Robert return; 1041c0b746e5SOllivier Robert } 10429c2daa00SOllivier Robert fprintf(fp, "time since restart: %ld\n", 1043c0b746e5SOllivier Robert (u_long)ntohl(ss->timeup)); 10449c2daa00SOllivier Robert fprintf(fp, "time since reset: %ld\n", 1045c0b746e5SOllivier Robert (u_long)ntohl(ss->timereset)); 10469c2daa00SOllivier Robert fprintf(fp, "packets received: %ld\n", 10479c2daa00SOllivier Robert (u_long)ntohl(ss->received)); 10489c2daa00SOllivier Robert fprintf(fp, "packets processed: %ld\n", 1049c0b746e5SOllivier Robert (u_long)ntohl(ss->processed)); 10509c2daa00SOllivier Robert fprintf(fp, "current version: %ld\n", 10519c2daa00SOllivier Robert (u_long)ntohl(ss->newversionpkt)); 10529c2daa00SOllivier Robert fprintf(fp, "previous version: %ld\n", 10539c2daa00SOllivier Robert (u_long)ntohl(ss->oldversionpkt)); 10549c2daa00SOllivier Robert fprintf(fp, "bad version: %ld\n", 10559c2daa00SOllivier Robert (u_long)ntohl(ss->unknownversion)); 10569c2daa00SOllivier Robert fprintf(fp, "access denied: %ld\n", 10579c2daa00SOllivier Robert (u_long)ntohl(ss->denied)); 10589c2daa00SOllivier Robert fprintf(fp, "bad length or format: %ld\n", 10599c2daa00SOllivier Robert (u_long)ntohl(ss->badlength)); 10609c2daa00SOllivier Robert fprintf(fp, "bad authentication: %ld\n", 1061c0b746e5SOllivier Robert (u_long)ntohl(ss->badauth)); 1062c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats)) 1063c0b746e5SOllivier Robert return; 1064c0b746e5SOllivier Robert 10659c2daa00SOllivier Robert fprintf(fp, "rate exceeded: %ld\n", 1066c0b746e5SOllivier Robert (u_long)ntohl(ss->limitrejected)); 1067c0b746e5SOllivier Robert } 1068c0b746e5SOllivier Robert 1069c0b746e5SOllivier Robert 1070c0b746e5SOllivier Robert 1071c0b746e5SOllivier Robert /* 1072c0b746e5SOllivier Robert * iostats - print I/O statistics 1073c0b746e5SOllivier Robert */ 1074c0b746e5SOllivier Robert /*ARGSUSED*/ 1075c0b746e5SOllivier Robert static void 1076c0b746e5SOllivier Robert iostats( 1077c0b746e5SOllivier Robert struct parse *pcmd, 1078c0b746e5SOllivier Robert FILE *fp 1079c0b746e5SOllivier Robert ) 1080c0b746e5SOllivier Robert { 1081c0b746e5SOllivier Robert struct info_io_stats *io; 1082c0b746e5SOllivier Robert int items; 1083c0b746e5SOllivier Robert int itemsize; 1084c0b746e5SOllivier Robert int res; 1085c0b746e5SOllivier Robert 10869c2daa00SOllivier Robert again: 10879c2daa00SOllivier Robert res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, (char *)NULL, 10889c2daa00SOllivier Robert &items, &itemsize, (void *)&io, 0, 10899c2daa00SOllivier Robert sizeof(struct info_io_stats)); 10909c2daa00SOllivier Robert 10919c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 10929c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 10939c2daa00SOllivier Robert goto again; 10949c2daa00SOllivier Robert } 1095c0b746e5SOllivier Robert 1096ea906c41SOllivier Robert if (res != 0) 1097c0b746e5SOllivier Robert return; 1098c0b746e5SOllivier Robert 1099c0b746e5SOllivier Robert if (!check1item(items, fp)) 1100c0b746e5SOllivier Robert return; 1101c0b746e5SOllivier Robert 1102c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_io_stats))) 1103c0b746e5SOllivier Robert return; 1104c0b746e5SOllivier Robert 1105c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 1106c0b746e5SOllivier Robert (u_long)ntohl(io->timereset)); 1107c0b746e5SOllivier Robert (void) fprintf(fp, "receive buffers: %d\n", 1108c0b746e5SOllivier Robert ntohs(io->totalrecvbufs)); 1109c0b746e5SOllivier Robert (void) fprintf(fp, "free receive buffers: %d\n", 1110c0b746e5SOllivier Robert ntohs(io->freerecvbufs)); 1111c0b746e5SOllivier Robert (void) fprintf(fp, "used receive buffers: %d\n", 1112c0b746e5SOllivier Robert ntohs(io->fullrecvbufs)); 1113c0b746e5SOllivier Robert (void) fprintf(fp, "low water refills: %d\n", 1114c0b746e5SOllivier Robert ntohs(io->lowwater)); 1115c0b746e5SOllivier Robert (void) fprintf(fp, "dropped packets: %ld\n", 1116c0b746e5SOllivier Robert (u_long)ntohl(io->dropped)); 1117c0b746e5SOllivier Robert (void) fprintf(fp, "ignored packets: %ld\n", 1118c0b746e5SOllivier Robert (u_long)ntohl(io->ignored)); 1119c0b746e5SOllivier Robert (void) fprintf(fp, "received packets: %ld\n", 1120c0b746e5SOllivier Robert (u_long)ntohl(io->received)); 1121c0b746e5SOllivier Robert (void) fprintf(fp, "packets sent: %ld\n", 1122c0b746e5SOllivier Robert (u_long)ntohl(io->sent)); 1123c0b746e5SOllivier Robert (void) fprintf(fp, "packets not sent: %ld\n", 1124c0b746e5SOllivier Robert (u_long)ntohl(io->notsent)); 1125c0b746e5SOllivier Robert (void) fprintf(fp, "interrupts handled: %ld\n", 1126c0b746e5SOllivier Robert (u_long)ntohl(io->interrupts)); 1127c0b746e5SOllivier Robert (void) fprintf(fp, "received by int: %ld\n", 1128c0b746e5SOllivier Robert (u_long)ntohl(io->int_received)); 1129c0b746e5SOllivier Robert } 1130c0b746e5SOllivier Robert 1131c0b746e5SOllivier Robert 1132c0b746e5SOllivier Robert /* 1133c0b746e5SOllivier Robert * memstats - print peer memory statistics 1134c0b746e5SOllivier Robert */ 1135c0b746e5SOllivier Robert /*ARGSUSED*/ 1136c0b746e5SOllivier Robert static void 1137c0b746e5SOllivier Robert memstats( 1138c0b746e5SOllivier Robert struct parse *pcmd, 1139c0b746e5SOllivier Robert FILE *fp 1140c0b746e5SOllivier Robert ) 1141c0b746e5SOllivier Robert { 1142c0b746e5SOllivier Robert struct info_mem_stats *mem; 1143c0b746e5SOllivier Robert int i; 1144c0b746e5SOllivier Robert int items; 1145c0b746e5SOllivier Robert int itemsize; 1146c0b746e5SOllivier Robert int res; 1147c0b746e5SOllivier Robert 11489c2daa00SOllivier Robert again: 11499c2daa00SOllivier Robert res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, (char *)NULL, 11509c2daa00SOllivier Robert &items, &itemsize, (void *)&mem, 0, 11519c2daa00SOllivier Robert sizeof(struct info_mem_stats)); 11529c2daa00SOllivier Robert 11539c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 11549c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 11559c2daa00SOllivier Robert goto again; 11569c2daa00SOllivier Robert } 1157c0b746e5SOllivier Robert 1158ea906c41SOllivier Robert if (res != 0) 1159c0b746e5SOllivier Robert return; 1160c0b746e5SOllivier Robert 1161c0b746e5SOllivier Robert if (!check1item(items, fp)) 1162c0b746e5SOllivier Robert return; 1163c0b746e5SOllivier Robert 1164c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_mem_stats))) 1165c0b746e5SOllivier Robert return; 1166c0b746e5SOllivier Robert 1167c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 1168c0b746e5SOllivier Robert (u_long)ntohl(mem->timereset)); 1169c0b746e5SOllivier Robert (void) fprintf(fp, "total peer memory: %d\n", 1170c0b746e5SOllivier Robert ntohs(mem->totalpeermem)); 1171c0b746e5SOllivier Robert (void) fprintf(fp, "free peer memory: %d\n", 1172c0b746e5SOllivier Robert ntohs(mem->freepeermem)); 1173c0b746e5SOllivier Robert (void) fprintf(fp, "calls to findpeer: %ld\n", 1174c0b746e5SOllivier Robert (u_long)ntohl(mem->findpeer_calls)); 1175c0b746e5SOllivier Robert (void) fprintf(fp, "new peer allocations: %ld\n", 1176c0b746e5SOllivier Robert (u_long)ntohl(mem->allocations)); 1177c0b746e5SOllivier Robert (void) fprintf(fp, "peer demobilizations: %ld\n", 1178c0b746e5SOllivier Robert (u_long)ntohl(mem->demobilizations)); 1179c0b746e5SOllivier Robert 1180c0b746e5SOllivier Robert (void) fprintf(fp, "hash table counts: "); 1181ea906c41SOllivier Robert for (i = 0; i < NTP_HASH_SIZE; i++) { 1182c0b746e5SOllivier Robert (void) fprintf(fp, "%4d", (int)mem->hashcount[i]); 1183ea906c41SOllivier Robert if ((i % 8) == 7 && i != (NTP_HASH_SIZE-1)) { 1184c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 1185c0b746e5SOllivier Robert } 1186c0b746e5SOllivier Robert } 1187c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 1188c0b746e5SOllivier Robert } 1189c0b746e5SOllivier Robert 1190c0b746e5SOllivier Robert 1191c0b746e5SOllivier Robert 1192c0b746e5SOllivier Robert /* 1193c0b746e5SOllivier Robert * timerstats - print timer statistics 1194c0b746e5SOllivier Robert */ 1195c0b746e5SOllivier Robert /*ARGSUSED*/ 1196c0b746e5SOllivier Robert static void 1197c0b746e5SOllivier Robert timerstats( 1198c0b746e5SOllivier Robert struct parse *pcmd, 1199c0b746e5SOllivier Robert FILE *fp 1200c0b746e5SOllivier Robert ) 1201c0b746e5SOllivier Robert { 1202c0b746e5SOllivier Robert struct info_timer_stats *tim; 1203c0b746e5SOllivier Robert int items; 1204c0b746e5SOllivier Robert int itemsize; 1205c0b746e5SOllivier Robert int res; 1206c0b746e5SOllivier Robert 12079c2daa00SOllivier Robert again: 12089c2daa00SOllivier Robert res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, (char *)NULL, 12099c2daa00SOllivier Robert &items, &itemsize, (void *)&tim, 0, 12109c2daa00SOllivier Robert sizeof(struct info_timer_stats)); 12119c2daa00SOllivier Robert 12129c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 12139c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 12149c2daa00SOllivier Robert goto again; 12159c2daa00SOllivier Robert } 1216c0b746e5SOllivier Robert 1217ea906c41SOllivier Robert if (res != 0) 1218c0b746e5SOllivier Robert return; 1219c0b746e5SOllivier Robert 1220c0b746e5SOllivier Robert if (!check1item(items, fp)) 1221c0b746e5SOllivier Robert return; 1222c0b746e5SOllivier Robert 1223c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_timer_stats))) 1224c0b746e5SOllivier Robert return; 1225c0b746e5SOllivier Robert 1226c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 1227c0b746e5SOllivier Robert (u_long)ntohl(tim->timereset)); 1228c0b746e5SOllivier Robert (void) fprintf(fp, "alarms handled: %ld\n", 1229c0b746e5SOllivier Robert (u_long)ntohl(tim->alarms)); 1230c0b746e5SOllivier Robert (void) fprintf(fp, "alarm overruns: %ld\n", 1231c0b746e5SOllivier Robert (u_long)ntohl(tim->overflows)); 1232c0b746e5SOllivier Robert (void) fprintf(fp, "calls to transmit: %ld\n", 1233c0b746e5SOllivier Robert (u_long)ntohl(tim->xmtcalls)); 1234c0b746e5SOllivier Robert } 1235c0b746e5SOllivier Robert 1236c0b746e5SOllivier Robert 1237c0b746e5SOllivier Robert /* 1238c0b746e5SOllivier Robert * addpeer - configure an active mode association 1239c0b746e5SOllivier Robert */ 1240c0b746e5SOllivier Robert static void 1241c0b746e5SOllivier Robert addpeer( 1242c0b746e5SOllivier Robert struct parse *pcmd, 1243c0b746e5SOllivier Robert FILE *fp 1244c0b746e5SOllivier Robert ) 1245c0b746e5SOllivier Robert { 1246c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_ACTIVE, 0); 1247c0b746e5SOllivier Robert } 1248c0b746e5SOllivier Robert 1249c0b746e5SOllivier Robert 1250c0b746e5SOllivier Robert /* 1251c0b746e5SOllivier Robert * addserver - configure a client mode association 1252c0b746e5SOllivier Robert */ 1253c0b746e5SOllivier Robert static void 1254c0b746e5SOllivier Robert addserver( 1255c0b746e5SOllivier Robert struct parse *pcmd, 1256c0b746e5SOllivier Robert FILE *fp 1257c0b746e5SOllivier Robert ) 1258c0b746e5SOllivier Robert { 1259c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 0); 1260c0b746e5SOllivier Robert } 1261c0b746e5SOllivier Robert 1262c0b746e5SOllivier Robert /* 1263c0b746e5SOllivier Robert * addrefclock - configure a reference clock association 1264c0b746e5SOllivier Robert */ 1265c0b746e5SOllivier Robert static void 1266c0b746e5SOllivier Robert addrefclock( 1267c0b746e5SOllivier Robert struct parse *pcmd, 1268c0b746e5SOllivier Robert FILE *fp 1269c0b746e5SOllivier Robert ) 1270c0b746e5SOllivier Robert { 1271c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 1); 1272c0b746e5SOllivier Robert } 1273c0b746e5SOllivier Robert 1274c0b746e5SOllivier Robert /* 1275c0b746e5SOllivier Robert * broadcast - configure a broadcast mode association 1276c0b746e5SOllivier Robert */ 1277c0b746e5SOllivier Robert static void 1278c0b746e5SOllivier Robert broadcast( 1279c0b746e5SOllivier Robert struct parse *pcmd, 1280c0b746e5SOllivier Robert FILE *fp 1281c0b746e5SOllivier Robert ) 1282c0b746e5SOllivier Robert { 1283c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_BROADCAST, 0); 1284c0b746e5SOllivier Robert } 1285c0b746e5SOllivier Robert 1286c0b746e5SOllivier Robert 1287c0b746e5SOllivier Robert /* 1288c0b746e5SOllivier Robert * config - configure a new peer association 1289c0b746e5SOllivier Robert */ 1290c0b746e5SOllivier Robert static void 1291c0b746e5SOllivier Robert doconfig( 1292c0b746e5SOllivier Robert struct parse *pcmd, 1293c0b746e5SOllivier Robert FILE *fp, 1294c0b746e5SOllivier Robert int mode, 1295c0b746e5SOllivier Robert int refc 1296c0b746e5SOllivier Robert ) 1297c0b746e5SOllivier Robert { 1298c0b746e5SOllivier Robert struct conf_peer cpeer; 1299c0b746e5SOllivier Robert int items; 1300c0b746e5SOllivier Robert int itemsize; 1301c0b746e5SOllivier Robert char *dummy; 1302c0b746e5SOllivier Robert u_long keyid; 1303c0b746e5SOllivier Robert u_int version; 1304c0b746e5SOllivier Robert u_char minpoll; 1305ea906c41SOllivier Robert u_char maxpoll; 1306c0b746e5SOllivier Robert u_int flags; 1307c0b746e5SOllivier Robert u_char cmode; 1308c0b746e5SOllivier Robert int res; 13099c2daa00SOllivier Robert int sendsize; 1310ea906c41SOllivier Robert int numtyp; 1311c0b746e5SOllivier Robert 13129c2daa00SOllivier Robert again: 1313c0b746e5SOllivier Robert keyid = 0; 1314ea906c41SOllivier Robert version = 3; 1315c0b746e5SOllivier Robert flags = 0; 1316c0b746e5SOllivier Robert res = 0; 1317c0b746e5SOllivier Robert cmode = 0; 1318c0b746e5SOllivier Robert minpoll = NTP_MINDPOLL; 1319ea906c41SOllivier Robert maxpoll = NTP_MAXDPOLL; 1320ea906c41SOllivier Robert numtyp = 1; 1321ea906c41SOllivier Robert if (refc) 1322ea906c41SOllivier Robert numtyp = 5; 1323c0b746e5SOllivier Robert 13249c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 13259c2daa00SOllivier Robert sendsize = sizeof(struct conf_peer); 13269c2daa00SOllivier Robert else 13279c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_peer); 13289c2daa00SOllivier Robert 1329ea906c41SOllivier Robert items = 1; 1330c0b746e5SOllivier Robert while (pcmd->nargs > items) { 1331c0b746e5SOllivier Robert if (STREQ(pcmd->argval[items].string, "prefer")) 1332c0b746e5SOllivier Robert flags |= CONF_FLAG_PREFER; 1333c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "burst")) 1334c0b746e5SOllivier Robert flags |= CONF_FLAG_BURST; 1335ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "dynamic")) 1336ea906c41SOllivier Robert (void) fprintf(fp, "Warning: the \"dynamic\" keyword has been obsoleted and will be removed in the next release\n"); 1337ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "iburst")) 1338ea906c41SOllivier Robert flags |= CONF_FLAG_IBURST; 1339ea906c41SOllivier Robert else if (!refc && STREQ(pcmd->argval[items].string, "keyid")) 1340ea906c41SOllivier Robert numtyp = 1; 1341ea906c41SOllivier Robert else if (!refc && STREQ(pcmd->argval[items].string, "version")) 1342ea906c41SOllivier Robert numtyp = 2; 1343ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "minpoll")) 1344ea906c41SOllivier Robert numtyp = 3; 1345ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "maxpoll")) 1346ea906c41SOllivier Robert numtyp = 4; 1347c0b746e5SOllivier Robert else { 1348c0b746e5SOllivier Robert long val; 1349ea906c41SOllivier Robert if (!atoint(pcmd->argval[items].string, &val)) 1350ea906c41SOllivier Robert numtyp = 0; 1351ea906c41SOllivier Robert switch (numtyp) { 1352ea906c41SOllivier Robert case 1: 1353ea906c41SOllivier Robert keyid = val; 1354ea906c41SOllivier Robert numtyp = 2; 1355ea906c41SOllivier Robert break; 1356ea906c41SOllivier Robert 1357ea906c41SOllivier Robert case 2: 1358ea906c41SOllivier Robert version = (u_int) val; 1359ea906c41SOllivier Robert numtyp = 0; 1360ea906c41SOllivier Robert break; 1361ea906c41SOllivier Robert 1362ea906c41SOllivier Robert case 3: 1363ea906c41SOllivier Robert minpoll = (u_char)val; 1364ea906c41SOllivier Robert numtyp = 0; 1365ea906c41SOllivier Robert break; 1366ea906c41SOllivier Robert 1367ea906c41SOllivier Robert case 4: 1368ea906c41SOllivier Robert maxpoll = (u_char)val; 1369ea906c41SOllivier Robert numtyp = 0; 1370ea906c41SOllivier Robert break; 1371ea906c41SOllivier Robert 1372ea906c41SOllivier Robert case 5: 1373ea906c41SOllivier Robert cmode = (u_char)val; 1374ea906c41SOllivier Robert numtyp = 0; 1375ea906c41SOllivier Robert break; 1376ea906c41SOllivier Robert 1377ea906c41SOllivier Robert default: 1378ea906c41SOllivier Robert (void) fprintf(fp, "*** '%s' not understood\n", 1379c0b746e5SOllivier Robert pcmd->argval[items].string); 1380c0b746e5SOllivier Robert res++; 1381ea906c41SOllivier Robert numtyp = 0; 1382c0b746e5SOllivier Robert } 1383ea906c41SOllivier Robert if (val < 0) { 1384ea906c41SOllivier Robert (void) fprintf(stderr, 1385ea906c41SOllivier Robert "***Value '%s' should be unsigned\n", 1386ea906c41SOllivier Robert pcmd->argval[items].string); 1387ea906c41SOllivier Robert res++; 1388c0b746e5SOllivier Robert } 1389c0b746e5SOllivier Robert } 1390c0b746e5SOllivier Robert items++; 1391c0b746e5SOllivier Robert } 1392ea906c41SOllivier Robert if (keyid > 0) 1393ea906c41SOllivier Robert flags |= CONF_FLAG_AUTHENABLE; 1394ea906c41SOllivier Robert if (version > NTP_VERSION || 1395ea906c41SOllivier Robert version < NTP_OLDVERSION) { 1396ea906c41SOllivier Robert (void)fprintf(fp, "***invalid version number: %u\n", 1397ea906c41SOllivier Robert version); 1398ea906c41SOllivier Robert res++; 1399ea906c41SOllivier Robert } 1400ea906c41SOllivier Robert if (minpoll < NTP_MINPOLL || minpoll > NTP_MAXPOLL || 1401ea906c41SOllivier Robert maxpoll < NTP_MINPOLL || maxpoll > NTP_MAXPOLL || 1402ea906c41SOllivier Robert minpoll > maxpoll) { 1403ea906c41SOllivier Robert (void) fprintf(fp, "***min/max-poll must be within %d..%d\n", 1404ea906c41SOllivier Robert NTP_MINPOLL, NTP_MAXPOLL); 1405ea906c41SOllivier Robert res++; 1406ea906c41SOllivier Robert } 1407c0b746e5SOllivier Robert 1408c0b746e5SOllivier Robert if (res) 1409c0b746e5SOllivier Robert return; 1410c0b746e5SOllivier Robert 14119c2daa00SOllivier Robert memset((void *)&cpeer, 0, sizeof(cpeer)); 1412c0b746e5SOllivier Robert 14139c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 14149c2daa00SOllivier Robert cpeer.peeraddr = GET_INADDR(pcmd->argval[0].netnum); 14159c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14169c2daa00SOllivier Robert cpeer.v6_flag = 0; 14179c2daa00SOllivier Robert } else { 14189c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 14199c2daa00SOllivier Robert fprintf(stderr, 14209c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 14219c2daa00SOllivier Robert return; 14229c2daa00SOllivier Robert } 14239c2daa00SOllivier Robert cpeer.peeraddr6 = GET_INADDR6(pcmd->argval[0].netnum); 14249c2daa00SOllivier Robert cpeer.v6_flag = 1; 14259c2daa00SOllivier Robert } 1426c0b746e5SOllivier Robert cpeer.hmode = (u_char) mode; 1427c0b746e5SOllivier Robert cpeer.keyid = keyid; 1428c0b746e5SOllivier Robert cpeer.version = (u_char) version; 1429c0b746e5SOllivier Robert cpeer.minpoll = minpoll; 1430ea906c41SOllivier Robert cpeer.maxpoll = maxpoll; 1431c0b746e5SOllivier Robert cpeer.flags = (u_char)flags; 1432c0b746e5SOllivier Robert cpeer.ttl = cmode; 1433c0b746e5SOllivier Robert 14349c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 14359c2daa00SOllivier Robert sendsize, (char *)&cpeer, &items, 14369c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_peer)); 14379c2daa00SOllivier Robert 14389c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 14399c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 14409c2daa00SOllivier Robert goto again; 14419c2daa00SOllivier Robert } 1442c0b746e5SOllivier Robert 1443ce265a54SOllivier Robert if (res == INFO_ERR_FMT) { 1444ce265a54SOllivier Robert (void) fprintf(fp, 1445ce265a54SOllivier Robert "***Retrying command with old conf_peer size\n"); 14469c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 1447ce265a54SOllivier Robert sizeof(struct old_conf_peer), (char *)&cpeer, 14489c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, 14499c2daa00SOllivier Robert sizeof(struct conf_peer)); 1450ce265a54SOllivier Robert } 1451c0b746e5SOllivier Robert if (res == 0) 1452c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1453c0b746e5SOllivier Robert return; 1454c0b746e5SOllivier Robert } 1455c0b746e5SOllivier Robert 1456c0b746e5SOllivier Robert 1457c0b746e5SOllivier Robert /* 1458c0b746e5SOllivier Robert * unconfig - unconfigure some associations 1459c0b746e5SOllivier Robert */ 1460c0b746e5SOllivier Robert static void 1461c0b746e5SOllivier Robert unconfig( 1462c0b746e5SOllivier Robert struct parse *pcmd, 1463c0b746e5SOllivier Robert FILE *fp 1464c0b746e5SOllivier Robert ) 1465c0b746e5SOllivier Robert { 1466c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 14679c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 1468c0b746e5SOllivier Robert int qitems; 1469c0b746e5SOllivier Robert int items; 1470c0b746e5SOllivier Robert int itemsize; 1471c0b746e5SOllivier Robert char *dummy; 1472c0b746e5SOllivier Robert int res; 14739c2daa00SOllivier Robert int sendsize; 1474c0b746e5SOllivier Robert 14759c2daa00SOllivier Robert again: 14769c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14779c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 14789c2daa00SOllivier Robert else 14799c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 14809c2daa00SOllivier Robert 14819c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 8); qitems++) { 14829c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 14839c2daa00SOllivier Robert pl->peeraddr = GET_INADDR(pcmd->argval[qitems].netnum); 14849c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14859c2daa00SOllivier Robert pl->v6_flag = 0; 14869c2daa00SOllivier Robert } else { 14879c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 14889c2daa00SOllivier Robert fprintf(stderr, 14899c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 14909c2daa00SOllivier Robert return; 14919c2daa00SOllivier Robert } 14929c2daa00SOllivier Robert pl->peeraddr6 = 14939c2daa00SOllivier Robert GET_INADDR6(pcmd->argval[qitems].netnum); 14949c2daa00SOllivier Robert pl->v6_flag = 1; 14959c2daa00SOllivier Robert } 14969c2daa00SOllivier Robert pl = (struct conf_unpeer *)((char *)pl + sendsize); 1497c0b746e5SOllivier Robert } 1498c0b746e5SOllivier Robert 14999c2daa00SOllivier Robert res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems, 15009c2daa00SOllivier Robert sendsize, (char *)plist, &items, 15019c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 15029c2daa00SOllivier Robert 15039c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 15049c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 15059c2daa00SOllivier Robert goto again; 15069c2daa00SOllivier Robert } 1507c0b746e5SOllivier Robert 1508c0b746e5SOllivier Robert if (res == 0) 1509c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1510c0b746e5SOllivier Robert } 1511c0b746e5SOllivier Robert 1512c0b746e5SOllivier Robert 1513c0b746e5SOllivier Robert /* 1514c0b746e5SOllivier Robert * set - set some system flags 1515c0b746e5SOllivier Robert */ 1516c0b746e5SOllivier Robert static void 1517c0b746e5SOllivier Robert set( 1518c0b746e5SOllivier Robert struct parse *pcmd, 1519c0b746e5SOllivier Robert FILE *fp 1520c0b746e5SOllivier Robert ) 1521c0b746e5SOllivier Robert { 1522c0b746e5SOllivier Robert doset(pcmd, fp, REQ_SET_SYS_FLAG); 1523c0b746e5SOllivier Robert } 1524c0b746e5SOllivier Robert 1525c0b746e5SOllivier Robert 1526c0b746e5SOllivier Robert /* 1527c0b746e5SOllivier Robert * clear - clear some system flags 1528c0b746e5SOllivier Robert */ 1529c0b746e5SOllivier Robert static void 1530c0b746e5SOllivier Robert sys_clear( 1531c0b746e5SOllivier Robert struct parse *pcmd, 1532c0b746e5SOllivier Robert FILE *fp 1533c0b746e5SOllivier Robert ) 1534c0b746e5SOllivier Robert { 1535c0b746e5SOllivier Robert doset(pcmd, fp, REQ_CLR_SYS_FLAG); 1536c0b746e5SOllivier Robert } 1537c0b746e5SOllivier Robert 1538c0b746e5SOllivier Robert 1539c0b746e5SOllivier Robert /* 1540c0b746e5SOllivier Robert * doset - set/clear system flags 1541c0b746e5SOllivier Robert */ 1542c0b746e5SOllivier Robert static void 1543c0b746e5SOllivier Robert doset( 1544c0b746e5SOllivier Robert struct parse *pcmd, 1545c0b746e5SOllivier Robert FILE *fp, 1546c0b746e5SOllivier Robert int req 1547c0b746e5SOllivier Robert ) 1548c0b746e5SOllivier Robert { 1549c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 1550c0b746e5SOllivier Robert struct conf_sys_flags sys; 1551c0b746e5SOllivier Robert int items; 1552c0b746e5SOllivier Robert int itemsize; 1553c0b746e5SOllivier Robert char *dummy; 1554c0b746e5SOllivier Robert int res; 1555c0b746e5SOllivier Robert 1556c0b746e5SOllivier Robert sys.flags = 0; 1557c0b746e5SOllivier Robert res = 0; 1558c0b746e5SOllivier Robert for (items = 0; items < pcmd->nargs; items++) { 1559ce265a54SOllivier Robert if (STREQ(pcmd->argval[items].string, "auth")) 1560ce265a54SOllivier Robert sys.flags |= SYS_FLAG_AUTH; 1561c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "bclient")) 1562c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_BCLIENT; 1563ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "calibrate")) 1564ce265a54SOllivier Robert sys.flags |= SYS_FLAG_CAL; 1565ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "kernel")) 1566ce265a54SOllivier Robert sys.flags |= SYS_FLAG_KERNEL; 1567c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "monitor")) 1568c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_MONITOR; 1569c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "ntp")) 1570c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_NTP; 1571ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "pps")) 1572ce265a54SOllivier Robert sys.flags |= SYS_FLAG_PPS; 1573c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "stats")) 1574c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_FILEGEN; 1575c0b746e5SOllivier Robert else { 1576c0b746e5SOllivier Robert (void) fprintf(fp, "Unknown flag %s\n", 1577c0b746e5SOllivier Robert pcmd->argval[items].string); 1578c0b746e5SOllivier Robert res = 1; 1579c0b746e5SOllivier Robert } 1580c0b746e5SOllivier Robert } 1581c0b746e5SOllivier Robert 1582ea906c41SOllivier Robert sys.flags = htonl(sys.flags); 1583c0b746e5SOllivier Robert if (res || sys.flags == 0) 1584c0b746e5SOllivier Robert return; 1585c0b746e5SOllivier Robert 15869c2daa00SOllivier Robert again: 15879c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, 1588c0b746e5SOllivier Robert sizeof(struct conf_sys_flags), (char *)&sys, &items, 15899c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_sys_flags)); 15909c2daa00SOllivier Robert 15919c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 15929c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 15939c2daa00SOllivier Robert goto again; 15949c2daa00SOllivier Robert } 1595c0b746e5SOllivier Robert 1596c0b746e5SOllivier Robert if (res == 0) 1597c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1598c0b746e5SOllivier Robert } 1599c0b746e5SOllivier Robert 1600c0b746e5SOllivier Robert 1601c0b746e5SOllivier Robert /* 1602c0b746e5SOllivier Robert * data for printing/interrpreting the restrict flags 1603c0b746e5SOllivier Robert */ 1604c0b746e5SOllivier Robert struct resflags { 1605c0b746e5SOllivier Robert const char *str; 1606c0b746e5SOllivier Robert int bit; 1607c0b746e5SOllivier Robert }; 1608c0b746e5SOllivier Robert 1609ea906c41SOllivier Robert /* XXX: HMS: we apparently don't report set bits we do not recognize. */ 1610ea906c41SOllivier Robert 1611ea906c41SOllivier Robert static struct resflags resflagsV2[] = { 1612ea906c41SOllivier Robert { "ignore", 0x001 }, 1613ea906c41SOllivier Robert { "noserve", 0x002 }, 1614ea906c41SOllivier Robert { "notrust", 0x004 }, 1615ea906c41SOllivier Robert { "noquery", 0x008 }, 1616ea906c41SOllivier Robert { "nomodify", 0x010 }, 1617ea906c41SOllivier Robert { "nopeer", 0x020 }, 1618ea906c41SOllivier Robert { "notrap", 0x040 }, 1619ea906c41SOllivier Robert { "lptrap", 0x080 }, 1620ea906c41SOllivier Robert { "limited", 0x100 }, 1621ea906c41SOllivier Robert { "", 0 } 1622ea906c41SOllivier Robert }; 1623ea906c41SOllivier Robert 1624ea906c41SOllivier Robert static struct resflags resflagsV3[] = { 1625c0b746e5SOllivier Robert { "ignore", RES_IGNORE }, 1626c0b746e5SOllivier Robert { "noserve", RES_DONTSERVE }, 1627c0b746e5SOllivier Robert { "notrust", RES_DONTTRUST }, 1628c0b746e5SOllivier Robert { "noquery", RES_NOQUERY }, 1629c0b746e5SOllivier Robert { "nomodify", RES_NOMODIFY }, 1630c0b746e5SOllivier Robert { "nopeer", RES_NOPEER }, 1631c0b746e5SOllivier Robert { "notrap", RES_NOTRAP }, 1632c0b746e5SOllivier Robert { "lptrap", RES_LPTRAP }, 1633c0b746e5SOllivier Robert { "limited", RES_LIMITED }, 1634224ba2bdSOllivier Robert { "version", RES_VERSION }, 1635224ba2bdSOllivier Robert { "kod", RES_DEMOBILIZE }, 16369c2daa00SOllivier Robert { "timeout", RES_TIMEOUT }, 1637224ba2bdSOllivier Robert 1638c0b746e5SOllivier Robert { "", 0 } 1639c0b746e5SOllivier Robert }; 1640c0b746e5SOllivier Robert 1641c0b746e5SOllivier Robert static struct resflags resmflags[] = { 1642c0b746e5SOllivier Robert { "ntpport", RESM_NTPONLY }, 1643c0b746e5SOllivier Robert { "interface", RESM_INTERFACE }, 1644c0b746e5SOllivier Robert { "", 0 } 1645c0b746e5SOllivier Robert }; 1646c0b746e5SOllivier Robert 1647c0b746e5SOllivier Robert 1648c0b746e5SOllivier Robert /* 1649c0b746e5SOllivier Robert * reslist - obtain and print the server's restrict list 1650c0b746e5SOllivier Robert */ 1651c0b746e5SOllivier Robert /*ARGSUSED*/ 1652c0b746e5SOllivier Robert static void 1653c0b746e5SOllivier Robert reslist( 1654c0b746e5SOllivier Robert struct parse *pcmd, 1655c0b746e5SOllivier Robert FILE *fp 1656c0b746e5SOllivier Robert ) 1657c0b746e5SOllivier Robert { 1658c0b746e5SOllivier Robert struct info_restrict *rl; 16599c2daa00SOllivier Robert struct sockaddr_storage resaddr; 16609c2daa00SOllivier Robert struct sockaddr_storage maskaddr; 1661c0b746e5SOllivier Robert int items; 1662c0b746e5SOllivier Robert int itemsize; 1663c0b746e5SOllivier Robert int res; 16649c2daa00SOllivier Robert int skip; 1665c0b746e5SOllivier Robert char *addr; 1666c0b746e5SOllivier Robert char *mask; 1667c0b746e5SOllivier Robert struct resflags *rf; 1668c0b746e5SOllivier Robert u_int32 count; 1669c0b746e5SOllivier Robert u_short flags; 1670c0b746e5SOllivier Robert u_short mflags; 1671c0b746e5SOllivier Robert char flagstr[300]; 1672c0b746e5SOllivier Robert static const char *comma = ", "; 1673c0b746e5SOllivier Robert 16749c2daa00SOllivier Robert again: 16759c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL, 16769c2daa00SOllivier Robert &items, &itemsize, (void *)&rl, 0, 16779c2daa00SOllivier Robert sizeof(struct info_restrict)); 16789c2daa00SOllivier Robert 16799c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 16809c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 16819c2daa00SOllivier Robert goto again; 16829c2daa00SOllivier Robert } 1683c0b746e5SOllivier Robert 1684ea906c41SOllivier Robert if (res != 0) 1685c0b746e5SOllivier Robert return; 1686c0b746e5SOllivier Robert 1687c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1688c0b746e5SOllivier Robert return; 1689c0b746e5SOllivier Robert 16909c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_restrict)) && 16919c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_restrict))) 1692c0b746e5SOllivier Robert return; 1693c0b746e5SOllivier Robert 1694c0b746e5SOllivier Robert (void) fprintf(fp, 1695c0b746e5SOllivier Robert " address mask count flags\n"); 1696c0b746e5SOllivier Robert (void) fprintf(fp, 1697c0b746e5SOllivier Robert "=====================================================================\n"); 16989c2daa00SOllivier Robert 1699c0b746e5SOllivier Robert while (items > 0) { 17009c2daa00SOllivier Robert memset((char *)&resaddr, 0, sizeof(resaddr)); 17019c2daa00SOllivier Robert memset((char *)&maskaddr, 0, sizeof(maskaddr)); 17029c2daa00SOllivier Robert if (rl->v6_flag != 0) { 17039c2daa00SOllivier Robert GET_INADDR6(resaddr) = rl->addr6; 17049c2daa00SOllivier Robert GET_INADDR6(maskaddr) = rl->mask6; 17059c2daa00SOllivier Robert resaddr.ss_family = AF_INET6; 17069c2daa00SOllivier Robert maskaddr.ss_family = AF_INET6; 17079c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 17089c2daa00SOllivier Robert resaddr.ss_len = SOCKLEN(&resaddr); 17099c2daa00SOllivier Robert #endif 17109c2daa00SOllivier Robert addr = nntohost(&resaddr); 17119c2daa00SOllivier Robert } else { 17129c2daa00SOllivier Robert GET_INADDR(resaddr) = rl->addr; 17139c2daa00SOllivier Robert GET_INADDR(maskaddr) = rl->mask; 17149c2daa00SOllivier Robert resaddr.ss_family = AF_INET; 17159c2daa00SOllivier Robert maskaddr.ss_family = AF_INET; 17169c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 17179c2daa00SOllivier Robert resaddr.ss_len = SOCKLEN(&resaddr); 17189c2daa00SOllivier Robert #endif 1719c0b746e5SOllivier Robert if ((rl->mask == (u_int32)0xffffffff)) 17209c2daa00SOllivier Robert addr = nntohost(&resaddr); 1721c0b746e5SOllivier Robert else 17229c2daa00SOllivier Robert addr = stoa(&resaddr); 17239c2daa00SOllivier Robert } 17249c2daa00SOllivier Robert mask = stoa(&maskaddr); 17259c2daa00SOllivier Robert skip = 1; 17269c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 17279c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) || 17289c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (rl->v6_flag == 0))) 17299c2daa00SOllivier Robert skip = 0; 1730c0b746e5SOllivier Robert count = ntohl(rl->count); 1731c0b746e5SOllivier Robert flags = ntohs(rl->flags); 1732c0b746e5SOllivier Robert mflags = ntohs(rl->mflags); 1733c0b746e5SOllivier Robert flagstr[0] = '\0'; 1734c0b746e5SOllivier Robert 1735c0b746e5SOllivier Robert res = 1; 1736c0b746e5SOllivier Robert rf = &resmflags[0]; 1737c0b746e5SOllivier Robert while (rf->bit != 0) { 1738c0b746e5SOllivier Robert if (mflags & rf->bit) { 1739c0b746e5SOllivier Robert if (!res) 1740c0b746e5SOllivier Robert (void) strcat(flagstr, comma); 1741c0b746e5SOllivier Robert res = 0; 1742c0b746e5SOllivier Robert (void) strcat(flagstr, rf->str); 1743c0b746e5SOllivier Robert } 1744c0b746e5SOllivier Robert rf++; 1745c0b746e5SOllivier Robert } 1746c0b746e5SOllivier Robert 1747ea906c41SOllivier Robert rf = (impl_ver == IMPL_XNTPD_OLD) 1748ea906c41SOllivier Robert ? &resflagsV2[0] 1749ea906c41SOllivier Robert : &resflagsV3[0] 1750ea906c41SOllivier Robert ; 1751c0b746e5SOllivier Robert while (rf->bit != 0) { 1752c0b746e5SOllivier Robert if (flags & rf->bit) { 1753c0b746e5SOllivier Robert if (!res) 1754c0b746e5SOllivier Robert (void) strcat(flagstr, comma); 1755c0b746e5SOllivier Robert res = 0; 1756c0b746e5SOllivier Robert (void) strcat(flagstr, rf->str); 1757c0b746e5SOllivier Robert } 1758c0b746e5SOllivier Robert rf++; 1759c0b746e5SOllivier Robert } 1760c0b746e5SOllivier Robert 1761c0b746e5SOllivier Robert if (flagstr[0] == '\0') 1762c0b746e5SOllivier Robert (void) strcpy(flagstr, "none"); 1763c0b746e5SOllivier Robert 17649c2daa00SOllivier Robert if (!skip) 1765c0b746e5SOllivier Robert (void) fprintf(fp, "%-15.15s %-15.15s %9ld %s\n", 1766c0b746e5SOllivier Robert addr, mask, (u_long)count, flagstr); 1767c0b746e5SOllivier Robert rl++; 1768c0b746e5SOllivier Robert items--; 1769c0b746e5SOllivier Robert } 1770c0b746e5SOllivier Robert } 1771c0b746e5SOllivier Robert 1772c0b746e5SOllivier Robert 1773c0b746e5SOllivier Robert 1774c0b746e5SOllivier Robert /* 1775c0b746e5SOllivier Robert * new_restrict - create/add a set of restrictions 1776c0b746e5SOllivier Robert */ 1777c0b746e5SOllivier Robert static void 1778c0b746e5SOllivier Robert new_restrict( 1779c0b746e5SOllivier Robert struct parse *pcmd, 1780c0b746e5SOllivier Robert FILE *fp 1781c0b746e5SOllivier Robert ) 1782c0b746e5SOllivier Robert { 1783c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESADDFLAGS); 1784c0b746e5SOllivier Robert } 1785c0b746e5SOllivier Robert 1786c0b746e5SOllivier Robert 1787c0b746e5SOllivier Robert /* 1788c0b746e5SOllivier Robert * unrestrict - remove restriction flags from existing entry 1789c0b746e5SOllivier Robert */ 1790c0b746e5SOllivier Robert static void 1791c0b746e5SOllivier Robert unrestrict( 1792c0b746e5SOllivier Robert struct parse *pcmd, 1793c0b746e5SOllivier Robert FILE *fp 1794c0b746e5SOllivier Robert ) 1795c0b746e5SOllivier Robert { 1796c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESSUBFLAGS); 1797c0b746e5SOllivier Robert } 1798c0b746e5SOllivier Robert 1799c0b746e5SOllivier Robert 1800c0b746e5SOllivier Robert /* 1801c0b746e5SOllivier Robert * delrestrict - delete an existing restriction 1802c0b746e5SOllivier Robert */ 1803c0b746e5SOllivier Robert static void 1804c0b746e5SOllivier Robert delrestrict( 1805c0b746e5SOllivier Robert struct parse *pcmd, 1806c0b746e5SOllivier Robert FILE *fp 1807c0b746e5SOllivier Robert ) 1808c0b746e5SOllivier Robert { 1809c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_UNRESTRICT); 1810c0b746e5SOllivier Robert } 1811c0b746e5SOllivier Robert 1812c0b746e5SOllivier Robert 1813c0b746e5SOllivier Robert /* 1814c0b746e5SOllivier Robert * do_restrict - decode commandline restrictions and make the request 1815c0b746e5SOllivier Robert */ 1816c0b746e5SOllivier Robert static void 1817c0b746e5SOllivier Robert do_restrict( 1818c0b746e5SOllivier Robert struct parse *pcmd, 1819c0b746e5SOllivier Robert FILE *fp, 1820c0b746e5SOllivier Robert int req_code 1821c0b746e5SOllivier Robert ) 1822c0b746e5SOllivier Robert { 1823c0b746e5SOllivier Robert struct conf_restrict cres; 1824c0b746e5SOllivier Robert int items; 1825c0b746e5SOllivier Robert int itemsize; 1826c0b746e5SOllivier Robert char *dummy; 1827c0b746e5SOllivier Robert u_int32 num; 1828c0b746e5SOllivier Robert u_long bit; 1829c0b746e5SOllivier Robert int i; 1830c0b746e5SOllivier Robert int res; 1831c0b746e5SOllivier Robert int err; 18329c2daa00SOllivier Robert int sendsize; 1833c0b746e5SOllivier Robert 18349c2daa00SOllivier Robert /* Initialize cres */ 18359c2daa00SOllivier Robert cres.addr = 0; 18369c2daa00SOllivier Robert cres.mask = 0; 18379c2daa00SOllivier Robert cres.flags = 0; 18389c2daa00SOllivier Robert cres.mflags = 0; 18399c2daa00SOllivier Robert cres.v6_flag = 0; 18409c2daa00SOllivier Robert 18419c2daa00SOllivier Robert again: 18429c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 18439c2daa00SOllivier Robert sendsize = sizeof(struct conf_restrict); 18449c2daa00SOllivier Robert else 18459c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_restrict); 18469c2daa00SOllivier Robert 18479c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 18489c2daa00SOllivier Robert cres.addr = GET_INADDR(pcmd->argval[0].netnum); 18499c2daa00SOllivier Robert cres.mask = GET_INADDR(pcmd->argval[1].netnum); 18509c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 18519c2daa00SOllivier Robert cres.v6_flag = 0; 18529c2daa00SOllivier Robert } else { 18539c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 18549c2daa00SOllivier Robert fprintf(stderr, 18559c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 18569c2daa00SOllivier Robert return; 18579c2daa00SOllivier Robert } 18589c2daa00SOllivier Robert cres.addr6 = GET_INADDR6(pcmd->argval[0].netnum); 18599c2daa00SOllivier Robert cres.v6_flag = 1; 18609c2daa00SOllivier Robert } 1861c0b746e5SOllivier Robert cres.flags = 0; 1862c0b746e5SOllivier Robert cres.mflags = 0; 1863c0b746e5SOllivier Robert err = 0; 1864c0b746e5SOllivier Robert for (res = 2; res < pcmd->nargs; res++) { 1865c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, "ntpport")) { 1866c0b746e5SOllivier Robert cres.mflags |= RESM_NTPONLY; 1867c0b746e5SOllivier Robert } else { 1868ea906c41SOllivier Robert for (i = 0; resflagsV3[i].bit != 0; i++) { 1869c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, 1870ea906c41SOllivier Robert resflagsV3[i].str)) 1871c0b746e5SOllivier Robert break; 1872c0b746e5SOllivier Robert } 1873ea906c41SOllivier Robert if (resflagsV3[i].bit != 0) { 1874ea906c41SOllivier Robert cres.flags |= resflagsV3[i].bit; 1875c0b746e5SOllivier Robert if (req_code == REQ_UNRESTRICT) { 1876c0b746e5SOllivier Robert (void) fprintf(fp, 1877c0b746e5SOllivier Robert "Flag %s inappropriate\n", 1878ea906c41SOllivier Robert resflagsV3[i].str); 1879c0b746e5SOllivier Robert err++; 1880c0b746e5SOllivier Robert } 1881c0b746e5SOllivier Robert } else { 1882c0b746e5SOllivier Robert (void) fprintf(fp, "Unknown flag %s\n", 1883c0b746e5SOllivier Robert pcmd->argval[res].string); 1884c0b746e5SOllivier Robert err++; 1885c0b746e5SOllivier Robert } 1886c0b746e5SOllivier Robert } 1887c0b746e5SOllivier Robert } 1888ea906c41SOllivier Robert cres.flags = htons(cres.flags); 1889ea906c41SOllivier Robert cres.mflags = htons(cres.mflags); 1890c0b746e5SOllivier Robert 1891c0b746e5SOllivier Robert /* 1892c0b746e5SOllivier Robert * Make sure mask for default address is zero. Otherwise, 1893c0b746e5SOllivier Robert * make sure mask bits are contiguous. 1894c0b746e5SOllivier Robert */ 18959c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 1896c0b746e5SOllivier Robert if (cres.addr == 0) { 1897c0b746e5SOllivier Robert cres.mask = 0; 1898c0b746e5SOllivier Robert } else { 1899c0b746e5SOllivier Robert num = ntohl(cres.mask); 1900c0b746e5SOllivier Robert for (bit = 0x80000000; bit != 0; bit >>= 1) 1901c0b746e5SOllivier Robert if ((num & bit) == 0) 1902c0b746e5SOllivier Robert break; 1903c0b746e5SOllivier Robert for ( ; bit != 0; bit >>= 1) 1904c0b746e5SOllivier Robert if ((num & bit) != 0) 1905c0b746e5SOllivier Robert break; 1906c0b746e5SOllivier Robert if (bit != 0) { 1907c0b746e5SOllivier Robert (void) fprintf(fp, "Invalid mask %s\n", 1908c0b746e5SOllivier Robert numtoa(cres.mask)); 1909c0b746e5SOllivier Robert err++; 1910c0b746e5SOllivier Robert } 1911c0b746e5SOllivier Robert } 19129c2daa00SOllivier Robert } else { 19139c2daa00SOllivier Robert /* XXX IPv6 sanity checking stuff */ 19149c2daa00SOllivier Robert } 1915c0b746e5SOllivier Robert 1916c0b746e5SOllivier Robert if (err) 1917c0b746e5SOllivier Robert return; 1918c0b746e5SOllivier Robert 19199c2daa00SOllivier Robert res = doquery(impl_ver, req_code, 1, 1, 19209c2daa00SOllivier Robert sendsize, (char *)&cres, &items, 19219c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_restrict)); 19229c2daa00SOllivier Robert 19239c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 19249c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 19259c2daa00SOllivier Robert goto again; 19269c2daa00SOllivier Robert } 1927c0b746e5SOllivier Robert 1928c0b746e5SOllivier Robert if (res == 0) 1929c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1930c0b746e5SOllivier Robert return; 1931c0b746e5SOllivier Robert } 1932c0b746e5SOllivier Robert 1933c0b746e5SOllivier Robert 1934c0b746e5SOllivier Robert /* 1935c0b746e5SOllivier Robert * monlist - obtain and print the server's monitor data 1936c0b746e5SOllivier Robert */ 1937c0b746e5SOllivier Robert /*ARGSUSED*/ 1938c0b746e5SOllivier Robert static void 1939c0b746e5SOllivier Robert monlist( 1940c0b746e5SOllivier Robert struct parse *pcmd, 1941c0b746e5SOllivier Robert FILE *fp 1942c0b746e5SOllivier Robert ) 1943c0b746e5SOllivier Robert { 1944c0b746e5SOllivier Robert char *struct_star; 19459c2daa00SOllivier Robert struct sockaddr_storage addr; 19469c2daa00SOllivier Robert struct sockaddr_storage dstadr; 1947c0b746e5SOllivier Robert int items; 1948c0b746e5SOllivier Robert int itemsize; 1949c0b746e5SOllivier Robert int res; 1950c0b746e5SOllivier Robert int version = -1; 1951c0b746e5SOllivier Robert 1952c0b746e5SOllivier Robert if (pcmd->nargs > 0) { 1953c0b746e5SOllivier Robert version = pcmd->argval[0].ival; 1954c0b746e5SOllivier Robert } 1955c0b746e5SOllivier Robert 19569c2daa00SOllivier Robert again: 19579c2daa00SOllivier Robert res = doquery(impl_ver, 1958c0b746e5SOllivier Robert (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : 1959c0b746e5SOllivier Robert REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 1960c0b746e5SOllivier Robert &items, &itemsize, &struct_star, 19619c2daa00SOllivier Robert (version < 0) ? (1 << INFO_ERR_REQ) : 0, 19629c2daa00SOllivier Robert sizeof(struct info_monitor_1)); 19639c2daa00SOllivier Robert 19649c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 19659c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 19669c2daa00SOllivier Robert goto again; 19679c2daa00SOllivier Robert } 1968c0b746e5SOllivier Robert 1969c0b746e5SOllivier Robert if (res == INFO_ERR_REQ && version < 0) 19709c2daa00SOllivier Robert res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 19719c2daa00SOllivier Robert &items, &itemsize, &struct_star, 0, 19729c2daa00SOllivier Robert sizeof(struct info_monitor)); 1973c0b746e5SOllivier Robert 1974ea906c41SOllivier Robert if (res != 0) 1975c0b746e5SOllivier Robert return; 1976c0b746e5SOllivier Robert 1977c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1978c0b746e5SOllivier Robert return; 1979c0b746e5SOllivier Robert 19809c2daa00SOllivier Robert if (itemsize == sizeof(struct info_monitor_1) || 19819c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor_1)) { 1982c0b746e5SOllivier Robert struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star; 1983c0b746e5SOllivier Robert 1984c0b746e5SOllivier Robert (void) fprintf(fp, 19859c2daa00SOllivier Robert "remote address port local address count m ver code avgint lstint\n"); 1986c0b746e5SOllivier Robert (void) fprintf(fp, 1987c0b746e5SOllivier Robert "===============================================================================\n"); 1988c0b746e5SOllivier Robert while (items > 0) { 19899c2daa00SOllivier Robert memset((char *)&addr, 0, sizeof(addr)); 19909c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 19919c2daa00SOllivier Robert if (ml->v6_flag != 0) { 19929c2daa00SOllivier Robert GET_INADDR6(addr) = ml->addr6; 19939c2daa00SOllivier Robert addr.ss_family = AF_INET6; 19949c2daa00SOllivier Robert GET_INADDR6(dstadr) = ml->daddr6; 19959c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 19969c2daa00SOllivier Robert } else { 19979c2daa00SOllivier Robert GET_INADDR(addr) = ml->addr; 19989c2daa00SOllivier Robert addr.ss_family = AF_INET; 19999c2daa00SOllivier Robert GET_INADDR(dstadr) = ml->daddr; 20009c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 20019c2daa00SOllivier Robert } 20029c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 20039c2daa00SOllivier Robert addr.ss_len = SOCKLEN(&addr); 20049c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 20059c2daa00SOllivier Robert #endif 20069c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 20079c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || 20089c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) 2009c0b746e5SOllivier Robert (void) fprintf(fp, 20109c2daa00SOllivier Robert "%-22.22s %5d %-15s %8ld %1d %1d %6lx %6lu %7lu\n", 20119c2daa00SOllivier Robert nntohost(&addr), 2012c0b746e5SOllivier Robert ntohs(ml->port), 20139c2daa00SOllivier Robert stoa(&dstadr), 2014c0b746e5SOllivier Robert (u_long)ntohl(ml->count), 2015c0b746e5SOllivier Robert ml->mode, 2016c0b746e5SOllivier Robert ml->version, 2017c0b746e5SOllivier Robert (u_long)ntohl(ml->lastdrop), 2018c0b746e5SOllivier Robert (u_long)ntohl(ml->lasttime), 2019c0b746e5SOllivier Robert (u_long)ntohl(ml->firsttime)); 2020c0b746e5SOllivier Robert ml++; 2021c0b746e5SOllivier Robert items--; 2022c0b746e5SOllivier Robert } 20239c2daa00SOllivier Robert } else if (itemsize == sizeof(struct info_monitor) || 20249c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor)) { 2025c0b746e5SOllivier Robert struct info_monitor *ml = (struct info_monitor *) struct_star; 2026c0b746e5SOllivier Robert 2027c0b746e5SOllivier Robert (void) fprintf(fp, 20289c2daa00SOllivier Robert " address port count mode ver code avgint lstint\n"); 2029c0b746e5SOllivier Robert (void) fprintf(fp, 2030c0b746e5SOllivier Robert "===============================================================================\n"); 2031c0b746e5SOllivier Robert while (items > 0) { 20329c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 20339c2daa00SOllivier Robert if (ml->v6_flag != 0) { 20349c2daa00SOllivier Robert GET_INADDR6(dstadr) = ml->addr6; 20359c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 20369c2daa00SOllivier Robert } else { 20379c2daa00SOllivier Robert GET_INADDR(dstadr) = ml->addr; 20389c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 20399c2daa00SOllivier Robert } 20409c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 20419c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 20429c2daa00SOllivier Robert #endif 20439c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 20449c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || 20459c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) 2046c0b746e5SOllivier Robert (void) fprintf(fp, 20479c2daa00SOllivier Robert "%-25.25s %5d %9ld %4d %2d %9lx %9lu %9lu\n", 20489c2daa00SOllivier Robert nntohost(&dstadr), 2049c0b746e5SOllivier Robert ntohs(ml->port), 2050c0b746e5SOllivier Robert (u_long)ntohl(ml->count), 2051c0b746e5SOllivier Robert ml->mode, 2052c0b746e5SOllivier Robert ml->version, 2053c0b746e5SOllivier Robert (u_long)ntohl(ml->lastdrop), 2054c0b746e5SOllivier Robert (u_long)ntohl(ml->lasttime), 2055c0b746e5SOllivier Robert (u_long)ntohl(ml->firsttime)); 2056c0b746e5SOllivier Robert ml++; 2057c0b746e5SOllivier Robert items--; 2058c0b746e5SOllivier Robert } 2059c0b746e5SOllivier Robert } else if (itemsize == sizeof(struct old_info_monitor)) { 2060c0b746e5SOllivier Robert struct old_info_monitor *oml = (struct old_info_monitor *)struct_star; 2061c0b746e5SOllivier Robert (void) fprintf(fp, 2062c0b746e5SOllivier Robert " address port count mode version lasttime firsttime\n"); 2063c0b746e5SOllivier Robert (void) fprintf(fp, 2064c0b746e5SOllivier Robert "======================================================================\n"); 2065c0b746e5SOllivier Robert while (items > 0) { 20669c2daa00SOllivier Robert memset((char *)&dstadr, 0, sizeof(dstadr)); 20679c2daa00SOllivier Robert if (oml->v6_flag != 0) { 20689c2daa00SOllivier Robert GET_INADDR6(dstadr) = oml->addr6; 20699c2daa00SOllivier Robert dstadr.ss_family = AF_INET6; 20709c2daa00SOllivier Robert } else { 20719c2daa00SOllivier Robert GET_INADDR(dstadr) = oml->addr; 20729c2daa00SOllivier Robert dstadr.ss_family = AF_INET; 20739c2daa00SOllivier Robert } 20749c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 20759c2daa00SOllivier Robert dstadr.ss_len = SOCKLEN(&dstadr); 20769c2daa00SOllivier Robert #endif 2077c0b746e5SOllivier Robert (void) fprintf(fp, "%-20.20s %5d %9ld %4d %3d %9lu %9lu\n", 20789c2daa00SOllivier Robert nntohost(&dstadr), 2079c0b746e5SOllivier Robert ntohs(oml->port), 2080c0b746e5SOllivier Robert (u_long)ntohl(oml->count), 2081c0b746e5SOllivier Robert oml->mode, 2082c0b746e5SOllivier Robert oml->version, 2083c0b746e5SOllivier Robert (u_long)ntohl(oml->lasttime), 2084c0b746e5SOllivier Robert (u_long)ntohl(oml->firsttime)); 2085c0b746e5SOllivier Robert oml++; 2086c0b746e5SOllivier Robert items--; 2087c0b746e5SOllivier Robert } 2088c0b746e5SOllivier Robert } else { 2089c0b746e5SOllivier Robert /* issue warning according to new info_monitor size */ 2090c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_monitor)); 2091c0b746e5SOllivier Robert } 2092c0b746e5SOllivier Robert } 2093c0b746e5SOllivier Robert 2094c0b746e5SOllivier Robert 2095c0b746e5SOllivier Robert /* 2096c0b746e5SOllivier Robert * Mapping between command line strings and stat reset flags 2097c0b746e5SOllivier Robert */ 2098c0b746e5SOllivier Robert struct statreset { 2099c0b746e5SOllivier Robert const char *str; 2100c0b746e5SOllivier Robert int flag; 2101c0b746e5SOllivier Robert } sreset[] = { 2102c0b746e5SOllivier Robert { "io", RESET_FLAG_IO }, 2103c0b746e5SOllivier Robert { "sys", RESET_FLAG_SYS }, 2104c0b746e5SOllivier Robert { "mem", RESET_FLAG_MEM }, 2105c0b746e5SOllivier Robert { "timer", RESET_FLAG_TIMER }, 2106c0b746e5SOllivier Robert { "auth", RESET_FLAG_AUTH }, 2107c0b746e5SOllivier Robert { "allpeers", RESET_FLAG_ALLPEERS }, 2108c0b746e5SOllivier Robert { "", 0 } 2109c0b746e5SOllivier Robert }; 2110c0b746e5SOllivier Robert 2111c0b746e5SOllivier Robert /* 2112c0b746e5SOllivier Robert * reset - reset statistic counters 2113c0b746e5SOllivier Robert */ 2114c0b746e5SOllivier Robert static void 2115c0b746e5SOllivier Robert reset( 2116c0b746e5SOllivier Robert struct parse *pcmd, 2117c0b746e5SOllivier Robert FILE *fp 2118c0b746e5SOllivier Robert ) 2119c0b746e5SOllivier Robert { 2120c0b746e5SOllivier Robert struct reset_flags rflags; 2121c0b746e5SOllivier Robert int items; 2122c0b746e5SOllivier Robert int itemsize; 2123c0b746e5SOllivier Robert char *dummy; 2124c0b746e5SOllivier Robert int i; 2125c0b746e5SOllivier Robert int res; 2126c0b746e5SOllivier Robert int err; 2127c0b746e5SOllivier Robert 2128c0b746e5SOllivier Robert err = 0; 2129c0b746e5SOllivier Robert rflags.flags = 0; 2130c0b746e5SOllivier Robert for (res = 0; res < pcmd->nargs; res++) { 2131c0b746e5SOllivier Robert for (i = 0; sreset[i].flag != 0; i++) { 2132c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, sreset[i].str)) 2133c0b746e5SOllivier Robert break; 2134c0b746e5SOllivier Robert } 2135c0b746e5SOllivier Robert if (sreset[i].flag == 0) { 2136c0b746e5SOllivier Robert (void) fprintf(fp, "Flag %s unknown\n", 2137c0b746e5SOllivier Robert pcmd->argval[res].string); 2138c0b746e5SOllivier Robert err++; 2139c0b746e5SOllivier Robert } else { 2140c0b746e5SOllivier Robert rflags.flags |= sreset[i].flag; 2141c0b746e5SOllivier Robert } 2142c0b746e5SOllivier Robert } 2143ea906c41SOllivier Robert rflags.flags = htonl(rflags.flags); 2144c0b746e5SOllivier Robert 2145c0b746e5SOllivier Robert if (err) { 2146c0b746e5SOllivier Robert (void) fprintf(fp, "Not done due to errors\n"); 2147c0b746e5SOllivier Robert return; 2148c0b746e5SOllivier Robert } 2149c0b746e5SOllivier Robert 21509c2daa00SOllivier Robert again: 21519c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_STATS, 1, 1, 2152c0b746e5SOllivier Robert sizeof(struct reset_flags), (char *)&rflags, &items, 21539c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct reset_flags)); 21549c2daa00SOllivier Robert 21559c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 21569c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 21579c2daa00SOllivier Robert goto again; 21589c2daa00SOllivier Robert } 2159c0b746e5SOllivier Robert 2160c0b746e5SOllivier Robert if (res == 0) 2161c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2162c0b746e5SOllivier Robert return; 2163c0b746e5SOllivier Robert } 2164c0b746e5SOllivier Robert 2165c0b746e5SOllivier Robert 2166c0b746e5SOllivier Robert 2167c0b746e5SOllivier Robert /* 2168c0b746e5SOllivier Robert * preset - reset stat counters for particular peers 2169c0b746e5SOllivier Robert */ 2170c0b746e5SOllivier Robert static void 2171c0b746e5SOllivier Robert preset( 2172c0b746e5SOllivier Robert struct parse *pcmd, 2173c0b746e5SOllivier Robert FILE *fp 2174c0b746e5SOllivier Robert ) 2175c0b746e5SOllivier Robert { 2176c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 21779c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 2178c0b746e5SOllivier Robert int qitems; 2179c0b746e5SOllivier Robert int items; 2180c0b746e5SOllivier Robert int itemsize; 2181c0b746e5SOllivier Robert char *dummy; 2182c0b746e5SOllivier Robert int res; 21839c2daa00SOllivier Robert int sendsize; 2184c0b746e5SOllivier Robert 21859c2daa00SOllivier Robert again: 21869c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21879c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 21889c2daa00SOllivier Robert else 21899c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 21909c2daa00SOllivier Robert 21919c2daa00SOllivier Robert for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 8); qitems++) { 21929c2daa00SOllivier Robert if (pcmd->argval[qitems].netnum.ss_family == AF_INET) { 21939c2daa00SOllivier Robert pl->peeraddr = GET_INADDR(pcmd->argval[qitems].netnum); 21949c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21959c2daa00SOllivier Robert pl->v6_flag = 0; 21969c2daa00SOllivier Robert } else { 21979c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 21989c2daa00SOllivier Robert fprintf(stderr, 21999c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 22009c2daa00SOllivier Robert return; 22019c2daa00SOllivier Robert } 22029c2daa00SOllivier Robert pl->peeraddr6 = 22039c2daa00SOllivier Robert GET_INADDR6(pcmd->argval[qitems].netnum); 22049c2daa00SOllivier Robert pl->v6_flag = 1; 22059c2daa00SOllivier Robert } 22069c2daa00SOllivier Robert pl = (struct conf_unpeer *)((char *)pl + sendsize); 2207c0b746e5SOllivier Robert } 2208c0b746e5SOllivier Robert 22099c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems, 22109c2daa00SOllivier Robert sendsize, (char *)plist, &items, 22119c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 22129c2daa00SOllivier Robert 22139c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22149c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22159c2daa00SOllivier Robert goto again; 22169c2daa00SOllivier Robert } 2217c0b746e5SOllivier Robert 2218c0b746e5SOllivier Robert if (res == 0) 2219c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2220c0b746e5SOllivier Robert } 2221c0b746e5SOllivier Robert 2222c0b746e5SOllivier Robert 2223c0b746e5SOllivier Robert /* 2224c0b746e5SOllivier Robert * readkeys - request the server to reread the keys file 2225c0b746e5SOllivier Robert */ 2226c0b746e5SOllivier Robert /*ARGSUSED*/ 2227c0b746e5SOllivier Robert static void 2228c0b746e5SOllivier Robert readkeys( 2229c0b746e5SOllivier Robert struct parse *pcmd, 2230c0b746e5SOllivier Robert FILE *fp 2231c0b746e5SOllivier Robert ) 2232c0b746e5SOllivier Robert { 2233c0b746e5SOllivier Robert int items; 2234c0b746e5SOllivier Robert int itemsize; 2235c0b746e5SOllivier Robert char *dummy; 2236c0b746e5SOllivier Robert int res; 2237c0b746e5SOllivier Robert 22389c2daa00SOllivier Robert again: 22399c2daa00SOllivier Robert res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0, 22409c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, sizeof(dummy)); 22419c2daa00SOllivier Robert 22429c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22439c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22449c2daa00SOllivier Robert goto again; 22459c2daa00SOllivier Robert } 2246c0b746e5SOllivier Robert 2247c0b746e5SOllivier Robert if (res == 0) 2248c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2249c0b746e5SOllivier Robert return; 2250c0b746e5SOllivier Robert } 2251c0b746e5SOllivier Robert 2252c0b746e5SOllivier Robert 2253c0b746e5SOllivier Robert /* 2254c0b746e5SOllivier Robert * trustkey - add some keys to the trusted key list 2255c0b746e5SOllivier Robert */ 2256c0b746e5SOllivier Robert static void 2257c0b746e5SOllivier Robert trustkey( 2258c0b746e5SOllivier Robert struct parse *pcmd, 2259c0b746e5SOllivier Robert FILE *fp 2260c0b746e5SOllivier Robert ) 2261c0b746e5SOllivier Robert { 2262c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_TRUSTKEY); 2263c0b746e5SOllivier Robert } 2264c0b746e5SOllivier Robert 2265c0b746e5SOllivier Robert 2266c0b746e5SOllivier Robert /* 2267c0b746e5SOllivier Robert * untrustkey - remove some keys from the trusted key list 2268c0b746e5SOllivier Robert */ 2269c0b746e5SOllivier Robert static void 2270c0b746e5SOllivier Robert untrustkey( 2271c0b746e5SOllivier Robert struct parse *pcmd, 2272c0b746e5SOllivier Robert FILE *fp 2273c0b746e5SOllivier Robert ) 2274c0b746e5SOllivier Robert { 2275c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_UNTRUSTKEY); 2276c0b746e5SOllivier Robert } 2277c0b746e5SOllivier Robert 2278c0b746e5SOllivier Robert 2279c0b746e5SOllivier Robert /* 2280c0b746e5SOllivier Robert * do_trustkey - do grunge work of adding/deleting keys 2281c0b746e5SOllivier Robert */ 2282c0b746e5SOllivier Robert static void 2283c0b746e5SOllivier Robert do_trustkey( 2284c0b746e5SOllivier Robert struct parse *pcmd, 2285c0b746e5SOllivier Robert FILE *fp, 2286c0b746e5SOllivier Robert int req 2287c0b746e5SOllivier Robert ) 2288c0b746e5SOllivier Robert { 2289c0b746e5SOllivier Robert u_long keyids[MAXARGS]; 2290c0b746e5SOllivier Robert int i; 2291c0b746e5SOllivier Robert int items; 2292c0b746e5SOllivier Robert int itemsize; 2293c0b746e5SOllivier Robert char *dummy; 2294c0b746e5SOllivier Robert int ritems; 2295c0b746e5SOllivier Robert int res; 2296c0b746e5SOllivier Robert 2297c0b746e5SOllivier Robert ritems = 0; 2298c0b746e5SOllivier Robert for (i = 0; i < pcmd->nargs; i++) { 2299c0b746e5SOllivier Robert keyids[ritems++] = pcmd->argval[i].uval; 2300c0b746e5SOllivier Robert } 2301c0b746e5SOllivier Robert 23029c2daa00SOllivier Robert again: 23039c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, ritems, sizeof(u_long), 23049c2daa00SOllivier Robert (char *)keyids, &items, &itemsize, &dummy, 0, 23059c2daa00SOllivier Robert sizeof(dummy)); 23069c2daa00SOllivier Robert 23079c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23089c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23099c2daa00SOllivier Robert goto again; 23109c2daa00SOllivier Robert } 2311c0b746e5SOllivier Robert 2312c0b746e5SOllivier Robert if (res == 0) 2313c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2314c0b746e5SOllivier Robert return; 2315c0b746e5SOllivier Robert } 2316c0b746e5SOllivier Robert 2317c0b746e5SOllivier Robert 2318c0b746e5SOllivier Robert 2319c0b746e5SOllivier Robert /* 2320c0b746e5SOllivier Robert * authinfo - obtain and print info about authentication 2321c0b746e5SOllivier Robert */ 2322c0b746e5SOllivier Robert /*ARGSUSED*/ 2323c0b746e5SOllivier Robert static void 2324c0b746e5SOllivier Robert authinfo( 2325c0b746e5SOllivier Robert struct parse *pcmd, 2326c0b746e5SOllivier Robert FILE *fp 2327c0b746e5SOllivier Robert ) 2328c0b746e5SOllivier Robert { 2329c0b746e5SOllivier Robert struct info_auth *ia; 2330c0b746e5SOllivier Robert int items; 2331c0b746e5SOllivier Robert int itemsize; 2332c0b746e5SOllivier Robert int res; 2333c0b746e5SOllivier Robert 23349c2daa00SOllivier Robert again: 23359c2daa00SOllivier Robert res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, (char *)NULL, 23369c2daa00SOllivier Robert &items, &itemsize, (void *)&ia, 0, 23379c2daa00SOllivier Robert sizeof(struct info_auth)); 23389c2daa00SOllivier Robert 23399c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23409c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23419c2daa00SOllivier Robert goto again; 23429c2daa00SOllivier Robert } 2343c0b746e5SOllivier Robert 2344ea906c41SOllivier Robert if (res != 0) 2345c0b746e5SOllivier Robert return; 2346c0b746e5SOllivier Robert 2347c0b746e5SOllivier Robert if (!check1item(items, fp)) 2348c0b746e5SOllivier Robert return; 2349c0b746e5SOllivier Robert 2350c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_auth))) 2351c0b746e5SOllivier Robert return; 2352c0b746e5SOllivier Robert 2353c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 2354c0b746e5SOllivier Robert (u_long)ntohl(ia->timereset)); 2355c0b746e5SOllivier Robert (void) fprintf(fp, "stored keys: %ld\n", 2356c0b746e5SOllivier Robert (u_long)ntohl(ia->numkeys)); 2357c0b746e5SOllivier Robert (void) fprintf(fp, "free keys: %ld\n", 2358c0b746e5SOllivier Robert (u_long)ntohl(ia->numfreekeys)); 2359c0b746e5SOllivier Robert (void) fprintf(fp, "key lookups: %ld\n", 2360c0b746e5SOllivier Robert (u_long)ntohl(ia->keylookups)); 2361c0b746e5SOllivier Robert (void) fprintf(fp, "keys not found: %ld\n", 2362c0b746e5SOllivier Robert (u_long)ntohl(ia->keynotfound)); 2363c0b746e5SOllivier Robert (void) fprintf(fp, "uncached keys: %ld\n", 2364c0b746e5SOllivier Robert (u_long)ntohl(ia->keyuncached)); 2365c0b746e5SOllivier Robert (void) fprintf(fp, "encryptions: %ld\n", 2366c0b746e5SOllivier Robert (u_long)ntohl(ia->encryptions)); 2367c0b746e5SOllivier Robert (void) fprintf(fp, "decryptions: %ld\n", 2368c0b746e5SOllivier Robert (u_long)ntohl(ia->decryptions)); 2369c0b746e5SOllivier Robert (void) fprintf(fp, "expired keys: %ld\n", 2370c0b746e5SOllivier Robert (u_long)ntohl(ia->expired)); 2371c0b746e5SOllivier Robert } 2372c0b746e5SOllivier Robert 2373c0b746e5SOllivier Robert 2374c0b746e5SOllivier Robert 2375c0b746e5SOllivier Robert /* 2376c0b746e5SOllivier Robert * traps - obtain and print a list of traps 2377c0b746e5SOllivier Robert */ 2378c0b746e5SOllivier Robert /*ARGSUSED*/ 2379c0b746e5SOllivier Robert static void 2380c0b746e5SOllivier Robert traps( 2381c0b746e5SOllivier Robert struct parse *pcmd, 2382c0b746e5SOllivier Robert FILE *fp 2383c0b746e5SOllivier Robert ) 2384c0b746e5SOllivier Robert { 2385c0b746e5SOllivier Robert int i; 2386c0b746e5SOllivier Robert struct info_trap *it; 23879c2daa00SOllivier Robert struct sockaddr_storage trap_addr, local_addr; 2388c0b746e5SOllivier Robert int items; 2389c0b746e5SOllivier Robert int itemsize; 2390c0b746e5SOllivier Robert int res; 2391c0b746e5SOllivier Robert 23929c2daa00SOllivier Robert again: 23939c2daa00SOllivier Robert res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, (char *)NULL, 23949c2daa00SOllivier Robert &items, &itemsize, (void *)&it, 0, 23959c2daa00SOllivier Robert sizeof(struct info_trap)); 23969c2daa00SOllivier Robert 23979c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23989c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23999c2daa00SOllivier Robert goto again; 24009c2daa00SOllivier Robert } 2401c0b746e5SOllivier Robert 2402ea906c41SOllivier Robert if (res != 0) 2403c0b746e5SOllivier Robert return; 2404c0b746e5SOllivier Robert 2405c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2406c0b746e5SOllivier Robert return; 2407c0b746e5SOllivier Robert 24089c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_trap)) && 24099c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_trap))) 2410c0b746e5SOllivier Robert return; 2411c0b746e5SOllivier Robert 2412c0b746e5SOllivier Robert for (i = 0; i < items; i++ ) { 2413c0b746e5SOllivier Robert if (i != 0) 2414c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 24159c2daa00SOllivier Robert memset((char *)&trap_addr, 0, sizeof(trap_addr)); 24169c2daa00SOllivier Robert memset((char *)&local_addr, 0, sizeof(local_addr)); 24179c2daa00SOllivier Robert if (it->v6_flag != 0) { 24189c2daa00SOllivier Robert GET_INADDR6(trap_addr) = it->trap_address6; 24199c2daa00SOllivier Robert GET_INADDR6(local_addr) = it->local_address6; 24209c2daa00SOllivier Robert trap_addr.ss_family = AF_INET6; 24219c2daa00SOllivier Robert local_addr.ss_family = AF_INET6; 24229c2daa00SOllivier Robert } else { 24239c2daa00SOllivier Robert GET_INADDR(trap_addr) = it->trap_address; 24249c2daa00SOllivier Robert GET_INADDR(local_addr) = it->local_address; 24259c2daa00SOllivier Robert trap_addr.ss_family = AF_INET; 24269c2daa00SOllivier Robert local_addr.ss_family = AF_INET; 24279c2daa00SOllivier Robert } 24289c2daa00SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 24299c2daa00SOllivier Robert trap_addr.ss_len = SOCKLEN(&trap_addr); 24309c2daa00SOllivier Robert local_addr.ss_len = SOCKLEN(&local_addr); 24319c2daa00SOllivier Robert #endif 2432c0b746e5SOllivier Robert (void) fprintf(fp, "address %s, port %d\n", 24339c2daa00SOllivier Robert stoa(&trap_addr), 24349c2daa00SOllivier Robert ntohs(it->trap_port)); 2435c0b746e5SOllivier Robert (void) fprintf(fp, "interface: %s, ", 2436c0b746e5SOllivier Robert (it->local_address == 0) 2437c0b746e5SOllivier Robert ? "wildcard" 24389c2daa00SOllivier Robert : stoa(&local_addr)); 2439c0b746e5SOllivier Robert if (ntohl(it->flags) & TRAP_CONFIGURED) 2440c0b746e5SOllivier Robert (void) fprintf(fp, "configured\n"); 2441c0b746e5SOllivier Robert else if (ntohl(it->flags) & TRAP_NONPRIO) 2442c0b746e5SOllivier Robert (void) fprintf(fp, "low priority\n"); 2443c0b746e5SOllivier Robert else 2444c0b746e5SOllivier Robert (void) fprintf(fp, "normal priority\n"); 2445c0b746e5SOllivier Robert 2446c0b746e5SOllivier Robert (void) fprintf(fp, "set for %ld secs, last set %ld secs ago\n", 2447c0b746e5SOllivier Robert (long)ntohl(it->origtime), 2448c0b746e5SOllivier Robert (long)ntohl(it->settime)); 2449c0b746e5SOllivier Robert (void) fprintf(fp, "sequence %d, number of resets %ld\n", 2450c0b746e5SOllivier Robert ntohs(it->sequence), 2451c0b746e5SOllivier Robert (long)ntohl(it->resets)); 2452c0b746e5SOllivier Robert } 2453c0b746e5SOllivier Robert } 2454c0b746e5SOllivier Robert 2455c0b746e5SOllivier Robert 2456c0b746e5SOllivier Robert /* 2457c0b746e5SOllivier Robert * addtrap - configure a trap 2458c0b746e5SOllivier Robert */ 2459c0b746e5SOllivier Robert static void 2460c0b746e5SOllivier Robert addtrap( 2461c0b746e5SOllivier Robert struct parse *pcmd, 2462c0b746e5SOllivier Robert FILE *fp 2463c0b746e5SOllivier Robert ) 2464c0b746e5SOllivier Robert { 2465c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_ADD_TRAP); 2466c0b746e5SOllivier Robert } 2467c0b746e5SOllivier Robert 2468c0b746e5SOllivier Robert 2469c0b746e5SOllivier Robert /* 2470c0b746e5SOllivier Robert * clrtrap - clear a trap from the server 2471c0b746e5SOllivier Robert */ 2472c0b746e5SOllivier Robert static void 2473c0b746e5SOllivier Robert clrtrap( 2474c0b746e5SOllivier Robert struct parse *pcmd, 2475c0b746e5SOllivier Robert FILE *fp 2476c0b746e5SOllivier Robert ) 2477c0b746e5SOllivier Robert { 2478c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_CLR_TRAP); 2479c0b746e5SOllivier Robert } 2480c0b746e5SOllivier Robert 2481c0b746e5SOllivier Robert 2482c0b746e5SOllivier Robert /* 2483c0b746e5SOllivier Robert * do_addclr_trap - do grunge work of adding/deleting traps 2484c0b746e5SOllivier Robert */ 2485c0b746e5SOllivier Robert static void 2486c0b746e5SOllivier Robert do_addclr_trap( 2487c0b746e5SOllivier Robert struct parse *pcmd, 2488c0b746e5SOllivier Robert FILE *fp, 2489c0b746e5SOllivier Robert int req 2490c0b746e5SOllivier Robert ) 2491c0b746e5SOllivier Robert { 2492c0b746e5SOllivier Robert struct conf_trap ctrap; 2493c0b746e5SOllivier Robert int items; 2494c0b746e5SOllivier Robert int itemsize; 2495c0b746e5SOllivier Robert char *dummy; 2496c0b746e5SOllivier Robert int res; 24979c2daa00SOllivier Robert int sendsize; 2498c0b746e5SOllivier Robert 24999c2daa00SOllivier Robert again: 25009c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 25019c2daa00SOllivier Robert sendsize = sizeof(struct conf_trap); 25029c2daa00SOllivier Robert else 25039c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_trap); 25049c2daa00SOllivier Robert 25059c2daa00SOllivier Robert if (pcmd->argval[0].netnum.ss_family == AF_INET) { 25069c2daa00SOllivier Robert ctrap.trap_address = GET_INADDR(pcmd->argval[0].netnum); 25079c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 25089c2daa00SOllivier Robert ctrap.v6_flag = 0; 25099c2daa00SOllivier Robert } else { 25109c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 25119c2daa00SOllivier Robert fprintf(stderr, 25129c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 25139c2daa00SOllivier Robert return; 25149c2daa00SOllivier Robert } 25159c2daa00SOllivier Robert ctrap.trap_address6 = GET_INADDR6(pcmd->argval[0].netnum); 25169c2daa00SOllivier Robert ctrap.v6_flag = 1; 25179c2daa00SOllivier Robert } 2518c0b746e5SOllivier Robert ctrap.local_address = 0; 2519c0b746e5SOllivier Robert ctrap.trap_port = htons(TRAPPORT); 2520c0b746e5SOllivier Robert ctrap.unused = 0; 2521c0b746e5SOllivier Robert 2522c0b746e5SOllivier Robert if (pcmd->nargs > 1) { 2523c0b746e5SOllivier Robert ctrap.trap_port 2524c0b746e5SOllivier Robert = htons((u_short)(pcmd->argval[1].uval & 0xffff)); 25259c2daa00SOllivier Robert if (pcmd->nargs > 2) { 25269c2daa00SOllivier Robert if (pcmd->argval[2].netnum.ss_family != 25279c2daa00SOllivier Robert pcmd->argval[0].netnum.ss_family) { 25289c2daa00SOllivier Robert fprintf(stderr, 25299c2daa00SOllivier Robert "***Cannot mix IPv4 and IPv6 addresses\n"); 25309c2daa00SOllivier Robert return; 25319c2daa00SOllivier Robert } 25329c2daa00SOllivier Robert if (pcmd->argval[2].netnum.ss_family == AF_INET) 25339c2daa00SOllivier Robert ctrap.local_address = GET_INADDR(pcmd->argval[2].netnum); 25349c2daa00SOllivier Robert else 25359c2daa00SOllivier Robert ctrap.local_address6 = GET_INADDR6(pcmd->argval[2].netnum); 25369c2daa00SOllivier Robert } 2537c0b746e5SOllivier Robert } 2538c0b746e5SOllivier Robert 25399c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sendsize, 25409c2daa00SOllivier Robert (char *)&ctrap, &items, &itemsize, &dummy, 0, 25419c2daa00SOllivier Robert sizeof(struct conf_trap)); 25429c2daa00SOllivier Robert 25439c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 25449c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25459c2daa00SOllivier Robert goto again; 25469c2daa00SOllivier Robert } 2547c0b746e5SOllivier Robert 2548c0b746e5SOllivier Robert if (res == 0) 2549c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2550c0b746e5SOllivier Robert return; 2551c0b746e5SOllivier Robert } 2552c0b746e5SOllivier Robert 2553c0b746e5SOllivier Robert 2554c0b746e5SOllivier Robert 2555c0b746e5SOllivier Robert /* 2556c0b746e5SOllivier Robert * requestkey - change the server's request key (a dangerous request) 2557c0b746e5SOllivier Robert */ 2558c0b746e5SOllivier Robert static void 2559c0b746e5SOllivier Robert requestkey( 2560c0b746e5SOllivier Robert struct parse *pcmd, 2561c0b746e5SOllivier Robert FILE *fp 2562c0b746e5SOllivier Robert ) 2563c0b746e5SOllivier Robert { 2564c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_REQUEST_KEY); 2565c0b746e5SOllivier Robert } 2566c0b746e5SOllivier Robert 2567c0b746e5SOllivier Robert 2568c0b746e5SOllivier Robert /* 2569c0b746e5SOllivier Robert * controlkey - change the server's control key 2570c0b746e5SOllivier Robert */ 2571c0b746e5SOllivier Robert static void 2572c0b746e5SOllivier Robert controlkey( 2573c0b746e5SOllivier Robert struct parse *pcmd, 2574c0b746e5SOllivier Robert FILE *fp 2575c0b746e5SOllivier Robert ) 2576c0b746e5SOllivier Robert { 2577c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_CONTROL_KEY); 2578c0b746e5SOllivier Robert } 2579c0b746e5SOllivier Robert 2580c0b746e5SOllivier Robert 2581c0b746e5SOllivier Robert 2582c0b746e5SOllivier Robert /* 2583c0b746e5SOllivier Robert * do_changekey - do grunge work of changing keys 2584c0b746e5SOllivier Robert */ 2585c0b746e5SOllivier Robert static void 2586c0b746e5SOllivier Robert do_changekey( 2587c0b746e5SOllivier Robert struct parse *pcmd, 2588c0b746e5SOllivier Robert FILE *fp, 2589c0b746e5SOllivier Robert int req 2590c0b746e5SOllivier Robert ) 2591c0b746e5SOllivier Robert { 2592c0b746e5SOllivier Robert u_long key; 2593c0b746e5SOllivier Robert int items; 2594c0b746e5SOllivier Robert int itemsize; 2595c0b746e5SOllivier Robert char *dummy; 2596c0b746e5SOllivier Robert int res; 2597c0b746e5SOllivier Robert 2598c0b746e5SOllivier Robert 2599c0b746e5SOllivier Robert key = htonl((u_int32)pcmd->argval[0].uval); 2600c0b746e5SOllivier Robert 26019c2daa00SOllivier Robert again: 26029c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sizeof(u_int32), 26039c2daa00SOllivier Robert (char *)&key, &items, &itemsize, &dummy, 0, 26049c2daa00SOllivier Robert sizeof(dummy)); 26059c2daa00SOllivier Robert 26069c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 26079c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 26089c2daa00SOllivier Robert goto again; 26099c2daa00SOllivier Robert } 2610c0b746e5SOllivier Robert 2611c0b746e5SOllivier Robert if (res == 0) 2612c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2613c0b746e5SOllivier Robert return; 2614c0b746e5SOllivier Robert } 2615c0b746e5SOllivier Robert 2616c0b746e5SOllivier Robert 2617c0b746e5SOllivier Robert 2618c0b746e5SOllivier Robert /* 2619c0b746e5SOllivier Robert * ctlstats - obtain and print info about authentication 2620c0b746e5SOllivier Robert */ 2621c0b746e5SOllivier Robert /*ARGSUSED*/ 2622c0b746e5SOllivier Robert static void 2623c0b746e5SOllivier Robert ctlstats( 2624c0b746e5SOllivier Robert struct parse *pcmd, 2625c0b746e5SOllivier Robert FILE *fp 2626c0b746e5SOllivier Robert ) 2627c0b746e5SOllivier Robert { 2628c0b746e5SOllivier Robert struct info_control *ic; 2629c0b746e5SOllivier Robert int items; 2630c0b746e5SOllivier Robert int itemsize; 2631c0b746e5SOllivier Robert int res; 2632c0b746e5SOllivier Robert 26339c2daa00SOllivier Robert again: 26349c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, (char *)NULL, 26359c2daa00SOllivier Robert &items, &itemsize, (void *)&ic, 0, 26369c2daa00SOllivier Robert sizeof(struct info_control)); 26379c2daa00SOllivier Robert 26389c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 26399c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 26409c2daa00SOllivier Robert goto again; 26419c2daa00SOllivier Robert } 2642c0b746e5SOllivier Robert 2643ea906c41SOllivier Robert if (res != 0) 2644c0b746e5SOllivier Robert return; 2645c0b746e5SOllivier Robert 2646c0b746e5SOllivier Robert if (!check1item(items, fp)) 2647c0b746e5SOllivier Robert return; 2648c0b746e5SOllivier Robert 2649c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_control))) 2650c0b746e5SOllivier Robert return; 2651c0b746e5SOllivier Robert 2652c0b746e5SOllivier Robert (void) fprintf(fp, "time since reset: %ld\n", 2653c0b746e5SOllivier Robert (u_long)ntohl(ic->ctltimereset)); 2654c0b746e5SOllivier Robert (void) fprintf(fp, "requests received: %ld\n", 2655c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlreq)); 2656c0b746e5SOllivier Robert (void) fprintf(fp, "responses sent: %ld\n", 2657c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlresponses)); 2658c0b746e5SOllivier Robert (void) fprintf(fp, "fragments sent: %ld\n", 2659c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlfrags)); 2660c0b746e5SOllivier Robert (void) fprintf(fp, "async messages sent: %ld\n", 2661c0b746e5SOllivier Robert (u_long)ntohl(ic->numasyncmsgs)); 2662c0b746e5SOllivier Robert (void) fprintf(fp, "error msgs sent: %ld\n", 2663c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlerrors)); 2664c0b746e5SOllivier Robert (void) fprintf(fp, "total bad pkts: %ld\n", 2665c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadpkts)); 2666c0b746e5SOllivier Robert (void) fprintf(fp, "packet too short: %ld\n", 2667c0b746e5SOllivier Robert (u_long)ntohl(ic->numctltooshort)); 2668c0b746e5SOllivier Robert (void) fprintf(fp, "response on input: %ld\n", 2669c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputresp)); 2670c0b746e5SOllivier Robert (void) fprintf(fp, "fragment on input: %ld\n", 2671c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputfrag)); 2672c0b746e5SOllivier Robert (void) fprintf(fp, "error set on input: %ld\n", 2673c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputerr)); 2674c0b746e5SOllivier Robert (void) fprintf(fp, "bad offset on input: %ld\n", 2675c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadoffset)); 2676c0b746e5SOllivier Robert (void) fprintf(fp, "bad version packets: %ld\n", 2677c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadversion)); 2678c0b746e5SOllivier Robert (void) fprintf(fp, "data in pkt too short: %ld\n", 2679c0b746e5SOllivier Robert (u_long)ntohl(ic->numctldatatooshort)); 2680c0b746e5SOllivier Robert (void) fprintf(fp, "unknown op codes: %ld\n", 2681c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadop)); 2682c0b746e5SOllivier Robert } 2683c0b746e5SOllivier Robert 2684c0b746e5SOllivier Robert 2685c0b746e5SOllivier Robert /* 2686c0b746e5SOllivier Robert * clockstat - get and print clock status information 2687c0b746e5SOllivier Robert */ 2688c0b746e5SOllivier Robert static void 2689c0b746e5SOllivier Robert clockstat( 2690c0b746e5SOllivier Robert struct parse *pcmd, 2691c0b746e5SOllivier Robert FILE *fp 2692c0b746e5SOllivier Robert ) 2693c0b746e5SOllivier Robert { 2694c0b746e5SOllivier Robert struct info_clock *cl; 2695c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2696c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 2697c0b746e5SOllivier Robert int qitems; 2698c0b746e5SOllivier Robert int items; 2699c0b746e5SOllivier Robert int itemsize; 2700c0b746e5SOllivier Robert int res; 2701c0b746e5SOllivier Robert l_fp ts; 2702c0b746e5SOllivier Robert struct clktype *clk; 2703c0b746e5SOllivier Robert 2704c0b746e5SOllivier Robert for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 27059c2daa00SOllivier Robert clist[qitems] = GET_INADDR(pcmd->argval[qitems].netnum); 2706c0b746e5SOllivier Robert 27079c2daa00SOllivier Robert again: 27089c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems, 2709c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 27109c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clock)); 27119c2daa00SOllivier Robert 27129c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 27139c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 27149c2daa00SOllivier Robert goto again; 27159c2daa00SOllivier Robert } 2716c0b746e5SOllivier Robert 2717ea906c41SOllivier Robert if (res != 0) 2718c0b746e5SOllivier Robert return; 2719c0b746e5SOllivier Robert 2720c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2721c0b746e5SOllivier Robert return; 2722c0b746e5SOllivier Robert 2723c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clock))) 2724c0b746e5SOllivier Robert return; 2725c0b746e5SOllivier Robert 2726c0b746e5SOllivier Robert while (items-- > 0) { 2727c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2728c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2729c0b746e5SOllivier Robert for (clk = clktypes; clk->code >= 0; clk++) 2730c0b746e5SOllivier Robert if (clk->code == cl->type) 2731c0b746e5SOllivier Robert break; 2732c0b746e5SOllivier Robert if (clk->code >= 0) 2733c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: %s\n", 2734c0b746e5SOllivier Robert clk->clocktype); 2735c0b746e5SOllivier Robert else 2736c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: unknown type (%d)\n", 2737c0b746e5SOllivier Robert cl->type); 2738c0b746e5SOllivier Robert (void) fprintf(fp, "last event: %d\n", 2739c0b746e5SOllivier Robert cl->lastevent); 2740c0b746e5SOllivier Robert (void) fprintf(fp, "current status: %d\n", 2741c0b746e5SOllivier Robert cl->currentstatus); 2742c0b746e5SOllivier Robert (void) fprintf(fp, "number of polls: %lu\n", 2743c0b746e5SOllivier Robert (u_long)ntohl(cl->polls)); 2744c0b746e5SOllivier Robert (void) fprintf(fp, "no response to poll: %lu\n", 2745c0b746e5SOllivier Robert (u_long)ntohl(cl->noresponse)); 2746c0b746e5SOllivier Robert (void) fprintf(fp, "bad format responses: %lu\n", 2747c0b746e5SOllivier Robert (u_long)ntohl(cl->badformat)); 2748c0b746e5SOllivier Robert (void) fprintf(fp, "bad data responses: %lu\n", 2749c0b746e5SOllivier Robert (u_long)ntohl(cl->baddata)); 2750c0b746e5SOllivier Robert (void) fprintf(fp, "running time: %lu\n", 2751c0b746e5SOllivier Robert (u_long)ntohl(cl->timestarted)); 2752c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime1, &ts); 2753c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 1: %s\n", 2754c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2755c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime2, &ts); 2756c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 2: %s\n", 2757c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2758c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %ld\n", 2759c0b746e5SOllivier Robert (u_long)ntohl(cl->fudgeval1)); 2760c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: %s\n", 2761ea906c41SOllivier Robert refid_string(ntohl(cl->fudgeval2), 0)); 2762c0b746e5SOllivier Robert (void) fprintf(fp, "fudge flags: 0x%x\n", 2763c0b746e5SOllivier Robert cl->flags); 2764c0b746e5SOllivier Robert 2765c0b746e5SOllivier Robert if (items > 0) 2766c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2767c0b746e5SOllivier Robert cl++; 2768c0b746e5SOllivier Robert } 2769c0b746e5SOllivier Robert } 2770c0b746e5SOllivier Robert 2771c0b746e5SOllivier Robert 2772c0b746e5SOllivier Robert /* 2773c0b746e5SOllivier Robert * fudge - set clock fudge factors 2774c0b746e5SOllivier Robert */ 2775c0b746e5SOllivier Robert static void 2776c0b746e5SOllivier Robert fudge( 2777c0b746e5SOllivier Robert struct parse *pcmd, 2778c0b746e5SOllivier Robert FILE *fp 2779c0b746e5SOllivier Robert ) 2780c0b746e5SOllivier Robert { 2781c0b746e5SOllivier Robert struct conf_fudge fudgedata; 2782c0b746e5SOllivier Robert int items; 2783c0b746e5SOllivier Robert int itemsize; 2784c0b746e5SOllivier Robert char *dummy; 2785c0b746e5SOllivier Robert l_fp ts; 2786c0b746e5SOllivier Robert int res; 2787c0b746e5SOllivier Robert long val; 2788c0b746e5SOllivier Robert u_long u_val; 2789c0b746e5SOllivier Robert int err; 2790c0b746e5SOllivier Robert 2791c0b746e5SOllivier Robert 2792c0b746e5SOllivier Robert err = 0; 2793c0b746e5SOllivier Robert memset((char *)&fudgedata, 0, sizeof fudgedata); 27949c2daa00SOllivier Robert fudgedata.clockadr = GET_INADDR(pcmd->argval[0].netnum); 2795c0b746e5SOllivier Robert 2796c0b746e5SOllivier Robert if (STREQ(pcmd->argval[1].string, "time1")) { 2797c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME1); 2798c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2799c0b746e5SOllivier Robert err = 1; 2800c0b746e5SOllivier Robert else 2801c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2802c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "time2")) { 2803c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME2); 2804c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2805c0b746e5SOllivier Robert err = 1; 2806c0b746e5SOllivier Robert else 2807c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2808c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val1")) { 2809c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL1); 2810c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2811c0b746e5SOllivier Robert err = 1; 2812c0b746e5SOllivier Robert else 2813c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl(val); 2814c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val2")) { 2815c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL2); 2816c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2817c0b746e5SOllivier Robert err = 1; 2818c0b746e5SOllivier Robert else 2819c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)val); 2820c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "flags")) { 2821c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_FLAGS); 2822c0b746e5SOllivier Robert if (!hextoint(pcmd->argval[2].string, &u_val)) 2823c0b746e5SOllivier Robert err = 1; 2824c0b746e5SOllivier Robert else 2825c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf)); 2826c0b746e5SOllivier Robert } else { 2827c0b746e5SOllivier Robert (void) fprintf(stderr, "What fudge is %s?\n", 2828c0b746e5SOllivier Robert pcmd->argval[1].string); 2829c0b746e5SOllivier Robert return; 2830c0b746e5SOllivier Robert } 2831c0b746e5SOllivier Robert 2832c0b746e5SOllivier Robert if (err) { 2833c0b746e5SOllivier Robert (void) fprintf(stderr, "Unknown fudge parameter %s\n", 2834c0b746e5SOllivier Robert pcmd->argval[2].string); 2835c0b746e5SOllivier Robert return; 2836c0b746e5SOllivier Robert } 2837c0b746e5SOllivier Robert 28389c2daa00SOllivier Robert again: 28399c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1, 2840c0b746e5SOllivier Robert sizeof(struct conf_fudge), (char *)&fudgedata, &items, 28419c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(dummy)); 28429c2daa00SOllivier Robert 28439c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 28449c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 28459c2daa00SOllivier Robert goto again; 28469c2daa00SOllivier Robert } 2847c0b746e5SOllivier Robert 2848c0b746e5SOllivier Robert if (res == 0) 2849c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2850c0b746e5SOllivier Robert return; 2851c0b746e5SOllivier Robert } 2852c0b746e5SOllivier Robert 2853c0b746e5SOllivier Robert /* 2854c0b746e5SOllivier Robert * clkbug - get and print clock debugging information 2855c0b746e5SOllivier Robert */ 2856c0b746e5SOllivier Robert static void 2857c0b746e5SOllivier Robert clkbug( 2858c0b746e5SOllivier Robert struct parse *pcmd, 2859c0b746e5SOllivier Robert FILE *fp 2860c0b746e5SOllivier Robert ) 2861c0b746e5SOllivier Robert { 2862c0b746e5SOllivier Robert register int i; 2863c0b746e5SOllivier Robert register int n; 2864c0b746e5SOllivier Robert register u_int32 s; 2865c0b746e5SOllivier Robert struct info_clkbug *cl; 2866c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2867c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 2868c0b746e5SOllivier Robert u_int32 ltemp; 2869c0b746e5SOllivier Robert int qitems; 2870c0b746e5SOllivier Robert int items; 2871c0b746e5SOllivier Robert int itemsize; 2872c0b746e5SOllivier Robert int res; 2873c0b746e5SOllivier Robert int needsp; 2874c0b746e5SOllivier Robert l_fp ts; 2875c0b746e5SOllivier Robert 2876c0b746e5SOllivier Robert for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 28779c2daa00SOllivier Robert clist[qitems] = GET_INADDR(pcmd->argval[qitems].netnum); 2878c0b746e5SOllivier Robert 28799c2daa00SOllivier Robert again: 28809c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems, 2881c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 28829c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug)); 28839c2daa00SOllivier Robert 28849c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 28859c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 28869c2daa00SOllivier Robert goto again; 28879c2daa00SOllivier Robert } 2888c0b746e5SOllivier Robert 2889ea906c41SOllivier Robert if (res != 0) 2890c0b746e5SOllivier Robert return; 2891c0b746e5SOllivier Robert 2892c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2893c0b746e5SOllivier Robert return; 2894c0b746e5SOllivier Robert 2895c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clkbug))) 2896c0b746e5SOllivier Robert return; 2897c0b746e5SOllivier Robert 2898c0b746e5SOllivier Robert while (items-- > 0) { 2899c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2900c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2901c0b746e5SOllivier Robert n = (int)cl->nvalues; 2902c0b746e5SOllivier Robert (void) fprintf(fp, "values: %d", n); 2903c0b746e5SOllivier Robert s = ntohs(cl->svalues); 2904c0b746e5SOllivier Robert if (n > NUMCBUGVALUES) 2905c0b746e5SOllivier Robert n = NUMCBUGVALUES; 2906c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2907c0b746e5SOllivier Robert ltemp = ntohl(cl->values[i]); 2908c0b746e5SOllivier Robert ltemp &= 0xffffffff; /* HMS: This does nothing now */ 2909c0b746e5SOllivier Robert if ((i & 0x3) == 0) 2910c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2911c0b746e5SOllivier Robert if (s & (1 << i)) 2912c0b746e5SOllivier Robert (void) fprintf(fp, "%12ld", (u_long)ltemp); 2913c0b746e5SOllivier Robert else 2914c0b746e5SOllivier Robert (void) fprintf(fp, "%12lu", (u_long)ltemp); 2915c0b746e5SOllivier Robert } 2916c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2917c0b746e5SOllivier Robert 2918c0b746e5SOllivier Robert n = (int)cl->ntimes; 2919c0b746e5SOllivier Robert (void) fprintf(fp, "times: %d", n); 2920c0b746e5SOllivier Robert s = ntohl(cl->stimes); 2921c0b746e5SOllivier Robert if (n > NUMCBUGTIMES) 2922c0b746e5SOllivier Robert n = NUMCBUGTIMES; 2923c0b746e5SOllivier Robert needsp = 0; 2924c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2925c0b746e5SOllivier Robert if ((i & 0x1) == 0) { 2926c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2927c0b746e5SOllivier Robert } else { 2928c0b746e5SOllivier Robert for (;needsp > 0; needsp--) 2929c0b746e5SOllivier Robert putc(' ', fp); 2930c0b746e5SOllivier Robert } 2931c0b746e5SOllivier Robert NTOHL_FP(&cl->times[i], &ts); 2932c0b746e5SOllivier Robert if (s & (1 << i)) { 2933c0b746e5SOllivier Robert (void) fprintf(fp, "%17s", 2934c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2935c0b746e5SOllivier Robert needsp = 22; 2936c0b746e5SOllivier Robert } else { 2937c0b746e5SOllivier Robert (void) fprintf(fp, "%37s", 2938c0b746e5SOllivier Robert uglydate(&ts)); 2939c0b746e5SOllivier Robert needsp = 2; 2940c0b746e5SOllivier Robert } 2941c0b746e5SOllivier Robert } 2942c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2943c0b746e5SOllivier Robert if (items > 0) { 2944c0b746e5SOllivier Robert cl++; 2945c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2946c0b746e5SOllivier Robert } 2947c0b746e5SOllivier Robert } 2948c0b746e5SOllivier Robert } 2949c0b746e5SOllivier Robert 2950c0b746e5SOllivier Robert 2951c0b746e5SOllivier Robert /* 2952c0b746e5SOllivier Robert * kerninfo - display the kernel pll/pps variables 2953c0b746e5SOllivier Robert */ 2954c0b746e5SOllivier Robert static void 2955c0b746e5SOllivier Robert kerninfo( 2956c0b746e5SOllivier Robert struct parse *pcmd, 2957c0b746e5SOllivier Robert FILE *fp 2958c0b746e5SOllivier Robert ) 2959c0b746e5SOllivier Robert { 2960c0b746e5SOllivier Robert struct info_kernel *ik; 2961c0b746e5SOllivier Robert int items; 2962c0b746e5SOllivier Robert int itemsize; 2963c0b746e5SOllivier Robert int res; 2964c0b746e5SOllivier Robert unsigned status; 2965c0b746e5SOllivier Robert double tscale = 1e-6; 2966c0b746e5SOllivier Robert 29679c2daa00SOllivier Robert again: 29689c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL, 29699c2daa00SOllivier Robert &items, &itemsize, (void *)&ik, 0, 29709c2daa00SOllivier Robert sizeof(struct info_kernel)); 29719c2daa00SOllivier Robert 29729c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 29739c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 29749c2daa00SOllivier Robert goto again; 29759c2daa00SOllivier Robert } 29769c2daa00SOllivier Robert 2977ea906c41SOllivier Robert if (res != 0) 2978c0b746e5SOllivier Robert return; 2979c0b746e5SOllivier Robert if (!check1item(items, fp)) 2980c0b746e5SOllivier Robert return; 2981c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_kernel))) 2982c0b746e5SOllivier Robert return; 2983c0b746e5SOllivier Robert 2984c0b746e5SOllivier Robert status = ntohs(ik->status) & 0xffff; 2985c0b746e5SOllivier Robert /* 2986c0b746e5SOllivier Robert * pll variables. We know more than we should about the NANO bit. 2987c0b746e5SOllivier Robert */ 2988c0b746e5SOllivier Robert #ifdef STA_NANO 2989c0b746e5SOllivier Robert if (status & STA_NANO) 2990c0b746e5SOllivier Robert tscale = 1e-9; 2991c0b746e5SOllivier Robert #endif 2992c0b746e5SOllivier Robert (void)fprintf(fp, "pll offset: %g s\n", 2993ea906c41SOllivier Robert (int32_t)ntohl(ik->offset) * tscale); 2994c0b746e5SOllivier Robert (void)fprintf(fp, "pll frequency: %s ppm\n", 2995c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->freq), 3)); 2996c0b746e5SOllivier Robert (void)fprintf(fp, "maximum error: %g s\n", 2997c0b746e5SOllivier Robert (u_long)ntohl(ik->maxerror) * 1e-6); 2998c0b746e5SOllivier Robert (void)fprintf(fp, "estimated error: %g s\n", 2999c0b746e5SOllivier Robert (u_long)ntohl(ik->esterror) * 1e-6); 3000c0b746e5SOllivier Robert (void)fprintf(fp, "status: %04x ", status); 3001c0b746e5SOllivier Robert #ifdef STA_PLL 3002c0b746e5SOllivier Robert if (status & STA_PLL) (void)fprintf(fp, " pll"); 3003c0b746e5SOllivier Robert #endif 3004c0b746e5SOllivier Robert #ifdef STA_PPSFREQ 3005c0b746e5SOllivier Robert if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq"); 3006c0b746e5SOllivier Robert #endif 3007c0b746e5SOllivier Robert #ifdef STA_PPSTIME 3008c0b746e5SOllivier Robert if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime"); 3009c0b746e5SOllivier Robert #endif 3010c0b746e5SOllivier Robert #ifdef STA_FLL 3011c0b746e5SOllivier Robert if (status & STA_FLL) (void)fprintf(fp, " fll"); 3012c0b746e5SOllivier Robert #endif 3013c0b746e5SOllivier Robert #ifdef STA_INS 3014c0b746e5SOllivier Robert if (status & STA_INS) (void)fprintf(fp, " ins"); 3015c0b746e5SOllivier Robert #endif 3016c0b746e5SOllivier Robert #ifdef STA_DEL 3017c0b746e5SOllivier Robert if (status & STA_DEL) (void)fprintf(fp, " del"); 3018c0b746e5SOllivier Robert #endif 3019c0b746e5SOllivier Robert #ifdef STA_UNSYNC 3020c0b746e5SOllivier Robert if (status & STA_UNSYNC) (void)fprintf(fp, " unsync"); 3021c0b746e5SOllivier Robert #endif 3022c0b746e5SOllivier Robert #ifdef STA_FREQHOLD 3023c0b746e5SOllivier Robert if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold"); 3024c0b746e5SOllivier Robert #endif 3025c0b746e5SOllivier Robert #ifdef STA_PPSSIGNAL 3026c0b746e5SOllivier Robert if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal"); 3027c0b746e5SOllivier Robert #endif 3028c0b746e5SOllivier Robert #ifdef STA_PPSJITTER 3029c0b746e5SOllivier Robert if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter"); 3030c0b746e5SOllivier Robert #endif 3031c0b746e5SOllivier Robert #ifdef STA_PPSWANDER 3032c0b746e5SOllivier Robert if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander"); 3033c0b746e5SOllivier Robert #endif 3034c0b746e5SOllivier Robert #ifdef STA_PPSERROR 3035c0b746e5SOllivier Robert if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror"); 3036c0b746e5SOllivier Robert #endif 3037c0b746e5SOllivier Robert #ifdef STA_CLOCKERR 3038c0b746e5SOllivier Robert if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr"); 3039c0b746e5SOllivier Robert #endif 3040c0b746e5SOllivier Robert #ifdef STA_NANO 3041c0b746e5SOllivier Robert if (status & STA_NANO) (void)fprintf(fp, " nano"); 3042c0b746e5SOllivier Robert #endif 3043c0b746e5SOllivier Robert #ifdef STA_MODE 3044c0b746e5SOllivier Robert if (status & STA_MODE) (void)fprintf(fp, " mode=fll"); 3045c0b746e5SOllivier Robert #endif 3046c0b746e5SOllivier Robert #ifdef STA_CLK 3047c0b746e5SOllivier Robert if (status & STA_CLK) (void)fprintf(fp, " src=B"); 3048c0b746e5SOllivier Robert #endif 3049c0b746e5SOllivier Robert (void)fprintf(fp, "\n"); 3050c0b746e5SOllivier Robert (void)fprintf(fp, "pll time constant: %ld\n", 3051c0b746e5SOllivier Robert (u_long)ntohl(ik->constant)); 3052c0b746e5SOllivier Robert (void)fprintf(fp, "precision: %g s\n", 3053c0b746e5SOllivier Robert (u_long)ntohl(ik->precision) * tscale); 3054c0b746e5SOllivier Robert (void)fprintf(fp, "frequency tolerance: %s ppm\n", 3055c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->tolerance), 0)); 3056c0b746e5SOllivier Robert 3057c0b746e5SOllivier Robert /* 3058c0b746e5SOllivier Robert * For backwards compatibility (ugh), we find the pps variables 3059c0b746e5SOllivier Robert * only if the shift member is nonzero. 3060c0b746e5SOllivier Robert */ 3061c0b746e5SOllivier Robert if (!ik->shift) 3062c0b746e5SOllivier Robert return; 3063c0b746e5SOllivier Robert 3064c0b746e5SOllivier Robert /* 3065c0b746e5SOllivier Robert * pps variables 3066c0b746e5SOllivier Robert */ 3067c0b746e5SOllivier Robert (void)fprintf(fp, "pps frequency: %s ppm\n", 3068c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->ppsfreq), 3)); 3069c0b746e5SOllivier Robert (void)fprintf(fp, "pps stability: %s ppm\n", 3070c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->stabil), 3)); 3071c0b746e5SOllivier Robert (void)fprintf(fp, "pps jitter: %g s\n", 3072c0b746e5SOllivier Robert (u_long)ntohl(ik->jitter) * tscale); 3073c0b746e5SOllivier Robert (void)fprintf(fp, "calibration interval: %d s\n", 3074c0b746e5SOllivier Robert 1 << ntohs(ik->shift)); 3075c0b746e5SOllivier Robert (void)fprintf(fp, "calibration cycles: %ld\n", 3076c0b746e5SOllivier Robert (u_long)ntohl(ik->calcnt)); 3077c0b746e5SOllivier Robert (void)fprintf(fp, "jitter exceeded: %ld\n", 3078c0b746e5SOllivier Robert (u_long)ntohl(ik->jitcnt)); 3079c0b746e5SOllivier Robert (void)fprintf(fp, "stability exceeded: %ld\n", 3080c0b746e5SOllivier Robert (u_long)ntohl(ik->stbcnt)); 3081c0b746e5SOllivier Robert (void)fprintf(fp, "calibration errors: %ld\n", 3082c0b746e5SOllivier Robert (u_long)ntohl(ik->errcnt)); 3083c0b746e5SOllivier Robert } 3084ea906c41SOllivier Robert 3085ea906c41SOllivier Robert #define IF_LIST_FMT "%2d %c %48s %c %c %12.12s %03x %3d %2d %5d %5d %5d %2d %2d %3d %7d\n" 3086ea906c41SOllivier Robert #define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %2s %3s %7s\n" 3087ea906c41SOllivier Robert #define IF_LIST_AFMT_STR " %48s %c\n" 3088ea906c41SOllivier Robert #define IF_LIST_LABELS "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "IX", "PC", "uptime" 3089ea906c41SOllivier Robert #define IF_LIST_LINE "=====================================================================================================================\n" 3090ea906c41SOllivier Robert 3091ea906c41SOllivier Robert static void 3092ea906c41SOllivier Robert iflist( 3093ea906c41SOllivier Robert FILE *fp, 3094ea906c41SOllivier Robert struct info_if_stats *ifs, 3095ea906c41SOllivier Robert int items, 3096ea906c41SOllivier Robert int itemsize, 3097ea906c41SOllivier Robert int res 3098ea906c41SOllivier Robert ) 3099ea906c41SOllivier Robert { 3100ea906c41SOllivier Robert static char *actions = "?.+-"; 3101ea906c41SOllivier Robert struct sockaddr_storage saddr; 3102ea906c41SOllivier Robert 3103ea906c41SOllivier Robert if (res != 0) 3104ea906c41SOllivier Robert return; 3105ea906c41SOllivier Robert 3106ea906c41SOllivier Robert if (!checkitems(items, fp)) 3107ea906c41SOllivier Robert return; 3108ea906c41SOllivier Robert 3109ea906c41SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_if_stats))) 3110ea906c41SOllivier Robert return; 3111ea906c41SOllivier Robert 3112ea906c41SOllivier Robert fprintf(fp, IF_LIST_FMT_STR, IF_LIST_LABELS); 3113ea906c41SOllivier Robert fprintf(fp, IF_LIST_LINE); 3114ea906c41SOllivier Robert 3115ea906c41SOllivier Robert while (items > 0) { 3116ea906c41SOllivier Robert if (ntohl(ifs->v6_flag)) { 3117ea906c41SOllivier Robert memcpy((char *)&GET_INADDR6(saddr), (char *)&ifs->unaddr.addr6, sizeof(ifs->unaddr.addr6)); 3118ea906c41SOllivier Robert saddr.ss_family = AF_INET6; 3119ea906c41SOllivier Robert } else { 3120ea906c41SOllivier Robert memcpy((char *)&GET_INADDR(saddr), (char *)&ifs->unaddr.addr, sizeof(ifs->unaddr.addr)); 3121ea906c41SOllivier Robert saddr.ss_family = AF_INET; 3122ea906c41SOllivier Robert } 3123ea906c41SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 3124ea906c41SOllivier Robert saddr.ss_len = SOCKLEN(&saddr); 3125ea906c41SOllivier Robert #endif 3126ea906c41SOllivier Robert fprintf(fp, IF_LIST_FMT, 3127ea906c41SOllivier Robert ntohl(ifs->ifnum), 3128ea906c41SOllivier Robert actions[(ifs->action >= 1 && ifs->action < 4) ? ifs->action : 0], 3129ea906c41SOllivier Robert stoa((&saddr)), 'A', 3130ea906c41SOllivier Robert ifs->ignore_packets ? 'D' : 'E', 3131ea906c41SOllivier Robert ifs->name, 3132ea906c41SOllivier Robert ntohl(ifs->flags), 3133ea906c41SOllivier Robert ntohl(ifs->last_ttl), 3134ea906c41SOllivier Robert ntohl(ifs->num_mcast), 3135ea906c41SOllivier Robert ntohl(ifs->received), 3136ea906c41SOllivier Robert ntohl(ifs->sent), 3137ea906c41SOllivier Robert ntohl(ifs->notsent), 3138ea906c41SOllivier Robert ntohl(ifs->scopeid), 3139ea906c41SOllivier Robert ntohl(ifs->ifindex), 3140ea906c41SOllivier Robert ntohl(ifs->peercnt), 3141ea906c41SOllivier Robert ntohl(ifs->uptime)); 3142ea906c41SOllivier Robert 3143ea906c41SOllivier Robert if (ntohl(ifs->v6_flag)) { 3144ea906c41SOllivier Robert memcpy((char *)&GET_INADDR6(saddr), (char *)&ifs->unmask.addr6, sizeof(ifs->unmask.addr6)); 3145ea906c41SOllivier Robert saddr.ss_family = AF_INET6; 3146ea906c41SOllivier Robert } else { 3147ea906c41SOllivier Robert memcpy((char *)&GET_INADDR(saddr), (char *)&ifs->unmask.addr, sizeof(ifs->unmask.addr)); 3148ea906c41SOllivier Robert saddr.ss_family = AF_INET; 3149ea906c41SOllivier Robert } 3150ea906c41SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 3151ea906c41SOllivier Robert saddr.ss_len = SOCKLEN(&saddr); 3152ea906c41SOllivier Robert #endif 3153ea906c41SOllivier Robert fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'M'); 3154ea906c41SOllivier Robert 3155ea906c41SOllivier Robert if (!ntohl(ifs->v6_flag) && ntohl(ifs->flags) & (INT_BCASTOPEN)) { 3156ea906c41SOllivier Robert memcpy((char *)&GET_INADDR(saddr), (char *)&ifs->unbcast.addr, sizeof(ifs->unbcast.addr)); 3157ea906c41SOllivier Robert saddr.ss_family = AF_INET; 3158ea906c41SOllivier Robert #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 3159ea906c41SOllivier Robert saddr.ss_len = SOCKLEN(&saddr); 3160ea906c41SOllivier Robert #endif 3161ea906c41SOllivier Robert fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'B'); 3162ea906c41SOllivier Robert 3163ea906c41SOllivier Robert } 3164ea906c41SOllivier Robert 3165ea906c41SOllivier Robert ifs++; 3166ea906c41SOllivier Robert items--; 3167ea906c41SOllivier Robert } 3168ea906c41SOllivier Robert } 3169ea906c41SOllivier Robert 3170ea906c41SOllivier Robert /*ARGSUSED*/ 3171ea906c41SOllivier Robert static void 3172ea906c41SOllivier Robert get_if_stats( 3173ea906c41SOllivier Robert struct parse *pcmd, 3174ea906c41SOllivier Robert FILE *fp 3175ea906c41SOllivier Robert ) 3176ea906c41SOllivier Robert { 3177ea906c41SOllivier Robert struct info_if_stats *ifs; 3178ea906c41SOllivier Robert int items; 3179ea906c41SOllivier Robert int itemsize; 3180ea906c41SOllivier Robert int res; 3181ea906c41SOllivier Robert 3182ea906c41SOllivier Robert res = doquery(impl_ver, REQ_IF_STATS, 1, 0, 0, (char *)NULL, &items, 3183ea906c41SOllivier Robert &itemsize, (void *)&ifs, 0, 3184ea906c41SOllivier Robert sizeof(struct info_if_stats)); 3185ea906c41SOllivier Robert iflist(fp, ifs, items, itemsize, res); 3186ea906c41SOllivier Robert } 3187ea906c41SOllivier Robert 3188ea906c41SOllivier Robert /*ARGSUSED*/ 3189ea906c41SOllivier Robert static void 3190ea906c41SOllivier Robert do_if_reload( 3191ea906c41SOllivier Robert struct parse *pcmd, 3192ea906c41SOllivier Robert FILE *fp 3193ea906c41SOllivier Robert ) 3194ea906c41SOllivier Robert { 3195ea906c41SOllivier Robert struct info_if_stats *ifs; 3196ea906c41SOllivier Robert int items; 3197ea906c41SOllivier Robert int itemsize; 3198ea906c41SOllivier Robert int res; 3199ea906c41SOllivier Robert 3200ea906c41SOllivier Robert res = doquery(impl_ver, REQ_IF_RELOAD, 1, 0, 0, (char *)NULL, &items, 3201ea906c41SOllivier Robert &itemsize, (void *)&ifs, 0, 3202ea906c41SOllivier Robert sizeof(struct info_if_stats)); 3203ea906c41SOllivier Robert iflist(fp, ifs, items, itemsize, res); 3204ea906c41SOllivier Robert } 3205