1 /* 2 * ntpdc_ops.c - subroutines which are called to perform operations by ntpdc 3 */ 4 5 #ifdef HAVE_CONFIG_H 6 # include <config.h> 7 #endif 8 9 #include <stdio.h> 10 11 #include "ntpdc.h" 12 #include "ntp_control.h" 13 #include "ntp_refclock.h" 14 #include "ntp_stdlib.h" 15 16 #include <ctype.h> 17 #ifdef HAVE_SYS_TIMEX_H 18 # include <sys/timex.h> 19 #endif 20 #include <netdb.h> 21 #if !defined(__bsdi__) && !defined(apollo) 22 #include <netinet/in.h> 23 #endif 24 25 #include <arpa/inet.h> 26 27 /* 28 * Declarations for command handlers in here 29 */ 30 static int checkitems P((int, FILE *)); 31 static int checkitemsize P((int, int)); 32 static int check1item P((int, FILE *)); 33 static void peerlist P((struct parse *, FILE *)); 34 static void peers P((struct parse *, FILE *)); 35 static void doconfig P((struct parse *pcmd, FILE *fp, int mode, int refc)); 36 static void dmpeers P((struct parse *, FILE *)); 37 static void dopeers P((struct parse *, FILE *, int)); 38 static void printpeer P((struct info_peer *, FILE *)); 39 static void showpeer P((struct parse *, FILE *)); 40 static void peerstats P((struct parse *, FILE *)); 41 static void loopinfo P((struct parse *, FILE *)); 42 static void sysinfo P((struct parse *, FILE *)); 43 static void sysstats P((struct parse *, FILE *)); 44 static void iostats P((struct parse *, FILE *)); 45 static void memstats P((struct parse *, FILE *)); 46 static void timerstats P((struct parse *, FILE *)); 47 static void addpeer P((struct parse *, FILE *)); 48 static void addserver P((struct parse *, FILE *)); 49 static void addrefclock P((struct parse *, FILE *)); 50 static void broadcast P((struct parse *, FILE *)); 51 static void doconfig P((struct parse *, FILE *, int, int)); 52 static void unconfig P((struct parse *, FILE *)); 53 static void set P((struct parse *, FILE *)); 54 static void sys_clear P((struct parse *, FILE *)); 55 static void doset P((struct parse *, FILE *, int)); 56 static void reslist P((struct parse *, FILE *)); 57 static void new_restrict P((struct parse *, FILE *)); 58 static void unrestrict P((struct parse *, FILE *)); 59 static void delrestrict P((struct parse *, FILE *)); 60 static void do_restrict P((struct parse *, FILE *, int)); 61 static void monlist P((struct parse *, FILE *)); 62 static void reset P((struct parse *, FILE *)); 63 static void preset P((struct parse *, FILE *)); 64 static void readkeys P((struct parse *, FILE *)); 65 static void trustkey P((struct parse *, FILE *)); 66 static void untrustkey P((struct parse *, FILE *)); 67 static void do_trustkey P((struct parse *, FILE *, int)); 68 static void authinfo P((struct parse *, FILE *)); 69 static void traps P((struct parse *, FILE *)); 70 static void addtrap P((struct parse *, FILE *)); 71 static void clrtrap P((struct parse *, FILE *)); 72 static void do_addclr_trap P((struct parse *, FILE *, int)); 73 static void requestkey P((struct parse *, FILE *)); 74 static void controlkey P((struct parse *, FILE *)); 75 static void do_changekey P((struct parse *, FILE *, int)); 76 static void ctlstats P((struct parse *, FILE *)); 77 static void clockstat P((struct parse *, FILE *)); 78 static void fudge P((struct parse *, FILE *)); 79 static void clkbug P((struct parse *, FILE *)); 80 static void kerninfo P((struct parse *, FILE *)); 81 82 /* 83 * Commands we understand. Ntpdc imports this. 84 */ 85 struct xcmd opcmds[] = { 86 { "listpeers", peerlist, { NO, NO, NO, NO }, 87 { "", "", "", "" }, 88 "display list of peers the server knows about" }, 89 { "peers", peers, { NO, NO, NO, NO }, 90 { "", "", "", "" }, 91 "display peer summary information" }, 92 { "dmpeers", dmpeers, { NO, NO, NO, NO }, 93 { "", "", "", "" }, 94 "display peer summary info the way Dave Mills likes it" }, 95 { "showpeer", showpeer, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 96 { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 97 "display detailed information for one or more peers" }, 98 { "pstats", peerstats, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 99 { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 100 "display statistical information for one or more peers" }, 101 { "loopinfo", loopinfo, { OPT|NTP_STR, NO, NO, NO }, 102 { "oneline|multiline", "", "", "" }, 103 "display loop filter information" }, 104 { "sysinfo", sysinfo, { NO, NO, NO, NO }, 105 { "", "", "", "" }, 106 "display local server information" }, 107 { "sysstats", sysstats, { NO, NO, NO, NO }, 108 { "", "", "", "" }, 109 "display local server statistics" }, 110 { "memstats", memstats, { NO, NO, NO, NO }, 111 { "", "", "", "" }, 112 "display peer memory usage statistics" }, 113 { "iostats", iostats, { NO, NO, NO, NO }, 114 { "", "", "", "" }, 115 "display I/O subsystem statistics" }, 116 { "timerstats", timerstats, { NO, NO, NO, NO }, 117 { "", "", "", "" }, 118 "display event timer subsystem statistics" }, 119 { "addpeer", addpeer, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR }, 120 { "addr", "keyid", "version", "minpoll|prefer" }, 121 "configure a new peer association" }, 122 { "addserver", addserver, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR }, 123 { "addr", "keyid", "version", "minpoll|prefer" }, 124 "configure a new server" }, 125 { "addrefclock",addrefclock, { ADD, OPT|UINT, OPT|NTP_STR, OPT|NTP_STR }, 126 { "addr", "mode", "minpoll|prefer", "minpoll|prefer" }, 127 "configure a new server" }, 128 { "broadcast", broadcast, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR }, 129 { "addr", "keyid", "version", "minpoll" }, 130 "configure broadcasting time service" }, 131 { "unconfig", unconfig, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 132 { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 133 "unconfigure existing peer assocations" }, 134 { "enable", set, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 135 { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 136 "set a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 137 { "disable", sys_clear, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 138 { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 139 "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 140 { "reslist", reslist, { NO, NO, NO, NO }, 141 { "", "", "", "" }, 142 "display the server's restrict list" }, 143 { "restrict", new_restrict, { ADD, ADD, NTP_STR, OPT|NTP_STR }, 144 { "address", "mask", 145 "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 146 "..." }, 147 "create restrict entry/add flags to entry" }, 148 { "unrestrict", unrestrict, { ADD, ADD, NTP_STR, OPT|NTP_STR }, 149 { "address", "mask", 150 "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 151 "..." }, 152 "remove flags from a restrict entry" }, 153 { "delrestrict", delrestrict, { ADD, ADD, OPT|NTP_STR, NO }, 154 { "address", "mask", "ntpport", "" }, 155 "delete a restrict entry" }, 156 { "monlist", monlist, { OPT|INT, NO, NO, NO }, 157 { "version", "", "", "" }, 158 "display data the server's monitor routines have collected" }, 159 { "reset", reset, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 160 { "io|sys|mem|timer|auth|allpeers", "...", "...", "..." }, 161 "reset various subsystem statistics counters" }, 162 { "preset", preset, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 163 { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 164 "reset stat counters associated with particular peer(s)" }, 165 { "readkeys", readkeys, { NO, NO, NO, NO }, 166 { "", "", "", "" }, 167 "request a reread of the keys file and re-init of system keys" }, 168 { "trustedkey", trustkey, { UINT, OPT|UINT, OPT|UINT, OPT|UINT }, 169 { "keyid", "keyid", "keyid", "keyid" }, 170 "add one or more key ID's to the trusted list" }, 171 { "untrustedkey", untrustkey, { UINT, OPT|UINT, OPT|UINT, OPT|UINT }, 172 { "keyid", "keyid", "keyid", "keyid" }, 173 "remove one or more key ID's from the trusted list" }, 174 { "authinfo", authinfo, { NO, NO, NO, NO }, 175 { "", "", "", "" }, 176 "display the state of the authentication code" }, 177 { "traps", traps, { NO, NO, NO, NO }, 178 { "", "", "", "" }, 179 "display the traps set in the server" }, 180 { "addtrap", addtrap, { ADD, OPT|UINT, OPT|ADD, NO }, 181 { "address", "port", "interface", "" }, 182 "configure a trap in the server" }, 183 { "clrtrap", clrtrap, { ADD, OPT|UINT, OPT|ADD, NO }, 184 { "address", "port", "interface", "" }, 185 "remove a trap (configured or otherwise) from the server" }, 186 { "requestkey", requestkey, { UINT, NO, NO, NO }, 187 { "keyid", "", "", "" }, 188 "change the keyid the server uses to authenticate requests" }, 189 { "controlkey", controlkey, { UINT, NO, NO, NO }, 190 { "keyid", "", "", "" }, 191 "change the keyid the server uses to authenticate control messages" }, 192 { "ctlstats", ctlstats, { NO, NO, NO, NO }, 193 { "", "", "", "" }, 194 "display packet count statistics from the control module" }, 195 { "clockstat", clockstat, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 196 { "address", "address", "address", "address" }, 197 "display clock status information" }, 198 { "fudge", fudge, { ADD, NTP_STR, NTP_STR, NO }, 199 { "address", "time1|time2|val1|val2|flags", "value", "" }, 200 "set/change one of a clock's fudge factors" }, 201 { "clkbug", clkbug, { ADD, OPT|ADD, OPT|ADD, OPT|ADD }, 202 { "address", "address", "address", "address" }, 203 "display clock debugging information" }, 204 { "kerninfo", kerninfo, { NO, NO, NO, NO }, 205 { "", "", "", "" }, 206 "display the kernel pll/pps variables" }, 207 208 { 0, 0, { NO, NO, NO, NO }, 209 { "", "", "", "" }, "" } 210 }; 211 212 213 /* 214 * Imported from ntpdc.c 215 */ 216 extern int showhostnames; 217 extern struct servent *server_entry; 218 219 /* 220 * For quick string comparisons 221 */ 222 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 223 224 225 /* 226 * checkitems - utility to print a message if no items were returned 227 */ 228 static int 229 checkitems( 230 int items, 231 FILE *fp 232 ) 233 { 234 if (items == 0) { 235 (void) fprintf(fp, "No data returned in response to query\n"); 236 return 0; 237 } 238 return 1; 239 } 240 241 242 /* 243 * checkitemsize - utility to print a message if the item size is wrong 244 */ 245 static int 246 checkitemsize( 247 int itemsize, 248 int expected 249 ) 250 { 251 if (itemsize != expected) { 252 (void) fprintf(stderr, 253 "***Incorrect item size returned by remote host (%d should be %d)\n", 254 itemsize, expected); 255 return 0; 256 } 257 return 1; 258 } 259 260 261 /* 262 * check1item - check to make sure we have exactly one item 263 */ 264 static int 265 check1item( 266 int items, 267 FILE *fp 268 ) 269 { 270 if (items == 0) { 271 (void) fprintf(fp, "No data returned in response to query\n"); 272 return 0; 273 } 274 if (items > 1) { 275 (void) fprintf(fp, "Expected one item in response, got %d\n", 276 items); 277 return 0; 278 } 279 return 1; 280 } 281 282 283 284 /* 285 * peerlist - get a short list of peers 286 */ 287 /*ARGSUSED*/ 288 static void 289 peerlist( 290 struct parse *pcmd, 291 FILE *fp 292 ) 293 { 294 struct info_peer_list *plist; 295 int items; 296 int itemsize; 297 int res; 298 299 res = doquery(IMPL_XNTPD, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items, 300 &itemsize, (char **)&plist, 0); 301 302 if (res != 0 && items == 0) 303 return; 304 305 if (!checkitems(items, fp)) 306 return; 307 308 if (!checkitemsize(itemsize, sizeof(struct info_peer_list))) 309 return; 310 311 while (items > 0) { 312 (void) fprintf(fp, "%-9s %s\n", modetoa(plist->hmode), 313 nntohost(plist->address)); 314 plist++; 315 items--; 316 } 317 } 318 319 320 /* 321 * peers - show peer summary 322 */ 323 static void 324 peers( 325 struct parse *pcmd, 326 FILE *fp 327 ) 328 { 329 dopeers(pcmd, fp, 0); 330 } 331 332 /* 333 * dmpeers - show peer summary, Dave Mills style 334 */ 335 static void 336 dmpeers( 337 struct parse *pcmd, 338 FILE *fp 339 ) 340 { 341 dopeers(pcmd, fp, 1); 342 } 343 344 345 /* 346 * peers - show peer summary 347 */ 348 /*ARGSUSED*/ 349 static void 350 dopeers( 351 struct parse *pcmd, 352 FILE *fp, 353 int dmstyle 354 ) 355 { 356 struct info_peer_summary *plist; 357 int items; 358 int itemsize; 359 int ntp_poll; 360 int res; 361 int c; 362 l_fp tempts; 363 364 res = doquery(IMPL_XNTPD, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL, 365 &items, &itemsize, (char **)&plist, 0); 366 367 if (res != 0 && items == 0) 368 return; 369 370 if (!checkitems(items, fp)) 371 return; 372 373 if (!checkitemsize(itemsize, sizeof(struct info_peer_summary))) 374 return; 375 376 (void) fprintf(fp, 377 " remote local st poll reach delay offset disp\n"); 378 (void) fprintf(fp, 379 "=======================================================================\n"); 380 while (items > 0) { 381 if (!dmstyle) { 382 if (plist->flags & INFO_FLAG_SYSPEER) 383 c = '*'; 384 else if (plist->hmode == MODE_ACTIVE) 385 c = '+'; 386 else if (plist->hmode == MODE_PASSIVE) 387 c = '-'; 388 else if (plist->hmode == MODE_CLIENT) 389 c = '='; 390 else if (plist->hmode == MODE_BROADCAST) 391 c = '^'; 392 else if (plist->hmode == MODE_BCLIENT) 393 c = '~'; 394 else 395 c = ' '; 396 } else { 397 if (plist->flags & INFO_FLAG_SYSPEER) 398 c = '*'; 399 else if (plist->flags & INFO_FLAG_SHORTLIST) 400 c = '+'; 401 else if (plist->flags & INFO_FLAG_SEL_CANDIDATE) 402 c = '.'; 403 else 404 c = ' '; 405 } 406 NTOHL_FP(&(plist->offset), &tempts); 407 ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL), 408 NTP_MINPOLL); 409 (void) fprintf(fp, 410 "%c%-15.15s %-15.15s %2d %4d %3o %7.7s %9.9s %7.7s\n", 411 c, nntohost(plist->srcadr), 412 numtoa(plist->dstadr), 413 plist->stratum, ntp_poll, plist->reach, 414 fptoa(NTOHS_FP(plist->delay), 5), 415 lfptoa(&tempts, 6), 416 ufptoa(NTOHS_FP(plist->dispersion), 5)); 417 418 plist++; 419 items--; 420 } 421 } 422 423 /* Convert a refid & stratum (in host order) to a string */ 424 static char* 425 refid_string( 426 u_int32 refid, 427 int stratum 428 ) 429 { 430 if (stratum <= 1) { 431 static char junk[5]; 432 junk[4] = 0; 433 memmove(junk, (char *)&refid, 4); 434 return junk; 435 } 436 437 return numtoa(refid); 438 } 439 440 /* 441 * printpeer - print detail information for a peer 442 */ 443 static void 444 printpeer( 445 register struct info_peer *pp, 446 FILE *fp 447 ) 448 { 449 register int i; 450 const char *str; 451 l_fp tempts; 452 453 (void) fprintf(fp, "remote %s, local %s\n", 454 numtoa(pp->srcadr), numtoa(pp->dstadr)); 455 456 (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n", 457 modetoa(pp->hmode), modetoa(pp->pmode), 458 pp->stratum, pp->precision); 459 460 (void) fprintf(fp, 461 "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n", 462 pp->leap & 0x2 ? '1' : '0', 463 pp->leap & 0x1 ? '1' : '0', 464 refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5), 465 ufptoa(NTOHS_FP(pp->rootdispersion), 5)); 466 467 (void) fprintf(fp, 468 "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n", 469 pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd)); 470 471 (void) fprintf(fp, 472 "reach %03o, unreach %d, flash 0x%04x, ", 473 pp->reach, pp->unreach, pp->flash2); 474 475 (void) fprintf(fp, "boffset %s, ttl/mode %d\n", 476 fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl); 477 478 (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer)); 479 if (pp->flags == 0) { 480 (void) fprintf(fp, " none\n"); 481 } else { 482 str = ""; 483 if (pp->flags & INFO_FLAG_SYSPEER) { 484 (void) fprintf(fp, " system_peer"); 485 str = ","; 486 } 487 if (pp->flags & INFO_FLAG_CONFIG) { 488 (void) fprintf(fp, "%s config", str); 489 str = ","; 490 } 491 if (pp->flags & INFO_FLAG_REFCLOCK) { 492 (void) fprintf(fp, "%s refclock", str); 493 str = ","; 494 } 495 if (pp->flags & INFO_FLAG_AUTHENABLE) { 496 (void) fprintf(fp, "%s auth", str); 497 str = ","; 498 } 499 if (pp->flags & INFO_FLAG_BCLIENT) { 500 (void) fprintf(fp, "%s bclient", str); 501 str = ","; 502 } 503 if (pp->flags & INFO_FLAG_PREFER) { 504 (void) fprintf(fp, "%s prefer", str); 505 str = ","; 506 } 507 if (pp->flags & INFO_FLAG_BURST) { 508 (void) fprintf(fp, "%s burst", str); 509 } 510 (void) fprintf(fp, "\n"); 511 } 512 513 NTOHL_FP(&pp->reftime, &tempts); 514 (void) fprintf(fp, "reference time: %s\n", 515 prettydate(&tempts)); 516 NTOHL_FP(&pp->org, &tempts); 517 (void) fprintf(fp, "originate timestamp: %s\n", 518 prettydate(&tempts)); 519 NTOHL_FP(&pp->rec, &tempts); 520 (void) fprintf(fp, "receive timestamp: %s\n", 521 prettydate(&tempts)); 522 NTOHL_FP(&pp->xmt, &tempts); 523 (void) fprintf(fp, "transmit timestamp: %s\n", 524 prettydate(&tempts)); 525 526 (void) fprintf(fp, "filter delay: "); 527 for (i = 0; i < NTP_SHIFT; i++) { 528 (void) fprintf(fp, " %-8.8s", 529 fptoa(NTOHS_FP(pp->filtdelay[i]), 5)); 530 if (i == (NTP_SHIFT>>1)-1) 531 (void) fprintf(fp, "\n "); 532 } 533 (void) fprintf(fp, "\n"); 534 535 (void) fprintf(fp, "filter offset:"); 536 for (i = 0; i < NTP_SHIFT; i++) { 537 NTOHL_FP(&pp->filtoffset[i], &tempts); 538 (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6)); 539 if (i == (NTP_SHIFT>>1)-1) 540 (void) fprintf(fp, "\n "); 541 } 542 (void) fprintf(fp, "\n"); 543 544 (void) fprintf(fp, "filter order: "); 545 for (i = 0; i < NTP_SHIFT; i++) { 546 (void) fprintf(fp, " %-8d", pp->order[i]); 547 if (i == (NTP_SHIFT>>1)-1) 548 (void) fprintf(fp, "\n "); 549 } 550 (void) fprintf(fp, "\n"); 551 552 553 NTOHL_FP(&pp->offset, &tempts); 554 (void) fprintf(fp, 555 "offset %s, delay %s, error bound %s, filter error %s\n", 556 lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5), 557 ufptoa(NTOHS_FP(pp->dispersion), 5), 558 ufptoa(NTOHS_FP(pp->selectdisp), 5)); 559 } 560 561 562 /* 563 * showpeer - show detailed information for a peer 564 */ 565 static void 566 showpeer( 567 struct parse *pcmd, 568 FILE *fp 569 ) 570 { 571 struct info_peer *pp; 572 /* 4 is the maximum number of peers which will fit in a packet */ 573 struct info_peer_list plist[min(MAXARGS, 4)]; 574 int qitems; 575 int items; 576 int itemsize; 577 int res; 578 579 for (qitems = 0; qitems < min(pcmd->nargs, 4); qitems++) { 580 plist[qitems].address = pcmd->argval[qitems].netnum; 581 plist[qitems].port = server_entry->s_port; 582 plist[qitems].hmode = plist[qitems].flags = 0; 583 } 584 585 res = doquery(IMPL_XNTPD, REQ_PEER_INFO, 0, qitems, 586 sizeof(struct info_peer_list), (char *)plist, &items, 587 &itemsize, (char **)&pp, 0); 588 589 if (res != 0 && items == 0) 590 return; 591 592 if (!checkitems(items, fp)) 593 return; 594 595 if (!checkitemsize(itemsize, sizeof(struct info_peer))) 596 return; 597 598 while (items-- > 0) { 599 printpeer(pp, fp); 600 if (items > 0) 601 (void) fprintf(fp, "\n"); 602 pp++; 603 } 604 } 605 606 607 /* 608 * peerstats - return statistics for a peer 609 */ 610 static void 611 peerstats( 612 struct parse *pcmd, 613 FILE *fp 614 ) 615 { 616 struct info_peer_stats *pp; 617 /* 4 is the maximum number of peers which will fit in a packet */ 618 struct info_peer_list plist[min(MAXARGS, 4)]; 619 int qitems; 620 int items; 621 int itemsize; 622 int res; 623 624 for (qitems = 0; qitems < min(pcmd->nargs, 4); qitems++) { 625 plist[qitems].address = pcmd->argval[qitems].netnum; 626 plist[qitems].port = server_entry->s_port; 627 plist[qitems].hmode = plist[qitems].flags = 0; 628 } 629 630 res = doquery(IMPL_XNTPD, REQ_PEER_STATS, 0, qitems, 631 sizeof(struct info_peer_list), (char *)plist, &items, 632 &itemsize, (char **)&pp, 0); 633 634 if (res != 0 && items == 0) 635 return; 636 637 if (!checkitems(items, fp)) 638 return; 639 640 if (!checkitemsize(itemsize, sizeof(struct info_peer_stats))) 641 return; 642 643 while (items-- > 0) { 644 (void) fprintf(fp, "remote host: %s\n", 645 nntohost(pp->srcadr)); 646 (void) fprintf(fp, "local interface: %s\n", 647 numtoa(pp->dstadr)); 648 (void) fprintf(fp, "time last received: %lds\n", 649 (long)ntohl(pp->timereceived)); 650 (void) fprintf(fp, "time until next send: %lds\n", 651 (long)ntohl(pp->timetosend)); 652 (void) fprintf(fp, "reachability change: %lds\n", 653 (long)ntohl(pp->timereachable)); 654 (void) fprintf(fp, "packets sent: %ld\n", 655 (long)ntohl(pp->sent)); 656 (void) fprintf(fp, "packets received: %ld\n", 657 (long)ntohl(pp->processed)); 658 (void) fprintf(fp, "bad authentication: %ld\n", 659 (long)ntohl(pp->badauth)); 660 (void) fprintf(fp, "bogus origin: %ld\n", 661 (long)ntohl(pp->bogusorg)); 662 (void) fprintf(fp, "duplicate: %ld\n", 663 (long)ntohl(pp->oldpkt)); 664 (void) fprintf(fp, "bad dispersion: %ld\n", 665 (long)ntohl(pp->seldisp)); 666 (void) fprintf(fp, "bad reference time: %ld\n", 667 (long)ntohl(pp->selbroken)); 668 (void) fprintf(fp, "candidate order: %d\n", 669 (int)pp->candidate); 670 if (items > 0) 671 (void) fprintf(fp, "\n"); 672 pp++; 673 } 674 } 675 676 677 /* 678 * loopinfo - show loop filter information 679 */ 680 static void 681 loopinfo( 682 struct parse *pcmd, 683 FILE *fp 684 ) 685 { 686 struct info_loop *il; 687 int items; 688 int itemsize; 689 int oneline = 0; 690 int res; 691 l_fp tempts; 692 693 if (pcmd->nargs > 0) { 694 if (STREQ(pcmd->argval[0].string, "oneline")) 695 oneline = 1; 696 else if (STREQ(pcmd->argval[0].string, "multiline")) 697 oneline = 0; 698 else { 699 (void) fprintf(stderr, "How many lines?\n"); 700 return; 701 } 702 } 703 704 res = doquery(IMPL_XNTPD, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL, 705 &items, &itemsize, (char **)&il, 0); 706 707 if (res != 0 && items == 0) 708 return; 709 710 if (!check1item(items, fp)) 711 return; 712 713 if (!checkitemsize(itemsize, sizeof(struct info_loop))) 714 return; 715 716 if (oneline) { 717 l_fp temp2ts; 718 719 NTOHL_FP(&il->last_offset, &tempts); 720 NTOHL_FP(&il->drift_comp, &temp2ts); 721 722 (void) fprintf(fp, 723 "offset %s, frequency %s, time_const %ld, watchdog %ld\n", 724 lfptoa(&tempts, 6), 725 lfptoa(&temp2ts, 3), 726 (u_long)ntohl(il->compliance), 727 (u_long)ntohl(il->watchdog_timer)); 728 } else { 729 NTOHL_FP(&il->last_offset, &tempts); 730 (void) fprintf(fp, "offset: %s s\n", 731 lfptoa(&tempts, 6)); 732 NTOHL_FP(&il->drift_comp, &tempts); 733 (void) fprintf(fp, "frequency: %s ppm\n", 734 lfptoa(&tempts, 3)); 735 (void) fprintf(fp, "poll adjust: %ld\n", 736 (u_long)ntohl(il->compliance)); 737 (void) fprintf(fp, "watchdog timer: %ld s\n", 738 (u_long)ntohl(il->watchdog_timer)); 739 } 740 } 741 742 743 /* 744 * sysinfo - show current system state 745 */ 746 /*ARGSUSED*/ 747 static void 748 sysinfo( 749 struct parse *pcmd, 750 FILE *fp 751 ) 752 { 753 struct info_sys *is; 754 int items; 755 int itemsize; 756 int res; 757 l_fp tempts; 758 759 res = doquery(IMPL_XNTPD, REQ_SYS_INFO, 0, 0, 0, (char *)NULL, 760 &items, &itemsize, (char **)&is, 0); 761 762 if (res != 0 && items == 0) 763 return; 764 765 if (!check1item(items, fp)) 766 return; 767 768 if (!checkitemsize(itemsize, sizeof(struct info_sys))) 769 return; 770 771 (void) fprintf(fp, "system peer: %s\n", nntohost(is->peer)); 772 (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode)); 773 (void) fprintf(fp, "leap indicator: %c%c\n", 774 is->leap & 0x2 ? '1' : '0', 775 is->leap & 0x1 ? '1' : '0'); 776 (void) fprintf(fp, "stratum: %d\n", (int)is->stratum); 777 (void) fprintf(fp, "precision: %d\n", (int)is->precision); 778 (void) fprintf(fp, "root distance: %s s\n", 779 fptoa(NTOHS_FP(is->rootdelay), 5)); 780 (void) fprintf(fp, "root dispersion: %s s\n", 781 ufptoa(NTOHS_FP(is->rootdispersion), 5)); 782 (void) fprintf(fp, "reference ID: [%s]\n", 783 refid_string(is->refid, is->stratum)); 784 NTOHL_FP(&is->reftime, &tempts); 785 (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts)); 786 787 (void) fprintf(fp, "system flags: "); 788 if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE | 789 INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL | 790 INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) { 791 (void) fprintf(fp, "none\n"); 792 } else { 793 if (is->flags & INFO_FLAG_BCLIENT) 794 (void) fprintf(fp, "bclient "); 795 if (is->flags & INFO_FLAG_AUTHENTICATE) 796 (void) fprintf(fp, "auth "); 797 if (is->flags & INFO_FLAG_MONITOR) 798 (void) fprintf(fp, "monitor "); 799 if (is->flags & INFO_FLAG_NTP) 800 (void) fprintf(fp, "ntp "); 801 if (is->flags & INFO_FLAG_KERNEL) 802 (void) fprintf(fp, "kernel "); 803 if (is->flags & INFO_FLAG_FILEGEN) 804 (void) fprintf(fp, "stats "); 805 if (is->flags & INFO_FLAG_CAL) 806 (void) fprintf(fp, "calibrate "); 807 if (is->flags & INFO_FLAG_PPS_SYNC) 808 (void) fprintf(fp, "pps "); 809 (void) fprintf(fp, "\n"); 810 } 811 (void) fprintf(fp, "jitter: %s s\n", 812 fptoa(ntohl(is->frequency), 6)); 813 (void) fprintf(fp, "stability: %s ppm\n", 814 ufptoa(ntohl(is->stability), 3)); 815 (void) fprintf(fp, "broadcastdelay: %s s\n", 816 fptoa(NTOHS_FP(is->bdelay), 6)); 817 NTOHL_FP(&is->authdelay, &tempts); 818 (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6)); 819 } 820 821 822 /* 823 * sysstats - print system statistics 824 */ 825 /*ARGSUSED*/ 826 static void 827 sysstats( 828 struct parse *pcmd, 829 FILE *fp 830 ) 831 { 832 struct info_sys_stats *ss; 833 int items; 834 int itemsize; 835 int res; 836 837 res = doquery(IMPL_XNTPD, REQ_SYS_STATS, 0, 0, 0, (char *)NULL, 838 &items, &itemsize, (char **)&ss, 0); 839 840 if (res != 0 && items == 0) 841 return; 842 843 if (!check1item(items, fp)) 844 return; 845 846 if (itemsize != sizeof(struct info_sys_stats) && 847 itemsize != sizeof(struct old_info_sys_stats)) { 848 /* issue warning according to new structure size */ 849 checkitemsize(itemsize, sizeof(struct info_sys_stats)); 850 return; 851 } 852 853 (void) fprintf(fp, "system uptime: %ld\n", 854 (u_long)ntohl(ss->timeup)); 855 (void) fprintf(fp, "time since reset: %ld\n", 856 (u_long)ntohl(ss->timereset)); 857 (void) fprintf(fp, "bad stratum in packet: %ld\n", 858 (u_long)ntohl(ss->badstratum)); 859 (void) fprintf(fp, "old version packets: %ld\n", 860 (u_long)ntohl(ss->oldversionpkt)); 861 (void) fprintf(fp, "new version packets: %ld\n", 862 (u_long)ntohl(ss->newversionpkt)); 863 (void) fprintf(fp, "unknown version number: %ld\n", 864 (u_long)ntohl(ss->unknownversion)); 865 (void) fprintf(fp, "bad packet format: %ld\n", 866 (u_long)ntohl(ss->badlength)); 867 (void) fprintf(fp, "packets processed: %ld\n", 868 (u_long)ntohl(ss->processed)); 869 (void) fprintf(fp, "bad authentication: %ld\n", 870 (u_long)ntohl(ss->badauth)); 871 if (itemsize != sizeof(struct info_sys_stats)) 872 return; 873 874 (void) fprintf(fp, "packets rejected: %ld\n", 875 (u_long)ntohl(ss->limitrejected)); 876 } 877 878 879 880 /* 881 * iostats - print I/O statistics 882 */ 883 /*ARGSUSED*/ 884 static void 885 iostats( 886 struct parse *pcmd, 887 FILE *fp 888 ) 889 { 890 struct info_io_stats *io; 891 int items; 892 int itemsize; 893 int res; 894 895 res = doquery(IMPL_XNTPD, REQ_IO_STATS, 0, 0, 0, (char *)NULL, 896 &items, &itemsize, (char **)&io, 0); 897 898 if (res != 0 && items == 0) 899 return; 900 901 if (!check1item(items, fp)) 902 return; 903 904 if (!checkitemsize(itemsize, sizeof(struct info_io_stats))) 905 return; 906 907 (void) fprintf(fp, "time since reset: %ld\n", 908 (u_long)ntohl(io->timereset)); 909 (void) fprintf(fp, "receive buffers: %d\n", 910 ntohs(io->totalrecvbufs)); 911 (void) fprintf(fp, "free receive buffers: %d\n", 912 ntohs(io->freerecvbufs)); 913 (void) fprintf(fp, "used receive buffers: %d\n", 914 ntohs(io->fullrecvbufs)); 915 (void) fprintf(fp, "low water refills: %d\n", 916 ntohs(io->lowwater)); 917 (void) fprintf(fp, "dropped packets: %ld\n", 918 (u_long)ntohl(io->dropped)); 919 (void) fprintf(fp, "ignored packets: %ld\n", 920 (u_long)ntohl(io->ignored)); 921 (void) fprintf(fp, "received packets: %ld\n", 922 (u_long)ntohl(io->received)); 923 (void) fprintf(fp, "packets sent: %ld\n", 924 (u_long)ntohl(io->sent)); 925 (void) fprintf(fp, "packets not sent: %ld\n", 926 (u_long)ntohl(io->notsent)); 927 (void) fprintf(fp, "interrupts handled: %ld\n", 928 (u_long)ntohl(io->interrupts)); 929 (void) fprintf(fp, "received by int: %ld\n", 930 (u_long)ntohl(io->int_received)); 931 } 932 933 934 /* 935 * memstats - print peer memory statistics 936 */ 937 /*ARGSUSED*/ 938 static void 939 memstats( 940 struct parse *pcmd, 941 FILE *fp 942 ) 943 { 944 struct info_mem_stats *mem; 945 int i; 946 int items; 947 int itemsize; 948 int res; 949 950 res = doquery(IMPL_XNTPD, REQ_MEM_STATS, 0, 0, 0, (char *)NULL, 951 &items, &itemsize, (char **)&mem, 0); 952 953 if (res != 0 && items == 0) 954 return; 955 956 if (!check1item(items, fp)) 957 return; 958 959 if (!checkitemsize(itemsize, sizeof(struct info_mem_stats))) 960 return; 961 962 (void) fprintf(fp, "time since reset: %ld\n", 963 (u_long)ntohl(mem->timereset)); 964 (void) fprintf(fp, "total peer memory: %d\n", 965 ntohs(mem->totalpeermem)); 966 (void) fprintf(fp, "free peer memory: %d\n", 967 ntohs(mem->freepeermem)); 968 (void) fprintf(fp, "calls to findpeer: %ld\n", 969 (u_long)ntohl(mem->findpeer_calls)); 970 (void) fprintf(fp, "new peer allocations: %ld\n", 971 (u_long)ntohl(mem->allocations)); 972 (void) fprintf(fp, "peer demobilizations: %ld\n", 973 (u_long)ntohl(mem->demobilizations)); 974 975 (void) fprintf(fp, "hash table counts: "); 976 for (i = 0; i < HASH_SIZE; i++) { 977 (void) fprintf(fp, "%4d", (int)mem->hashcount[i]); 978 if ((i % 8) == 7 && i != (HASH_SIZE-1)) { 979 (void) fprintf(fp, "\n "); 980 } 981 } 982 (void) fprintf(fp, "\n"); 983 } 984 985 986 987 /* 988 * timerstats - print timer statistics 989 */ 990 /*ARGSUSED*/ 991 static void 992 timerstats( 993 struct parse *pcmd, 994 FILE *fp 995 ) 996 { 997 struct info_timer_stats *tim; 998 int items; 999 int itemsize; 1000 int res; 1001 1002 res = doquery(IMPL_XNTPD, REQ_TIMER_STATS, 0, 0, 0, (char *)NULL, 1003 &items, &itemsize, (char **)&tim, 0); 1004 1005 if (res != 0 && items == 0) 1006 return; 1007 1008 if (!check1item(items, fp)) 1009 return; 1010 1011 if (!checkitemsize(itemsize, sizeof(struct info_timer_stats))) 1012 return; 1013 1014 (void) fprintf(fp, "time since reset: %ld\n", 1015 (u_long)ntohl(tim->timereset)); 1016 (void) fprintf(fp, "alarms handled: %ld\n", 1017 (u_long)ntohl(tim->alarms)); 1018 (void) fprintf(fp, "alarm overruns: %ld\n", 1019 (u_long)ntohl(tim->overflows)); 1020 (void) fprintf(fp, "calls to transmit: %ld\n", 1021 (u_long)ntohl(tim->xmtcalls)); 1022 } 1023 1024 1025 /* 1026 * addpeer - configure an active mode association 1027 */ 1028 static void 1029 addpeer( 1030 struct parse *pcmd, 1031 FILE *fp 1032 ) 1033 { 1034 doconfig(pcmd, fp, MODE_ACTIVE, 0); 1035 } 1036 1037 1038 /* 1039 * addserver - configure a client mode association 1040 */ 1041 static void 1042 addserver( 1043 struct parse *pcmd, 1044 FILE *fp 1045 ) 1046 { 1047 doconfig(pcmd, fp, MODE_CLIENT, 0); 1048 } 1049 1050 /* 1051 * addrefclock - configure a reference clock association 1052 */ 1053 static void 1054 addrefclock( 1055 struct parse *pcmd, 1056 FILE *fp 1057 ) 1058 { 1059 doconfig(pcmd, fp, MODE_CLIENT, 1); 1060 } 1061 1062 /* 1063 * broadcast - configure a broadcast mode association 1064 */ 1065 static void 1066 broadcast( 1067 struct parse *pcmd, 1068 FILE *fp 1069 ) 1070 { 1071 doconfig(pcmd, fp, MODE_BROADCAST, 0); 1072 } 1073 1074 1075 /* 1076 * config - configure a new peer association 1077 */ 1078 static void 1079 doconfig( 1080 struct parse *pcmd, 1081 FILE *fp, 1082 int mode, 1083 int refc 1084 ) 1085 { 1086 struct conf_peer cpeer; 1087 int items; 1088 int itemsize; 1089 char *dummy; 1090 u_long keyid; 1091 u_int version; 1092 u_char minpoll; 1093 u_int flags; 1094 u_char cmode; 1095 int res; 1096 1097 keyid = 0; 1098 version = NTP_OLDVERSION + 1; 1099 flags = 0; 1100 res = 0; 1101 cmode = 0; 1102 minpoll = NTP_MINDPOLL; 1103 1104 items = pcmd->nargs; 1105 1106 if (refc) { 1107 if (pcmd->nargs > 1) { 1108 cmode = (u_char) pcmd->argval[1].uval; 1109 items = 2; 1110 } 1111 } else { 1112 if (pcmd->nargs > 1) { 1113 keyid = pcmd->argval[1].uval; 1114 if (keyid > 0) { 1115 flags |= CONF_FLAG_AUTHENABLE; 1116 } 1117 if (pcmd->nargs > 2) { 1118 version = (u_int)pcmd->argval[2].uval; 1119 if (version > NTP_VERSION || 1120 version < NTP_OLDVERSION) { 1121 (void)fprintf(fp, 1122 "invalid version number %u\n", 1123 version); 1124 res++; 1125 } 1126 items = 3; 1127 } 1128 } 1129 } 1130 1131 while (pcmd->nargs > items) { 1132 if (STREQ(pcmd->argval[items].string, "prefer")) 1133 flags |= CONF_FLAG_PREFER; 1134 else if (STREQ(pcmd->argval[items].string, "burst")) 1135 flags |= CONF_FLAG_BURST; 1136 else { 1137 long val; 1138 if (!atoint(pcmd->argval[items].string, &val)) { 1139 (void) fprintf(fp, 1140 "%s not understood\n", 1141 pcmd->argval[items].string); 1142 res++; 1143 break; 1144 } else { 1145 if (val >= NTP_MINPOLL && val <= NTP_MAXPOLL) { 1146 minpoll = (u_char)val; 1147 } else { 1148 (void) fprintf(fp, 1149 "minpol must be within %d..%d\n", 1150 NTP_MINPOLL, NTP_MAXPOLL); 1151 res++; 1152 break; 1153 } 1154 } 1155 } 1156 items++; 1157 } 1158 1159 if (res) 1160 return; 1161 1162 memset((void *)&cpeer, 0, sizeof cpeer); 1163 1164 cpeer.peeraddr = pcmd->argval[0].netnum; 1165 cpeer.hmode = (u_char) mode; 1166 cpeer.keyid = keyid; 1167 cpeer.version = (u_char) version; 1168 cpeer.minpoll = minpoll; 1169 cpeer.maxpoll = NTP_MAXDPOLL; 1170 cpeer.flags = (u_char)flags; 1171 cpeer.ttl = cmode; 1172 1173 res = doquery(IMPL_XNTPD, REQ_CONFIG, 1, 1, 1174 sizeof(struct conf_peer), (char *)&cpeer, &items, 1175 &itemsize, &dummy, 0); 1176 1177 if (res == INFO_ERR_FMT) { 1178 (void) fprintf(fp, 1179 "***Retrying command with old conf_peer size\n"); 1180 res = doquery(IMPL_XNTPD, REQ_CONFIG, 1, 1, 1181 sizeof(struct old_conf_peer), (char *)&cpeer, 1182 &items, &itemsize, &dummy, 0); 1183 } 1184 if (res == 0) 1185 (void) fprintf(fp, "done!\n"); 1186 return; 1187 } 1188 1189 1190 /* 1191 * unconfig - unconfigure some associations 1192 */ 1193 static void 1194 unconfig( 1195 struct parse *pcmd, 1196 FILE *fp 1197 ) 1198 { 1199 /* 8 is the maximum number of peers which will fit in a packet */ 1200 struct conf_unpeer plist[min(MAXARGS, 8)]; 1201 int qitems; 1202 int items; 1203 int itemsize; 1204 char *dummy; 1205 int res; 1206 1207 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) { 1208 plist[qitems].peeraddr = pcmd->argval[qitems].netnum; 1209 } 1210 1211 res = doquery(IMPL_XNTPD, REQ_UNCONFIG, 1, qitems, 1212 sizeof(struct conf_unpeer), (char *)plist, &items, 1213 &itemsize, &dummy, 0); 1214 1215 if (res == 0) 1216 (void) fprintf(fp, "done!\n"); 1217 } 1218 1219 1220 /* 1221 * set - set some system flags 1222 */ 1223 static void 1224 set( 1225 struct parse *pcmd, 1226 FILE *fp 1227 ) 1228 { 1229 doset(pcmd, fp, REQ_SET_SYS_FLAG); 1230 } 1231 1232 1233 /* 1234 * clear - clear some system flags 1235 */ 1236 static void 1237 sys_clear( 1238 struct parse *pcmd, 1239 FILE *fp 1240 ) 1241 { 1242 doset(pcmd, fp, REQ_CLR_SYS_FLAG); 1243 } 1244 1245 1246 /* 1247 * doset - set/clear system flags 1248 */ 1249 static void 1250 doset( 1251 struct parse *pcmd, 1252 FILE *fp, 1253 int req 1254 ) 1255 { 1256 /* 8 is the maximum number of peers which will fit in a packet */ 1257 struct conf_sys_flags sys; 1258 int items; 1259 int itemsize; 1260 char *dummy; 1261 int res; 1262 1263 sys.flags = 0; 1264 res = 0; 1265 for (items = 0; items < pcmd->nargs; items++) { 1266 if (STREQ(pcmd->argval[items].string, "auth")) 1267 sys.flags |= SYS_FLAG_AUTH; 1268 else if (STREQ(pcmd->argval[items].string, "bclient")) 1269 sys.flags |= SYS_FLAG_BCLIENT; 1270 else if (STREQ(pcmd->argval[items].string, "calibrate")) 1271 sys.flags |= SYS_FLAG_CAL; 1272 else if (STREQ(pcmd->argval[items].string, "kernel")) 1273 sys.flags |= SYS_FLAG_KERNEL; 1274 else if (STREQ(pcmd->argval[items].string, "monitor")) 1275 sys.flags |= SYS_FLAG_MONITOR; 1276 else if (STREQ(pcmd->argval[items].string, "ntp")) 1277 sys.flags |= SYS_FLAG_NTP; 1278 else if (STREQ(pcmd->argval[items].string, "pps")) 1279 sys.flags |= SYS_FLAG_PPS; 1280 else if (STREQ(pcmd->argval[items].string, "stats")) 1281 sys.flags |= SYS_FLAG_FILEGEN; 1282 else { 1283 (void) fprintf(fp, "Unknown flag %s\n", 1284 pcmd->argval[items].string); 1285 res = 1; 1286 } 1287 } 1288 1289 if (res || sys.flags == 0) 1290 return; 1291 1292 res = doquery(IMPL_XNTPD, req, 1, 1, 1293 sizeof(struct conf_sys_flags), (char *)&sys, &items, 1294 &itemsize, &dummy, 0); 1295 1296 if (res == 0) 1297 (void) fprintf(fp, "done!\n"); 1298 } 1299 1300 1301 /* 1302 * data for printing/interrpreting the restrict flags 1303 */ 1304 struct resflags { 1305 const char *str; 1306 int bit; 1307 }; 1308 1309 static struct resflags resflags[] = { 1310 { "ignore", RES_IGNORE }, 1311 { "noserve", RES_DONTSERVE }, 1312 { "notrust", RES_DONTTRUST }, 1313 { "noquery", RES_NOQUERY }, 1314 { "nomodify", RES_NOMODIFY }, 1315 { "nopeer", RES_NOPEER }, 1316 { "notrap", RES_NOTRAP }, 1317 { "lptrap", RES_LPTRAP }, 1318 { "limited", RES_LIMITED }, 1319 { "version", RES_VERSION }, 1320 { "kod", RES_DEMOBILIZE }, 1321 1322 { "", 0 } 1323 }; 1324 1325 static struct resflags resmflags[] = { 1326 { "ntpport", RESM_NTPONLY }, 1327 { "interface", RESM_INTERFACE }, 1328 { "", 0 } 1329 }; 1330 1331 1332 /* 1333 * reslist - obtain and print the server's restrict list 1334 */ 1335 /*ARGSUSED*/ 1336 static void 1337 reslist( 1338 struct parse *pcmd, 1339 FILE *fp 1340 ) 1341 { 1342 struct info_restrict *rl; 1343 int items; 1344 int itemsize; 1345 int res; 1346 char *addr; 1347 char *mask; 1348 struct resflags *rf; 1349 u_int32 count; 1350 u_short flags; 1351 u_short mflags; 1352 char flagstr[300]; 1353 static const char *comma = ", "; 1354 1355 res = doquery(IMPL_XNTPD, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL, 1356 &items, &itemsize, (char **)&rl, 0); 1357 1358 if (res != 0 && items == 0) 1359 return; 1360 1361 if (!checkitems(items, fp)) 1362 return; 1363 1364 if (!checkitemsize(itemsize, sizeof(struct info_restrict))) 1365 return; 1366 1367 (void) fprintf(fp, 1368 " address mask count flags\n"); 1369 (void) fprintf(fp, 1370 "=====================================================================\n"); 1371 while (items > 0) { 1372 if ((rl->mask == (u_int32)0xffffffff)) 1373 addr = nntohost(rl->addr); 1374 else 1375 addr = numtoa( rl->addr ); 1376 mask = numtoa(rl->mask); 1377 count = ntohl(rl->count); 1378 flags = ntohs(rl->flags); 1379 mflags = ntohs(rl->mflags); 1380 flagstr[0] = '\0'; 1381 1382 res = 1; 1383 rf = &resmflags[0]; 1384 while (rf->bit != 0) { 1385 if (mflags & rf->bit) { 1386 if (!res) 1387 (void) strcat(flagstr, comma); 1388 res = 0; 1389 (void) strcat(flagstr, rf->str); 1390 } 1391 rf++; 1392 } 1393 1394 rf = &resflags[0]; 1395 while (rf->bit != 0) { 1396 if (flags & rf->bit) { 1397 if (!res) 1398 (void) strcat(flagstr, comma); 1399 res = 0; 1400 (void) strcat(flagstr, rf->str); 1401 } 1402 rf++; 1403 } 1404 1405 if (flagstr[0] == '\0') 1406 (void) strcpy(flagstr, "none"); 1407 1408 (void) fprintf(fp, "%-15.15s %-15.15s %9ld %s\n", 1409 addr, mask, (u_long)count, flagstr); 1410 rl++; 1411 items--; 1412 } 1413 } 1414 1415 1416 1417 /* 1418 * new_restrict - create/add a set of restrictions 1419 */ 1420 static void 1421 new_restrict( 1422 struct parse *pcmd, 1423 FILE *fp 1424 ) 1425 { 1426 do_restrict(pcmd, fp, REQ_RESADDFLAGS); 1427 } 1428 1429 1430 /* 1431 * unrestrict - remove restriction flags from existing entry 1432 */ 1433 static void 1434 unrestrict( 1435 struct parse *pcmd, 1436 FILE *fp 1437 ) 1438 { 1439 do_restrict(pcmd, fp, REQ_RESSUBFLAGS); 1440 } 1441 1442 1443 /* 1444 * delrestrict - delete an existing restriction 1445 */ 1446 static void 1447 delrestrict( 1448 struct parse *pcmd, 1449 FILE *fp 1450 ) 1451 { 1452 do_restrict(pcmd, fp, REQ_UNRESTRICT); 1453 } 1454 1455 1456 /* 1457 * do_restrict - decode commandline restrictions and make the request 1458 */ 1459 static void 1460 do_restrict( 1461 struct parse *pcmd, 1462 FILE *fp, 1463 int req_code 1464 ) 1465 { 1466 struct conf_restrict cres; 1467 int items; 1468 int itemsize; 1469 char *dummy; 1470 u_int32 num; 1471 u_long bit; 1472 int i; 1473 int res; 1474 int err; 1475 1476 cres.addr = pcmd->argval[0].netnum; 1477 cres.mask = pcmd->argval[1].netnum; 1478 cres.flags = 0; 1479 cres.mflags = 0; 1480 err = 0; 1481 for (res = 2; res < pcmd->nargs; res++) { 1482 if (STREQ(pcmd->argval[res].string, "ntpport")) { 1483 cres.mflags |= RESM_NTPONLY; 1484 } else { 1485 for (i = 0; resflags[i].bit != 0; i++) { 1486 if (STREQ(pcmd->argval[res].string, 1487 resflags[i].str)) 1488 break; 1489 } 1490 if (resflags[i].bit != 0) { 1491 cres.flags |= resflags[i].bit; 1492 if (req_code == REQ_UNRESTRICT) { 1493 (void) fprintf(fp, 1494 "Flag %s inappropriate\n", 1495 resflags[i].str); 1496 err++; 1497 } 1498 } else { 1499 (void) fprintf(fp, "Unknown flag %s\n", 1500 pcmd->argval[res].string); 1501 err++; 1502 } 1503 } 1504 } 1505 1506 /* 1507 * Make sure mask for default address is zero. Otherwise, 1508 * make sure mask bits are contiguous. 1509 */ 1510 if (cres.addr == 0) { 1511 cres.mask = 0; 1512 } else { 1513 num = ntohl(cres.mask); 1514 for (bit = 0x80000000; bit != 0; bit >>= 1) 1515 if ((num & bit) == 0) 1516 break; 1517 for ( ; bit != 0; bit >>= 1) 1518 if ((num & bit) != 0) 1519 break; 1520 if (bit != 0) { 1521 (void) fprintf(fp, "Invalid mask %s\n", 1522 numtoa(cres.mask)); 1523 err++; 1524 } 1525 } 1526 1527 if (err) 1528 return; 1529 1530 res = doquery(IMPL_XNTPD, req_code, 1, 1, 1531 sizeof(struct conf_restrict), (char *)&cres, &items, 1532 &itemsize, &dummy, 0); 1533 1534 if (res == 0) 1535 (void) fprintf(fp, "done!\n"); 1536 return; 1537 } 1538 1539 1540 /* 1541 * monlist - obtain and print the server's monitor data 1542 */ 1543 /*ARGSUSED*/ 1544 static void 1545 monlist( 1546 struct parse *pcmd, 1547 FILE *fp 1548 ) 1549 { 1550 char *struct_star; 1551 struct in_addr addr; 1552 int items; 1553 int itemsize; 1554 int res; 1555 int version = -1; 1556 1557 if (pcmd->nargs > 0) { 1558 version = pcmd->argval[0].ival; 1559 } 1560 1561 res = doquery(IMPL_XNTPD, 1562 (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : 1563 REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 1564 &items, &itemsize, &struct_star, 1565 (version < 0) ? (1 << INFO_ERR_REQ) : 0); 1566 1567 if (res == INFO_ERR_REQ && version < 0) 1568 res = doquery(IMPL_XNTPD, REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 1569 &items, &itemsize, &struct_star, 0); 1570 1571 if (res != 0 && items == 0) 1572 return; 1573 1574 if (!checkitems(items, fp)) 1575 return; 1576 1577 if (itemsize == sizeof(struct info_monitor_1)) { 1578 struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star; 1579 1580 (void) fprintf(fp, 1581 "remote address port local address count m ver drop last first\n"); 1582 (void) fprintf(fp, 1583 "===============================================================================\n"); 1584 while (items > 0) { 1585 addr.s_addr = ml->daddr; 1586 (void) fprintf(fp, 1587 "%-22.22s %5d %-15s %8ld %1d %1d %6lu %6lu %7lu\n", 1588 nntohost(ml->addr), 1589 ntohs(ml->port), 1590 inet_ntoa(addr), 1591 (u_long)ntohl(ml->count), 1592 ml->mode, 1593 ml->version, 1594 (u_long)ntohl(ml->lastdrop), 1595 (u_long)ntohl(ml->lasttime), 1596 (u_long)ntohl(ml->firsttime)); 1597 ml++; 1598 items--; 1599 } 1600 } else if (itemsize == sizeof(struct info_monitor)) { 1601 struct info_monitor *ml = (struct info_monitor *) struct_star; 1602 1603 (void) fprintf(fp, 1604 " address port count mode ver lastdrop lasttime firsttime\n"); 1605 (void) fprintf(fp, 1606 "===============================================================================\n"); 1607 while (items > 0) { 1608 addr.s_addr = ml->lastdrop; 1609 (void) fprintf(fp, 1610 "%-25.25s %5d %9ld %4d %2d %9lu %9lu %9lu\n", 1611 nntohost(ml->addr), 1612 ntohs(ml->port), 1613 (u_long)ntohl(ml->count), 1614 ml->mode, 1615 ml->version, 1616 (u_long)ntohl(ml->lastdrop), 1617 (u_long)ntohl(ml->lasttime), 1618 (u_long)ntohl(ml->firsttime)); 1619 ml++; 1620 items--; 1621 } 1622 } else if (itemsize == sizeof(struct old_info_monitor)) { 1623 struct old_info_monitor *oml = (struct old_info_monitor *)struct_star; 1624 (void) fprintf(fp, 1625 " address port count mode version lasttime firsttime\n"); 1626 (void) fprintf(fp, 1627 "======================================================================\n"); 1628 while (items > 0) { 1629 (void) fprintf(fp, "%-20.20s %5d %9ld %4d %3d %9lu %9lu\n", 1630 nntohost(oml->addr), 1631 ntohs(oml->port), 1632 (u_long)ntohl(oml->count), 1633 oml->mode, 1634 oml->version, 1635 (u_long)ntohl(oml->lasttime), 1636 (u_long)ntohl(oml->firsttime)); 1637 oml++; 1638 items--; 1639 } 1640 } else { 1641 /* issue warning according to new info_monitor size */ 1642 checkitemsize(itemsize, sizeof(struct info_monitor)); 1643 } 1644 } 1645 1646 1647 /* 1648 * Mapping between command line strings and stat reset flags 1649 */ 1650 struct statreset { 1651 const char *str; 1652 int flag; 1653 } sreset[] = { 1654 { "io", RESET_FLAG_IO }, 1655 { "sys", RESET_FLAG_SYS }, 1656 { "mem", RESET_FLAG_MEM }, 1657 { "timer", RESET_FLAG_TIMER }, 1658 { "auth", RESET_FLAG_AUTH }, 1659 { "allpeers", RESET_FLAG_ALLPEERS }, 1660 { "", 0 } 1661 }; 1662 1663 /* 1664 * reset - reset statistic counters 1665 */ 1666 static void 1667 reset( 1668 struct parse *pcmd, 1669 FILE *fp 1670 ) 1671 { 1672 struct reset_flags rflags; 1673 int items; 1674 int itemsize; 1675 char *dummy; 1676 int i; 1677 int res; 1678 int err; 1679 1680 err = 0; 1681 rflags.flags = 0; 1682 for (res = 0; res < pcmd->nargs; res++) { 1683 for (i = 0; sreset[i].flag != 0; i++) { 1684 if (STREQ(pcmd->argval[res].string, sreset[i].str)) 1685 break; 1686 } 1687 if (sreset[i].flag == 0) { 1688 (void) fprintf(fp, "Flag %s unknown\n", 1689 pcmd->argval[res].string); 1690 err++; 1691 } else { 1692 rflags.flags |= sreset[i].flag; 1693 } 1694 } 1695 1696 if (err) { 1697 (void) fprintf(fp, "Not done due to errors\n"); 1698 return; 1699 } 1700 1701 res = doquery(IMPL_XNTPD, REQ_RESET_STATS, 1, 1, 1702 sizeof(struct reset_flags), (char *)&rflags, &items, 1703 &itemsize, &dummy, 0); 1704 1705 if (res == 0) 1706 (void) fprintf(fp, "done!\n"); 1707 return; 1708 } 1709 1710 1711 1712 /* 1713 * preset - reset stat counters for particular peers 1714 */ 1715 static void 1716 preset( 1717 struct parse *pcmd, 1718 FILE *fp 1719 ) 1720 { 1721 /* 8 is the maximum number of peers which will fit in a packet */ 1722 struct conf_unpeer plist[min(MAXARGS, 8)]; 1723 int qitems; 1724 int items; 1725 int itemsize; 1726 char *dummy; 1727 int res; 1728 1729 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) { 1730 plist[qitems].peeraddr = pcmd->argval[qitems].netnum; 1731 } 1732 1733 res = doquery(IMPL_XNTPD, REQ_RESET_PEER, 1, qitems, 1734 sizeof(struct conf_unpeer), (char *)plist, &items, 1735 &itemsize, &dummy, 0); 1736 1737 if (res == 0) 1738 (void) fprintf(fp, "done!\n"); 1739 } 1740 1741 1742 /* 1743 * readkeys - request the server to reread the keys file 1744 */ 1745 /*ARGSUSED*/ 1746 static void 1747 readkeys( 1748 struct parse *pcmd, 1749 FILE *fp 1750 ) 1751 { 1752 int items; 1753 int itemsize; 1754 char *dummy; 1755 int res; 1756 1757 res = doquery(IMPL_XNTPD, REQ_REREAD_KEYS, 1, 0, 0, (char *)0, 1758 &items, &itemsize, &dummy, 0); 1759 1760 if (res == 0) 1761 (void) fprintf(fp, "done!\n"); 1762 return; 1763 } 1764 1765 1766 /* 1767 * trustkey - add some keys to the trusted key list 1768 */ 1769 static void 1770 trustkey( 1771 struct parse *pcmd, 1772 FILE *fp 1773 ) 1774 { 1775 do_trustkey(pcmd, fp, REQ_TRUSTKEY); 1776 } 1777 1778 1779 /* 1780 * untrustkey - remove some keys from the trusted key list 1781 */ 1782 static void 1783 untrustkey( 1784 struct parse *pcmd, 1785 FILE *fp 1786 ) 1787 { 1788 do_trustkey(pcmd, fp, REQ_UNTRUSTKEY); 1789 } 1790 1791 1792 /* 1793 * do_trustkey - do grunge work of adding/deleting keys 1794 */ 1795 static void 1796 do_trustkey( 1797 struct parse *pcmd, 1798 FILE *fp, 1799 int req 1800 ) 1801 { 1802 u_long keyids[MAXARGS]; 1803 int i; 1804 int items; 1805 int itemsize; 1806 char *dummy; 1807 int ritems; 1808 int res; 1809 1810 ritems = 0; 1811 for (i = 0; i < pcmd->nargs; i++) { 1812 keyids[ritems++] = pcmd->argval[i].uval; 1813 } 1814 1815 res = doquery(IMPL_XNTPD, req, 1, ritems, sizeof(u_long), 1816 (char *)keyids, &items, &itemsize, &dummy, 0); 1817 1818 if (res == 0) 1819 (void) fprintf(fp, "done!\n"); 1820 return; 1821 } 1822 1823 1824 1825 /* 1826 * authinfo - obtain and print info about authentication 1827 */ 1828 /*ARGSUSED*/ 1829 static void 1830 authinfo( 1831 struct parse *pcmd, 1832 FILE *fp 1833 ) 1834 { 1835 struct info_auth *ia; 1836 int items; 1837 int itemsize; 1838 int res; 1839 1840 res = doquery(IMPL_XNTPD, REQ_AUTHINFO, 0, 0, 0, (char *)NULL, 1841 &items, &itemsize, (char **)&ia, 0); 1842 1843 if (res != 0 && items == 0) 1844 return; 1845 1846 if (!check1item(items, fp)) 1847 return; 1848 1849 if (!checkitemsize(itemsize, sizeof(struct info_auth))) 1850 return; 1851 1852 (void) fprintf(fp, "time since reset: %ld\n", 1853 (u_long)ntohl(ia->timereset)); 1854 (void) fprintf(fp, "stored keys: %ld\n", 1855 (u_long)ntohl(ia->numkeys)); 1856 (void) fprintf(fp, "free keys: %ld\n", 1857 (u_long)ntohl(ia->numfreekeys)); 1858 (void) fprintf(fp, "key lookups: %ld\n", 1859 (u_long)ntohl(ia->keylookups)); 1860 (void) fprintf(fp, "keys not found: %ld\n", 1861 (u_long)ntohl(ia->keynotfound)); 1862 (void) fprintf(fp, "uncached keys: %ld\n", 1863 (u_long)ntohl(ia->keyuncached)); 1864 (void) fprintf(fp, "encryptions: %ld\n", 1865 (u_long)ntohl(ia->encryptions)); 1866 (void) fprintf(fp, "decryptions: %ld\n", 1867 (u_long)ntohl(ia->decryptions)); 1868 (void) fprintf(fp, "expired keys: %ld\n", 1869 (u_long)ntohl(ia->expired)); 1870 } 1871 1872 1873 1874 /* 1875 * traps - obtain and print a list of traps 1876 */ 1877 /*ARGSUSED*/ 1878 static void 1879 traps( 1880 struct parse *pcmd, 1881 FILE *fp 1882 ) 1883 { 1884 int i; 1885 struct info_trap *it; 1886 int items; 1887 int itemsize; 1888 int res; 1889 1890 res = doquery(IMPL_XNTPD, REQ_TRAPS, 0, 0, 0, (char *)NULL, 1891 &items, &itemsize, (char **)&it, 0); 1892 1893 if (res != 0 && items == 0) 1894 return; 1895 1896 if (!checkitems(items, fp)) 1897 return; 1898 1899 if (!checkitemsize(itemsize, sizeof(struct info_trap))) 1900 return; 1901 1902 for (i = 0; i < items; i++ ) { 1903 if (i != 0) 1904 (void) fprintf(fp, "\n"); 1905 (void) fprintf(fp, "address %s, port %d\n", 1906 numtoa(it->trap_address), ntohs(it->trap_port)); 1907 (void) fprintf(fp, "interface: %s, ", 1908 (it->local_address == 0) 1909 ? "wildcard" 1910 : numtoa(it->local_address)); 1911 1912 if (ntohl(it->flags) & TRAP_CONFIGURED) 1913 (void) fprintf(fp, "configured\n"); 1914 else if (ntohl(it->flags) & TRAP_NONPRIO) 1915 (void) fprintf(fp, "low priority\n"); 1916 else 1917 (void) fprintf(fp, "normal priority\n"); 1918 1919 (void) fprintf(fp, "set for %ld secs, last set %ld secs ago\n", 1920 (long)ntohl(it->origtime), 1921 (long)ntohl(it->settime)); 1922 (void) fprintf(fp, "sequence %d, number of resets %ld\n", 1923 ntohs(it->sequence), 1924 (long)ntohl(it->resets)); 1925 } 1926 } 1927 1928 1929 /* 1930 * addtrap - configure a trap 1931 */ 1932 static void 1933 addtrap( 1934 struct parse *pcmd, 1935 FILE *fp 1936 ) 1937 { 1938 do_addclr_trap(pcmd, fp, REQ_ADD_TRAP); 1939 } 1940 1941 1942 /* 1943 * clrtrap - clear a trap from the server 1944 */ 1945 static void 1946 clrtrap( 1947 struct parse *pcmd, 1948 FILE *fp 1949 ) 1950 { 1951 do_addclr_trap(pcmd, fp, REQ_CLR_TRAP); 1952 } 1953 1954 1955 /* 1956 * do_addclr_trap - do grunge work of adding/deleting traps 1957 */ 1958 static void 1959 do_addclr_trap( 1960 struct parse *pcmd, 1961 FILE *fp, 1962 int req 1963 ) 1964 { 1965 struct conf_trap ctrap; 1966 int items; 1967 int itemsize; 1968 char *dummy; 1969 int res; 1970 1971 ctrap.trap_address = pcmd->argval[0].netnum; 1972 ctrap.local_address = 0; 1973 ctrap.trap_port = htons(TRAPPORT); 1974 ctrap.unused = 0; 1975 1976 if (pcmd->nargs > 1) { 1977 ctrap.trap_port 1978 = htons((u_short)(pcmd->argval[1].uval & 0xffff)); 1979 if (pcmd->nargs > 2) 1980 ctrap.local_address = pcmd->argval[2].netnum; 1981 } 1982 1983 res = doquery(IMPL_XNTPD, req, 1, 1, sizeof(struct conf_trap), 1984 (char *)&ctrap, &items, &itemsize, &dummy, 0); 1985 1986 if (res == 0) 1987 (void) fprintf(fp, "done!\n"); 1988 return; 1989 } 1990 1991 1992 1993 /* 1994 * requestkey - change the server's request key (a dangerous request) 1995 */ 1996 static void 1997 requestkey( 1998 struct parse *pcmd, 1999 FILE *fp 2000 ) 2001 { 2002 do_changekey(pcmd, fp, REQ_REQUEST_KEY); 2003 } 2004 2005 2006 /* 2007 * controlkey - change the server's control key 2008 */ 2009 static void 2010 controlkey( 2011 struct parse *pcmd, 2012 FILE *fp 2013 ) 2014 { 2015 do_changekey(pcmd, fp, REQ_CONTROL_KEY); 2016 } 2017 2018 2019 2020 /* 2021 * do_changekey - do grunge work of changing keys 2022 */ 2023 static void 2024 do_changekey( 2025 struct parse *pcmd, 2026 FILE *fp, 2027 int req 2028 ) 2029 { 2030 u_long key; 2031 int items; 2032 int itemsize; 2033 char *dummy; 2034 int res; 2035 2036 2037 key = htonl((u_int32)pcmd->argval[0].uval); 2038 2039 res = doquery(IMPL_XNTPD, req, 1, 1, sizeof(u_int32), 2040 (char *)&key, &items, &itemsize, &dummy, 0); 2041 2042 if (res == 0) 2043 (void) fprintf(fp, "done!\n"); 2044 return; 2045 } 2046 2047 2048 2049 /* 2050 * ctlstats - obtain and print info about authentication 2051 */ 2052 /*ARGSUSED*/ 2053 static void 2054 ctlstats( 2055 struct parse *pcmd, 2056 FILE *fp 2057 ) 2058 { 2059 struct info_control *ic; 2060 int items; 2061 int itemsize; 2062 int res; 2063 2064 res = doquery(IMPL_XNTPD, REQ_GET_CTLSTATS, 0, 0, 0, (char *)NULL, 2065 &items, &itemsize, (char **)&ic, 0); 2066 2067 if (res != 0 && items == 0) 2068 return; 2069 2070 if (!check1item(items, fp)) 2071 return; 2072 2073 if (!checkitemsize(itemsize, sizeof(struct info_control))) 2074 return; 2075 2076 (void) fprintf(fp, "time since reset: %ld\n", 2077 (u_long)ntohl(ic->ctltimereset)); 2078 (void) fprintf(fp, "requests received: %ld\n", 2079 (u_long)ntohl(ic->numctlreq)); 2080 (void) fprintf(fp, "responses sent: %ld\n", 2081 (u_long)ntohl(ic->numctlresponses)); 2082 (void) fprintf(fp, "fragments sent: %ld\n", 2083 (u_long)ntohl(ic->numctlfrags)); 2084 (void) fprintf(fp, "async messages sent: %ld\n", 2085 (u_long)ntohl(ic->numasyncmsgs)); 2086 (void) fprintf(fp, "error msgs sent: %ld\n", 2087 (u_long)ntohl(ic->numctlerrors)); 2088 (void) fprintf(fp, "total bad pkts: %ld\n", 2089 (u_long)ntohl(ic->numctlbadpkts)); 2090 (void) fprintf(fp, "packet too short: %ld\n", 2091 (u_long)ntohl(ic->numctltooshort)); 2092 (void) fprintf(fp, "response on input: %ld\n", 2093 (u_long)ntohl(ic->numctlinputresp)); 2094 (void) fprintf(fp, "fragment on input: %ld\n", 2095 (u_long)ntohl(ic->numctlinputfrag)); 2096 (void) fprintf(fp, "error set on input: %ld\n", 2097 (u_long)ntohl(ic->numctlinputerr)); 2098 (void) fprintf(fp, "bad offset on input: %ld\n", 2099 (u_long)ntohl(ic->numctlbadoffset)); 2100 (void) fprintf(fp, "bad version packets: %ld\n", 2101 (u_long)ntohl(ic->numctlbadversion)); 2102 (void) fprintf(fp, "data in pkt too short: %ld\n", 2103 (u_long)ntohl(ic->numctldatatooshort)); 2104 (void) fprintf(fp, "unknown op codes: %ld\n", 2105 (u_long)ntohl(ic->numctlbadop)); 2106 } 2107 2108 2109 /* 2110 * clockstat - get and print clock status information 2111 */ 2112 static void 2113 clockstat( 2114 struct parse *pcmd, 2115 FILE *fp 2116 ) 2117 { 2118 struct info_clock *cl; 2119 /* 8 is the maximum number of clocks which will fit in a packet */ 2120 u_long clist[min(MAXARGS, 8)]; 2121 int qitems; 2122 int items; 2123 int itemsize; 2124 int res; 2125 l_fp ts; 2126 struct clktype *clk; 2127 u_long ltemp; 2128 2129 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 2130 clist[qitems] = pcmd->argval[qitems].netnum; 2131 2132 res = doquery(IMPL_XNTPD, REQ_GET_CLOCKINFO, 0, qitems, 2133 sizeof(u_int32), (char *)clist, &items, 2134 &itemsize, (char **)&cl, 0); 2135 2136 if (res != 0 && items == 0) 2137 return; 2138 2139 if (!checkitems(items, fp)) 2140 return; 2141 2142 if (!checkitemsize(itemsize, sizeof(struct info_clock))) 2143 return; 2144 2145 while (items-- > 0) { 2146 (void) fprintf(fp, "clock address: %s\n", 2147 numtoa(cl->clockadr)); 2148 for (clk = clktypes; clk->code >= 0; clk++) 2149 if (clk->code == cl->type) 2150 break; 2151 if (clk->code >= 0) 2152 (void) fprintf(fp, "clock type: %s\n", 2153 clk->clocktype); 2154 else 2155 (void) fprintf(fp, "clock type: unknown type (%d)\n", 2156 cl->type); 2157 (void) fprintf(fp, "last event: %d\n", 2158 cl->lastevent); 2159 (void) fprintf(fp, "current status: %d\n", 2160 cl->currentstatus); 2161 (void) fprintf(fp, "number of polls: %lu\n", 2162 (u_long)ntohl(cl->polls)); 2163 (void) fprintf(fp, "no response to poll: %lu\n", 2164 (u_long)ntohl(cl->noresponse)); 2165 (void) fprintf(fp, "bad format responses: %lu\n", 2166 (u_long)ntohl(cl->badformat)); 2167 (void) fprintf(fp, "bad data responses: %lu\n", 2168 (u_long)ntohl(cl->baddata)); 2169 (void) fprintf(fp, "running time: %lu\n", 2170 (u_long)ntohl(cl->timestarted)); 2171 NTOHL_FP(&cl->fudgetime1, &ts); 2172 (void) fprintf(fp, "fudge time 1: %s\n", 2173 lfptoa(&ts, 6)); 2174 NTOHL_FP(&cl->fudgetime2, &ts); 2175 (void) fprintf(fp, "fudge time 2: %s\n", 2176 lfptoa(&ts, 6)); 2177 (void) fprintf(fp, "stratum: %ld\n", 2178 (u_long)ntohl(cl->fudgeval1)); 2179 ltemp = ntohl(cl->fudgeval2); 2180 (void) fprintf(fp, "reference ID: %s\n", 2181 (char *)<emp); 2182 (void) fprintf(fp, "fudge flags: 0x%x\n", 2183 cl->flags); 2184 2185 if (items > 0) 2186 (void) fprintf(fp, "\n"); 2187 cl++; 2188 } 2189 } 2190 2191 2192 /* 2193 * fudge - set clock fudge factors 2194 */ 2195 static void 2196 fudge( 2197 struct parse *pcmd, 2198 FILE *fp 2199 ) 2200 { 2201 struct conf_fudge fudgedata; 2202 int items; 2203 int itemsize; 2204 char *dummy; 2205 l_fp ts; 2206 int res; 2207 long val; 2208 u_long u_val; 2209 int err; 2210 2211 2212 err = 0; 2213 memset((char *)&fudgedata, 0, sizeof fudgedata); 2214 fudgedata.clockadr = pcmd->argval[0].netnum; 2215 2216 if (STREQ(pcmd->argval[1].string, "time1")) { 2217 fudgedata.which = htonl(FUDGE_TIME1); 2218 if (!atolfp(pcmd->argval[2].string, &ts)) 2219 err = 1; 2220 else 2221 NTOHL_FP(&ts, &fudgedata.fudgetime); 2222 } else if (STREQ(pcmd->argval[1].string, "time2")) { 2223 fudgedata.which = htonl(FUDGE_TIME2); 2224 if (!atolfp(pcmd->argval[2].string, &ts)) 2225 err = 1; 2226 else 2227 NTOHL_FP(&ts, &fudgedata.fudgetime); 2228 } else if (STREQ(pcmd->argval[1].string, "val1")) { 2229 fudgedata.which = htonl(FUDGE_VAL1); 2230 if (!atoint(pcmd->argval[2].string, &val)) 2231 err = 1; 2232 else 2233 fudgedata.fudgeval_flags = htonl(val); 2234 } else if (STREQ(pcmd->argval[1].string, "val2")) { 2235 fudgedata.which = htonl(FUDGE_VAL2); 2236 if (!atoint(pcmd->argval[2].string, &val)) 2237 err = 1; 2238 else 2239 fudgedata.fudgeval_flags = htonl((u_int32)val); 2240 } else if (STREQ(pcmd->argval[1].string, "flags")) { 2241 fudgedata.which = htonl(FUDGE_FLAGS); 2242 if (!hextoint(pcmd->argval[2].string, &u_val)) 2243 err = 1; 2244 else 2245 fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf)); 2246 } else { 2247 (void) fprintf(stderr, "What fudge is %s?\n", 2248 pcmd->argval[1].string); 2249 return; 2250 } 2251 2252 if (err) { 2253 (void) fprintf(stderr, "Unknown fudge parameter %s\n", 2254 pcmd->argval[2].string); 2255 return; 2256 } 2257 2258 2259 res = doquery(IMPL_XNTPD, REQ_SET_CLKFUDGE, 1, 1, 2260 sizeof(struct conf_fudge), (char *)&fudgedata, &items, 2261 &itemsize, &dummy, 0); 2262 2263 if (res == 0) 2264 (void) fprintf(fp, "done!\n"); 2265 return; 2266 } 2267 2268 /* 2269 * clkbug - get and print clock debugging information 2270 */ 2271 static void 2272 clkbug( 2273 struct parse *pcmd, 2274 FILE *fp 2275 ) 2276 { 2277 register int i; 2278 register int n; 2279 register u_int32 s; 2280 struct info_clkbug *cl; 2281 /* 8 is the maximum number of clocks which will fit in a packet */ 2282 u_long clist[min(MAXARGS, 8)]; 2283 u_int32 ltemp; 2284 int qitems; 2285 int items; 2286 int itemsize; 2287 int res; 2288 int needsp; 2289 l_fp ts; 2290 2291 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 2292 clist[qitems] = pcmd->argval[qitems].netnum; 2293 2294 res = doquery(IMPL_XNTPD, REQ_GET_CLKBUGINFO, 0, qitems, 2295 sizeof(u_int32), (char *)clist, &items, 2296 &itemsize, (char **)&cl, 0); 2297 2298 if (res != 0 && items == 0) 2299 return; 2300 2301 if (!checkitems(items, fp)) 2302 return; 2303 2304 if (!checkitemsize(itemsize, sizeof(struct info_clkbug))) 2305 return; 2306 2307 while (items-- > 0) { 2308 (void) fprintf(fp, "clock address: %s\n", 2309 numtoa(cl->clockadr)); 2310 n = (int)cl->nvalues; 2311 (void) fprintf(fp, "values: %d", n); 2312 s = ntohs(cl->svalues); 2313 if (n > NUMCBUGVALUES) 2314 n = NUMCBUGVALUES; 2315 for (i = 0; i < n; i++) { 2316 ltemp = ntohl(cl->values[i]); 2317 ltemp &= 0xffffffff; /* HMS: This does nothing now */ 2318 if ((i & 0x3) == 0) 2319 (void) fprintf(fp, "\n"); 2320 if (s & (1 << i)) 2321 (void) fprintf(fp, "%12ld", (u_long)ltemp); 2322 else 2323 (void) fprintf(fp, "%12lu", (u_long)ltemp); 2324 } 2325 (void) fprintf(fp, "\n"); 2326 2327 n = (int)cl->ntimes; 2328 (void) fprintf(fp, "times: %d", n); 2329 s = ntohl(cl->stimes); 2330 if (n > NUMCBUGTIMES) 2331 n = NUMCBUGTIMES; 2332 needsp = 0; 2333 for (i = 0; i < n; i++) { 2334 if ((i & 0x1) == 0) { 2335 (void) fprintf(fp, "\n"); 2336 } else { 2337 for (;needsp > 0; needsp--) 2338 putc(' ', fp); 2339 } 2340 NTOHL_FP(&cl->times[i], &ts); 2341 if (s & (1 << i)) { 2342 (void) fprintf(fp, "%17s", 2343 lfptoa(&ts, 6)); 2344 needsp = 22; 2345 } else { 2346 (void) fprintf(fp, "%37s", 2347 uglydate(&ts)); 2348 needsp = 2; 2349 } 2350 } 2351 (void) fprintf(fp, "\n"); 2352 if (items > 0) { 2353 cl++; 2354 (void) fprintf(fp, "\n"); 2355 } 2356 } 2357 } 2358 2359 2360 /* 2361 * kerninfo - display the kernel pll/pps variables 2362 */ 2363 static void 2364 kerninfo( 2365 struct parse *pcmd, 2366 FILE *fp 2367 ) 2368 { 2369 struct info_kernel *ik; 2370 int items; 2371 int itemsize; 2372 int res; 2373 unsigned status; 2374 double tscale = 1e-6; 2375 2376 res = doquery(IMPL_XNTPD, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL, 2377 &items, &itemsize, (char **)&ik, 0); 2378 if (res != 0 && items == 0) 2379 return; 2380 if (!check1item(items, fp)) 2381 return; 2382 if (!checkitemsize(itemsize, sizeof(struct info_kernel))) 2383 return; 2384 2385 status = ntohs(ik->status) & 0xffff; 2386 /* 2387 * pll variables. We know more than we should about the NANO bit. 2388 */ 2389 #ifdef STA_NANO 2390 if (status & STA_NANO) 2391 tscale = 1e-9; 2392 #endif 2393 (void)fprintf(fp, "pll offset: %g s\n", 2394 (long)ntohl(ik->offset) * tscale); 2395 (void)fprintf(fp, "pll frequency: %s ppm\n", 2396 fptoa((s_fp)ntohl(ik->freq), 3)); 2397 (void)fprintf(fp, "maximum error: %g s\n", 2398 (u_long)ntohl(ik->maxerror) * 1e-6); 2399 (void)fprintf(fp, "estimated error: %g s\n", 2400 (u_long)ntohl(ik->esterror) * 1e-6); 2401 (void)fprintf(fp, "status: %04x ", status); 2402 #ifdef STA_PLL 2403 if (status & STA_PLL) (void)fprintf(fp, " pll"); 2404 #endif 2405 #ifdef STA_PPSFREQ 2406 if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq"); 2407 #endif 2408 #ifdef STA_PPSTIME 2409 if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime"); 2410 #endif 2411 #ifdef STA_FLL 2412 if (status & STA_FLL) (void)fprintf(fp, " fll"); 2413 #endif 2414 #ifdef STA_INS 2415 if (status & STA_INS) (void)fprintf(fp, " ins"); 2416 #endif 2417 #ifdef STA_DEL 2418 if (status & STA_DEL) (void)fprintf(fp, " del"); 2419 #endif 2420 #ifdef STA_UNSYNC 2421 if (status & STA_UNSYNC) (void)fprintf(fp, " unsync"); 2422 #endif 2423 #ifdef STA_FREQHOLD 2424 if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold"); 2425 #endif 2426 #ifdef STA_PPSSIGNAL 2427 if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal"); 2428 #endif 2429 #ifdef STA_PPSJITTER 2430 if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter"); 2431 #endif 2432 #ifdef STA_PPSWANDER 2433 if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander"); 2434 #endif 2435 #ifdef STA_PPSERROR 2436 if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror"); 2437 #endif 2438 #ifdef STA_CLOCKERR 2439 if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr"); 2440 #endif 2441 #ifdef STA_NANO 2442 if (status & STA_NANO) (void)fprintf(fp, " nano"); 2443 #endif 2444 #ifdef STA_MODE 2445 if (status & STA_MODE) (void)fprintf(fp, " mode=fll"); 2446 #endif 2447 #ifdef STA_CLK 2448 if (status & STA_CLK) (void)fprintf(fp, " src=B"); 2449 #endif 2450 (void)fprintf(fp, "\n"); 2451 (void)fprintf(fp, "pll time constant: %ld\n", 2452 (u_long)ntohl(ik->constant)); 2453 (void)fprintf(fp, "precision: %g s\n", 2454 (u_long)ntohl(ik->precision) * tscale); 2455 (void)fprintf(fp, "frequency tolerance: %s ppm\n", 2456 fptoa((s_fp)ntohl(ik->tolerance), 0)); 2457 2458 /* 2459 * For backwards compatibility (ugh), we find the pps variables 2460 * only if the shift member is nonzero. 2461 */ 2462 if (!ik->shift) 2463 return; 2464 2465 /* 2466 * pps variables 2467 */ 2468 (void)fprintf(fp, "pps frequency: %s ppm\n", 2469 fptoa((s_fp)ntohl(ik->ppsfreq), 3)); 2470 (void)fprintf(fp, "pps stability: %s ppm\n", 2471 fptoa((s_fp)ntohl(ik->stabil), 3)); 2472 (void)fprintf(fp, "pps jitter: %g s\n", 2473 (u_long)ntohl(ik->jitter) * tscale); 2474 (void)fprintf(fp, "calibration interval: %d s\n", 2475 1 << ntohs(ik->shift)); 2476 (void)fprintf(fp, "calibration cycles: %ld\n", 2477 (u_long)ntohl(ik->calcnt)); 2478 (void)fprintf(fp, "jitter exceeded: %ld\n", 2479 (u_long)ntohl(ik->jitcnt)); 2480 (void)fprintf(fp, "stability exceeded: %ld\n", 2481 (u_long)ntohl(ik->stbcnt)); 2482 (void)fprintf(fp, "calibration errors: %ld\n", 2483 (u_long)ntohl(ik->errcnt)); 2484 } 2485