154359Sroberto/* 2285612Sdelphij * ntpdc_ops.c - subroutines which are called to perform operations by 3285612Sdelphij * ntpdc 454359Sroberto */ 554359Sroberto 654359Sroberto#ifdef HAVE_CONFIG_H 754359Sroberto# include <config.h> 854359Sroberto#endif 954359Sroberto 1054359Sroberto#include <stdio.h> 11132451Sroberto#include <stddef.h> 1282498Sroberto 1382498Sroberto#include "ntpdc.h" 14285612Sdelphij#include "ntp_net.h" 1582498Sroberto#include "ntp_control.h" 1682498Sroberto#include "ntp_refclock.h" 1782498Sroberto#include "ntp_stdlib.h" 1882498Sroberto 1954359Sroberto#include <ctype.h> 2054359Sroberto#ifdef HAVE_SYS_TIMEX_H 2154359Sroberto# include <sys/timex.h> 2254359Sroberto#endif 2354359Sroberto#if !defined(__bsdi__) && !defined(apollo) 24285612Sdelphij#ifdef HAVE_NETINET_IN_H 2554359Sroberto#include <netinet/in.h> 2654359Sroberto#endif 27285612Sdelphij#endif 2854359Sroberto 2954359Sroberto#include <arpa/inet.h> 3054359Sroberto 3154359Sroberto/* 32285612Sdelphij * utility functions 33285612Sdelphij */ 34293650Sglebiusstatic int checkitems (size_t, FILE *); 35293650Sglebiusstatic int checkitemsize (size_t, size_t); 36293650Sglebiusstatic int check1item (size_t, FILE *); 37285612Sdelphij 38285612Sdelphij/* 3954359Sroberto * Declarations for command handlers in here 4054359Sroberto */ 41285612Sdelphijstatic void peerlist (struct parse *, FILE *); 42285612Sdelphijstatic void peers (struct parse *, FILE *); 43285612Sdelphijstatic void doconfig (struct parse *pcmd, FILE *fp, int mode, int refc); 44285612Sdelphijstatic void dmpeers (struct parse *, FILE *); 45285612Sdelphijstatic void dopeers (struct parse *, FILE *, int); 46285612Sdelphijstatic void printpeer (struct info_peer *, FILE *); 47285612Sdelphijstatic void showpeer (struct parse *, FILE *); 48285612Sdelphijstatic void peerstats (struct parse *, FILE *); 49285612Sdelphijstatic void loopinfo (struct parse *, FILE *); 50285612Sdelphijstatic void sysinfo (struct parse *, FILE *); 51285612Sdelphijstatic void sysstats (struct parse *, FILE *); 52285612Sdelphijstatic void iostats (struct parse *, FILE *); 53285612Sdelphijstatic void memstats (struct parse *, FILE *); 54285612Sdelphijstatic void timerstats (struct parse *, FILE *); 55285612Sdelphijstatic void addpeer (struct parse *, FILE *); 56285612Sdelphijstatic void addserver (struct parse *, FILE *); 57285612Sdelphijstatic void addrefclock (struct parse *, FILE *); 58285612Sdelphijstatic void broadcast (struct parse *, FILE *); 59285612Sdelphijstatic void doconfig (struct parse *, FILE *, int, int); 60285612Sdelphijstatic void unconfig (struct parse *, FILE *); 61285612Sdelphijstatic void set (struct parse *, FILE *); 62285612Sdelphijstatic void sys_clear (struct parse *, FILE *); 63285612Sdelphijstatic void doset (struct parse *, FILE *, int); 64285612Sdelphijstatic void reslist (struct parse *, FILE *); 65285612Sdelphijstatic void new_restrict (struct parse *, FILE *); 66285612Sdelphijstatic void unrestrict (struct parse *, FILE *); 67285612Sdelphijstatic void delrestrict (struct parse *, FILE *); 68285612Sdelphijstatic void do_restrict (struct parse *, FILE *, int); 69285612Sdelphijstatic void monlist (struct parse *, FILE *); 70285612Sdelphijstatic void reset (struct parse *, FILE *); 71285612Sdelphijstatic void preset (struct parse *, FILE *); 72285612Sdelphijstatic void readkeys (struct parse *, FILE *); 73285612Sdelphijstatic void trustkey (struct parse *, FILE *); 74285612Sdelphijstatic void untrustkey (struct parse *, FILE *); 75285612Sdelphijstatic void do_trustkey (struct parse *, FILE *, int); 76285612Sdelphijstatic void authinfo (struct parse *, FILE *); 77285612Sdelphijstatic void traps (struct parse *, FILE *); 78285612Sdelphijstatic void addtrap (struct parse *, FILE *); 79285612Sdelphijstatic void clrtrap (struct parse *, FILE *); 80285612Sdelphijstatic void do_addclr_trap (struct parse *, FILE *, int); 81285612Sdelphijstatic void requestkey (struct parse *, FILE *); 82285612Sdelphijstatic void controlkey (struct parse *, FILE *); 83285612Sdelphijstatic void do_changekey (struct parse *, FILE *, int); 84285612Sdelphijstatic void ctlstats (struct parse *, FILE *); 85285612Sdelphijstatic void clockstat (struct parse *, FILE *); 86285612Sdelphijstatic void fudge (struct parse *, FILE *); 87285612Sdelphijstatic void clkbug (struct parse *, FILE *); 88285612Sdelphijstatic void kerninfo (struct parse *, FILE *); 89285612Sdelphijstatic void get_if_stats (struct parse *, FILE *); 90285612Sdelphijstatic void do_if_reload (struct parse *, FILE *); 9154359Sroberto 9254359Sroberto/* 9354359Sroberto * Commands we understand. Ntpdc imports this. 9454359Sroberto */ 9554359Srobertostruct xcmd opcmds[] = { 96132451Sroberto { "listpeers", peerlist, { OPT|IP_VERSION, NO, NO, NO }, 97132451Sroberto { "-4|-6", "", "", "" }, 98132451Sroberto "display list of peers the server knows about [IP Version]" }, 99132451Sroberto { "peers", peers, { OPT|IP_VERSION, NO, NO, NO }, 100132451Sroberto { "-4|-6", "", "", "" }, 101132451Sroberto "display peer summary information [IP Version]" }, 102132451Sroberto { "dmpeers", dmpeers, { OPT|IP_VERSION, NO, NO, NO }, 103132451Sroberto { "-4|-6", "", "", "" }, 104132451Sroberto "display peer summary info the way Dave Mills likes it (IP Version)" }, 105182007Sroberto { "showpeer", showpeer, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD}, 10654359Sroberto { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 10754359Sroberto "display detailed information for one or more peers" }, 108182007Sroberto { "pstats", peerstats, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 10954359Sroberto { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 11054359Sroberto "display statistical information for one or more peers" }, 11154359Sroberto { "loopinfo", loopinfo, { OPT|NTP_STR, NO, NO, NO }, 11254359Sroberto { "oneline|multiline", "", "", "" }, 11354359Sroberto "display loop filter information" }, 11454359Sroberto { "sysinfo", sysinfo, { NO, NO, NO, NO }, 11554359Sroberto { "", "", "", "" }, 11654359Sroberto "display local server information" }, 11754359Sroberto { "sysstats", sysstats, { NO, NO, NO, NO }, 11854359Sroberto { "", "", "", "" }, 11954359Sroberto "display local server statistics" }, 12054359Sroberto { "memstats", memstats, { NO, NO, NO, NO }, 12154359Sroberto { "", "", "", "" }, 12254359Sroberto "display peer memory usage statistics" }, 12354359Sroberto { "iostats", iostats, { NO, NO, NO, NO }, 12454359Sroberto { "", "", "", "" }, 12554359Sroberto "display I/O subsystem statistics" }, 12654359Sroberto { "timerstats", timerstats, { NO, NO, NO, NO }, 12754359Sroberto { "", "", "", "" }, 12854359Sroberto "display event timer subsystem statistics" }, 129182007Sroberto { "addpeer", addpeer, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 130182007Sroberto { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." }, 13154359Sroberto "configure a new peer association" }, 132182007Sroberto { "addserver", addserver, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 133182007Sroberto { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." }, 13454359Sroberto "configure a new server" }, 135182007Sroberto { "addrefclock",addrefclock, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_STR, OPT|NTP_STR }, 13654359Sroberto { "addr", "mode", "minpoll|prefer", "minpoll|prefer" }, 13754359Sroberto "configure a new server" }, 138182007Sroberto { "broadcast", broadcast, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 13954359Sroberto { "addr", "keyid", "version", "minpoll" }, 14054359Sroberto "configure broadcasting time service" }, 141182007Sroberto { "unconfig", unconfig, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 14254359Sroberto { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 14354359Sroberto "unconfigure existing peer assocations" }, 14454359Sroberto { "enable", set, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 14554359Sroberto { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 14654359Sroberto "set a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 147285612Sdelphij { "disable", sys_clear, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 14854359Sroberto { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 14954359Sroberto "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 150132451Sroberto { "reslist", reslist, {OPT|IP_VERSION, NO, NO, NO }, 151132451Sroberto { "-4|-6", "", "", "" }, 15254359Sroberto "display the server's restrict list" }, 153182007Sroberto { "restrict", new_restrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR }, 15454359Sroberto { "address", "mask", 15582498Sroberto "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 15654359Sroberto "..." }, 15754359Sroberto "create restrict entry/add flags to entry" }, 158182007Sroberto { "unrestrict", unrestrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR }, 15954359Sroberto { "address", "mask", 16082498Sroberto "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 16154359Sroberto "..." }, 16254359Sroberto "remove flags from a restrict entry" }, 163182007Sroberto { "delrestrict", delrestrict, { NTP_ADD, NTP_ADD, OPT|NTP_STR, NO }, 16454359Sroberto { "address", "mask", "ntpport", "" }, 16554359Sroberto "delete a restrict entry" }, 166182007Sroberto { "monlist", monlist, { OPT|NTP_INT, NO, NO, NO }, 16754359Sroberto { "version", "", "", "" }, 16854359Sroberto "display data the server's monitor routines have collected" }, 16954359Sroberto { "reset", reset, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 170285612Sdelphij { "io|sys|mem|timer|auth|ctl|allpeers", "...", "...", "..." }, 17154359Sroberto "reset various subsystem statistics counters" }, 172182007Sroberto { "preset", preset, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 17354359Sroberto { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 17454359Sroberto "reset stat counters associated with particular peer(s)" }, 17554359Sroberto { "readkeys", readkeys, { NO, NO, NO, NO }, 17654359Sroberto { "", "", "", "" }, 17754359Sroberto "request a reread of the keys file and re-init of system keys" }, 178182007Sroberto { "trustedkey", trustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT }, 17954359Sroberto { "keyid", "keyid", "keyid", "keyid" }, 18054359Sroberto "add one or more key ID's to the trusted list" }, 181182007Sroberto { "untrustedkey", untrustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT }, 18254359Sroberto { "keyid", "keyid", "keyid", "keyid" }, 18354359Sroberto "remove one or more key ID's from the trusted list" }, 18454359Sroberto { "authinfo", authinfo, { NO, NO, NO, NO }, 18554359Sroberto { "", "", "", "" }, 18654359Sroberto "display the state of the authentication code" }, 18754359Sroberto { "traps", traps, { NO, NO, NO, NO }, 18854359Sroberto { "", "", "", "" }, 18954359Sroberto "display the traps set in the server" }, 190182007Sroberto { "addtrap", addtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO }, 19154359Sroberto { "address", "port", "interface", "" }, 19254359Sroberto "configure a trap in the server" }, 193182007Sroberto { "clrtrap", clrtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO }, 19454359Sroberto { "address", "port", "interface", "" }, 19554359Sroberto "remove a trap (configured or otherwise) from the server" }, 196182007Sroberto { "requestkey", requestkey, { NTP_UINT, NO, NO, NO }, 19754359Sroberto { "keyid", "", "", "" }, 19854359Sroberto "change the keyid the server uses to authenticate requests" }, 199182007Sroberto { "controlkey", controlkey, { NTP_UINT, NO, NO, NO }, 20054359Sroberto { "keyid", "", "", "" }, 20154359Sroberto "change the keyid the server uses to authenticate control messages" }, 20254359Sroberto { "ctlstats", ctlstats, { NO, NO, NO, NO }, 20354359Sroberto { "", "", "", "" }, 20454359Sroberto "display packet count statistics from the control module" }, 205182007Sroberto { "clockstat", clockstat, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 20654359Sroberto { "address", "address", "address", "address" }, 20754359Sroberto "display clock status information" }, 208182007Sroberto { "fudge", fudge, { NTP_ADD, NTP_STR, NTP_STR, NO }, 20954359Sroberto { "address", "time1|time2|val1|val2|flags", "value", "" }, 21054359Sroberto "set/change one of a clock's fudge factors" }, 211182007Sroberto { "clkbug", clkbug, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 21254359Sroberto { "address", "address", "address", "address" }, 21354359Sroberto "display clock debugging information" }, 21454359Sroberto { "kerninfo", kerninfo, { NO, NO, NO, NO }, 21554359Sroberto { "", "", "", "" }, 21654359Sroberto "display the kernel pll/pps variables" }, 217182007Sroberto { "ifstats", get_if_stats, { NO, NO, NO, NO }, 218182007Sroberto { "", "", "", "" }, 219182007Sroberto "list interface statistics" }, 220182007Sroberto { "ifreload", do_if_reload, { NO, NO, NO, NO }, 221182007Sroberto { "", "", "", "" }, 222182007Sroberto "reload interface configuration" }, 22354359Sroberto { 0, 0, { NO, NO, NO, NO }, 22454359Sroberto { "", "", "", "" }, "" } 22554359Sroberto}; 22654359Sroberto 22754359Sroberto/* 22854359Sroberto * For quick string comparisons 22954359Sroberto */ 23054359Sroberto#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 23154359Sroberto 232285612Sdelphij/* 233285612Sdelphij * SET_SS_LEN_IF_PRESENT - used by SET_ADDR, SET_ADDRS macros 234285612Sdelphij */ 23554359Sroberto 236285612Sdelphij#ifdef ISC_PLATFORM_HAVESALEN 237285612Sdelphij#define SET_SS_LEN_IF_PRESENT(psau) \ 238285612Sdelphij do { \ 239285612Sdelphij (psau)->sa.sa_len = SOCKLEN(psau); \ 240285612Sdelphij } while (0) 241285612Sdelphij#else 242285612Sdelphij#define SET_SS_LEN_IF_PRESENT(psau) do { } while (0) 243285612Sdelphij#endif 244285612Sdelphij 24554359Sroberto/* 246285612Sdelphij * SET_ADDR - setup address for v4/v6 as needed 247285612Sdelphij */ 248285612Sdelphij#define SET_ADDR(address, v6flag, v4addr, v6addr) \ 249285612Sdelphijdo { \ 250285612Sdelphij ZERO(address); \ 251285612Sdelphij if (v6flag) { \ 252285612Sdelphij AF(&(address)) = AF_INET6; \ 253285612Sdelphij SOCK_ADDR6(&(address)) = (v6addr); \ 254285612Sdelphij } else { \ 255285612Sdelphij AF(&(address)) = AF_INET; \ 256285612Sdelphij NSRCADR(&(address)) = (v4addr); \ 257285612Sdelphij } \ 258285612Sdelphij SET_SS_LEN_IF_PRESENT(&(address)); \ 259285612Sdelphij} while (0) 260285612Sdelphij 261285612Sdelphij 262285612Sdelphij/* 263285612Sdelphij * SET_ADDRS - setup source and destination addresses for 264285612Sdelphij * v4/v6 as needed 265285612Sdelphij */ 266285612Sdelphij#define SET_ADDRS(a1, a2, info, a1prefix, a2prefix) \ 267285612Sdelphijdo { \ 268285612Sdelphij ZERO(a1); \ 269285612Sdelphij ZERO(a2); \ 270285612Sdelphij if ((info)->v6_flag) { \ 271285612Sdelphij AF(&(a1)) = AF_INET6; \ 272285612Sdelphij AF(&(a2)) = AF_INET6; \ 273285612Sdelphij SOCK_ADDR6(&(a1)) = (info)->a1prefix##6; \ 274285612Sdelphij SOCK_ADDR6(&(a2)) = (info)->a2prefix##6; \ 275285612Sdelphij } else { \ 276285612Sdelphij AF(&(a1)) = AF_INET; \ 277285612Sdelphij AF(&(a2)) = AF_INET; \ 278285612Sdelphij NSRCADR(&(a1)) = (info)->a1prefix; \ 279285612Sdelphij NSRCADR(&(a2)) = (info)->a2prefix; \ 280285612Sdelphij } \ 281285612Sdelphij SET_SS_LEN_IF_PRESENT(&(a1)); \ 282285612Sdelphij SET_SS_LEN_IF_PRESENT(&(a2)); \ 283285612Sdelphij} while (0) 284285612Sdelphij 285285612Sdelphij 286285612Sdelphij/* 28754359Sroberto * checkitems - utility to print a message if no items were returned 28854359Sroberto */ 28954359Srobertostatic int 29054359Srobertocheckitems( 291293650Sglebius size_t items, 29254359Sroberto FILE *fp 29354359Sroberto ) 29454359Sroberto{ 29554359Sroberto if (items == 0) { 29654359Sroberto (void) fprintf(fp, "No data returned in response to query\n"); 29754359Sroberto return 0; 29854359Sroberto } 29954359Sroberto return 1; 30054359Sroberto} 30154359Sroberto 30254359Sroberto 30354359Sroberto/* 30454359Sroberto * checkitemsize - utility to print a message if the item size is wrong 30554359Sroberto */ 30654359Srobertostatic int 30754359Srobertocheckitemsize( 308293650Sglebius size_t itemsize, 309293650Sglebius size_t expected 31054359Sroberto ) 31154359Sroberto{ 31254359Sroberto if (itemsize != expected) { 31354359Sroberto (void) fprintf(stderr, 314293650Sglebius "***Incorrect item size returned by remote host (%lu should be %lu)\n", 315293650Sglebius (u_long)itemsize, (u_long)expected); 31654359Sroberto return 0; 31754359Sroberto } 31854359Sroberto return 1; 31954359Sroberto} 32054359Sroberto 32154359Sroberto 32254359Sroberto/* 32354359Sroberto * check1item - check to make sure we have exactly one item 32454359Sroberto */ 32554359Srobertostatic int 32654359Srobertocheck1item( 327293650Sglebius size_t items, 32854359Sroberto FILE *fp 32954359Sroberto ) 33054359Sroberto{ 33154359Sroberto if (items == 0) { 33254359Sroberto (void) fprintf(fp, "No data returned in response to query\n"); 33354359Sroberto return 0; 33454359Sroberto } 33554359Sroberto if (items > 1) { 336293650Sglebius (void) fprintf(fp, "Expected one item in response, got %lu\n", 337293650Sglebius (u_long)items); 33854359Sroberto return 0; 33954359Sroberto } 34054359Sroberto return 1; 34154359Sroberto} 34254359Sroberto 34354359Sroberto 34454359Sroberto/* 34554359Sroberto * peerlist - get a short list of peers 34654359Sroberto */ 34754359Sroberto/*ARGSUSED*/ 34854359Srobertostatic void 34954359Srobertopeerlist( 35054359Sroberto struct parse *pcmd, 35154359Sroberto FILE *fp 35254359Sroberto ) 35354359Sroberto{ 35454359Sroberto struct info_peer_list *plist; 355285612Sdelphij sockaddr_u paddr; 356293650Sglebius size_t items; 357293650Sglebius size_t itemsize; 35854359Sroberto int res; 35954359Sroberto 360132451Srobertoagain: 361132451Sroberto res = doquery(impl_ver, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items, 362132451Sroberto &itemsize, (void *)&plist, 0, 363132451Sroberto sizeof(struct info_peer_list)); 36454359Sroberto 365132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 366132451Sroberto impl_ver = IMPL_XNTPD_OLD; 367132451Sroberto goto again; 368132451Sroberto } 369132451Sroberto 370182007Sroberto if (res != 0) 37154359Sroberto return; 37254359Sroberto 37354359Sroberto if (!checkitems(items, fp)) 37454359Sroberto return; 37554359Sroberto 376132451Sroberto if (!checkitemsize(itemsize, sizeof(struct info_peer_list)) && 377132451Sroberto !checkitemsize(itemsize, v4sizeof(struct info_peer_list))) 37854359Sroberto return; 37954359Sroberto 38054359Sroberto while (items > 0) { 381285612Sdelphij SET_ADDR(paddr, plist->v6_flag, plist->addr, plist->addr6); 382132451Sroberto if ((pcmd->nargs == 0) || 383132451Sroberto ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 384132451Sroberto ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 385132451Sroberto (void) fprintf(fp, "%-9s %s\n", 386132451Sroberto modetoa(plist->hmode), 387132451Sroberto nntohost(&paddr)); 38854359Sroberto plist++; 38954359Sroberto items--; 39054359Sroberto } 39154359Sroberto} 39254359Sroberto 39354359Sroberto 39454359Sroberto/* 39554359Sroberto * peers - show peer summary 39654359Sroberto */ 39754359Srobertostatic void 39854359Srobertopeers( 39954359Sroberto struct parse *pcmd, 40054359Sroberto FILE *fp 40154359Sroberto ) 40254359Sroberto{ 40354359Sroberto dopeers(pcmd, fp, 0); 40454359Sroberto} 40554359Sroberto 40654359Sroberto/* 40754359Sroberto * dmpeers - show peer summary, Dave Mills style 40854359Sroberto */ 40954359Srobertostatic void 41054359Srobertodmpeers( 41154359Sroberto struct parse *pcmd, 41254359Sroberto FILE *fp 41354359Sroberto ) 41454359Sroberto{ 41554359Sroberto dopeers(pcmd, fp, 1); 41654359Sroberto} 41754359Sroberto 41854359Sroberto 41954359Sroberto/* 42054359Sroberto * peers - show peer summary 42154359Sroberto */ 42254359Sroberto/*ARGSUSED*/ 42354359Srobertostatic void 42454359Srobertodopeers( 42554359Sroberto struct parse *pcmd, 42654359Sroberto FILE *fp, 42754359Sroberto int dmstyle 42854359Sroberto ) 42954359Sroberto{ 43054359Sroberto struct info_peer_summary *plist; 431285612Sdelphij sockaddr_u dstadr; 432285612Sdelphij sockaddr_u srcadr; 433293650Sglebius size_t items; 434293650Sglebius size_t itemsize; 43554359Sroberto int ntp_poll; 43654359Sroberto int res; 43754359Sroberto int c; 43854359Sroberto l_fp tempts; 43954359Sroberto 440132451Srobertoagain: 441132451Sroberto res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL, 442132451Sroberto &items, &itemsize, (void *)&plist, 0, 443132451Sroberto sizeof(struct info_peer_summary)); 44454359Sroberto 445132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 446132451Sroberto impl_ver = IMPL_XNTPD_OLD; 447132451Sroberto goto again; 448132451Sroberto } 449132451Sroberto 450182007Sroberto if (res != 0) 45154359Sroberto return; 45254359Sroberto 45354359Sroberto if (!checkitems(items, fp)) 45454359Sroberto return; 45554359Sroberto 456132451Sroberto if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) && 457132451Sroberto !checkitemsize(itemsize, v4sizeof(struct info_peer_summary))) 458132451Sroberto return; 45954359Sroberto 46054359Sroberto (void) fprintf(fp, 46154359Sroberto " remote local st poll reach delay offset disp\n"); 46254359Sroberto (void) fprintf(fp, 46354359Sroberto "=======================================================================\n"); 46454359Sroberto while (items > 0) { 46554359Sroberto if (!dmstyle) { 46654359Sroberto if (plist->flags & INFO_FLAG_SYSPEER) 46754359Sroberto c = '*'; 46854359Sroberto else if (plist->hmode == MODE_ACTIVE) 46954359Sroberto c = '+'; 47054359Sroberto else if (plist->hmode == MODE_PASSIVE) 47154359Sroberto c = '-'; 47254359Sroberto else if (plist->hmode == MODE_CLIENT) 47354359Sroberto c = '='; 47454359Sroberto else if (plist->hmode == MODE_BROADCAST) 47554359Sroberto c = '^'; 47654359Sroberto else if (plist->hmode == MODE_BCLIENT) 47754359Sroberto c = '~'; 47854359Sroberto else 47954359Sroberto c = ' '; 48054359Sroberto } else { 48154359Sroberto if (plist->flags & INFO_FLAG_SYSPEER) 48254359Sroberto c = '*'; 48354359Sroberto else if (plist->flags & INFO_FLAG_SHORTLIST) 48454359Sroberto c = '+'; 48554359Sroberto else if (plist->flags & INFO_FLAG_SEL_CANDIDATE) 48654359Sroberto c = '.'; 48754359Sroberto else 48854359Sroberto c = ' '; 48954359Sroberto } 49054359Sroberto NTOHL_FP(&(plist->offset), &tempts); 49154359Sroberto ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL), 49254359Sroberto NTP_MINPOLL); 493285612Sdelphij SET_ADDRS(dstadr, srcadr, plist, dstadr, srcadr); 494132451Sroberto if ((pcmd->nargs == 0) || 495132451Sroberto ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 496132451Sroberto ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 497132451Sroberto (void) fprintf(fp, 498285612Sdelphij "%c%-15.15s %-15.15s %2u %4d %3o %7.7s %9.9s %7.7s\n", 499132451Sroberto c, nntohost(&srcadr), stoa(&dstadr), 500132451Sroberto plist->stratum, ntp_poll, plist->reach, 501132451Sroberto fptoa(NTOHS_FP(plist->delay), 5), 502132451Sroberto lfptoa(&tempts, 6), 503132451Sroberto ufptoa(NTOHS_FP(plist->dispersion), 5)); 50454359Sroberto plist++; 50554359Sroberto items--; 50654359Sroberto } 50754359Sroberto} 50854359Sroberto 50954359Sroberto/* Convert a refid & stratum (in host order) to a string */ 510285612Sdelphijstatic char * 51154359Srobertorefid_string( 51254359Sroberto u_int32 refid, 51354359Sroberto int stratum 51454359Sroberto ) 51554359Sroberto{ 51654359Sroberto if (stratum <= 1) { 51754359Sroberto static char junk[5]; 51854359Sroberto junk[4] = 0; 519285612Sdelphij memcpy(junk, &refid, 4); 52054359Sroberto return junk; 52154359Sroberto } 52254359Sroberto 52354359Sroberto return numtoa(refid); 52454359Sroberto} 52554359Sroberto 526182007Srobertostatic void 527182007Srobertoprint_pflag( 528285612Sdelphij FILE * fp, 529285612Sdelphij u_int32 flags 530285612Sdelphij ) 531182007Sroberto{ 532285612Sdelphij static const char none[] = ""; 533285612Sdelphij static const char comma[] = ","; 534285612Sdelphij const char *dlim; 535182007Sroberto 536285612Sdelphij if (0 == flags) { 537285612Sdelphij fprintf(fp, " none\n"); 538285612Sdelphij return; 539182007Sroberto } 540285612Sdelphij dlim = none; 541285612Sdelphij if (flags & INFO_FLAG_SYSPEER) { 542285612Sdelphij fprintf(fp, " system_peer"); 543285612Sdelphij dlim = comma; 544285612Sdelphij } 545285612Sdelphij if (flags & INFO_FLAG_CONFIG) { 546285612Sdelphij fprintf(fp, "%s config", dlim); 547285612Sdelphij dlim = comma; 548285612Sdelphij } 549285612Sdelphij if (flags & INFO_FLAG_REFCLOCK) { 550285612Sdelphij fprintf(fp, "%s refclock", dlim); 551285612Sdelphij dlim = comma; 552285612Sdelphij } 553285612Sdelphij if (flags & INFO_FLAG_AUTHENABLE) { 554285612Sdelphij fprintf(fp, "%s auth", dlim); 555285612Sdelphij dlim = comma; 556285612Sdelphij } 557285612Sdelphij if (flags & INFO_FLAG_PREFER) { 558285612Sdelphij fprintf(fp, "%s prefer", dlim); 559285612Sdelphij dlim = comma; 560285612Sdelphij } 561285612Sdelphij if (flags & INFO_FLAG_IBURST) { 562285612Sdelphij fprintf(fp, "%s iburst", dlim); 563285612Sdelphij dlim = comma; 564285612Sdelphij } 565285612Sdelphij if (flags & INFO_FLAG_BURST) { 566285612Sdelphij fprintf(fp, "%s burst", dlim); 567285612Sdelphij dlim = comma; 568285612Sdelphij } 569285612Sdelphij if (flags & INFO_FLAG_SEL_CANDIDATE) { 570285612Sdelphij fprintf(fp, "%s candidate", dlim); 571285612Sdelphij dlim = comma; 572285612Sdelphij } 573285612Sdelphij if (flags & INFO_FLAG_SHORTLIST) { 574285612Sdelphij fprintf(fp, "%s shortlist", dlim); 575285612Sdelphij dlim = comma; 576285612Sdelphij } 577285612Sdelphij fprintf(fp, "\n"); 578182007Sroberto} 57954359Sroberto/* 58054359Sroberto * printpeer - print detail information for a peer 58154359Sroberto */ 58254359Srobertostatic void 58354359Srobertoprintpeer( 58454359Sroberto register struct info_peer *pp, 58554359Sroberto FILE *fp 58654359Sroberto ) 58754359Sroberto{ 58854359Sroberto register int i; 58954359Sroberto l_fp tempts; 590285612Sdelphij sockaddr_u srcadr, dstadr; 591132451Sroberto 592285612Sdelphij SET_ADDRS(dstadr, srcadr, pp, dstadr, srcadr); 593285612Sdelphij 59454359Sroberto (void) fprintf(fp, "remote %s, local %s\n", 595132451Sroberto stoa(&srcadr), stoa(&dstadr)); 59654359Sroberto (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n", 59754359Sroberto modetoa(pp->hmode), modetoa(pp->pmode), 59854359Sroberto pp->stratum, pp->precision); 59954359Sroberto 60054359Sroberto (void) fprintf(fp, 60154359Sroberto "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n", 60254359Sroberto pp->leap & 0x2 ? '1' : '0', 60354359Sroberto pp->leap & 0x1 ? '1' : '0', 60454359Sroberto refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5), 60554359Sroberto ufptoa(NTOHS_FP(pp->rootdispersion), 5)); 60654359Sroberto 60754359Sroberto (void) fprintf(fp, 60854359Sroberto "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n", 60954359Sroberto pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd)); 61054359Sroberto 61154359Sroberto (void) fprintf(fp, 61282498Sroberto "reach %03o, unreach %d, flash 0x%04x, ", 61382498Sroberto pp->reach, pp->unreach, pp->flash2); 61454359Sroberto 61554359Sroberto (void) fprintf(fp, "boffset %s, ttl/mode %d\n", 61654359Sroberto fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl); 61754359Sroberto 61854359Sroberto (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer)); 619182007Sroberto print_pflag(fp, pp->flags); 62054359Sroberto 62154359Sroberto NTOHL_FP(&pp->reftime, &tempts); 62254359Sroberto (void) fprintf(fp, "reference time: %s\n", 62354359Sroberto prettydate(&tempts)); 62454359Sroberto NTOHL_FP(&pp->org, &tempts); 62554359Sroberto (void) fprintf(fp, "originate timestamp: %s\n", 62654359Sroberto prettydate(&tempts)); 62754359Sroberto NTOHL_FP(&pp->rec, &tempts); 62854359Sroberto (void) fprintf(fp, "receive timestamp: %s\n", 62954359Sroberto prettydate(&tempts)); 63054359Sroberto NTOHL_FP(&pp->xmt, &tempts); 63154359Sroberto (void) fprintf(fp, "transmit timestamp: %s\n", 63254359Sroberto prettydate(&tempts)); 63354359Sroberto 63454359Sroberto (void) fprintf(fp, "filter delay: "); 63554359Sroberto for (i = 0; i < NTP_SHIFT; i++) { 63654359Sroberto (void) fprintf(fp, " %-8.8s", 63754359Sroberto fptoa(NTOHS_FP(pp->filtdelay[i]), 5)); 63854359Sroberto if (i == (NTP_SHIFT>>1)-1) 63954359Sroberto (void) fprintf(fp, "\n "); 64054359Sroberto } 64154359Sroberto (void) fprintf(fp, "\n"); 64254359Sroberto 64354359Sroberto (void) fprintf(fp, "filter offset:"); 64454359Sroberto for (i = 0; i < NTP_SHIFT; i++) { 64554359Sroberto NTOHL_FP(&pp->filtoffset[i], &tempts); 64654359Sroberto (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6)); 64754359Sroberto if (i == (NTP_SHIFT>>1)-1) 64854359Sroberto (void) fprintf(fp, "\n "); 64954359Sroberto } 65054359Sroberto (void) fprintf(fp, "\n"); 65154359Sroberto 65254359Sroberto (void) fprintf(fp, "filter order: "); 65354359Sroberto for (i = 0; i < NTP_SHIFT; i++) { 65454359Sroberto (void) fprintf(fp, " %-8d", pp->order[i]); 65554359Sroberto if (i == (NTP_SHIFT>>1)-1) 65654359Sroberto (void) fprintf(fp, "\n "); 65754359Sroberto } 65854359Sroberto (void) fprintf(fp, "\n"); 65954359Sroberto 66054359Sroberto 66154359Sroberto NTOHL_FP(&pp->offset, &tempts); 66254359Sroberto (void) fprintf(fp, 66354359Sroberto "offset %s, delay %s, error bound %s, filter error %s\n", 66454359Sroberto lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5), 66554359Sroberto ufptoa(NTOHS_FP(pp->dispersion), 5), 66654359Sroberto ufptoa(NTOHS_FP(pp->selectdisp), 5)); 66754359Sroberto} 66854359Sroberto 66954359Sroberto 67054359Sroberto/* 67154359Sroberto * showpeer - show detailed information for a peer 67254359Sroberto */ 67354359Srobertostatic void 67454359Srobertoshowpeer( 67554359Sroberto struct parse *pcmd, 67654359Sroberto FILE *fp 67754359Sroberto ) 67854359Sroberto{ 67954359Sroberto struct info_peer *pp; 68054359Sroberto /* 4 is the maximum number of peers which will fit in a packet */ 681132451Sroberto struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 682293650Sglebius size_t qitemlim; 683293650Sglebius size_t qitems; 684293650Sglebius size_t items; 685293650Sglebius size_t itemsize; 68654359Sroberto int res; 687132451Sroberto int sendsize; 68854359Sroberto 689132451Srobertoagain: 690132451Sroberto if (impl_ver == IMPL_XNTPD) 691132451Sroberto sendsize = sizeof(struct info_peer_list); 692132451Sroberto else 693132451Sroberto sendsize = v4sizeof(struct info_peer_list); 694132451Sroberto 695285612Sdelphij qitemlim = min(pcmd->nargs, COUNTOF(plist)); 696285612Sdelphij for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 697285612Sdelphij if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 698285612Sdelphij pl->addr = NSRCADR(&pcmd->argval[qitems].netnum); 699132451Sroberto if (impl_ver == IMPL_XNTPD) 700132451Sroberto pl->v6_flag = 0; 701132451Sroberto } else { 702132451Sroberto if (impl_ver == IMPL_XNTPD_OLD) { 703132451Sroberto fprintf(stderr, 704132451Sroberto "***Server doesn't understand IPv6 addresses\n"); 705132451Sroberto return; 706132451Sroberto } 707285612Sdelphij pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum); 708132451Sroberto pl->v6_flag = 1; 709132451Sroberto } 710132451Sroberto pl->port = (u_short)s_port; 711132451Sroberto pl->hmode = pl->flags = 0; 712285612Sdelphij pl = (void *)((char *)pl + sendsize); 71354359Sroberto } 71454359Sroberto 715132451Sroberto res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems, 716132451Sroberto sendsize, (char *)plist, &items, 717132451Sroberto &itemsize, (void *)&pp, 0, sizeof(struct info_peer)); 71854359Sroberto 719132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 720132451Sroberto impl_ver = IMPL_XNTPD_OLD; 721132451Sroberto goto again; 722132451Sroberto } 723132451Sroberto 724182007Sroberto if (res != 0) 725285612Sdelphij return; 72654359Sroberto 72754359Sroberto if (!checkitems(items, fp)) 728285612Sdelphij return; 72954359Sroberto 730132451Sroberto if (!checkitemsize(itemsize, sizeof(struct info_peer)) && 731132451Sroberto !checkitemsize(itemsize, v4sizeof(struct info_peer))) 732285612Sdelphij return; 73354359Sroberto 73454359Sroberto while (items-- > 0) { 73554359Sroberto printpeer(pp, fp); 73654359Sroberto if (items > 0) 737285612Sdelphij fprintf(fp, "\n"); 73854359Sroberto pp++; 73954359Sroberto } 74054359Sroberto} 74154359Sroberto 74254359Sroberto 74354359Sroberto/* 74454359Sroberto * peerstats - return statistics for a peer 74554359Sroberto */ 74654359Srobertostatic void 74754359Srobertopeerstats( 74854359Sroberto struct parse *pcmd, 74954359Sroberto FILE *fp 75054359Sroberto ) 75154359Sroberto{ 75254359Sroberto struct info_peer_stats *pp; 75354359Sroberto /* 4 is the maximum number of peers which will fit in a packet */ 754132451Sroberto struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 755285612Sdelphij sockaddr_u src, dst; 756293650Sglebius size_t qitemlim; 757293650Sglebius size_t qitems; 758293650Sglebius size_t items; 759293650Sglebius size_t itemsize; 76054359Sroberto int res; 761293650Sglebius size_t sendsize; 76254359Sroberto 763132451Srobertoagain: 764132451Sroberto if (impl_ver == IMPL_XNTPD) 765132451Sroberto sendsize = sizeof(struct info_peer_list); 766132451Sroberto else 767132451Sroberto sendsize = v4sizeof(struct info_peer_list); 768132451Sroberto 769285612Sdelphij ZERO(plist); 770285612Sdelphij 771285612Sdelphij qitemlim = min(pcmd->nargs, COUNTOF(plist)); 772285612Sdelphij for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 773285612Sdelphij if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 774285612Sdelphij pl->addr = NSRCADR(&pcmd->argval[qitems].netnum); 775132451Sroberto if (impl_ver == IMPL_XNTPD) 776132451Sroberto pl->v6_flag = 0; 777132451Sroberto } else { 778132451Sroberto if (impl_ver == IMPL_XNTPD_OLD) { 779132451Sroberto fprintf(stderr, 780132451Sroberto "***Server doesn't understand IPv6 addresses\n"); 781132451Sroberto return; 782132451Sroberto } 783285612Sdelphij pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum); 784132451Sroberto pl->v6_flag = 1; 785132451Sroberto } 786132451Sroberto pl->port = (u_short)s_port; 787132451Sroberto pl->hmode = plist[qitems].flags = 0; 788285612Sdelphij pl = (void *)((char *)pl + sendsize); 78954359Sroberto } 79054359Sroberto 791132451Sroberto res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems, 792132451Sroberto sendsize, (char *)plist, &items, 793132451Sroberto &itemsize, (void *)&pp, 0, 794132451Sroberto sizeof(struct info_peer_stats)); 79554359Sroberto 796132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 797132451Sroberto impl_ver = IMPL_XNTPD_OLD; 798132451Sroberto goto again; 799132451Sroberto } 800132451Sroberto 801182007Sroberto if (res != 0) 802285612Sdelphij return; 80354359Sroberto 80454359Sroberto if (!checkitems(items, fp)) 80554359Sroberto return; 80654359Sroberto 807132451Sroberto if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) && 808132451Sroberto !checkitemsize(itemsize, v4sizeof(struct info_peer_stats))) 80954359Sroberto return; 81054359Sroberto 81154359Sroberto while (items-- > 0) { 812285612Sdelphij ZERO_SOCK(&dst); 813285612Sdelphij ZERO_SOCK(&src); 814132451Sroberto if (pp->v6_flag != 0) { 815285612Sdelphij AF(&dst) = AF_INET6; 816285612Sdelphij AF(&src) = AF_INET6; 817285612Sdelphij SOCK_ADDR6(&dst) = pp->dstadr6; 818285612Sdelphij SOCK_ADDR6(&src) = pp->srcadr6; 819132451Sroberto } else { 820285612Sdelphij AF(&dst) = AF_INET; 821285612Sdelphij AF(&src) = AF_INET; 822285612Sdelphij NSRCADR(&dst) = pp->dstadr; 823285612Sdelphij NSRCADR(&src) = pp->srcadr; 824132451Sroberto } 825285612Sdelphij#ifdef ISC_PLATFORM_HAVESALEN 826285612Sdelphij src.sa.sa_len = SOCKLEN(&src); 827285612Sdelphij dst.sa.sa_len = SOCKLEN(&dst); 828132451Sroberto#endif 829285612Sdelphij fprintf(fp, "remote host: %s\n", 830285612Sdelphij nntohost(&src)); 831285612Sdelphij fprintf(fp, "local interface: %s\n", 832285612Sdelphij stoa(&dst)); 833285612Sdelphij fprintf(fp, "time last received: %lus\n", 834285612Sdelphij (u_long)ntohl(pp->timereceived)); 835285612Sdelphij fprintf(fp, "time until next send: %lus\n", 836285612Sdelphij (u_long)ntohl(pp->timetosend)); 837285612Sdelphij fprintf(fp, "reachability change: %lus\n", 838285612Sdelphij (u_long)ntohl(pp->timereachable)); 839285612Sdelphij fprintf(fp, "packets sent: %lu\n", 840285612Sdelphij (u_long)ntohl(pp->sent)); 841285612Sdelphij fprintf(fp, "packets received: %lu\n", 842285612Sdelphij (u_long)ntohl(pp->processed)); 843285612Sdelphij fprintf(fp, "bad authentication: %lu\n", 844285612Sdelphij (u_long)ntohl(pp->badauth)); 845285612Sdelphij fprintf(fp, "bogus origin: %lu\n", 846285612Sdelphij (u_long)ntohl(pp->bogusorg)); 847285612Sdelphij fprintf(fp, "duplicate: %lu\n", 848285612Sdelphij (u_long)ntohl(pp->oldpkt)); 849285612Sdelphij fprintf(fp, "bad dispersion: %lu\n", 850285612Sdelphij (u_long)ntohl(pp->seldisp)); 851285612Sdelphij fprintf(fp, "bad reference time: %lu\n", 852285612Sdelphij (u_long)ntohl(pp->selbroken)); 853285612Sdelphij fprintf(fp, "candidate order: %u\n", 854285612Sdelphij pp->candidate); 85554359Sroberto if (items > 0) 856285612Sdelphij fprintf(fp, "\n"); 857285612Sdelphij fprintf(fp, "flags: "); 858182007Sroberto print_pflag(fp, ntohs(pp->flags)); 859285612Sdelphij pp++; 86054359Sroberto } 86154359Sroberto} 86254359Sroberto 86354359Sroberto 86454359Sroberto/* 86554359Sroberto * loopinfo - show loop filter information 86654359Sroberto */ 86754359Srobertostatic void 86854359Srobertoloopinfo( 86954359Sroberto struct parse *pcmd, 87054359Sroberto FILE *fp 87154359Sroberto ) 87254359Sroberto{ 87354359Sroberto struct info_loop *il; 874293650Sglebius size_t items; 875293650Sglebius size_t itemsize; 87654359Sroberto int oneline = 0; 87754359Sroberto int res; 87854359Sroberto l_fp tempts; 87954359Sroberto 88054359Sroberto if (pcmd->nargs > 0) { 88154359Sroberto if (STREQ(pcmd->argval[0].string, "oneline")) 88254359Sroberto oneline = 1; 88354359Sroberto else if (STREQ(pcmd->argval[0].string, "multiline")) 88454359Sroberto oneline = 0; 88554359Sroberto else { 88654359Sroberto (void) fprintf(stderr, "How many lines?\n"); 88754359Sroberto return; 88854359Sroberto } 88954359Sroberto } 89054359Sroberto 891132451Srobertoagain: 892132451Sroberto res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL, 893132451Sroberto &items, &itemsize, (void *)&il, 0, 894132451Sroberto sizeof(struct info_loop)); 89554359Sroberto 896132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 897132451Sroberto impl_ver = IMPL_XNTPD_OLD; 898132451Sroberto goto again; 899132451Sroberto } 900132451Sroberto 901182007Sroberto if (res != 0) 90254359Sroberto return; 90354359Sroberto 90454359Sroberto if (!check1item(items, fp)) 90554359Sroberto return; 90654359Sroberto 90754359Sroberto if (!checkitemsize(itemsize, sizeof(struct info_loop))) 90854359Sroberto return; 90954359Sroberto 91054359Sroberto if (oneline) { 91154359Sroberto l_fp temp2ts; 91254359Sroberto 91354359Sroberto NTOHL_FP(&il->last_offset, &tempts); 91454359Sroberto NTOHL_FP(&il->drift_comp, &temp2ts); 91554359Sroberto 91654359Sroberto (void) fprintf(fp, 91754359Sroberto "offset %s, frequency %s, time_const %ld, watchdog %ld\n", 91854359Sroberto lfptoa(&tempts, 6), 91954359Sroberto lfptoa(&temp2ts, 3), 920285612Sdelphij (long)(int32)ntohl((u_long)il->compliance), 921182007Sroberto (u_long)ntohl((u_long)il->watchdog_timer)); 92254359Sroberto } else { 92354359Sroberto NTOHL_FP(&il->last_offset, &tempts); 92454359Sroberto (void) fprintf(fp, "offset: %s s\n", 92554359Sroberto lfptoa(&tempts, 6)); 92654359Sroberto NTOHL_FP(&il->drift_comp, &tempts); 92754359Sroberto (void) fprintf(fp, "frequency: %s ppm\n", 92854359Sroberto lfptoa(&tempts, 3)); 92954359Sroberto (void) fprintf(fp, "poll adjust: %ld\n", 930285612Sdelphij (long)(int32)ntohl(il->compliance)); 93154359Sroberto (void) fprintf(fp, "watchdog timer: %ld s\n", 93254359Sroberto (u_long)ntohl(il->watchdog_timer)); 93354359Sroberto } 93454359Sroberto} 93554359Sroberto 93654359Sroberto 93754359Sroberto/* 93854359Sroberto * sysinfo - show current system state 93954359Sroberto */ 94054359Sroberto/*ARGSUSED*/ 94154359Srobertostatic void 94254359Srobertosysinfo( 94354359Sroberto struct parse *pcmd, 94454359Sroberto FILE *fp 94554359Sroberto ) 94654359Sroberto{ 94754359Sroberto struct info_sys *is; 948285612Sdelphij sockaddr_u peeraddr; 949293650Sglebius size_t items; 950293650Sglebius size_t itemsize; 95154359Sroberto int res; 95254359Sroberto l_fp tempts; 95354359Sroberto 954132451Srobertoagain: 955132451Sroberto res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL, 956132451Sroberto &items, &itemsize, (void *)&is, 0, 957132451Sroberto sizeof(struct info_sys)); 95854359Sroberto 959132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 960132451Sroberto impl_ver = IMPL_XNTPD_OLD; 961132451Sroberto goto again; 962132451Sroberto } 963132451Sroberto 964182007Sroberto if (res != 0) 96554359Sroberto return; 96654359Sroberto 96754359Sroberto if (!check1item(items, fp)) 96854359Sroberto return; 96954359Sroberto 970132451Sroberto if (!checkitemsize(itemsize, sizeof(struct info_sys)) && 971132451Sroberto !checkitemsize(itemsize, v4sizeof(struct info_sys))) 97254359Sroberto return; 97354359Sroberto 974285612Sdelphij SET_ADDR(peeraddr, is->v6_flag, is->peer, is->peer6); 975285612Sdelphij 976132451Sroberto (void) fprintf(fp, "system peer: %s\n", nntohost(&peeraddr)); 97754359Sroberto (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode)); 97854359Sroberto (void) fprintf(fp, "leap indicator: %c%c\n", 97954359Sroberto is->leap & 0x2 ? '1' : '0', 98054359Sroberto is->leap & 0x1 ? '1' : '0'); 98154359Sroberto (void) fprintf(fp, "stratum: %d\n", (int)is->stratum); 98254359Sroberto (void) fprintf(fp, "precision: %d\n", (int)is->precision); 98354359Sroberto (void) fprintf(fp, "root distance: %s s\n", 98454359Sroberto fptoa(NTOHS_FP(is->rootdelay), 5)); 98554359Sroberto (void) fprintf(fp, "root dispersion: %s s\n", 98654359Sroberto ufptoa(NTOHS_FP(is->rootdispersion), 5)); 98754359Sroberto (void) fprintf(fp, "reference ID: [%s]\n", 98854359Sroberto refid_string(is->refid, is->stratum)); 98954359Sroberto NTOHL_FP(&is->reftime, &tempts); 99054359Sroberto (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts)); 99154359Sroberto 99254359Sroberto (void) fprintf(fp, "system flags: "); 99354359Sroberto if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE | 994106163Sroberto INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL | 99554359Sroberto INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) { 99654359Sroberto (void) fprintf(fp, "none\n"); 99754359Sroberto } else { 99854359Sroberto if (is->flags & INFO_FLAG_BCLIENT) 99954359Sroberto (void) fprintf(fp, "bclient "); 100054359Sroberto if (is->flags & INFO_FLAG_AUTHENTICATE) 100154359Sroberto (void) fprintf(fp, "auth "); 100254359Sroberto if (is->flags & INFO_FLAG_MONITOR) 100354359Sroberto (void) fprintf(fp, "monitor "); 100454359Sroberto if (is->flags & INFO_FLAG_NTP) 100554359Sroberto (void) fprintf(fp, "ntp "); 100654359Sroberto if (is->flags & INFO_FLAG_KERNEL) 100754359Sroberto (void) fprintf(fp, "kernel "); 100854359Sroberto if (is->flags & INFO_FLAG_FILEGEN) 100954359Sroberto (void) fprintf(fp, "stats "); 1010106163Sroberto if (is->flags & INFO_FLAG_CAL) 1011106163Sroberto (void) fprintf(fp, "calibrate "); 101254359Sroberto if (is->flags & INFO_FLAG_PPS_SYNC) 1013106163Sroberto (void) fprintf(fp, "pps "); 101454359Sroberto (void) fprintf(fp, "\n"); 101554359Sroberto } 101654359Sroberto (void) fprintf(fp, "jitter: %s s\n", 101754359Sroberto fptoa(ntohl(is->frequency), 6)); 101854359Sroberto (void) fprintf(fp, "stability: %s ppm\n", 101954359Sroberto ufptoa(ntohl(is->stability), 3)); 102054359Sroberto (void) fprintf(fp, "broadcastdelay: %s s\n", 102154359Sroberto fptoa(NTOHS_FP(is->bdelay), 6)); 102254359Sroberto NTOHL_FP(&is->authdelay, &tempts); 102354359Sroberto (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6)); 102454359Sroberto} 102554359Sroberto 102654359Sroberto 102754359Sroberto/* 102854359Sroberto * sysstats - print system statistics 102954359Sroberto */ 103054359Sroberto/*ARGSUSED*/ 103154359Srobertostatic void 103254359Srobertosysstats( 103354359Sroberto struct parse *pcmd, 103454359Sroberto FILE *fp 103554359Sroberto ) 103654359Sroberto{ 103754359Sroberto struct info_sys_stats *ss; 1038293650Sglebius size_t items; 1039293650Sglebius size_t itemsize; 104054359Sroberto int res; 104154359Sroberto 1042132451Srobertoagain: 1043132451Sroberto res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL, 1044132451Sroberto &items, &itemsize, (void *)&ss, 0, 1045132451Sroberto sizeof(struct info_sys_stats)); 104654359Sroberto 1047132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1048132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1049132451Sroberto goto again; 1050132451Sroberto } 1051132451Sroberto 1052182007Sroberto if (res != 0) 105354359Sroberto return; 105454359Sroberto 105554359Sroberto if (!check1item(items, fp)) 105654359Sroberto return; 105754359Sroberto 105854359Sroberto if (itemsize != sizeof(struct info_sys_stats) && 105954359Sroberto itemsize != sizeof(struct old_info_sys_stats)) { 106054359Sroberto /* issue warning according to new structure size */ 106154359Sroberto checkitemsize(itemsize, sizeof(struct info_sys_stats)); 106254359Sroberto return; 106354359Sroberto } 1064285612Sdelphij fprintf(fp, "time since restart: %lu\n", 1065285612Sdelphij (u_long)ntohl(ss->timeup)); 1066285612Sdelphij fprintf(fp, "time since reset: %lu\n", 1067132451Sroberto (u_long)ntohl(ss->timereset)); 1068285612Sdelphij fprintf(fp, "packets received: %lu\n", 1069132451Sroberto (u_long)ntohl(ss->received)); 1070285612Sdelphij fprintf(fp, "packets processed: %lu\n", 1071132451Sroberto (u_long)ntohl(ss->processed)); 1072285612Sdelphij fprintf(fp, "current version: %lu\n", 1073285612Sdelphij (u_long)ntohl(ss->newversionpkt)); 1074285612Sdelphij fprintf(fp, "previous version: %lu\n", 1075285612Sdelphij (u_long)ntohl(ss->oldversionpkt)); 1076285612Sdelphij fprintf(fp, "declined: %lu\n", 1077285612Sdelphij (u_long)ntohl(ss->unknownversion)); 1078285612Sdelphij fprintf(fp, "access denied: %lu\n", 1079132451Sroberto (u_long)ntohl(ss->denied)); 1080285612Sdelphij fprintf(fp, "bad length or format: %lu\n", 1081285612Sdelphij (u_long)ntohl(ss->badlength)); 1082285612Sdelphij fprintf(fp, "bad authentication: %lu\n", 1083285612Sdelphij (u_long)ntohl(ss->badauth)); 108454359Sroberto if (itemsize != sizeof(struct info_sys_stats)) 108554359Sroberto return; 108654359Sroberto 1087285612Sdelphij fprintf(fp, "rate exceeded: %lu\n", 1088132451Sroberto (u_long)ntohl(ss->limitrejected)); 108954359Sroberto} 109054359Sroberto 109154359Sroberto 109254359Sroberto 109354359Sroberto/* 109454359Sroberto * iostats - print I/O statistics 109554359Sroberto */ 109654359Sroberto/*ARGSUSED*/ 109754359Srobertostatic void 109854359Srobertoiostats( 109954359Sroberto struct parse *pcmd, 110054359Sroberto FILE *fp 110154359Sroberto ) 110254359Sroberto{ 110354359Sroberto struct info_io_stats *io; 1104293650Sglebius size_t items; 1105293650Sglebius size_t itemsize; 110654359Sroberto int res; 110754359Sroberto 1108132451Srobertoagain: 1109285612Sdelphij res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, NULL, &items, 1110285612Sdelphij &itemsize, (void *)&io, 0, sizeof(*io)); 111154359Sroberto 1112132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1113132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1114132451Sroberto goto again; 1115132451Sroberto } 1116132451Sroberto 1117182007Sroberto if (res != 0) 1118285612Sdelphij return; 111954359Sroberto 112054359Sroberto if (!check1item(items, fp)) 1121285612Sdelphij return; 112254359Sroberto 1123285612Sdelphij if (!checkitemsize(itemsize, sizeof(*io))) 1124285612Sdelphij return; 112554359Sroberto 1126285612Sdelphij fprintf(fp, "time since reset: %lu\n", 1127285612Sdelphij (u_long)ntohl(io->timereset)); 1128285612Sdelphij fprintf(fp, "receive buffers: %u\n", 1129285612Sdelphij (u_int)ntohs(io->totalrecvbufs)); 1130285612Sdelphij fprintf(fp, "free receive buffers: %u\n", 1131285612Sdelphij (u_int)ntohs(io->freerecvbufs)); 1132285612Sdelphij fprintf(fp, "used receive buffers: %u\n", 1133285612Sdelphij (u_int)ntohs(io->fullrecvbufs)); 1134285612Sdelphij fprintf(fp, "low water refills: %u\n", 1135285612Sdelphij (u_int)ntohs(io->lowwater)); 1136285612Sdelphij fprintf(fp, "dropped packets: %lu\n", 1137285612Sdelphij (u_long)ntohl(io->dropped)); 1138285612Sdelphij fprintf(fp, "ignored packets: %lu\n", 1139285612Sdelphij (u_long)ntohl(io->ignored)); 1140285612Sdelphij fprintf(fp, "received packets: %lu\n", 1141285612Sdelphij (u_long)ntohl(io->received)); 1142285612Sdelphij fprintf(fp, "packets sent: %lu\n", 1143285612Sdelphij (u_long)ntohl(io->sent)); 1144285612Sdelphij fprintf(fp, "packets not sent: %lu\n", 1145285612Sdelphij (u_long)ntohl(io->notsent)); 1146285612Sdelphij fprintf(fp, "interrupts handled: %lu\n", 1147285612Sdelphij (u_long)ntohl(io->interrupts)); 1148285612Sdelphij fprintf(fp, "received by int: %lu\n", 1149285612Sdelphij (u_long)ntohl(io->int_received)); 115054359Sroberto} 115154359Sroberto 115254359Sroberto 115354359Sroberto/* 115454359Sroberto * memstats - print peer memory statistics 115554359Sroberto */ 115654359Sroberto/*ARGSUSED*/ 115754359Srobertostatic void 115854359Srobertomemstats( 115954359Sroberto struct parse *pcmd, 116054359Sroberto FILE *fp 116154359Sroberto ) 116254359Sroberto{ 116354359Sroberto struct info_mem_stats *mem; 116454359Sroberto int i; 1165293650Sglebius size_t items; 1166293650Sglebius size_t itemsize; 116754359Sroberto int res; 116854359Sroberto 1169132451Srobertoagain: 1170285612Sdelphij res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, NULL, &items, 1171285612Sdelphij &itemsize, (void *)&mem, 0, sizeof(*mem)); 117254359Sroberto 1173132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1174132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1175132451Sroberto goto again; 1176132451Sroberto } 1177132451Sroberto 1178182007Sroberto if (res != 0) 1179285612Sdelphij return; 118054359Sroberto 118154359Sroberto if (!check1item(items, fp)) 1182285612Sdelphij return; 118354359Sroberto 1184285612Sdelphij if (!checkitemsize(itemsize, sizeof(*mem))) 1185285612Sdelphij return; 118654359Sroberto 1187285612Sdelphij fprintf(fp, "time since reset: %lu\n", 1188285612Sdelphij (u_long)ntohl(mem->timereset)); 1189285612Sdelphij fprintf(fp, "total peer memory: %u\n", 1190285612Sdelphij (u_int)ntohs(mem->totalpeermem)); 1191285612Sdelphij fprintf(fp, "free peer memory: %u\n", 1192285612Sdelphij (u_int)ntohs(mem->freepeermem)); 1193285612Sdelphij fprintf(fp, "calls to findpeer: %lu\n", 1194285612Sdelphij (u_long)ntohl(mem->findpeer_calls)); 1195285612Sdelphij fprintf(fp, "new peer allocations: %lu\n", 1196285612Sdelphij (u_long)ntohl(mem->allocations)); 1197285612Sdelphij fprintf(fp, "peer demobilizations: %lu\n", 1198285612Sdelphij (u_long)ntohl(mem->demobilizations)); 119954359Sroberto 1200285612Sdelphij fprintf(fp, "hash table counts: "); 1201182007Sroberto for (i = 0; i < NTP_HASH_SIZE; i++) { 1202285612Sdelphij fprintf(fp, "%4d", (int)mem->hashcount[i]); 1203285612Sdelphij if ((i % 8) == 7 && i != (NTP_HASH_SIZE-1)) 1204285612Sdelphij fprintf(fp, "\n "); 120554359Sroberto } 1206285612Sdelphij fprintf(fp, "\n"); 120754359Sroberto} 120854359Sroberto 120954359Sroberto 121054359Sroberto 121154359Sroberto/* 121254359Sroberto * timerstats - print timer statistics 121354359Sroberto */ 121454359Sroberto/*ARGSUSED*/ 121554359Srobertostatic void 121654359Srobertotimerstats( 121754359Sroberto struct parse *pcmd, 121854359Sroberto FILE *fp 121954359Sroberto ) 122054359Sroberto{ 122154359Sroberto struct info_timer_stats *tim; 1222293650Sglebius size_t items; 1223293650Sglebius size_t itemsize; 122454359Sroberto int res; 122554359Sroberto 1226132451Srobertoagain: 1227285612Sdelphij res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, NULL, &items, 1228285612Sdelphij &itemsize, (void *)&tim, 0, sizeof(*tim)); 122954359Sroberto 1230132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1231132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1232132451Sroberto goto again; 1233132451Sroberto } 1234132451Sroberto 1235182007Sroberto if (res != 0) 1236285612Sdelphij return; 123754359Sroberto 123854359Sroberto if (!check1item(items, fp)) 1239285612Sdelphij return; 124054359Sroberto 1241285612Sdelphij if (!checkitemsize(itemsize, sizeof(*tim))) 1242285612Sdelphij return; 124354359Sroberto 1244285612Sdelphij fprintf(fp, "time since reset: %lu\n", 1245285612Sdelphij (u_long)ntohl(tim->timereset)); 1246285612Sdelphij fprintf(fp, "alarms handled: %lu\n", 1247285612Sdelphij (u_long)ntohl(tim->alarms)); 1248285612Sdelphij fprintf(fp, "alarm overruns: %lu\n", 1249285612Sdelphij (u_long)ntohl(tim->overflows)); 1250285612Sdelphij fprintf(fp, "calls to transmit: %lu\n", 1251285612Sdelphij (u_long)ntohl(tim->xmtcalls)); 125254359Sroberto} 125354359Sroberto 125454359Sroberto 125554359Sroberto/* 125654359Sroberto * addpeer - configure an active mode association 125754359Sroberto */ 125854359Srobertostatic void 125954359Srobertoaddpeer( 126054359Sroberto struct parse *pcmd, 126154359Sroberto FILE *fp 126254359Sroberto ) 126354359Sroberto{ 126454359Sroberto doconfig(pcmd, fp, MODE_ACTIVE, 0); 126554359Sroberto} 126654359Sroberto 126754359Sroberto 126854359Sroberto/* 126954359Sroberto * addserver - configure a client mode association 127054359Sroberto */ 127154359Srobertostatic void 127254359Srobertoaddserver( 127354359Sroberto struct parse *pcmd, 127454359Sroberto FILE *fp 127554359Sroberto ) 127654359Sroberto{ 127754359Sroberto doconfig(pcmd, fp, MODE_CLIENT, 0); 127854359Sroberto} 127954359Sroberto 128054359Sroberto/* 128154359Sroberto * addrefclock - configure a reference clock association 128254359Sroberto */ 128354359Srobertostatic void 128454359Srobertoaddrefclock( 128554359Sroberto struct parse *pcmd, 128654359Sroberto FILE *fp 128754359Sroberto ) 128854359Sroberto{ 128954359Sroberto doconfig(pcmd, fp, MODE_CLIENT, 1); 129054359Sroberto} 129154359Sroberto 129254359Sroberto/* 129354359Sroberto * broadcast - configure a broadcast mode association 129454359Sroberto */ 129554359Srobertostatic void 129654359Srobertobroadcast( 129754359Sroberto struct parse *pcmd, 129854359Sroberto FILE *fp 129954359Sroberto ) 130054359Sroberto{ 130154359Sroberto doconfig(pcmd, fp, MODE_BROADCAST, 0); 130254359Sroberto} 130354359Sroberto 130454359Sroberto 130554359Sroberto/* 130654359Sroberto * config - configure a new peer association 130754359Sroberto */ 130854359Srobertostatic void 130954359Srobertodoconfig( 131054359Sroberto struct parse *pcmd, 131154359Sroberto FILE *fp, 131254359Sroberto int mode, 1313285612Sdelphij int refc 131454359Sroberto ) 131554359Sroberto{ 131654359Sroberto struct conf_peer cpeer; 1317293650Sglebius size_t items; 1318293650Sglebius size_t itemsize; 1319293650Sglebius const char *dummy; 132054359Sroberto u_long keyid; 132154359Sroberto u_int version; 132254359Sroberto u_char minpoll; 1323182007Sroberto u_char maxpoll; 132454359Sroberto u_int flags; 132554359Sroberto u_char cmode; 132654359Sroberto int res; 1327132451Sroberto int sendsize; 1328182007Sroberto int numtyp; 1329285612Sdelphij long val; 133054359Sroberto 1331132451Srobertoagain: 133254359Sroberto keyid = 0; 1333182007Sroberto version = 3; 133454359Sroberto flags = 0; 1335285612Sdelphij res = FALSE; 133654359Sroberto cmode = 0; 133754359Sroberto minpoll = NTP_MINDPOLL; 1338182007Sroberto maxpoll = NTP_MAXDPOLL; 1339182007Sroberto numtyp = 1; 1340182007Sroberto if (refc) 1341285612Sdelphij numtyp = 5; 134254359Sroberto 1343132451Sroberto if (impl_ver == IMPL_XNTPD) 1344132451Sroberto sendsize = sizeof(struct conf_peer); 1345132451Sroberto else 1346132451Sroberto sendsize = v4sizeof(struct conf_peer); 1347132451Sroberto 1348182007Sroberto items = 1; 1349285612Sdelphij while (pcmd->nargs > (size_t)items) { 135054359Sroberto if (STREQ(pcmd->argval[items].string, "prefer")) 1351285612Sdelphij flags |= CONF_FLAG_PREFER; 135254359Sroberto else if (STREQ(pcmd->argval[items].string, "burst")) 1353285612Sdelphij flags |= CONF_FLAG_BURST; 1354182007Sroberto else if (STREQ(pcmd->argval[items].string, "iburst")) 1355285612Sdelphij flags |= CONF_FLAG_IBURST; 1356182007Sroberto else if (!refc && STREQ(pcmd->argval[items].string, "keyid")) 1357285612Sdelphij numtyp = 1; 1358182007Sroberto else if (!refc && STREQ(pcmd->argval[items].string, "version")) 1359285612Sdelphij numtyp = 2; 1360182007Sroberto else if (STREQ(pcmd->argval[items].string, "minpoll")) 1361285612Sdelphij numtyp = 3; 1362182007Sroberto else if (STREQ(pcmd->argval[items].string, "maxpoll")) 1363285612Sdelphij numtyp = 4; 136454359Sroberto else { 1365182007Sroberto if (!atoint(pcmd->argval[items].string, &val)) 1366285612Sdelphij numtyp = 0; 1367182007Sroberto switch (numtyp) { 1368182007Sroberto case 1: 1369285612Sdelphij keyid = val; 1370285612Sdelphij numtyp = 2; 1371285612Sdelphij break; 1372285612Sdelphij 1373182007Sroberto case 2: 1374285612Sdelphij version = (u_int)val; 1375285612Sdelphij numtyp = 0; 1376285612Sdelphij break; 1377182007Sroberto 1378182007Sroberto case 3: 1379285612Sdelphij minpoll = (u_char)val; 1380285612Sdelphij numtyp = 0; 1381285612Sdelphij break; 1382182007Sroberto 1383182007Sroberto case 4: 1384285612Sdelphij maxpoll = (u_char)val; 1385285612Sdelphij numtyp = 0; 1386285612Sdelphij break; 1387182007Sroberto 1388182007Sroberto case 5: 1389285612Sdelphij cmode = (u_char)val; 1390285612Sdelphij numtyp = 0; 1391285612Sdelphij break; 1392182007Sroberto 1393182007Sroberto default: 1394285612Sdelphij fprintf(fp, "*** '%s' not understood\n", 1395285612Sdelphij pcmd->argval[items].string); 1396285612Sdelphij res = TRUE; 1397285612Sdelphij numtyp = 0; 139854359Sroberto } 1399182007Sroberto if (val < 0) { 1400285612Sdelphij fprintf(stderr, 1401285612Sdelphij "*** Value '%s' should be unsigned\n", 1402285612Sdelphij pcmd->argval[items].string); 1403285612Sdelphij res = TRUE; 1404182007Sroberto } 1405285612Sdelphij } 1406285612Sdelphij items++; 140754359Sroberto } 1408182007Sroberto if (keyid > 0) 1409285612Sdelphij flags |= CONF_FLAG_AUTHENABLE; 1410285612Sdelphij if (version > NTP_VERSION || version < NTP_OLDVERSION) { 1411285612Sdelphij fprintf(fp, "***invalid version number: %u\n", 1412285612Sdelphij version); 1413285612Sdelphij res = TRUE; 1414182007Sroberto } 1415182007Sroberto if (minpoll < NTP_MINPOLL || minpoll > NTP_MAXPOLL || 1416182007Sroberto maxpoll < NTP_MINPOLL || maxpoll > NTP_MAXPOLL || 1417182007Sroberto minpoll > maxpoll) { 1418285612Sdelphij fprintf(fp, "***min/max-poll must be within %d..%d\n", 1419285612Sdelphij NTP_MINPOLL, NTP_MAXPOLL); 1420285612Sdelphij res = TRUE; 1421182007Sroberto } 142254359Sroberto 142354359Sroberto if (res) 1424285612Sdelphij return; 142554359Sroberto 1426285612Sdelphij ZERO(cpeer); 142754359Sroberto 1428285612Sdelphij if (IS_IPV4(&pcmd->argval[0].netnum)) { 1429285612Sdelphij cpeer.peeraddr = NSRCADR(&pcmd->argval[0].netnum); 1430132451Sroberto if (impl_ver == IMPL_XNTPD) 1431132451Sroberto cpeer.v6_flag = 0; 1432132451Sroberto } else { 1433132451Sroberto if (impl_ver == IMPL_XNTPD_OLD) { 1434132451Sroberto fprintf(stderr, 1435132451Sroberto "***Server doesn't understand IPv6 addresses\n"); 1436132451Sroberto return; 1437132451Sroberto } 1438285612Sdelphij cpeer.peeraddr6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 1439132451Sroberto cpeer.v6_flag = 1; 1440132451Sroberto } 144154359Sroberto cpeer.hmode = (u_char) mode; 144254359Sroberto cpeer.keyid = keyid; 144354359Sroberto cpeer.version = (u_char) version; 144454359Sroberto cpeer.minpoll = minpoll; 1445182007Sroberto cpeer.maxpoll = maxpoll; 144654359Sroberto cpeer.flags = (u_char)flags; 144754359Sroberto cpeer.ttl = cmode; 144854359Sroberto 1449132451Sroberto res = doquery(impl_ver, REQ_CONFIG, 1, 1, 1450132451Sroberto sendsize, (char *)&cpeer, &items, 1451132451Sroberto &itemsize, &dummy, 0, sizeof(struct conf_peer)); 145254359Sroberto 1453132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1454132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1455132451Sroberto goto again; 1456132451Sroberto } 1457132451Sroberto 1458106163Sroberto if (res == INFO_ERR_FMT) { 1459106163Sroberto (void) fprintf(fp, 1460106163Sroberto "***Retrying command with old conf_peer size\n"); 1461132451Sroberto res = doquery(impl_ver, REQ_CONFIG, 1, 1, 1462106163Sroberto sizeof(struct old_conf_peer), (char *)&cpeer, 1463132451Sroberto &items, &itemsize, &dummy, 0, 1464132451Sroberto sizeof(struct conf_peer)); 1465106163Sroberto } 146654359Sroberto if (res == 0) 146754359Sroberto (void) fprintf(fp, "done!\n"); 146854359Sroberto return; 146954359Sroberto} 147054359Sroberto 147154359Sroberto 147254359Sroberto/* 147354359Sroberto * unconfig - unconfigure some associations 147454359Sroberto */ 147554359Srobertostatic void 147654359Srobertounconfig( 147754359Sroberto struct parse *pcmd, 147854359Sroberto FILE *fp 147954359Sroberto ) 148054359Sroberto{ 148154359Sroberto /* 8 is the maximum number of peers which will fit in a packet */ 1482132451Sroberto struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 1483293650Sglebius size_t qitemlim; 1484293650Sglebius size_t qitems; 1485293650Sglebius size_t items; 1486293650Sglebius size_t itemsize; 1487293650Sglebius const char *dummy; 148854359Sroberto int res; 1489293650Sglebius size_t sendsize; 149054359Sroberto 1491132451Srobertoagain: 1492132451Sroberto if (impl_ver == IMPL_XNTPD) 1493132451Sroberto sendsize = sizeof(struct conf_unpeer); 1494132451Sroberto else 1495132451Sroberto sendsize = v4sizeof(struct conf_unpeer); 1496132451Sroberto 1497285612Sdelphij qitemlim = min(pcmd->nargs, COUNTOF(plist)); 1498285612Sdelphij for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 1499285612Sdelphij if (IS_IPV4(&pcmd->argval[0].netnum)) { 1500285612Sdelphij pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum); 1501132451Sroberto if (impl_ver == IMPL_XNTPD) 1502132451Sroberto pl->v6_flag = 0; 1503132451Sroberto } else { 1504132451Sroberto if (impl_ver == IMPL_XNTPD_OLD) { 1505132451Sroberto fprintf(stderr, 1506132451Sroberto "***Server doesn't understand IPv6 addresses\n"); 1507132451Sroberto return; 1508132451Sroberto } 1509132451Sroberto pl->peeraddr6 = 1510285612Sdelphij SOCK_ADDR6(&pcmd->argval[qitems].netnum); 1511132451Sroberto pl->v6_flag = 1; 1512132451Sroberto } 1513285612Sdelphij pl = (void *)((char *)pl + sendsize); 151454359Sroberto } 151554359Sroberto 1516132451Sroberto res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems, 1517132451Sroberto sendsize, (char *)plist, &items, 1518132451Sroberto &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 151954359Sroberto 1520132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1521132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1522132451Sroberto goto again; 1523132451Sroberto } 1524132451Sroberto 152554359Sroberto if (res == 0) 152654359Sroberto (void) fprintf(fp, "done!\n"); 152754359Sroberto} 152854359Sroberto 152954359Sroberto 153054359Sroberto/* 153154359Sroberto * set - set some system flags 153254359Sroberto */ 153354359Srobertostatic void 153454359Srobertoset( 153554359Sroberto struct parse *pcmd, 153654359Sroberto FILE *fp 153754359Sroberto ) 153854359Sroberto{ 153954359Sroberto doset(pcmd, fp, REQ_SET_SYS_FLAG); 154054359Sroberto} 154154359Sroberto 154254359Sroberto 154354359Sroberto/* 154454359Sroberto * clear - clear some system flags 154554359Sroberto */ 154654359Srobertostatic void 154754359Srobertosys_clear( 154854359Sroberto struct parse *pcmd, 154954359Sroberto FILE *fp 155054359Sroberto ) 155154359Sroberto{ 155254359Sroberto doset(pcmd, fp, REQ_CLR_SYS_FLAG); 155354359Sroberto} 155454359Sroberto 155554359Sroberto 155654359Sroberto/* 155754359Sroberto * doset - set/clear system flags 155854359Sroberto */ 155954359Srobertostatic void 156054359Srobertodoset( 156154359Sroberto struct parse *pcmd, 156254359Sroberto FILE *fp, 156354359Sroberto int req 156454359Sroberto ) 156554359Sroberto{ 156654359Sroberto struct conf_sys_flags sys; 1567293650Sglebius size_t items; 1568293650Sglebius size_t itemsize; 1569293650Sglebius const char *dummy; 157054359Sroberto int res; 157154359Sroberto 157254359Sroberto sys.flags = 0; 157354359Sroberto res = 0; 1574285612Sdelphij for (items = 0; (size_t)items < pcmd->nargs; items++) { 1575106163Sroberto if (STREQ(pcmd->argval[items].string, "auth")) 1576106163Sroberto sys.flags |= SYS_FLAG_AUTH; 157754359Sroberto else if (STREQ(pcmd->argval[items].string, "bclient")) 1578106163Sroberto sys.flags |= SYS_FLAG_BCLIENT; 1579106163Sroberto else if (STREQ(pcmd->argval[items].string, "calibrate")) 1580106163Sroberto sys.flags |= SYS_FLAG_CAL; 1581106163Sroberto else if (STREQ(pcmd->argval[items].string, "kernel")) 1582106163Sroberto sys.flags |= SYS_FLAG_KERNEL; 158354359Sroberto else if (STREQ(pcmd->argval[items].string, "monitor")) 1584106163Sroberto sys.flags |= SYS_FLAG_MONITOR; 158554359Sroberto else if (STREQ(pcmd->argval[items].string, "ntp")) 1586106163Sroberto sys.flags |= SYS_FLAG_NTP; 1587106163Sroberto else if (STREQ(pcmd->argval[items].string, "pps")) 1588106163Sroberto sys.flags |= SYS_FLAG_PPS; 158954359Sroberto else if (STREQ(pcmd->argval[items].string, "stats")) 1590106163Sroberto sys.flags |= SYS_FLAG_FILEGEN; 159154359Sroberto else { 159254359Sroberto (void) fprintf(fp, "Unknown flag %s\n", 1593106163Sroberto pcmd->argval[items].string); 159454359Sroberto res = 1; 159554359Sroberto } 159654359Sroberto } 159754359Sroberto 1598182007Sroberto sys.flags = htonl(sys.flags); 159954359Sroberto if (res || sys.flags == 0) 160054359Sroberto return; 160154359Sroberto 1602132451Srobertoagain: 1603132451Sroberto res = doquery(impl_ver, req, 1, 1, 160454359Sroberto sizeof(struct conf_sys_flags), (char *)&sys, &items, 1605132451Sroberto &itemsize, &dummy, 0, sizeof(struct conf_sys_flags)); 160654359Sroberto 1607132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1608132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1609132451Sroberto goto again; 1610132451Sroberto } 1611132451Sroberto 161254359Sroberto if (res == 0) 161354359Sroberto (void) fprintf(fp, "done!\n"); 161454359Sroberto} 161554359Sroberto 161654359Sroberto 161754359Sroberto/* 161854359Sroberto * data for printing/interrpreting the restrict flags 161954359Sroberto */ 162054359Srobertostruct resflags { 162154359Sroberto const char *str; 162254359Sroberto int bit; 162354359Sroberto}; 162454359Sroberto 1625182007Sroberto/* XXX: HMS: we apparently don't report set bits we do not recognize. */ 1626182007Sroberto 1627182007Srobertostatic struct resflags resflagsV2[] = { 1628182007Sroberto { "ignore", 0x001 }, 1629182007Sroberto { "noserve", 0x002 }, 1630182007Sroberto { "notrust", 0x004 }, 1631182007Sroberto { "noquery", 0x008 }, 1632182007Sroberto { "nomodify", 0x010 }, 1633182007Sroberto { "nopeer", 0x020 }, 1634182007Sroberto { "notrap", 0x040 }, 1635182007Sroberto { "lptrap", 0x080 }, 1636182007Sroberto { "limited", 0x100 }, 1637182007Sroberto { "", 0 } 1638182007Sroberto}; 1639182007Sroberto 1640182007Srobertostatic struct resflags resflagsV3[] = { 164154359Sroberto { "ignore", RES_IGNORE }, 164254359Sroberto { "noserve", RES_DONTSERVE }, 164354359Sroberto { "notrust", RES_DONTTRUST }, 164454359Sroberto { "noquery", RES_NOQUERY }, 164554359Sroberto { "nomodify", RES_NOMODIFY }, 164654359Sroberto { "nopeer", RES_NOPEER }, 164754359Sroberto { "notrap", RES_NOTRAP }, 164854359Sroberto { "lptrap", RES_LPTRAP }, 164954359Sroberto { "limited", RES_LIMITED }, 165082498Sroberto { "version", RES_VERSION }, 1651285612Sdelphij { "kod", RES_KOD }, 1652285612Sdelphij { "flake", RES_FLAKE }, 165382498Sroberto 165454359Sroberto { "", 0 } 165554359Sroberto}; 165654359Sroberto 165754359Srobertostatic struct resflags resmflags[] = { 165854359Sroberto { "ntpport", RESM_NTPONLY }, 165954359Sroberto { "interface", RESM_INTERFACE }, 1660285612Sdelphij { "source", RESM_SOURCE }, 166154359Sroberto { "", 0 } 166254359Sroberto}; 166354359Sroberto 166454359Sroberto 166554359Sroberto/* 166654359Sroberto * reslist - obtain and print the server's restrict list 166754359Sroberto */ 166854359Sroberto/*ARGSUSED*/ 166954359Srobertostatic void 167054359Srobertoreslist( 167154359Sroberto struct parse *pcmd, 167254359Sroberto FILE *fp 167354359Sroberto ) 167454359Sroberto{ 167554359Sroberto struct info_restrict *rl; 1676285612Sdelphij sockaddr_u resaddr; 1677285612Sdelphij sockaddr_u maskaddr; 1678293650Sglebius size_t items; 1679293650Sglebius size_t itemsize; 168054359Sroberto int res; 1681132451Sroberto int skip; 1682285612Sdelphij const char *addr; 1683285612Sdelphij const char *mask; 168454359Sroberto struct resflags *rf; 168554359Sroberto u_int32 count; 1686330567Sgordon u_short rflags; 168754359Sroberto u_short mflags; 168854359Sroberto char flagstr[300]; 168954359Sroberto static const char *comma = ", "; 169054359Sroberto 1691132451Srobertoagain: 1692132451Sroberto res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL, 1693132451Sroberto &items, &itemsize, (void *)&rl, 0, 1694132451Sroberto sizeof(struct info_restrict)); 169554359Sroberto 1696132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1697132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1698132451Sroberto goto again; 1699132451Sroberto } 1700132451Sroberto 1701182007Sroberto if (res != 0) 1702285612Sdelphij return; 170354359Sroberto 170454359Sroberto if (!checkitems(items, fp)) 1705285612Sdelphij return; 170654359Sroberto 1707132451Sroberto if (!checkitemsize(itemsize, sizeof(struct info_restrict)) && 1708132451Sroberto !checkitemsize(itemsize, v4sizeof(struct info_restrict))) 1709285612Sdelphij return; 171054359Sroberto 1711285612Sdelphij fprintf(fp, 1712285612Sdelphij " address mask count flags\n"); 1713285612Sdelphij fprintf(fp, 1714285612Sdelphij "=====================================================================\n"); 1715132451Sroberto 171654359Sroberto while (items > 0) { 1717285612Sdelphij SET_ADDRS(resaddr, maskaddr, rl, addr, mask); 1718132451Sroberto if (rl->v6_flag != 0) { 1719132451Sroberto addr = nntohost(&resaddr); 1720132451Sroberto } else { 1721285612Sdelphij if (rl->mask == (u_int32)0xffffffff) 1722285612Sdelphij addr = nntohost(&resaddr); 1723132451Sroberto else 1724132451Sroberto addr = stoa(&resaddr); 1725132451Sroberto } 1726132451Sroberto mask = stoa(&maskaddr); 1727132451Sroberto skip = 1; 1728132451Sroberto if ((pcmd->nargs == 0) || 1729132451Sroberto ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) || 1730132451Sroberto ((pcmd->argval->ival == 4) && (rl->v6_flag == 0))) 1731132451Sroberto skip = 0; 173254359Sroberto count = ntohl(rl->count); 1733330567Sgordon rflags = ntohs(rl->rflags); 173454359Sroberto mflags = ntohs(rl->mflags); 173554359Sroberto flagstr[0] = '\0'; 173654359Sroberto 173754359Sroberto res = 1; 173854359Sroberto rf = &resmflags[0]; 173954359Sroberto while (rf->bit != 0) { 174054359Sroberto if (mflags & rf->bit) { 174154359Sroberto if (!res) 1742285612Sdelphij strlcat(flagstr, comma, 1743285612Sdelphij sizeof(flagstr)); 174454359Sroberto res = 0; 1745285612Sdelphij strlcat(flagstr, rf->str, 1746285612Sdelphij sizeof(flagstr)); 174754359Sroberto } 174854359Sroberto rf++; 174954359Sroberto } 175054359Sroberto 1751182007Sroberto rf = (impl_ver == IMPL_XNTPD_OLD) 1752285612Sdelphij ? &resflagsV2[0] 1753285612Sdelphij : &resflagsV3[0]; 1754285612Sdelphij 175554359Sroberto while (rf->bit != 0) { 1756330567Sgordon if (rflags & rf->bit) { 175754359Sroberto if (!res) 1758285612Sdelphij strlcat(flagstr, comma, 1759285612Sdelphij sizeof(flagstr)); 176054359Sroberto res = 0; 1761285612Sdelphij strlcat(flagstr, rf->str, 1762285612Sdelphij sizeof(flagstr)); 176354359Sroberto } 176454359Sroberto rf++; 176554359Sroberto } 176654359Sroberto 176754359Sroberto if (flagstr[0] == '\0') 1768285612Sdelphij strlcpy(flagstr, "none", sizeof(flagstr)); 176954359Sroberto 1770132451Sroberto if (!skip) 1771285612Sdelphij fprintf(fp, "%-15.15s %-15.15s %9lu %s\n", 1772285612Sdelphij addr, mask, (u_long)count, flagstr); 177354359Sroberto rl++; 177454359Sroberto items--; 177554359Sroberto } 177654359Sroberto} 177754359Sroberto 177854359Sroberto 177954359Sroberto 178054359Sroberto/* 178154359Sroberto * new_restrict - create/add a set of restrictions 178254359Sroberto */ 178354359Srobertostatic void 178454359Srobertonew_restrict( 178554359Sroberto struct parse *pcmd, 178654359Sroberto FILE *fp 178754359Sroberto ) 178854359Sroberto{ 178954359Sroberto do_restrict(pcmd, fp, REQ_RESADDFLAGS); 179054359Sroberto} 179154359Sroberto 179254359Sroberto 179354359Sroberto/* 179454359Sroberto * unrestrict - remove restriction flags from existing entry 179554359Sroberto */ 179654359Srobertostatic void 179754359Srobertounrestrict( 179854359Sroberto struct parse *pcmd, 179954359Sroberto FILE *fp 180054359Sroberto ) 180154359Sroberto{ 180254359Sroberto do_restrict(pcmd, fp, REQ_RESSUBFLAGS); 180354359Sroberto} 180454359Sroberto 180554359Sroberto 180654359Sroberto/* 180754359Sroberto * delrestrict - delete an existing restriction 180854359Sroberto */ 180954359Srobertostatic void 181054359Srobertodelrestrict( 181154359Sroberto struct parse *pcmd, 181254359Sroberto FILE *fp 181354359Sroberto ) 181454359Sroberto{ 181554359Sroberto do_restrict(pcmd, fp, REQ_UNRESTRICT); 181654359Sroberto} 181754359Sroberto 181854359Sroberto 181954359Sroberto/* 182054359Sroberto * do_restrict - decode commandline restrictions and make the request 182154359Sroberto */ 182254359Srobertostatic void 182354359Srobertodo_restrict( 182454359Sroberto struct parse *pcmd, 182554359Sroberto FILE *fp, 182654359Sroberto int req_code 182754359Sroberto ) 182854359Sroberto{ 182954359Sroberto struct conf_restrict cres; 1830293650Sglebius size_t items; 1831293650Sglebius size_t itemsize; 1832293650Sglebius const char *dummy; 183354359Sroberto u_int32 num; 183454359Sroberto u_long bit; 183554359Sroberto int i; 1836285612Sdelphij size_t res; 183754359Sroberto int err; 1838132451Sroberto int sendsize; 183954359Sroberto 1840132451Sroberto /* Initialize cres */ 1841132451Sroberto cres.addr = 0; 1842132451Sroberto cres.mask = 0; 184354359Sroberto cres.flags = 0; 184454359Sroberto cres.mflags = 0; 1845132451Sroberto cres.v6_flag = 0; 1846132451Sroberto 1847132451Srobertoagain: 1848132451Sroberto if (impl_ver == IMPL_XNTPD) 1849132451Sroberto sendsize = sizeof(struct conf_restrict); 1850132451Sroberto else 1851132451Sroberto sendsize = v4sizeof(struct conf_restrict); 1852132451Sroberto 1853285612Sdelphij if (IS_IPV4(&pcmd->argval[0].netnum)) { 1854285612Sdelphij cres.addr = NSRCADR(&pcmd->argval[0].netnum); 1855285612Sdelphij cres.mask = NSRCADR(&pcmd->argval[1].netnum); 1856132451Sroberto if (impl_ver == IMPL_XNTPD) 1857132451Sroberto cres.v6_flag = 0; 1858132451Sroberto } else { 1859132451Sroberto if (impl_ver == IMPL_XNTPD_OLD) { 1860132451Sroberto fprintf(stderr, 1861285612Sdelphij "***Server doesn't understand IPv6 addresses\n"); 1862132451Sroberto return; 1863132451Sroberto } 1864285612Sdelphij cres.addr6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 1865132451Sroberto cres.v6_flag = 1; 1866132451Sroberto } 1867132451Sroberto cres.flags = 0; 1868132451Sroberto cres.mflags = 0; 1869285612Sdelphij err = FALSE; 187054359Sroberto for (res = 2; res < pcmd->nargs; res++) { 187154359Sroberto if (STREQ(pcmd->argval[res].string, "ntpport")) { 187254359Sroberto cres.mflags |= RESM_NTPONLY; 187354359Sroberto } else { 1874182007Sroberto for (i = 0; resflagsV3[i].bit != 0; i++) { 187554359Sroberto if (STREQ(pcmd->argval[res].string, 1876182007Sroberto resflagsV3[i].str)) 1877285612Sdelphij break; 187854359Sroberto } 1879182007Sroberto if (resflagsV3[i].bit != 0) { 1880182007Sroberto cres.flags |= resflagsV3[i].bit; 188154359Sroberto if (req_code == REQ_UNRESTRICT) { 1882285612Sdelphij fprintf(fp, 1883285612Sdelphij "Flag %s inappropriate\n", 1884285612Sdelphij resflagsV3[i].str); 1885285612Sdelphij err = TRUE; 188654359Sroberto } 188754359Sroberto } else { 1888285612Sdelphij fprintf(fp, "Unknown flag %s\n", 1889285612Sdelphij pcmd->argval[res].string); 1890285612Sdelphij err = TRUE; 189154359Sroberto } 189254359Sroberto } 189354359Sroberto } 1894182007Sroberto cres.flags = htons(cres.flags); 1895182007Sroberto cres.mflags = htons(cres.mflags); 189654359Sroberto 189754359Sroberto /* 189854359Sroberto * Make sure mask for default address is zero. Otherwise, 189954359Sroberto * make sure mask bits are contiguous. 190054359Sroberto */ 1901285612Sdelphij if (IS_IPV4(&pcmd->argval[0].netnum)) { 1902132451Sroberto if (cres.addr == 0) { 1903132451Sroberto cres.mask = 0; 1904132451Sroberto } else { 1905132451Sroberto num = ntohl(cres.mask); 1906132451Sroberto for (bit = 0x80000000; bit != 0; bit >>= 1) 1907285612Sdelphij if ((num & bit) == 0) 1908285612Sdelphij break; 1909132451Sroberto for ( ; bit != 0; bit >>= 1) 1910285612Sdelphij if ((num & bit) != 0) 1911285612Sdelphij break; 1912132451Sroberto if (bit != 0) { 1913285612Sdelphij fprintf(fp, "Invalid mask %s\n", 1914285612Sdelphij numtoa(cres.mask)); 1915285612Sdelphij err = TRUE; 1916132451Sroberto } 1917132451Sroberto } 191854359Sroberto } else { 1919132451Sroberto /* XXX IPv6 sanity checking stuff */ 192054359Sroberto } 192154359Sroberto 192254359Sroberto if (err) 1923285612Sdelphij return; 192454359Sroberto 1925285612Sdelphij res = doquery(impl_ver, req_code, 1, 1, sendsize, (char *)&cres, 1926285612Sdelphij &items, &itemsize, &dummy, 0, sizeof(cres)); 192754359Sroberto 1928132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1929132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1930132451Sroberto goto again; 1931132451Sroberto } 1932132451Sroberto 193354359Sroberto if (res == 0) 193454359Sroberto (void) fprintf(fp, "done!\n"); 193554359Sroberto return; 193654359Sroberto} 193754359Sroberto 193854359Sroberto 193954359Sroberto/* 194054359Sroberto * monlist - obtain and print the server's monitor data 194154359Sroberto */ 194254359Sroberto/*ARGSUSED*/ 194354359Srobertostatic void 194454359Srobertomonlist( 194554359Sroberto struct parse *pcmd, 194654359Sroberto FILE *fp 194754359Sroberto ) 194854359Sroberto{ 1949293650Sglebius const char *struct_star; 1950293650Sglebius const struct info_monitor *ml; 1951293650Sglebius const struct info_monitor_1 *m1; 1952293650Sglebius const struct old_info_monitor *oml; 1953285612Sdelphij sockaddr_u addr; 1954285612Sdelphij sockaddr_u dstadr; 1955293650Sglebius size_t items; 1956293650Sglebius size_t itemsize; 195754359Sroberto int res; 195854359Sroberto int version = -1; 195954359Sroberto 1960285612Sdelphij if (pcmd->nargs > 0) 196154359Sroberto version = pcmd->argval[0].ival; 196254359Sroberto 1963132451Srobertoagain: 1964132451Sroberto res = doquery(impl_ver, 196554359Sroberto (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : 1966285612Sdelphij REQ_MON_GETLIST, 0, 0, 0, NULL, 196754359Sroberto &items, &itemsize, &struct_star, 1968132451Sroberto (version < 0) ? (1 << INFO_ERR_REQ) : 0, 1969132451Sroberto sizeof(struct info_monitor_1)); 197054359Sroberto 1971132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 1972132451Sroberto impl_ver = IMPL_XNTPD_OLD; 1973132451Sroberto goto again; 1974132451Sroberto } 1975132451Sroberto 197654359Sroberto if (res == INFO_ERR_REQ && version < 0) 1977285612Sdelphij res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, NULL, 1978285612Sdelphij &items, &itemsize, &struct_star, 0, 1979285612Sdelphij sizeof(struct info_monitor)); 198054359Sroberto 1981182007Sroberto if (res != 0) 1982285612Sdelphij return; 198354359Sroberto 198454359Sroberto if (!checkitems(items, fp)) 1985285612Sdelphij return; 198654359Sroberto 1987132451Sroberto if (itemsize == sizeof(struct info_monitor_1) || 1988132451Sroberto itemsize == v4sizeof(struct info_monitor_1)) { 198954359Sroberto 1990293650Sglebius m1 = (const void*)struct_star; 1991285612Sdelphij fprintf(fp, 1992285612Sdelphij "remote address port local address count m ver rstr avgint lstint\n"); 1993285612Sdelphij fprintf(fp, 1994285612Sdelphij "===============================================================================\n"); 199554359Sroberto while (items > 0) { 1996285612Sdelphij SET_ADDRS(dstadr, addr, m1, daddr, addr); 1997132451Sroberto if ((pcmd->nargs == 0) || 1998285612Sdelphij ((pcmd->argval->ival == 6) && (m1->v6_flag != 0)) || 1999285612Sdelphij ((pcmd->argval->ival == 4) && (m1->v6_flag == 0))) 2000285612Sdelphij fprintf(fp, 2001285612Sdelphij "%-22.22s %5d %-15s %8lu %1u %1u %6lx %6lu %7lu\n", 2002132451Sroberto nntohost(&addr), 2003285612Sdelphij ntohs(m1->port), 2004132451Sroberto stoa(&dstadr), 2005285612Sdelphij (u_long)ntohl(m1->count), 2006285612Sdelphij m1->mode, 2007285612Sdelphij m1->version, 2008285612Sdelphij (u_long)ntohl(m1->restr), 2009285612Sdelphij (u_long)ntohl(m1->avg_int), 2010285612Sdelphij (u_long)ntohl(m1->last_int)); 2011285612Sdelphij m1++; 201254359Sroberto items--; 201354359Sroberto } 2014132451Sroberto } else if (itemsize == sizeof(struct info_monitor) || 2015132451Sroberto itemsize == v4sizeof(struct info_monitor)) { 201654359Sroberto 2017293650Sglebius ml = (const void *)struct_star; 2018285612Sdelphij fprintf(fp, 2019285612Sdelphij " address port count mode ver rstr avgint lstint\n"); 2020285612Sdelphij fprintf(fp, 2021285612Sdelphij "===============================================================================\n"); 202254359Sroberto while (items > 0) { 2023285612Sdelphij SET_ADDR(dstadr, ml->v6_flag, ml->addr, ml->addr6); 2024132451Sroberto if ((pcmd->nargs == 0) || 2025132451Sroberto ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || 2026132451Sroberto ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) 2027285612Sdelphij fprintf(fp, 2028285612Sdelphij "%-25.25s %5u %9lu %4u %2u %9lx %9lu %9lu\n", 2029132451Sroberto nntohost(&dstadr), 2030132451Sroberto ntohs(ml->port), 2031132451Sroberto (u_long)ntohl(ml->count), 2032132451Sroberto ml->mode, 2033132451Sroberto ml->version, 2034285612Sdelphij (u_long)ntohl(ml->restr), 2035285612Sdelphij (u_long)ntohl(ml->avg_int), 2036285612Sdelphij (u_long)ntohl(ml->last_int)); 203754359Sroberto ml++; 203854359Sroberto items--; 203954359Sroberto } 204054359Sroberto } else if (itemsize == sizeof(struct old_info_monitor)) { 2041285612Sdelphij 2042293650Sglebius oml = (const void *)struct_star; 2043285612Sdelphij fprintf(fp, 2044285612Sdelphij " address port count mode version lasttime firsttime\n"); 2045285612Sdelphij fprintf(fp, 2046285612Sdelphij "======================================================================\n"); 204754359Sroberto while (items > 0) { 2048285612Sdelphij SET_ADDR(dstadr, oml->v6_flag, oml->addr, oml->addr6); 2049285612Sdelphij fprintf(fp, "%-20.20s %5u %9lu %4u %3u %9lu %9lu\n", 2050285612Sdelphij nntohost(&dstadr), 2051285612Sdelphij ntohs(oml->port), 2052285612Sdelphij (u_long)ntohl(oml->count), 2053285612Sdelphij oml->mode, 2054285612Sdelphij oml->version, 2055285612Sdelphij (u_long)ntohl(oml->lasttime), 2056285612Sdelphij (u_long)ntohl(oml->firsttime)); 205754359Sroberto oml++; 205854359Sroberto items--; 205954359Sroberto } 206054359Sroberto } else { 206154359Sroberto /* issue warning according to new info_monitor size */ 206254359Sroberto checkitemsize(itemsize, sizeof(struct info_monitor)); 206354359Sroberto } 206454359Sroberto} 206554359Sroberto 206654359Sroberto 206754359Sroberto/* 206854359Sroberto * Mapping between command line strings and stat reset flags 206954359Sroberto */ 207054359Srobertostruct statreset { 2071285612Sdelphij const char * const str; 2072285612Sdelphij const int flag; 207354359Sroberto} sreset[] = { 2074285612Sdelphij { "allpeers", RESET_FLAG_ALLPEERS }, 207554359Sroberto { "io", RESET_FLAG_IO }, 207654359Sroberto { "sys", RESET_FLAG_SYS }, 207754359Sroberto { "mem", RESET_FLAG_MEM }, 207854359Sroberto { "timer", RESET_FLAG_TIMER }, 207954359Sroberto { "auth", RESET_FLAG_AUTH }, 2080285612Sdelphij { "ctl", RESET_FLAG_CTL }, 208154359Sroberto { "", 0 } 208254359Sroberto}; 208354359Sroberto 208454359Sroberto/* 208554359Sroberto * reset - reset statistic counters 208654359Sroberto */ 208754359Srobertostatic void 208854359Srobertoreset( 208954359Sroberto struct parse *pcmd, 209054359Sroberto FILE *fp 209154359Sroberto ) 209254359Sroberto{ 209354359Sroberto struct reset_flags rflags; 2094293650Sglebius size_t items; 2095293650Sglebius size_t itemsize; 2096293650Sglebius const char *dummy; 209754359Sroberto int i; 2098285612Sdelphij size_t res; 209954359Sroberto int err; 210054359Sroberto 210154359Sroberto err = 0; 210254359Sroberto rflags.flags = 0; 210354359Sroberto for (res = 0; res < pcmd->nargs; res++) { 210454359Sroberto for (i = 0; sreset[i].flag != 0; i++) { 210554359Sroberto if (STREQ(pcmd->argval[res].string, sreset[i].str)) 2106285612Sdelphij break; 210754359Sroberto } 210854359Sroberto if (sreset[i].flag == 0) { 2109285612Sdelphij fprintf(fp, "Flag %s unknown\n", 2110285612Sdelphij pcmd->argval[res].string); 2111316722Sdelphij err = 1; 211254359Sroberto } else { 211354359Sroberto rflags.flags |= sreset[i].flag; 211454359Sroberto } 211554359Sroberto } 2116182007Sroberto rflags.flags = htonl(rflags.flags); 211754359Sroberto 211854359Sroberto if (err) { 211954359Sroberto (void) fprintf(fp, "Not done due to errors\n"); 212054359Sroberto return; 212154359Sroberto } 212254359Sroberto 2123132451Srobertoagain: 2124132451Sroberto res = doquery(impl_ver, REQ_RESET_STATS, 1, 1, 212554359Sroberto sizeof(struct reset_flags), (char *)&rflags, &items, 2126132451Sroberto &itemsize, &dummy, 0, sizeof(struct reset_flags)); 212754359Sroberto 2128132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2129132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2130132451Sroberto goto again; 2131132451Sroberto } 2132132451Sroberto 213354359Sroberto if (res == 0) 213454359Sroberto (void) fprintf(fp, "done!\n"); 213554359Sroberto return; 213654359Sroberto} 213754359Sroberto 213854359Sroberto 213954359Sroberto 214054359Sroberto/* 214154359Sroberto * preset - reset stat counters for particular peers 214254359Sroberto */ 214354359Srobertostatic void 214454359Srobertopreset( 214554359Sroberto struct parse *pcmd, 214654359Sroberto FILE *fp 214754359Sroberto ) 214854359Sroberto{ 214954359Sroberto /* 8 is the maximum number of peers which will fit in a packet */ 2150132451Sroberto struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 2151293650Sglebius size_t qitemlim; 2152293650Sglebius size_t qitems; 2153293650Sglebius size_t items; 2154293650Sglebius size_t itemsize; 2155293650Sglebius const char *dummy; 215654359Sroberto int res; 2157293650Sglebius size_t sendsize; 215854359Sroberto 2159132451Srobertoagain: 2160132451Sroberto if (impl_ver == IMPL_XNTPD) 2161132451Sroberto sendsize = sizeof(struct conf_unpeer); 2162132451Sroberto else 2163132451Sroberto sendsize = v4sizeof(struct conf_unpeer); 2164132451Sroberto 2165285612Sdelphij qitemlim = min(pcmd->nargs, COUNTOF(plist)); 2166285612Sdelphij for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 2167285612Sdelphij if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 2168285612Sdelphij pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum); 2169132451Sroberto if (impl_ver == IMPL_XNTPD) 2170132451Sroberto pl->v6_flag = 0; 2171132451Sroberto } else { 2172132451Sroberto if (impl_ver == IMPL_XNTPD_OLD) { 2173132451Sroberto fprintf(stderr, 2174132451Sroberto "***Server doesn't understand IPv6 addresses\n"); 2175132451Sroberto return; 2176132451Sroberto } 2177132451Sroberto pl->peeraddr6 = 2178285612Sdelphij SOCK_ADDR6(&pcmd->argval[qitems].netnum); 2179132451Sroberto pl->v6_flag = 1; 2180132451Sroberto } 2181285612Sdelphij pl = (void *)((char *)pl + sendsize); 218254359Sroberto } 218354359Sroberto 2184132451Sroberto res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems, 2185132451Sroberto sendsize, (char *)plist, &items, 2186132451Sroberto &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 218754359Sroberto 2188132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2189132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2190132451Sroberto goto again; 2191132451Sroberto } 2192132451Sroberto 219354359Sroberto if (res == 0) 219454359Sroberto (void) fprintf(fp, "done!\n"); 219554359Sroberto} 219654359Sroberto 219754359Sroberto 219854359Sroberto/* 219954359Sroberto * readkeys - request the server to reread the keys file 220054359Sroberto */ 220154359Sroberto/*ARGSUSED*/ 220254359Srobertostatic void 220354359Srobertoreadkeys( 220454359Sroberto struct parse *pcmd, 220554359Sroberto FILE *fp 220654359Sroberto ) 220754359Sroberto{ 2208293650Sglebius size_t items; 2209293650Sglebius size_t itemsize; 2210293650Sglebius const char *dummy; 221154359Sroberto int res; 221254359Sroberto 2213132451Srobertoagain: 2214132451Sroberto res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0, 2215132451Sroberto &items, &itemsize, &dummy, 0, sizeof(dummy)); 221654359Sroberto 2217132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2218132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2219132451Sroberto goto again; 2220132451Sroberto } 2221132451Sroberto 222254359Sroberto if (res == 0) 222354359Sroberto (void) fprintf(fp, "done!\n"); 222454359Sroberto return; 222554359Sroberto} 222654359Sroberto 222754359Sroberto 222854359Sroberto/* 222954359Sroberto * trustkey - add some keys to the trusted key list 223054359Sroberto */ 223154359Srobertostatic void 223254359Srobertotrustkey( 223354359Sroberto struct parse *pcmd, 223454359Sroberto FILE *fp 223554359Sroberto ) 223654359Sroberto{ 223754359Sroberto do_trustkey(pcmd, fp, REQ_TRUSTKEY); 223854359Sroberto} 223954359Sroberto 224054359Sroberto 224154359Sroberto/* 224254359Sroberto * untrustkey - remove some keys from the trusted key list 224354359Sroberto */ 224454359Srobertostatic void 224554359Srobertountrustkey( 224654359Sroberto struct parse *pcmd, 224754359Sroberto FILE *fp 224854359Sroberto ) 224954359Sroberto{ 225054359Sroberto do_trustkey(pcmd, fp, REQ_UNTRUSTKEY); 225154359Sroberto} 225254359Sroberto 225354359Sroberto 225454359Sroberto/* 225554359Sroberto * do_trustkey - do grunge work of adding/deleting keys 225654359Sroberto */ 225754359Srobertostatic void 225854359Srobertodo_trustkey( 225954359Sroberto struct parse *pcmd, 226054359Sroberto FILE *fp, 226154359Sroberto int req 226254359Sroberto ) 226354359Sroberto{ 226454359Sroberto u_long keyids[MAXARGS]; 2265285612Sdelphij size_t i; 2266293650Sglebius size_t items; 2267293650Sglebius size_t itemsize; 2268293650Sglebius const char *dummy; 226954359Sroberto int ritems; 227054359Sroberto int res; 227154359Sroberto 227254359Sroberto ritems = 0; 227354359Sroberto for (i = 0; i < pcmd->nargs; i++) { 227454359Sroberto keyids[ritems++] = pcmd->argval[i].uval; 227554359Sroberto } 227654359Sroberto 2277132451Srobertoagain: 2278132451Sroberto res = doquery(impl_ver, req, 1, ritems, sizeof(u_long), 2279132451Sroberto (char *)keyids, &items, &itemsize, &dummy, 0, 2280132451Sroberto sizeof(dummy)); 228154359Sroberto 2282132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2283132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2284132451Sroberto goto again; 2285132451Sroberto } 2286132451Sroberto 228754359Sroberto if (res == 0) 228854359Sroberto (void) fprintf(fp, "done!\n"); 228954359Sroberto return; 229054359Sroberto} 229154359Sroberto 229254359Sroberto 229354359Sroberto 229454359Sroberto/* 229554359Sroberto * authinfo - obtain and print info about authentication 229654359Sroberto */ 229754359Sroberto/*ARGSUSED*/ 229854359Srobertostatic void 229954359Srobertoauthinfo( 230054359Sroberto struct parse *pcmd, 230154359Sroberto FILE *fp 230254359Sroberto ) 230354359Sroberto{ 230454359Sroberto struct info_auth *ia; 2305293650Sglebius size_t items; 2306293650Sglebius size_t itemsize; 230754359Sroberto int res; 230854359Sroberto 2309132451Srobertoagain: 2310285612Sdelphij res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, NULL, &items, 2311285612Sdelphij &itemsize, (void *)&ia, 0, sizeof(*ia)); 231254359Sroberto 2313132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2314132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2315132451Sroberto goto again; 2316132451Sroberto } 2317132451Sroberto 2318182007Sroberto if (res != 0) 2319285612Sdelphij return; 232054359Sroberto 232154359Sroberto if (!check1item(items, fp)) 2322285612Sdelphij return; 232354359Sroberto 2324285612Sdelphij if (!checkitemsize(itemsize, sizeof(*ia))) 2325285612Sdelphij return; 232654359Sroberto 2327285612Sdelphij fprintf(fp, "time since reset: %lu\n", 2328285612Sdelphij (u_long)ntohl(ia->timereset)); 2329285612Sdelphij fprintf(fp, "stored keys: %lu\n", 2330285612Sdelphij (u_long)ntohl(ia->numkeys)); 2331285612Sdelphij fprintf(fp, "free keys: %lu\n", 2332285612Sdelphij (u_long)ntohl(ia->numfreekeys)); 2333285612Sdelphij fprintf(fp, "key lookups: %lu\n", 2334285612Sdelphij (u_long)ntohl(ia->keylookups)); 2335285612Sdelphij fprintf(fp, "keys not found: %lu\n", 2336285612Sdelphij (u_long)ntohl(ia->keynotfound)); 2337285612Sdelphij fprintf(fp, "uncached keys: %lu\n", 2338285612Sdelphij (u_long)ntohl(ia->keyuncached)); 2339285612Sdelphij fprintf(fp, "encryptions: %lu\n", 2340285612Sdelphij (u_long)ntohl(ia->encryptions)); 2341285612Sdelphij fprintf(fp, "decryptions: %lu\n", 2342285612Sdelphij (u_long)ntohl(ia->decryptions)); 2343285612Sdelphij fprintf(fp, "expired keys: %lu\n", 2344285612Sdelphij (u_long)ntohl(ia->expired)); 234554359Sroberto} 234654359Sroberto 234754359Sroberto 234854359Sroberto 234954359Sroberto/* 235054359Sroberto * traps - obtain and print a list of traps 235154359Sroberto */ 235254359Sroberto/*ARGSUSED*/ 235354359Srobertostatic void 235454359Srobertotraps( 235554359Sroberto struct parse *pcmd, 235654359Sroberto FILE *fp 235754359Sroberto ) 235854359Sroberto{ 2359293650Sglebius size_t i; 236054359Sroberto struct info_trap *it; 2361285612Sdelphij sockaddr_u trap_addr, local_addr; 2362293650Sglebius size_t items; 2363293650Sglebius size_t itemsize; 236454359Sroberto int res; 236554359Sroberto 2366132451Srobertoagain: 2367285612Sdelphij res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, NULL, &items, 2368285612Sdelphij &itemsize, (void *)&it, 0, sizeof(*it)); 236954359Sroberto 2370132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2371132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2372132451Sroberto goto again; 2373132451Sroberto } 2374132451Sroberto 2375182007Sroberto if (res != 0) 2376285612Sdelphij return; 237754359Sroberto 237854359Sroberto if (!checkitems(items, fp)) 2379285612Sdelphij return; 238054359Sroberto 2381132451Sroberto if (!checkitemsize(itemsize, sizeof(struct info_trap)) && 2382132451Sroberto !checkitemsize(itemsize, v4sizeof(struct info_trap))) 2383285612Sdelphij return; 238454359Sroberto 238554359Sroberto for (i = 0; i < items; i++ ) { 2386285612Sdelphij SET_ADDRS(trap_addr, local_addr, it, trap_address, local_address); 2387285612Sdelphij fprintf(fp, "%saddress %s, port %d\n", 2388285612Sdelphij (0 == i) 2389285612Sdelphij ? "" 2390285612Sdelphij : "\n", 2391285612Sdelphij stoa(&trap_addr), ntohs(it->trap_port)); 2392285612Sdelphij fprintf(fp, "interface: %s, ", 2393285612Sdelphij (0 == it->local_address) 2394285612Sdelphij ? "wildcard" 2395285612Sdelphij : stoa(&local_addr)); 239654359Sroberto if (ntohl(it->flags) & TRAP_CONFIGURED) 2397285612Sdelphij fprintf(fp, "configured\n"); 239854359Sroberto else if (ntohl(it->flags) & TRAP_NONPRIO) 2399285612Sdelphij fprintf(fp, "low priority\n"); 240054359Sroberto else 2401285612Sdelphij fprintf(fp, "normal priority\n"); 240254359Sroberto 2403285612Sdelphij fprintf(fp, "set for %ld secs, last set %ld secs ago\n", 2404285612Sdelphij (long)ntohl(it->origtime), 2405285612Sdelphij (long)ntohl(it->settime)); 2406285612Sdelphij fprintf(fp, "sequence %d, number of resets %ld\n", 2407285612Sdelphij ntohs(it->sequence), (long)ntohl(it->resets)); 240854359Sroberto } 240954359Sroberto} 241054359Sroberto 241154359Sroberto 241254359Sroberto/* 241354359Sroberto * addtrap - configure a trap 241454359Sroberto */ 241554359Srobertostatic void 241654359Srobertoaddtrap( 241754359Sroberto struct parse *pcmd, 241854359Sroberto FILE *fp 241954359Sroberto ) 242054359Sroberto{ 242154359Sroberto do_addclr_trap(pcmd, fp, REQ_ADD_TRAP); 242254359Sroberto} 242354359Sroberto 242454359Sroberto 242554359Sroberto/* 242654359Sroberto * clrtrap - clear a trap from the server 242754359Sroberto */ 242854359Srobertostatic void 242954359Srobertoclrtrap( 243054359Sroberto struct parse *pcmd, 243154359Sroberto FILE *fp 243254359Sroberto ) 243354359Sroberto{ 243454359Sroberto do_addclr_trap(pcmd, fp, REQ_CLR_TRAP); 243554359Sroberto} 243654359Sroberto 243754359Sroberto 243854359Sroberto/* 243954359Sroberto * do_addclr_trap - do grunge work of adding/deleting traps 244054359Sroberto */ 244154359Srobertostatic void 244254359Srobertodo_addclr_trap( 244354359Sroberto struct parse *pcmd, 244454359Sroberto FILE *fp, 244554359Sroberto int req 244654359Sroberto ) 244754359Sroberto{ 244854359Sroberto struct conf_trap ctrap; 2449293650Sglebius size_t items; 2450293650Sglebius size_t itemsize; 2451293650Sglebius const char *dummy; 245254359Sroberto int res; 2453132451Sroberto int sendsize; 245454359Sroberto 2455132451Srobertoagain: 2456132451Sroberto if (impl_ver == IMPL_XNTPD) 2457132451Sroberto sendsize = sizeof(struct conf_trap); 2458132451Sroberto else 2459132451Sroberto sendsize = v4sizeof(struct conf_trap); 2460132451Sroberto 2461285612Sdelphij if (IS_IPV4(&pcmd->argval[0].netnum)) { 2462285612Sdelphij ctrap.trap_address = NSRCADR(&pcmd->argval[0].netnum); 2463132451Sroberto if (impl_ver == IMPL_XNTPD) 2464132451Sroberto ctrap.v6_flag = 0; 2465132451Sroberto } else { 2466132451Sroberto if (impl_ver == IMPL_XNTPD_OLD) { 2467132451Sroberto fprintf(stderr, 2468132451Sroberto "***Server doesn't understand IPv6 addresses\n"); 2469132451Sroberto return; 2470132451Sroberto } 2471285612Sdelphij ctrap.trap_address6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 2472132451Sroberto ctrap.v6_flag = 1; 2473132451Sroberto } 247454359Sroberto ctrap.local_address = 0; 247554359Sroberto ctrap.trap_port = htons(TRAPPORT); 247654359Sroberto ctrap.unused = 0; 247754359Sroberto 247854359Sroberto if (pcmd->nargs > 1) { 2479285612Sdelphij ctrap.trap_port = htons((u_short)pcmd->argval[1].uval); 2480132451Sroberto if (pcmd->nargs > 2) { 2481285612Sdelphij if (AF(&pcmd->argval[2].netnum) != 2482285612Sdelphij AF(&pcmd->argval[0].netnum)) { 2483132451Sroberto fprintf(stderr, 2484132451Sroberto "***Cannot mix IPv4 and IPv6 addresses\n"); 2485132451Sroberto return; 2486132451Sroberto } 2487285612Sdelphij if (IS_IPV4(&pcmd->argval[2].netnum)) 2488285612Sdelphij ctrap.local_address = NSRCADR(&pcmd->argval[2].netnum); 2489132451Sroberto else 2490285612Sdelphij ctrap.local_address6 = SOCK_ADDR6(&pcmd->argval[2].netnum); 2491132451Sroberto } 249254359Sroberto } 249354359Sroberto 2494132451Sroberto res = doquery(impl_ver, req, 1, 1, sendsize, 2495132451Sroberto (char *)&ctrap, &items, &itemsize, &dummy, 0, 2496132451Sroberto sizeof(struct conf_trap)); 249754359Sroberto 2498132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2499132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2500132451Sroberto goto again; 2501132451Sroberto } 2502132451Sroberto 250354359Sroberto if (res == 0) 250454359Sroberto (void) fprintf(fp, "done!\n"); 250554359Sroberto return; 250654359Sroberto} 250754359Sroberto 250854359Sroberto 250954359Sroberto 251054359Sroberto/* 251154359Sroberto * requestkey - change the server's request key (a dangerous request) 251254359Sroberto */ 251354359Srobertostatic void 251454359Srobertorequestkey( 251554359Sroberto struct parse *pcmd, 251654359Sroberto FILE *fp 251754359Sroberto ) 251854359Sroberto{ 251954359Sroberto do_changekey(pcmd, fp, REQ_REQUEST_KEY); 252054359Sroberto} 252154359Sroberto 252254359Sroberto 252354359Sroberto/* 252454359Sroberto * controlkey - change the server's control key 252554359Sroberto */ 252654359Srobertostatic void 252754359Srobertocontrolkey( 252854359Sroberto struct parse *pcmd, 252954359Sroberto FILE *fp 253054359Sroberto ) 253154359Sroberto{ 253254359Sroberto do_changekey(pcmd, fp, REQ_CONTROL_KEY); 253354359Sroberto} 253454359Sroberto 253554359Sroberto 253654359Sroberto 253754359Sroberto/* 253854359Sroberto * do_changekey - do grunge work of changing keys 253954359Sroberto */ 254054359Srobertostatic void 254154359Srobertodo_changekey( 254254359Sroberto struct parse *pcmd, 254354359Sroberto FILE *fp, 254454359Sroberto int req 254554359Sroberto ) 254654359Sroberto{ 254754359Sroberto u_long key; 2548293650Sglebius size_t items; 2549293650Sglebius size_t itemsize; 2550293650Sglebius const char *dummy; 255154359Sroberto int res; 255254359Sroberto 255354359Sroberto 255454359Sroberto key = htonl((u_int32)pcmd->argval[0].uval); 255554359Sroberto 2556132451Srobertoagain: 2557132451Sroberto res = doquery(impl_ver, req, 1, 1, sizeof(u_int32), 2558132451Sroberto (char *)&key, &items, &itemsize, &dummy, 0, 2559132451Sroberto sizeof(dummy)); 256054359Sroberto 2561132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2562132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2563132451Sroberto goto again; 2564132451Sroberto } 2565132451Sroberto 256654359Sroberto if (res == 0) 256754359Sroberto (void) fprintf(fp, "done!\n"); 256854359Sroberto return; 256954359Sroberto} 257054359Sroberto 257154359Sroberto 257254359Sroberto 257354359Sroberto/* 257454359Sroberto * ctlstats - obtain and print info about authentication 257554359Sroberto */ 257654359Sroberto/*ARGSUSED*/ 257754359Srobertostatic void 257854359Srobertoctlstats( 257954359Sroberto struct parse *pcmd, 258054359Sroberto FILE *fp 258154359Sroberto ) 258254359Sroberto{ 258354359Sroberto struct info_control *ic; 2584293650Sglebius size_t items; 2585293650Sglebius size_t itemsize; 258654359Sroberto int res; 258754359Sroberto 2588132451Srobertoagain: 2589285612Sdelphij res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, NULL, &items, 2590285612Sdelphij &itemsize, (void *)&ic, 0, sizeof(*ic)); 259154359Sroberto 2592132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2593132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2594132451Sroberto goto again; 2595132451Sroberto } 2596132451Sroberto 2597182007Sroberto if (res != 0) 2598285612Sdelphij return; 259954359Sroberto 260054359Sroberto if (!check1item(items, fp)) 2601285612Sdelphij return; 260254359Sroberto 2603285612Sdelphij if (!checkitemsize(itemsize, sizeof(*ic))) 2604285612Sdelphij return; 260554359Sroberto 2606285612Sdelphij fprintf(fp, "time since reset: %lu\n", 2607285612Sdelphij (u_long)ntohl(ic->ctltimereset)); 2608285612Sdelphij fprintf(fp, "requests received: %lu\n", 2609285612Sdelphij (u_long)ntohl(ic->numctlreq)); 2610285612Sdelphij fprintf(fp, "responses sent: %lu\n", 2611285612Sdelphij (u_long)ntohl(ic->numctlresponses)); 2612285612Sdelphij fprintf(fp, "fragments sent: %lu\n", 2613285612Sdelphij (u_long)ntohl(ic->numctlfrags)); 2614285612Sdelphij fprintf(fp, "async messages sent: %lu\n", 2615285612Sdelphij (u_long)ntohl(ic->numasyncmsgs)); 2616285612Sdelphij fprintf(fp, "error msgs sent: %lu\n", 2617285612Sdelphij (u_long)ntohl(ic->numctlerrors)); 2618285612Sdelphij fprintf(fp, "total bad pkts: %lu\n", 2619285612Sdelphij (u_long)ntohl(ic->numctlbadpkts)); 2620285612Sdelphij fprintf(fp, "packet too short: %lu\n", 2621285612Sdelphij (u_long)ntohl(ic->numctltooshort)); 2622285612Sdelphij fprintf(fp, "response on input: %lu\n", 2623285612Sdelphij (u_long)ntohl(ic->numctlinputresp)); 2624285612Sdelphij fprintf(fp, "fragment on input: %lu\n", 2625285612Sdelphij (u_long)ntohl(ic->numctlinputfrag)); 2626285612Sdelphij fprintf(fp, "error set on input: %lu\n", 2627285612Sdelphij (u_long)ntohl(ic->numctlinputerr)); 2628285612Sdelphij fprintf(fp, "bad offset on input: %lu\n", 2629285612Sdelphij (u_long)ntohl(ic->numctlbadoffset)); 2630285612Sdelphij fprintf(fp, "bad version packets: %lu\n", 2631285612Sdelphij (u_long)ntohl(ic->numctlbadversion)); 2632285612Sdelphij fprintf(fp, "data in pkt too short: %lu\n", 2633285612Sdelphij (u_long)ntohl(ic->numctldatatooshort)); 2634285612Sdelphij fprintf(fp, "unknown op codes: %lu\n", 2635285612Sdelphij (u_long)ntohl(ic->numctlbadop)); 263654359Sroberto} 263754359Sroberto 263854359Sroberto 263954359Sroberto/* 264054359Sroberto * clockstat - get and print clock status information 264154359Sroberto */ 264254359Srobertostatic void 264354359Srobertoclockstat( 264454359Sroberto struct parse *pcmd, 264554359Sroberto FILE *fp 264654359Sroberto ) 264754359Sroberto{ 264854359Sroberto struct info_clock *cl; 264954359Sroberto /* 8 is the maximum number of clocks which will fit in a packet */ 265054359Sroberto u_long clist[min(MAXARGS, 8)]; 2651293650Sglebius size_t qitemlim; 2652293650Sglebius size_t qitems; 2653293650Sglebius size_t items; 2654293650Sglebius size_t itemsize; 265554359Sroberto int res; 265654359Sroberto l_fp ts; 265754359Sroberto struct clktype *clk; 265854359Sroberto 2659285612Sdelphij qitemlim = min(pcmd->nargs, COUNTOF(clist)); 2660285612Sdelphij for (qitems = 0; qitems < qitemlim; qitems++) 2661285612Sdelphij clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum); 266254359Sroberto 2663132451Srobertoagain: 2664132451Sroberto res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems, 266554359Sroberto sizeof(u_int32), (char *)clist, &items, 2666132451Sroberto &itemsize, (void *)&cl, 0, sizeof(struct info_clock)); 266754359Sroberto 2668132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2669132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2670132451Sroberto goto again; 2671132451Sroberto } 2672132451Sroberto 2673182007Sroberto if (res != 0) 2674285612Sdelphij return; 267554359Sroberto 267654359Sroberto if (!checkitems(items, fp)) 2677285612Sdelphij return; 267854359Sroberto 267954359Sroberto if (!checkitemsize(itemsize, sizeof(struct info_clock))) 2680285612Sdelphij return; 268154359Sroberto 268254359Sroberto while (items-- > 0) { 268354359Sroberto (void) fprintf(fp, "clock address: %s\n", 268454359Sroberto numtoa(cl->clockadr)); 268554359Sroberto for (clk = clktypes; clk->code >= 0; clk++) 268654359Sroberto if (clk->code == cl->type) 268754359Sroberto break; 268854359Sroberto if (clk->code >= 0) 268954359Sroberto (void) fprintf(fp, "clock type: %s\n", 269054359Sroberto clk->clocktype); 269154359Sroberto else 269254359Sroberto (void) fprintf(fp, "clock type: unknown type (%d)\n", 269354359Sroberto cl->type); 269454359Sroberto (void) fprintf(fp, "last event: %d\n", 269554359Sroberto cl->lastevent); 269654359Sroberto (void) fprintf(fp, "current status: %d\n", 269754359Sroberto cl->currentstatus); 269854359Sroberto (void) fprintf(fp, "number of polls: %lu\n", 269954359Sroberto (u_long)ntohl(cl->polls)); 270054359Sroberto (void) fprintf(fp, "no response to poll: %lu\n", 270154359Sroberto (u_long)ntohl(cl->noresponse)); 270254359Sroberto (void) fprintf(fp, "bad format responses: %lu\n", 270354359Sroberto (u_long)ntohl(cl->badformat)); 270454359Sroberto (void) fprintf(fp, "bad data responses: %lu\n", 270554359Sroberto (u_long)ntohl(cl->baddata)); 270654359Sroberto (void) fprintf(fp, "running time: %lu\n", 270754359Sroberto (u_long)ntohl(cl->timestarted)); 270854359Sroberto NTOHL_FP(&cl->fudgetime1, &ts); 270954359Sroberto (void) fprintf(fp, "fudge time 1: %s\n", 271054359Sroberto lfptoa(&ts, 6)); 271154359Sroberto NTOHL_FP(&cl->fudgetime2, &ts); 271254359Sroberto (void) fprintf(fp, "fudge time 2: %s\n", 271354359Sroberto lfptoa(&ts, 6)); 271454359Sroberto (void) fprintf(fp, "stratum: %ld\n", 271554359Sroberto (u_long)ntohl(cl->fudgeval1)); 271654359Sroberto (void) fprintf(fp, "reference ID: %s\n", 2717182007Sroberto refid_string(ntohl(cl->fudgeval2), 0)); 271854359Sroberto (void) fprintf(fp, "fudge flags: 0x%x\n", 271954359Sroberto cl->flags); 272054359Sroberto 272154359Sroberto if (items > 0) 272254359Sroberto (void) fprintf(fp, "\n"); 272354359Sroberto cl++; 272454359Sroberto } 272554359Sroberto} 272654359Sroberto 272754359Sroberto 272854359Sroberto/* 272954359Sroberto * fudge - set clock fudge factors 273054359Sroberto */ 273154359Srobertostatic void 273254359Srobertofudge( 273354359Sroberto struct parse *pcmd, 273454359Sroberto FILE *fp 273554359Sroberto ) 273654359Sroberto{ 273754359Sroberto struct conf_fudge fudgedata; 2738293650Sglebius size_t items; 2739293650Sglebius size_t itemsize; 2740293650Sglebius const char *dummy; 274154359Sroberto l_fp ts; 274254359Sroberto int res; 274354359Sroberto long val; 274454359Sroberto u_long u_val; 274554359Sroberto int err; 274654359Sroberto 274754359Sroberto 274854359Sroberto err = 0; 2749285612Sdelphij ZERO(fudgedata); 2750285612Sdelphij fudgedata.clockadr = NSRCADR(&pcmd->argval[0].netnum); 275154359Sroberto 275254359Sroberto if (STREQ(pcmd->argval[1].string, "time1")) { 275354359Sroberto fudgedata.which = htonl(FUDGE_TIME1); 275454359Sroberto if (!atolfp(pcmd->argval[2].string, &ts)) 275554359Sroberto err = 1; 275654359Sroberto else 275754359Sroberto NTOHL_FP(&ts, &fudgedata.fudgetime); 275854359Sroberto } else if (STREQ(pcmd->argval[1].string, "time2")) { 275954359Sroberto fudgedata.which = htonl(FUDGE_TIME2); 276054359Sroberto if (!atolfp(pcmd->argval[2].string, &ts)) 276154359Sroberto err = 1; 276254359Sroberto else 276354359Sroberto NTOHL_FP(&ts, &fudgedata.fudgetime); 276454359Sroberto } else if (STREQ(pcmd->argval[1].string, "val1")) { 276554359Sroberto fudgedata.which = htonl(FUDGE_VAL1); 276654359Sroberto if (!atoint(pcmd->argval[2].string, &val)) 276754359Sroberto err = 1; 276854359Sroberto else 276954359Sroberto fudgedata.fudgeval_flags = htonl(val); 277054359Sroberto } else if (STREQ(pcmd->argval[1].string, "val2")) { 277154359Sroberto fudgedata.which = htonl(FUDGE_VAL2); 277254359Sroberto if (!atoint(pcmd->argval[2].string, &val)) 277354359Sroberto err = 1; 277454359Sroberto else 277554359Sroberto fudgedata.fudgeval_flags = htonl((u_int32)val); 277654359Sroberto } else if (STREQ(pcmd->argval[1].string, "flags")) { 277754359Sroberto fudgedata.which = htonl(FUDGE_FLAGS); 277854359Sroberto if (!hextoint(pcmd->argval[2].string, &u_val)) 277954359Sroberto err = 1; 278054359Sroberto else 278154359Sroberto fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf)); 278254359Sroberto } else { 278354359Sroberto (void) fprintf(stderr, "What fudge is %s?\n", 278454359Sroberto pcmd->argval[1].string); 278554359Sroberto return; 278654359Sroberto } 278754359Sroberto 278854359Sroberto if (err) { 278954359Sroberto (void) fprintf(stderr, "Unknown fudge parameter %s\n", 279054359Sroberto pcmd->argval[2].string); 279154359Sroberto return; 279254359Sroberto } 279354359Sroberto 2794132451Srobertoagain: 2795132451Sroberto res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1, 279654359Sroberto sizeof(struct conf_fudge), (char *)&fudgedata, &items, 2797132451Sroberto &itemsize, &dummy, 0, sizeof(dummy)); 279854359Sroberto 2799132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2800132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2801132451Sroberto goto again; 2802132451Sroberto } 2803132451Sroberto 280454359Sroberto if (res == 0) 280554359Sroberto (void) fprintf(fp, "done!\n"); 280654359Sroberto return; 280754359Sroberto} 280854359Sroberto 280954359Sroberto/* 281054359Sroberto * clkbug - get and print clock debugging information 281154359Sroberto */ 281254359Srobertostatic void 281354359Srobertoclkbug( 281454359Sroberto struct parse *pcmd, 281554359Sroberto FILE *fp 281654359Sroberto ) 281754359Sroberto{ 281854359Sroberto register int i; 281954359Sroberto register int n; 282054359Sroberto register u_int32 s; 282154359Sroberto struct info_clkbug *cl; 282254359Sroberto /* 8 is the maximum number of clocks which will fit in a packet */ 282354359Sroberto u_long clist[min(MAXARGS, 8)]; 282454359Sroberto u_int32 ltemp; 2825293650Sglebius size_t qitemlim; 2826293650Sglebius size_t qitems; 2827293650Sglebius size_t items; 2828293650Sglebius size_t itemsize; 282954359Sroberto int res; 283054359Sroberto int needsp; 283154359Sroberto l_fp ts; 283254359Sroberto 2833285612Sdelphij qitemlim = min(pcmd->nargs, COUNTOF(clist)); 2834285612Sdelphij for (qitems = 0; qitems < qitemlim; qitems++) 2835285612Sdelphij clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum); 283654359Sroberto 2837132451Srobertoagain: 2838132451Sroberto res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems, 283954359Sroberto sizeof(u_int32), (char *)clist, &items, 2840132451Sroberto &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug)); 284154359Sroberto 2842132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2843132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2844132451Sroberto goto again; 2845132451Sroberto } 2846132451Sroberto 2847182007Sroberto if (res != 0) 2848285612Sdelphij return; 284954359Sroberto 285054359Sroberto if (!checkitems(items, fp)) 2851285612Sdelphij return; 285254359Sroberto 285354359Sroberto if (!checkitemsize(itemsize, sizeof(struct info_clkbug))) 2854285612Sdelphij return; 285554359Sroberto 285654359Sroberto while (items-- > 0) { 285754359Sroberto (void) fprintf(fp, "clock address: %s\n", 285854359Sroberto numtoa(cl->clockadr)); 285954359Sroberto n = (int)cl->nvalues; 286054359Sroberto (void) fprintf(fp, "values: %d", n); 286154359Sroberto s = ntohs(cl->svalues); 286254359Sroberto if (n > NUMCBUGVALUES) 286354359Sroberto n = NUMCBUGVALUES; 286454359Sroberto for (i = 0; i < n; i++) { 286554359Sroberto ltemp = ntohl(cl->values[i]); 286654359Sroberto ltemp &= 0xffffffff; /* HMS: This does nothing now */ 286754359Sroberto if ((i & 0x3) == 0) 286854359Sroberto (void) fprintf(fp, "\n"); 286954359Sroberto if (s & (1 << i)) 287054359Sroberto (void) fprintf(fp, "%12ld", (u_long)ltemp); 287154359Sroberto else 287254359Sroberto (void) fprintf(fp, "%12lu", (u_long)ltemp); 287354359Sroberto } 287454359Sroberto (void) fprintf(fp, "\n"); 287554359Sroberto 287654359Sroberto n = (int)cl->ntimes; 287754359Sroberto (void) fprintf(fp, "times: %d", n); 287854359Sroberto s = ntohl(cl->stimes); 287954359Sroberto if (n > NUMCBUGTIMES) 288054359Sroberto n = NUMCBUGTIMES; 288154359Sroberto needsp = 0; 288254359Sroberto for (i = 0; i < n; i++) { 288354359Sroberto if ((i & 0x1) == 0) { 288454359Sroberto (void) fprintf(fp, "\n"); 288554359Sroberto } else { 288654359Sroberto for (;needsp > 0; needsp--) 288754359Sroberto putc(' ', fp); 288854359Sroberto } 288954359Sroberto NTOHL_FP(&cl->times[i], &ts); 289054359Sroberto if (s & (1 << i)) { 289154359Sroberto (void) fprintf(fp, "%17s", 289254359Sroberto lfptoa(&ts, 6)); 289354359Sroberto needsp = 22; 289454359Sroberto } else { 289554359Sroberto (void) fprintf(fp, "%37s", 289654359Sroberto uglydate(&ts)); 289754359Sroberto needsp = 2; 289854359Sroberto } 289954359Sroberto } 290054359Sroberto (void) fprintf(fp, "\n"); 290154359Sroberto if (items > 0) { 290254359Sroberto cl++; 290354359Sroberto (void) fprintf(fp, "\n"); 290454359Sroberto } 290554359Sroberto } 290654359Sroberto} 290754359Sroberto 290854359Sroberto 290954359Sroberto/* 291054359Sroberto * kerninfo - display the kernel pll/pps variables 291154359Sroberto */ 291254359Srobertostatic void 291354359Srobertokerninfo( 291454359Sroberto struct parse *pcmd, 291554359Sroberto FILE *fp 291654359Sroberto ) 291754359Sroberto{ 291854359Sroberto struct info_kernel *ik; 2919293650Sglebius size_t items; 2920293650Sglebius size_t itemsize; 292154359Sroberto int res; 292254359Sroberto unsigned status; 292354359Sroberto double tscale = 1e-6; 292454359Sroberto 2925132451Srobertoagain: 2926132451Sroberto res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL, 2927132451Sroberto &items, &itemsize, (void *)&ik, 0, 2928132451Sroberto sizeof(struct info_kernel)); 2929132451Sroberto 2930132451Sroberto if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 2931132451Sroberto impl_ver = IMPL_XNTPD_OLD; 2932132451Sroberto goto again; 2933132451Sroberto } 2934132451Sroberto 2935182007Sroberto if (res != 0) 293654359Sroberto return; 293754359Sroberto if (!check1item(items, fp)) 293854359Sroberto return; 293954359Sroberto if (!checkitemsize(itemsize, sizeof(struct info_kernel))) 294054359Sroberto return; 294154359Sroberto 294254359Sroberto status = ntohs(ik->status) & 0xffff; 294354359Sroberto /* 294454359Sroberto * pll variables. We know more than we should about the NANO bit. 294554359Sroberto */ 294654359Sroberto#ifdef STA_NANO 294754359Sroberto if (status & STA_NANO) 294854359Sroberto tscale = 1e-9; 294954359Sroberto#endif 295054359Sroberto (void)fprintf(fp, "pll offset: %g s\n", 2951285612Sdelphij (int32)ntohl(ik->offset) * tscale); 295254359Sroberto (void)fprintf(fp, "pll frequency: %s ppm\n", 295354359Sroberto fptoa((s_fp)ntohl(ik->freq), 3)); 295454359Sroberto (void)fprintf(fp, "maximum error: %g s\n", 2955285612Sdelphij (u_long)ntohl(ik->maxerror) * tscale); 295654359Sroberto (void)fprintf(fp, "estimated error: %g s\n", 2957285612Sdelphij (u_long)ntohl(ik->esterror) * tscale); 295854359Sroberto (void)fprintf(fp, "status: %04x ", status); 295954359Sroberto#ifdef STA_PLL 296054359Sroberto if (status & STA_PLL) (void)fprintf(fp, " pll"); 296154359Sroberto#endif 296254359Sroberto#ifdef STA_PPSFREQ 296354359Sroberto if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq"); 296454359Sroberto#endif 296554359Sroberto#ifdef STA_PPSTIME 296654359Sroberto if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime"); 296754359Sroberto#endif 296854359Sroberto#ifdef STA_FLL 296954359Sroberto if (status & STA_FLL) (void)fprintf(fp, " fll"); 297054359Sroberto#endif 297154359Sroberto#ifdef STA_INS 297254359Sroberto if (status & STA_INS) (void)fprintf(fp, " ins"); 297354359Sroberto#endif 297454359Sroberto#ifdef STA_DEL 297554359Sroberto if (status & STA_DEL) (void)fprintf(fp, " del"); 297654359Sroberto#endif 297754359Sroberto#ifdef STA_UNSYNC 297854359Sroberto if (status & STA_UNSYNC) (void)fprintf(fp, " unsync"); 297954359Sroberto#endif 298054359Sroberto#ifdef STA_FREQHOLD 298154359Sroberto if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold"); 298254359Sroberto#endif 298354359Sroberto#ifdef STA_PPSSIGNAL 298454359Sroberto if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal"); 298554359Sroberto#endif 298654359Sroberto#ifdef STA_PPSJITTER 298754359Sroberto if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter"); 298854359Sroberto#endif 298954359Sroberto#ifdef STA_PPSWANDER 299054359Sroberto if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander"); 299154359Sroberto#endif 299254359Sroberto#ifdef STA_PPSERROR 299354359Sroberto if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror"); 299454359Sroberto#endif 299554359Sroberto#ifdef STA_CLOCKERR 299654359Sroberto if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr"); 299754359Sroberto#endif 299854359Sroberto#ifdef STA_NANO 299954359Sroberto if (status & STA_NANO) (void)fprintf(fp, " nano"); 300054359Sroberto#endif 300154359Sroberto#ifdef STA_MODE 300254359Sroberto if (status & STA_MODE) (void)fprintf(fp, " mode=fll"); 300354359Sroberto#endif 300454359Sroberto#ifdef STA_CLK 300554359Sroberto if (status & STA_CLK) (void)fprintf(fp, " src=B"); 300654359Sroberto#endif 300754359Sroberto (void)fprintf(fp, "\n"); 300854359Sroberto (void)fprintf(fp, "pll time constant: %ld\n", 300954359Sroberto (u_long)ntohl(ik->constant)); 301054359Sroberto (void)fprintf(fp, "precision: %g s\n", 301154359Sroberto (u_long)ntohl(ik->precision) * tscale); 301254359Sroberto (void)fprintf(fp, "frequency tolerance: %s ppm\n", 301354359Sroberto fptoa((s_fp)ntohl(ik->tolerance), 0)); 301454359Sroberto 301554359Sroberto /* 301654359Sroberto * For backwards compatibility (ugh), we find the pps variables 301754359Sroberto * only if the shift member is nonzero. 301854359Sroberto */ 301954359Sroberto if (!ik->shift) 302054359Sroberto return; 302154359Sroberto 302254359Sroberto /* 302354359Sroberto * pps variables 302454359Sroberto */ 302554359Sroberto (void)fprintf(fp, "pps frequency: %s ppm\n", 302654359Sroberto fptoa((s_fp)ntohl(ik->ppsfreq), 3)); 302754359Sroberto (void)fprintf(fp, "pps stability: %s ppm\n", 302854359Sroberto fptoa((s_fp)ntohl(ik->stabil), 3)); 302954359Sroberto (void)fprintf(fp, "pps jitter: %g s\n", 303054359Sroberto (u_long)ntohl(ik->jitter) * tscale); 303154359Sroberto (void)fprintf(fp, "calibration interval: %d s\n", 303254359Sroberto 1 << ntohs(ik->shift)); 303354359Sroberto (void)fprintf(fp, "calibration cycles: %ld\n", 303454359Sroberto (u_long)ntohl(ik->calcnt)); 303554359Sroberto (void)fprintf(fp, "jitter exceeded: %ld\n", 303654359Sroberto (u_long)ntohl(ik->jitcnt)); 303754359Sroberto (void)fprintf(fp, "stability exceeded: %ld\n", 303854359Sroberto (u_long)ntohl(ik->stbcnt)); 303954359Sroberto (void)fprintf(fp, "calibration errors: %ld\n", 304054359Sroberto (u_long)ntohl(ik->errcnt)); 304154359Sroberto} 3042182007Sroberto 3043285612Sdelphij#define IF_LIST_FMT "%2d %c %48s %c %c %12.12s %03lx %3lu %2lu %5lu %5lu %5lu %2lu %3lu %7lu\n" 3044285612Sdelphij#define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %3s %7s\n" 3045182007Sroberto#define IF_LIST_AFMT_STR " %48s %c\n" 3046285612Sdelphij#define IF_LIST_LABELS "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "PC", "uptime" 3047285612Sdelphij#define IF_LIST_LINE "==================================================================================================================\n" 3048182007Sroberto 3049182007Srobertostatic void 3050182007Srobertoiflist( 3051182007Sroberto FILE *fp, 3052182007Sroberto struct info_if_stats *ifs, 3053293650Sglebius size_t items, 3054293650Sglebius size_t itemsize, 3055182007Sroberto int res 3056182007Sroberto ) 3057182007Sroberto{ 3058285612Sdelphij static const char *actions = "?.+-"; 3059285612Sdelphij sockaddr_u saddr; 3060182007Sroberto 3061182007Sroberto if (res != 0) 3062182007Sroberto return; 3063182007Sroberto 3064182007Sroberto if (!checkitems(items, fp)) 3065182007Sroberto return; 3066182007Sroberto 3067182007Sroberto if (!checkitemsize(itemsize, sizeof(struct info_if_stats))) 3068182007Sroberto return; 3069182007Sroberto 3070182007Sroberto fprintf(fp, IF_LIST_FMT_STR, IF_LIST_LABELS); 3071182007Sroberto fprintf(fp, IF_LIST_LINE); 3072182007Sroberto 3073182007Sroberto while (items > 0) { 3074285612Sdelphij SET_ADDR(saddr, ntohl(ifs->v6_flag), 3075285612Sdelphij ifs->unaddr.addr.s_addr, ifs->unaddr.addr6); 3076182007Sroberto fprintf(fp, IF_LIST_FMT, 3077182007Sroberto ntohl(ifs->ifnum), 3078182007Sroberto actions[(ifs->action >= 1 && ifs->action < 4) ? ifs->action : 0], 3079182007Sroberto stoa((&saddr)), 'A', 3080182007Sroberto ifs->ignore_packets ? 'D' : 'E', 3081182007Sroberto ifs->name, 3082285612Sdelphij (u_long)ntohl(ifs->flags), 3083285612Sdelphij (u_long)ntohl(ifs->last_ttl), 3084285612Sdelphij (u_long)ntohl(ifs->num_mcast), 3085285612Sdelphij (u_long)ntohl(ifs->received), 3086285612Sdelphij (u_long)ntohl(ifs->sent), 3087285612Sdelphij (u_long)ntohl(ifs->notsent), 3088285612Sdelphij (u_long)ntohl(ifs->scopeid), 3089285612Sdelphij (u_long)ntohl(ifs->peercnt), 3090285612Sdelphij (u_long)ntohl(ifs->uptime)); 3091182007Sroberto 3092285612Sdelphij SET_ADDR(saddr, ntohl(ifs->v6_flag), 3093285612Sdelphij ifs->unmask.addr.s_addr, ifs->unmask.addr6); 3094182007Sroberto fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'M'); 3095182007Sroberto 3096182007Sroberto if (!ntohl(ifs->v6_flag) && ntohl(ifs->flags) & (INT_BCASTOPEN)) { 3097285612Sdelphij SET_ADDR(saddr, ntohl(ifs->v6_flag), 3098285612Sdelphij ifs->unbcast.addr.s_addr, ifs->unbcast.addr6); 3099182007Sroberto fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'B'); 3100182007Sroberto 3101182007Sroberto } 3102182007Sroberto 3103182007Sroberto ifs++; 3104182007Sroberto items--; 3105182007Sroberto } 3106182007Sroberto} 3107182007Sroberto 3108182007Sroberto/*ARGSUSED*/ 3109182007Srobertostatic void 3110182007Srobertoget_if_stats( 3111182007Sroberto struct parse *pcmd, 3112182007Sroberto FILE *fp 3113182007Sroberto ) 3114182007Sroberto{ 3115182007Sroberto struct info_if_stats *ifs; 3116293650Sglebius size_t items; 3117293650Sglebius size_t itemsize; 3118182007Sroberto int res; 3119182007Sroberto 3120182007Sroberto res = doquery(impl_ver, REQ_IF_STATS, 1, 0, 0, (char *)NULL, &items, 3121182007Sroberto &itemsize, (void *)&ifs, 0, 3122182007Sroberto sizeof(struct info_if_stats)); 3123182007Sroberto iflist(fp, ifs, items, itemsize, res); 3124182007Sroberto} 3125182007Sroberto 3126182007Sroberto/*ARGSUSED*/ 3127182007Srobertostatic void 3128182007Srobertodo_if_reload( 3129182007Sroberto struct parse *pcmd, 3130182007Sroberto FILE *fp 3131182007Sroberto ) 3132182007Sroberto{ 3133182007Sroberto struct info_if_stats *ifs; 3134293650Sglebius size_t items; 3135293650Sglebius size_t itemsize; 3136182007Sroberto int res; 3137182007Sroberto 3138182007Sroberto res = doquery(impl_ver, REQ_IF_RELOAD, 1, 0, 0, (char *)NULL, &items, 3139182007Sroberto &itemsize, (void *)&ifs, 0, 3140182007Sroberto sizeof(struct info_if_stats)); 3141182007Sroberto iflist(fp, ifs, items, itemsize, res); 3142182007Sroberto} 3143