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_PLL_SYNC | 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_PLL_SYNC) 806 (void) fprintf(fp, "kernel_sync "); 807 if (is->flags & INFO_FLAG_PPS_SYNC) 808 (void) fprintf(fp, "pps_sync "); 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 == 0) 1178 (void) fprintf(fp, "done!\n"); 1179 return; 1180 } 1181 1182 1183 /* 1184 * unconfig - unconfigure some associations 1185 */ 1186 static void 1187 unconfig( 1188 struct parse *pcmd, 1189 FILE *fp 1190 ) 1191 { 1192 /* 8 is the maximum number of peers which will fit in a packet */ 1193 struct conf_unpeer plist[min(MAXARGS, 8)]; 1194 int qitems; 1195 int items; 1196 int itemsize; 1197 char *dummy; 1198 int res; 1199 1200 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) { 1201 plist[qitems].peeraddr = pcmd->argval[qitems].netnum; 1202 } 1203 1204 res = doquery(IMPL_XNTPD, REQ_UNCONFIG, 1, qitems, 1205 sizeof(struct conf_unpeer), (char *)plist, &items, 1206 &itemsize, &dummy, 0); 1207 1208 if (res == 0) 1209 (void) fprintf(fp, "done!\n"); 1210 } 1211 1212 1213 /* 1214 * set - set some system flags 1215 */ 1216 static void 1217 set( 1218 struct parse *pcmd, 1219 FILE *fp 1220 ) 1221 { 1222 doset(pcmd, fp, REQ_SET_SYS_FLAG); 1223 } 1224 1225 1226 /* 1227 * clear - clear some system flags 1228 */ 1229 static void 1230 sys_clear( 1231 struct parse *pcmd, 1232 FILE *fp 1233 ) 1234 { 1235 doset(pcmd, fp, REQ_CLR_SYS_FLAG); 1236 } 1237 1238 1239 /* 1240 * doset - set/clear system flags 1241 */ 1242 static void 1243 doset( 1244 struct parse *pcmd, 1245 FILE *fp, 1246 int req 1247 ) 1248 { 1249 /* 8 is the maximum number of peers which will fit in a packet */ 1250 struct conf_sys_flags sys; 1251 int items; 1252 int itemsize; 1253 char *dummy; 1254 int res; 1255 1256 sys.flags = 0; 1257 res = 0; 1258 for (items = 0; items < pcmd->nargs; items++) { 1259 if (STREQ(pcmd->argval[items].string, "pps")) 1260 sys.flags |= SYS_FLAG_PPS; 1261 else if (STREQ(pcmd->argval[items].string, "bclient")) 1262 sys.flags |= SYS_FLAG_BCLIENT; 1263 else if (STREQ(pcmd->argval[items].string, "monitor")) 1264 sys.flags |= SYS_FLAG_MONITOR; 1265 else if (STREQ(pcmd->argval[items].string, "ntp")) 1266 sys.flags |= SYS_FLAG_NTP; 1267 else if (STREQ(pcmd->argval[items].string, "kernel")) 1268 sys.flags |= SYS_FLAG_KERNEL; 1269 else if (STREQ(pcmd->argval[items].string, "stats")) 1270 sys.flags |= SYS_FLAG_FILEGEN; 1271 else { 1272 (void) fprintf(fp, "Unknown flag %s\n", 1273 pcmd->argval[items].string); 1274 res = 1; 1275 } 1276 } 1277 1278 if (res || sys.flags == 0) 1279 return; 1280 1281 res = doquery(IMPL_XNTPD, req, 1, 1, 1282 sizeof(struct conf_sys_flags), (char *)&sys, &items, 1283 &itemsize, &dummy, 0); 1284 1285 if (res == 0) 1286 (void) fprintf(fp, "done!\n"); 1287 } 1288 1289 1290 /* 1291 * data for printing/interrpreting the restrict flags 1292 */ 1293 struct resflags { 1294 const char *str; 1295 int bit; 1296 }; 1297 1298 static struct resflags resflags[] = { 1299 { "ignore", RES_IGNORE }, 1300 { "noserve", RES_DONTSERVE }, 1301 { "notrust", RES_DONTTRUST }, 1302 { "noquery", RES_NOQUERY }, 1303 { "nomodify", RES_NOMODIFY }, 1304 { "nopeer", RES_NOPEER }, 1305 { "notrap", RES_NOTRAP }, 1306 { "lptrap", RES_LPTRAP }, 1307 { "limited", RES_LIMITED }, 1308 { "version", RES_VERSION }, 1309 { "kod", RES_DEMOBILIZE }, 1310 1311 { "", 0 } 1312 }; 1313 1314 static struct resflags resmflags[] = { 1315 { "ntpport", RESM_NTPONLY }, 1316 { "interface", RESM_INTERFACE }, 1317 { "", 0 } 1318 }; 1319 1320 1321 /* 1322 * reslist - obtain and print the server's restrict list 1323 */ 1324 /*ARGSUSED*/ 1325 static void 1326 reslist( 1327 struct parse *pcmd, 1328 FILE *fp 1329 ) 1330 { 1331 struct info_restrict *rl; 1332 int items; 1333 int itemsize; 1334 int res; 1335 char *addr; 1336 char *mask; 1337 struct resflags *rf; 1338 u_int32 count; 1339 u_short flags; 1340 u_short mflags; 1341 char flagstr[300]; 1342 static const char *comma = ", "; 1343 1344 res = doquery(IMPL_XNTPD, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL, 1345 &items, &itemsize, (char **)&rl, 0); 1346 1347 if (res != 0 && items == 0) 1348 return; 1349 1350 if (!checkitems(items, fp)) 1351 return; 1352 1353 if (!checkitemsize(itemsize, sizeof(struct info_restrict))) 1354 return; 1355 1356 (void) fprintf(fp, 1357 " address mask count flags\n"); 1358 (void) fprintf(fp, 1359 "=====================================================================\n"); 1360 while (items > 0) { 1361 if ((rl->mask == (u_int32)0xffffffff)) 1362 addr = nntohost(rl->addr); 1363 else 1364 addr = numtoa( rl->addr ); 1365 mask = numtoa(rl->mask); 1366 count = ntohl(rl->count); 1367 flags = ntohs(rl->flags); 1368 mflags = ntohs(rl->mflags); 1369 flagstr[0] = '\0'; 1370 1371 res = 1; 1372 rf = &resmflags[0]; 1373 while (rf->bit != 0) { 1374 if (mflags & rf->bit) { 1375 if (!res) 1376 (void) strcat(flagstr, comma); 1377 res = 0; 1378 (void) strcat(flagstr, rf->str); 1379 } 1380 rf++; 1381 } 1382 1383 rf = &resflags[0]; 1384 while (rf->bit != 0) { 1385 if (flags & 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 if (flagstr[0] == '\0') 1395 (void) strcpy(flagstr, "none"); 1396 1397 (void) fprintf(fp, "%-15.15s %-15.15s %9ld %s\n", 1398 addr, mask, (u_long)count, flagstr); 1399 rl++; 1400 items--; 1401 } 1402 } 1403 1404 1405 1406 /* 1407 * new_restrict - create/add a set of restrictions 1408 */ 1409 static void 1410 new_restrict( 1411 struct parse *pcmd, 1412 FILE *fp 1413 ) 1414 { 1415 do_restrict(pcmd, fp, REQ_RESADDFLAGS); 1416 } 1417 1418 1419 /* 1420 * unrestrict - remove restriction flags from existing entry 1421 */ 1422 static void 1423 unrestrict( 1424 struct parse *pcmd, 1425 FILE *fp 1426 ) 1427 { 1428 do_restrict(pcmd, fp, REQ_RESSUBFLAGS); 1429 } 1430 1431 1432 /* 1433 * delrestrict - delete an existing restriction 1434 */ 1435 static void 1436 delrestrict( 1437 struct parse *pcmd, 1438 FILE *fp 1439 ) 1440 { 1441 do_restrict(pcmd, fp, REQ_UNRESTRICT); 1442 } 1443 1444 1445 /* 1446 * do_restrict - decode commandline restrictions and make the request 1447 */ 1448 static void 1449 do_restrict( 1450 struct parse *pcmd, 1451 FILE *fp, 1452 int req_code 1453 ) 1454 { 1455 struct conf_restrict cres; 1456 int items; 1457 int itemsize; 1458 char *dummy; 1459 u_int32 num; 1460 u_long bit; 1461 int i; 1462 int res; 1463 int err; 1464 1465 cres.addr = pcmd->argval[0].netnum; 1466 cres.mask = pcmd->argval[1].netnum; 1467 cres.flags = 0; 1468 cres.mflags = 0; 1469 err = 0; 1470 for (res = 2; res < pcmd->nargs; res++) { 1471 if (STREQ(pcmd->argval[res].string, "ntpport")) { 1472 cres.mflags |= RESM_NTPONLY; 1473 } else { 1474 for (i = 0; resflags[i].bit != 0; i++) { 1475 if (STREQ(pcmd->argval[res].string, 1476 resflags[i].str)) 1477 break; 1478 } 1479 if (resflags[i].bit != 0) { 1480 cres.flags |= resflags[i].bit; 1481 if (req_code == REQ_UNRESTRICT) { 1482 (void) fprintf(fp, 1483 "Flag %s inappropriate\n", 1484 resflags[i].str); 1485 err++; 1486 } 1487 } else { 1488 (void) fprintf(fp, "Unknown flag %s\n", 1489 pcmd->argval[res].string); 1490 err++; 1491 } 1492 } 1493 } 1494 1495 /* 1496 * Make sure mask for default address is zero. Otherwise, 1497 * make sure mask bits are contiguous. 1498 */ 1499 if (cres.addr == 0) { 1500 cres.mask = 0; 1501 } else { 1502 num = ntohl(cres.mask); 1503 for (bit = 0x80000000; bit != 0; bit >>= 1) 1504 if ((num & bit) == 0) 1505 break; 1506 for ( ; bit != 0; bit >>= 1) 1507 if ((num & bit) != 0) 1508 break; 1509 if (bit != 0) { 1510 (void) fprintf(fp, "Invalid mask %s\n", 1511 numtoa(cres.mask)); 1512 err++; 1513 } 1514 } 1515 1516 if (err) 1517 return; 1518 1519 res = doquery(IMPL_XNTPD, req_code, 1, 1, 1520 sizeof(struct conf_restrict), (char *)&cres, &items, 1521 &itemsize, &dummy, 0); 1522 1523 if (res == 0) 1524 (void) fprintf(fp, "done!\n"); 1525 return; 1526 } 1527 1528 1529 /* 1530 * monlist - obtain and print the server's monitor data 1531 */ 1532 /*ARGSUSED*/ 1533 static void 1534 monlist( 1535 struct parse *pcmd, 1536 FILE *fp 1537 ) 1538 { 1539 char *struct_star; 1540 struct in_addr addr; 1541 int items; 1542 int itemsize; 1543 int res; 1544 int version = -1; 1545 1546 if (pcmd->nargs > 0) { 1547 version = pcmd->argval[0].ival; 1548 } 1549 1550 res = doquery(IMPL_XNTPD, 1551 (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : 1552 REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 1553 &items, &itemsize, &struct_star, 1554 (version < 0) ? (1 << INFO_ERR_REQ) : 0); 1555 1556 if (res == INFO_ERR_REQ && version < 0) 1557 res = doquery(IMPL_XNTPD, REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, 1558 &items, &itemsize, &struct_star, 0); 1559 1560 if (res != 0 && items == 0) 1561 return; 1562 1563 if (!checkitems(items, fp)) 1564 return; 1565 1566 if (itemsize == sizeof(struct info_monitor_1)) { 1567 struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star; 1568 1569 (void) fprintf(fp, 1570 "remote address port local address count m ver drop last first\n"); 1571 (void) fprintf(fp, 1572 "===============================================================================\n"); 1573 while (items > 0) { 1574 addr.s_addr = ml->daddr; 1575 (void) fprintf(fp, 1576 "%-22.22s %5d %-15s %8ld %1d %1d %6lu %6lu %7lu\n", 1577 nntohost(ml->addr), 1578 ntohs(ml->port), 1579 inet_ntoa(addr), 1580 (u_long)ntohl(ml->count), 1581 ml->mode, 1582 ml->version, 1583 (u_long)ntohl(ml->lastdrop), 1584 (u_long)ntohl(ml->lasttime), 1585 (u_long)ntohl(ml->firsttime)); 1586 ml++; 1587 items--; 1588 } 1589 } else if (itemsize == sizeof(struct info_monitor)) { 1590 struct info_monitor *ml = (struct info_monitor *) struct_star; 1591 1592 (void) fprintf(fp, 1593 " address port count mode ver lastdrop lasttime firsttime\n"); 1594 (void) fprintf(fp, 1595 "===============================================================================\n"); 1596 while (items > 0) { 1597 addr.s_addr = ml->lastdrop; 1598 (void) fprintf(fp, 1599 "%-25.25s %5d %9ld %4d %2d %9lu %9lu %9lu\n", 1600 nntohost(ml->addr), 1601 ntohs(ml->port), 1602 (u_long)ntohl(ml->count), 1603 ml->mode, 1604 ml->version, 1605 (u_long)ntohl(ml->lastdrop), 1606 (u_long)ntohl(ml->lasttime), 1607 (u_long)ntohl(ml->firsttime)); 1608 ml++; 1609 items--; 1610 } 1611 } else if (itemsize == sizeof(struct old_info_monitor)) { 1612 struct old_info_monitor *oml = (struct old_info_monitor *)struct_star; 1613 (void) fprintf(fp, 1614 " address port count mode version lasttime firsttime\n"); 1615 (void) fprintf(fp, 1616 "======================================================================\n"); 1617 while (items > 0) { 1618 (void) fprintf(fp, "%-20.20s %5d %9ld %4d %3d %9lu %9lu\n", 1619 nntohost(oml->addr), 1620 ntohs(oml->port), 1621 (u_long)ntohl(oml->count), 1622 oml->mode, 1623 oml->version, 1624 (u_long)ntohl(oml->lasttime), 1625 (u_long)ntohl(oml->firsttime)); 1626 oml++; 1627 items--; 1628 } 1629 } else { 1630 /* issue warning according to new info_monitor size */ 1631 checkitemsize(itemsize, sizeof(struct info_monitor)); 1632 } 1633 } 1634 1635 1636 /* 1637 * Mapping between command line strings and stat reset flags 1638 */ 1639 struct statreset { 1640 const char *str; 1641 int flag; 1642 } sreset[] = { 1643 { "io", RESET_FLAG_IO }, 1644 { "sys", RESET_FLAG_SYS }, 1645 { "mem", RESET_FLAG_MEM }, 1646 { "timer", RESET_FLAG_TIMER }, 1647 { "auth", RESET_FLAG_AUTH }, 1648 { "allpeers", RESET_FLAG_ALLPEERS }, 1649 { "", 0 } 1650 }; 1651 1652 /* 1653 * reset - reset statistic counters 1654 */ 1655 static void 1656 reset( 1657 struct parse *pcmd, 1658 FILE *fp 1659 ) 1660 { 1661 struct reset_flags rflags; 1662 int items; 1663 int itemsize; 1664 char *dummy; 1665 int i; 1666 int res; 1667 int err; 1668 1669 err = 0; 1670 rflags.flags = 0; 1671 for (res = 0; res < pcmd->nargs; res++) { 1672 for (i = 0; sreset[i].flag != 0; i++) { 1673 if (STREQ(pcmd->argval[res].string, sreset[i].str)) 1674 break; 1675 } 1676 if (sreset[i].flag == 0) { 1677 (void) fprintf(fp, "Flag %s unknown\n", 1678 pcmd->argval[res].string); 1679 err++; 1680 } else { 1681 rflags.flags |= sreset[i].flag; 1682 } 1683 } 1684 1685 if (err) { 1686 (void) fprintf(fp, "Not done due to errors\n"); 1687 return; 1688 } 1689 1690 res = doquery(IMPL_XNTPD, REQ_RESET_STATS, 1, 1, 1691 sizeof(struct reset_flags), (char *)&rflags, &items, 1692 &itemsize, &dummy, 0); 1693 1694 if (res == 0) 1695 (void) fprintf(fp, "done!\n"); 1696 return; 1697 } 1698 1699 1700 1701 /* 1702 * preset - reset stat counters for particular peers 1703 */ 1704 static void 1705 preset( 1706 struct parse *pcmd, 1707 FILE *fp 1708 ) 1709 { 1710 /* 8 is the maximum number of peers which will fit in a packet */ 1711 struct conf_unpeer plist[min(MAXARGS, 8)]; 1712 int qitems; 1713 int items; 1714 int itemsize; 1715 char *dummy; 1716 int res; 1717 1718 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) { 1719 plist[qitems].peeraddr = pcmd->argval[qitems].netnum; 1720 } 1721 1722 res = doquery(IMPL_XNTPD, REQ_RESET_PEER, 1, qitems, 1723 sizeof(struct conf_unpeer), (char *)plist, &items, 1724 &itemsize, &dummy, 0); 1725 1726 if (res == 0) 1727 (void) fprintf(fp, "done!\n"); 1728 } 1729 1730 1731 /* 1732 * readkeys - request the server to reread the keys file 1733 */ 1734 /*ARGSUSED*/ 1735 static void 1736 readkeys( 1737 struct parse *pcmd, 1738 FILE *fp 1739 ) 1740 { 1741 int items; 1742 int itemsize; 1743 char *dummy; 1744 int res; 1745 1746 res = doquery(IMPL_XNTPD, REQ_REREAD_KEYS, 1, 0, 0, (char *)0, 1747 &items, &itemsize, &dummy, 0); 1748 1749 if (res == 0) 1750 (void) fprintf(fp, "done!\n"); 1751 return; 1752 } 1753 1754 1755 /* 1756 * trustkey - add some keys to the trusted key list 1757 */ 1758 static void 1759 trustkey( 1760 struct parse *pcmd, 1761 FILE *fp 1762 ) 1763 { 1764 do_trustkey(pcmd, fp, REQ_TRUSTKEY); 1765 } 1766 1767 1768 /* 1769 * untrustkey - remove some keys from the trusted key list 1770 */ 1771 static void 1772 untrustkey( 1773 struct parse *pcmd, 1774 FILE *fp 1775 ) 1776 { 1777 do_trustkey(pcmd, fp, REQ_UNTRUSTKEY); 1778 } 1779 1780 1781 /* 1782 * do_trustkey - do grunge work of adding/deleting keys 1783 */ 1784 static void 1785 do_trustkey( 1786 struct parse *pcmd, 1787 FILE *fp, 1788 int req 1789 ) 1790 { 1791 u_long keyids[MAXARGS]; 1792 int i; 1793 int items; 1794 int itemsize; 1795 char *dummy; 1796 int ritems; 1797 int res; 1798 1799 ritems = 0; 1800 for (i = 0; i < pcmd->nargs; i++) { 1801 keyids[ritems++] = pcmd->argval[i].uval; 1802 } 1803 1804 res = doquery(IMPL_XNTPD, req, 1, ritems, sizeof(u_long), 1805 (char *)keyids, &items, &itemsize, &dummy, 0); 1806 1807 if (res == 0) 1808 (void) fprintf(fp, "done!\n"); 1809 return; 1810 } 1811 1812 1813 1814 /* 1815 * authinfo - obtain and print info about authentication 1816 */ 1817 /*ARGSUSED*/ 1818 static void 1819 authinfo( 1820 struct parse *pcmd, 1821 FILE *fp 1822 ) 1823 { 1824 struct info_auth *ia; 1825 int items; 1826 int itemsize; 1827 int res; 1828 1829 res = doquery(IMPL_XNTPD, REQ_AUTHINFO, 0, 0, 0, (char *)NULL, 1830 &items, &itemsize, (char **)&ia, 0); 1831 1832 if (res != 0 && items == 0) 1833 return; 1834 1835 if (!check1item(items, fp)) 1836 return; 1837 1838 if (!checkitemsize(itemsize, sizeof(struct info_auth))) 1839 return; 1840 1841 (void) fprintf(fp, "time since reset: %ld\n", 1842 (u_long)ntohl(ia->timereset)); 1843 (void) fprintf(fp, "stored keys: %ld\n", 1844 (u_long)ntohl(ia->numkeys)); 1845 (void) fprintf(fp, "free keys: %ld\n", 1846 (u_long)ntohl(ia->numfreekeys)); 1847 (void) fprintf(fp, "key lookups: %ld\n", 1848 (u_long)ntohl(ia->keylookups)); 1849 (void) fprintf(fp, "keys not found: %ld\n", 1850 (u_long)ntohl(ia->keynotfound)); 1851 (void) fprintf(fp, "uncached keys: %ld\n", 1852 (u_long)ntohl(ia->keyuncached)); 1853 (void) fprintf(fp, "encryptions: %ld\n", 1854 (u_long)ntohl(ia->encryptions)); 1855 (void) fprintf(fp, "decryptions: %ld\n", 1856 (u_long)ntohl(ia->decryptions)); 1857 (void) fprintf(fp, "expired keys: %ld\n", 1858 (u_long)ntohl(ia->expired)); 1859 } 1860 1861 1862 1863 /* 1864 * traps - obtain and print a list of traps 1865 */ 1866 /*ARGSUSED*/ 1867 static void 1868 traps( 1869 struct parse *pcmd, 1870 FILE *fp 1871 ) 1872 { 1873 int i; 1874 struct info_trap *it; 1875 int items; 1876 int itemsize; 1877 int res; 1878 1879 res = doquery(IMPL_XNTPD, REQ_TRAPS, 0, 0, 0, (char *)NULL, 1880 &items, &itemsize, (char **)&it, 0); 1881 1882 if (res != 0 && items == 0) 1883 return; 1884 1885 if (!checkitems(items, fp)) 1886 return; 1887 1888 if (!checkitemsize(itemsize, sizeof(struct info_trap))) 1889 return; 1890 1891 for (i = 0; i < items; i++ ) { 1892 if (i != 0) 1893 (void) fprintf(fp, "\n"); 1894 (void) fprintf(fp, "address %s, port %d\n", 1895 numtoa(it->trap_address), ntohs(it->trap_port)); 1896 (void) fprintf(fp, "interface: %s, ", 1897 (it->local_address == 0) 1898 ? "wildcard" 1899 : numtoa(it->local_address)); 1900 1901 if (ntohl(it->flags) & TRAP_CONFIGURED) 1902 (void) fprintf(fp, "configured\n"); 1903 else if (ntohl(it->flags) & TRAP_NONPRIO) 1904 (void) fprintf(fp, "low priority\n"); 1905 else 1906 (void) fprintf(fp, "normal priority\n"); 1907 1908 (void) fprintf(fp, "set for %ld secs, last set %ld secs ago\n", 1909 (long)ntohl(it->origtime), 1910 (long)ntohl(it->settime)); 1911 (void) fprintf(fp, "sequence %d, number of resets %ld\n", 1912 ntohs(it->sequence), 1913 (long)ntohl(it->resets)); 1914 } 1915 } 1916 1917 1918 /* 1919 * addtrap - configure a trap 1920 */ 1921 static void 1922 addtrap( 1923 struct parse *pcmd, 1924 FILE *fp 1925 ) 1926 { 1927 do_addclr_trap(pcmd, fp, REQ_ADD_TRAP); 1928 } 1929 1930 1931 /* 1932 * clrtrap - clear a trap from the server 1933 */ 1934 static void 1935 clrtrap( 1936 struct parse *pcmd, 1937 FILE *fp 1938 ) 1939 { 1940 do_addclr_trap(pcmd, fp, REQ_CLR_TRAP); 1941 } 1942 1943 1944 /* 1945 * do_addclr_trap - do grunge work of adding/deleting traps 1946 */ 1947 static void 1948 do_addclr_trap( 1949 struct parse *pcmd, 1950 FILE *fp, 1951 int req 1952 ) 1953 { 1954 struct conf_trap ctrap; 1955 int items; 1956 int itemsize; 1957 char *dummy; 1958 int res; 1959 1960 ctrap.trap_address = pcmd->argval[0].netnum; 1961 ctrap.local_address = 0; 1962 ctrap.trap_port = htons(TRAPPORT); 1963 ctrap.unused = 0; 1964 1965 if (pcmd->nargs > 1) { 1966 ctrap.trap_port 1967 = htons((u_short)(pcmd->argval[1].uval & 0xffff)); 1968 if (pcmd->nargs > 2) 1969 ctrap.local_address = pcmd->argval[2].netnum; 1970 } 1971 1972 res = doquery(IMPL_XNTPD, req, 1, 1, sizeof(struct conf_trap), 1973 (char *)&ctrap, &items, &itemsize, &dummy, 0); 1974 1975 if (res == 0) 1976 (void) fprintf(fp, "done!\n"); 1977 return; 1978 } 1979 1980 1981 1982 /* 1983 * requestkey - change the server's request key (a dangerous request) 1984 */ 1985 static void 1986 requestkey( 1987 struct parse *pcmd, 1988 FILE *fp 1989 ) 1990 { 1991 do_changekey(pcmd, fp, REQ_REQUEST_KEY); 1992 } 1993 1994 1995 /* 1996 * controlkey - change the server's control key 1997 */ 1998 static void 1999 controlkey( 2000 struct parse *pcmd, 2001 FILE *fp 2002 ) 2003 { 2004 do_changekey(pcmd, fp, REQ_CONTROL_KEY); 2005 } 2006 2007 2008 2009 /* 2010 * do_changekey - do grunge work of changing keys 2011 */ 2012 static void 2013 do_changekey( 2014 struct parse *pcmd, 2015 FILE *fp, 2016 int req 2017 ) 2018 { 2019 u_long key; 2020 int items; 2021 int itemsize; 2022 char *dummy; 2023 int res; 2024 2025 2026 key = htonl((u_int32)pcmd->argval[0].uval); 2027 2028 res = doquery(IMPL_XNTPD, req, 1, 1, sizeof(u_int32), 2029 (char *)&key, &items, &itemsize, &dummy, 0); 2030 2031 if (res == 0) 2032 (void) fprintf(fp, "done!\n"); 2033 return; 2034 } 2035 2036 2037 2038 /* 2039 * ctlstats - obtain and print info about authentication 2040 */ 2041 /*ARGSUSED*/ 2042 static void 2043 ctlstats( 2044 struct parse *pcmd, 2045 FILE *fp 2046 ) 2047 { 2048 struct info_control *ic; 2049 int items; 2050 int itemsize; 2051 int res; 2052 2053 res = doquery(IMPL_XNTPD, REQ_GET_CTLSTATS, 0, 0, 0, (char *)NULL, 2054 &items, &itemsize, (char **)&ic, 0); 2055 2056 if (res != 0 && items == 0) 2057 return; 2058 2059 if (!check1item(items, fp)) 2060 return; 2061 2062 if (!checkitemsize(itemsize, sizeof(struct info_control))) 2063 return; 2064 2065 (void) fprintf(fp, "time since reset: %ld\n", 2066 (u_long)ntohl(ic->ctltimereset)); 2067 (void) fprintf(fp, "requests received: %ld\n", 2068 (u_long)ntohl(ic->numctlreq)); 2069 (void) fprintf(fp, "responses sent: %ld\n", 2070 (u_long)ntohl(ic->numctlresponses)); 2071 (void) fprintf(fp, "fragments sent: %ld\n", 2072 (u_long)ntohl(ic->numctlfrags)); 2073 (void) fprintf(fp, "async messages sent: %ld\n", 2074 (u_long)ntohl(ic->numasyncmsgs)); 2075 (void) fprintf(fp, "error msgs sent: %ld\n", 2076 (u_long)ntohl(ic->numctlerrors)); 2077 (void) fprintf(fp, "total bad pkts: %ld\n", 2078 (u_long)ntohl(ic->numctlbadpkts)); 2079 (void) fprintf(fp, "packet too short: %ld\n", 2080 (u_long)ntohl(ic->numctltooshort)); 2081 (void) fprintf(fp, "response on input: %ld\n", 2082 (u_long)ntohl(ic->numctlinputresp)); 2083 (void) fprintf(fp, "fragment on input: %ld\n", 2084 (u_long)ntohl(ic->numctlinputfrag)); 2085 (void) fprintf(fp, "error set on input: %ld\n", 2086 (u_long)ntohl(ic->numctlinputerr)); 2087 (void) fprintf(fp, "bad offset on input: %ld\n", 2088 (u_long)ntohl(ic->numctlbadoffset)); 2089 (void) fprintf(fp, "bad version packets: %ld\n", 2090 (u_long)ntohl(ic->numctlbadversion)); 2091 (void) fprintf(fp, "data in pkt too short: %ld\n", 2092 (u_long)ntohl(ic->numctldatatooshort)); 2093 (void) fprintf(fp, "unknown op codes: %ld\n", 2094 (u_long)ntohl(ic->numctlbadop)); 2095 } 2096 2097 2098 /* 2099 * clockstat - get and print clock status information 2100 */ 2101 static void 2102 clockstat( 2103 struct parse *pcmd, 2104 FILE *fp 2105 ) 2106 { 2107 struct info_clock *cl; 2108 /* 8 is the maximum number of clocks which will fit in a packet */ 2109 u_long clist[min(MAXARGS, 8)]; 2110 int qitems; 2111 int items; 2112 int itemsize; 2113 int res; 2114 l_fp ts; 2115 struct clktype *clk; 2116 u_long ltemp; 2117 2118 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 2119 clist[qitems] = pcmd->argval[qitems].netnum; 2120 2121 res = doquery(IMPL_XNTPD, REQ_GET_CLOCKINFO, 0, qitems, 2122 sizeof(u_int32), (char *)clist, &items, 2123 &itemsize, (char **)&cl, 0); 2124 2125 if (res != 0 && items == 0) 2126 return; 2127 2128 if (!checkitems(items, fp)) 2129 return; 2130 2131 if (!checkitemsize(itemsize, sizeof(struct info_clock))) 2132 return; 2133 2134 while (items-- > 0) { 2135 (void) fprintf(fp, "clock address: %s\n", 2136 numtoa(cl->clockadr)); 2137 for (clk = clktypes; clk->code >= 0; clk++) 2138 if (clk->code == cl->type) 2139 break; 2140 if (clk->code >= 0) 2141 (void) fprintf(fp, "clock type: %s\n", 2142 clk->clocktype); 2143 else 2144 (void) fprintf(fp, "clock type: unknown type (%d)\n", 2145 cl->type); 2146 (void) fprintf(fp, "last event: %d\n", 2147 cl->lastevent); 2148 (void) fprintf(fp, "current status: %d\n", 2149 cl->currentstatus); 2150 (void) fprintf(fp, "number of polls: %lu\n", 2151 (u_long)ntohl(cl->polls)); 2152 (void) fprintf(fp, "no response to poll: %lu\n", 2153 (u_long)ntohl(cl->noresponse)); 2154 (void) fprintf(fp, "bad format responses: %lu\n", 2155 (u_long)ntohl(cl->badformat)); 2156 (void) fprintf(fp, "bad data responses: %lu\n", 2157 (u_long)ntohl(cl->baddata)); 2158 (void) fprintf(fp, "running time: %lu\n", 2159 (u_long)ntohl(cl->timestarted)); 2160 NTOHL_FP(&cl->fudgetime1, &ts); 2161 (void) fprintf(fp, "fudge time 1: %s\n", 2162 lfptoa(&ts, 6)); 2163 NTOHL_FP(&cl->fudgetime2, &ts); 2164 (void) fprintf(fp, "fudge time 2: %s\n", 2165 lfptoa(&ts, 6)); 2166 (void) fprintf(fp, "stratum: %ld\n", 2167 (u_long)ntohl(cl->fudgeval1)); 2168 ltemp = ntohl(cl->fudgeval2); 2169 (void) fprintf(fp, "reference ID: %s\n", 2170 (char *)<emp); 2171 (void) fprintf(fp, "fudge flags: 0x%x\n", 2172 cl->flags); 2173 2174 if (items > 0) 2175 (void) fprintf(fp, "\n"); 2176 cl++; 2177 } 2178 } 2179 2180 2181 /* 2182 * fudge - set clock fudge factors 2183 */ 2184 static void 2185 fudge( 2186 struct parse *pcmd, 2187 FILE *fp 2188 ) 2189 { 2190 struct conf_fudge fudgedata; 2191 int items; 2192 int itemsize; 2193 char *dummy; 2194 l_fp ts; 2195 int res; 2196 long val; 2197 u_long u_val; 2198 int err; 2199 2200 2201 err = 0; 2202 memset((char *)&fudgedata, 0, sizeof fudgedata); 2203 fudgedata.clockadr = pcmd->argval[0].netnum; 2204 2205 if (STREQ(pcmd->argval[1].string, "time1")) { 2206 fudgedata.which = htonl(FUDGE_TIME1); 2207 if (!atolfp(pcmd->argval[2].string, &ts)) 2208 err = 1; 2209 else 2210 NTOHL_FP(&ts, &fudgedata.fudgetime); 2211 } else if (STREQ(pcmd->argval[1].string, "time2")) { 2212 fudgedata.which = htonl(FUDGE_TIME2); 2213 if (!atolfp(pcmd->argval[2].string, &ts)) 2214 err = 1; 2215 else 2216 NTOHL_FP(&ts, &fudgedata.fudgetime); 2217 } else if (STREQ(pcmd->argval[1].string, "val1")) { 2218 fudgedata.which = htonl(FUDGE_VAL1); 2219 if (!atoint(pcmd->argval[2].string, &val)) 2220 err = 1; 2221 else 2222 fudgedata.fudgeval_flags = htonl(val); 2223 } else if (STREQ(pcmd->argval[1].string, "val2")) { 2224 fudgedata.which = htonl(FUDGE_VAL2); 2225 if (!atoint(pcmd->argval[2].string, &val)) 2226 err = 1; 2227 else 2228 fudgedata.fudgeval_flags = htonl((u_int32)val); 2229 } else if (STREQ(pcmd->argval[1].string, "flags")) { 2230 fudgedata.which = htonl(FUDGE_FLAGS); 2231 if (!hextoint(pcmd->argval[2].string, &u_val)) 2232 err = 1; 2233 else 2234 fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf)); 2235 } else { 2236 (void) fprintf(stderr, "What fudge is %s?\n", 2237 pcmd->argval[1].string); 2238 return; 2239 } 2240 2241 if (err) { 2242 (void) fprintf(stderr, "Unknown fudge parameter %s\n", 2243 pcmd->argval[2].string); 2244 return; 2245 } 2246 2247 2248 res = doquery(IMPL_XNTPD, REQ_SET_CLKFUDGE, 1, 1, 2249 sizeof(struct conf_fudge), (char *)&fudgedata, &items, 2250 &itemsize, &dummy, 0); 2251 2252 if (res == 0) 2253 (void) fprintf(fp, "done!\n"); 2254 return; 2255 } 2256 2257 /* 2258 * clkbug - get and print clock debugging information 2259 */ 2260 static void 2261 clkbug( 2262 struct parse *pcmd, 2263 FILE *fp 2264 ) 2265 { 2266 register int i; 2267 register int n; 2268 register u_int32 s; 2269 struct info_clkbug *cl; 2270 /* 8 is the maximum number of clocks which will fit in a packet */ 2271 u_long clist[min(MAXARGS, 8)]; 2272 u_int32 ltemp; 2273 int qitems; 2274 int items; 2275 int itemsize; 2276 int res; 2277 int needsp; 2278 l_fp ts; 2279 2280 for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++) 2281 clist[qitems] = pcmd->argval[qitems].netnum; 2282 2283 res = doquery(IMPL_XNTPD, REQ_GET_CLKBUGINFO, 0, qitems, 2284 sizeof(u_int32), (char *)clist, &items, 2285 &itemsize, (char **)&cl, 0); 2286 2287 if (res != 0 && items == 0) 2288 return; 2289 2290 if (!checkitems(items, fp)) 2291 return; 2292 2293 if (!checkitemsize(itemsize, sizeof(struct info_clkbug))) 2294 return; 2295 2296 while (items-- > 0) { 2297 (void) fprintf(fp, "clock address: %s\n", 2298 numtoa(cl->clockadr)); 2299 n = (int)cl->nvalues; 2300 (void) fprintf(fp, "values: %d", n); 2301 s = ntohs(cl->svalues); 2302 if (n > NUMCBUGVALUES) 2303 n = NUMCBUGVALUES; 2304 for (i = 0; i < n; i++) { 2305 ltemp = ntohl(cl->values[i]); 2306 ltemp &= 0xffffffff; /* HMS: This does nothing now */ 2307 if ((i & 0x3) == 0) 2308 (void) fprintf(fp, "\n"); 2309 if (s & (1 << i)) 2310 (void) fprintf(fp, "%12ld", (u_long)ltemp); 2311 else 2312 (void) fprintf(fp, "%12lu", (u_long)ltemp); 2313 } 2314 (void) fprintf(fp, "\n"); 2315 2316 n = (int)cl->ntimes; 2317 (void) fprintf(fp, "times: %d", n); 2318 s = ntohl(cl->stimes); 2319 if (n > NUMCBUGTIMES) 2320 n = NUMCBUGTIMES; 2321 needsp = 0; 2322 for (i = 0; i < n; i++) { 2323 if ((i & 0x1) == 0) { 2324 (void) fprintf(fp, "\n"); 2325 } else { 2326 for (;needsp > 0; needsp--) 2327 putc(' ', fp); 2328 } 2329 NTOHL_FP(&cl->times[i], &ts); 2330 if (s & (1 << i)) { 2331 (void) fprintf(fp, "%17s", 2332 lfptoa(&ts, 6)); 2333 needsp = 22; 2334 } else { 2335 (void) fprintf(fp, "%37s", 2336 uglydate(&ts)); 2337 needsp = 2; 2338 } 2339 } 2340 (void) fprintf(fp, "\n"); 2341 if (items > 0) { 2342 cl++; 2343 (void) fprintf(fp, "\n"); 2344 } 2345 } 2346 } 2347 2348 2349 /* 2350 * kerninfo - display the kernel pll/pps variables 2351 */ 2352 static void 2353 kerninfo( 2354 struct parse *pcmd, 2355 FILE *fp 2356 ) 2357 { 2358 struct info_kernel *ik; 2359 int items; 2360 int itemsize; 2361 int res; 2362 unsigned status; 2363 double tscale = 1e-6; 2364 2365 res = doquery(IMPL_XNTPD, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL, 2366 &items, &itemsize, (char **)&ik, 0); 2367 if (res != 0 && items == 0) 2368 return; 2369 if (!check1item(items, fp)) 2370 return; 2371 if (!checkitemsize(itemsize, sizeof(struct info_kernel))) 2372 return; 2373 2374 status = ntohs(ik->status) & 0xffff; 2375 /* 2376 * pll variables. We know more than we should about the NANO bit. 2377 */ 2378 #ifdef STA_NANO 2379 if (status & STA_NANO) 2380 tscale = 1e-9; 2381 #endif 2382 (void)fprintf(fp, "pll offset: %g s\n", 2383 (long)ntohl(ik->offset) * tscale); 2384 (void)fprintf(fp, "pll frequency: %s ppm\n", 2385 fptoa((s_fp)ntohl(ik->freq), 3)); 2386 (void)fprintf(fp, "maximum error: %g s\n", 2387 (u_long)ntohl(ik->maxerror) * 1e-6); 2388 (void)fprintf(fp, "estimated error: %g s\n", 2389 (u_long)ntohl(ik->esterror) * 1e-6); 2390 (void)fprintf(fp, "status: %04x ", status); 2391 #ifdef STA_PLL 2392 if (status & STA_PLL) (void)fprintf(fp, " pll"); 2393 #endif 2394 #ifdef STA_PPSFREQ 2395 if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq"); 2396 #endif 2397 #ifdef STA_PPSTIME 2398 if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime"); 2399 #endif 2400 #ifdef STA_FLL 2401 if (status & STA_FLL) (void)fprintf(fp, " fll"); 2402 #endif 2403 #ifdef STA_INS 2404 if (status & STA_INS) (void)fprintf(fp, " ins"); 2405 #endif 2406 #ifdef STA_DEL 2407 if (status & STA_DEL) (void)fprintf(fp, " del"); 2408 #endif 2409 #ifdef STA_UNSYNC 2410 if (status & STA_UNSYNC) (void)fprintf(fp, " unsync"); 2411 #endif 2412 #ifdef STA_FREQHOLD 2413 if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold"); 2414 #endif 2415 #ifdef STA_PPSSIGNAL 2416 if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal"); 2417 #endif 2418 #ifdef STA_PPSJITTER 2419 if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter"); 2420 #endif 2421 #ifdef STA_PPSWANDER 2422 if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander"); 2423 #endif 2424 #ifdef STA_PPSERROR 2425 if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror"); 2426 #endif 2427 #ifdef STA_CLOCKERR 2428 if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr"); 2429 #endif 2430 #ifdef STA_NANO 2431 if (status & STA_NANO) (void)fprintf(fp, " nano"); 2432 #endif 2433 #ifdef STA_MODE 2434 if (status & STA_MODE) (void)fprintf(fp, " mode=fll"); 2435 #endif 2436 #ifdef STA_CLK 2437 if (status & STA_CLK) (void)fprintf(fp, " src=B"); 2438 #endif 2439 (void)fprintf(fp, "\n"); 2440 (void)fprintf(fp, "pll time constant: %ld\n", 2441 (u_long)ntohl(ik->constant)); 2442 (void)fprintf(fp, "precision: %g s\n", 2443 (u_long)ntohl(ik->precision) * tscale); 2444 (void)fprintf(fp, "frequency tolerance: %s ppm\n", 2445 fptoa((s_fp)ntohl(ik->tolerance), 0)); 2446 2447 /* 2448 * For backwards compatibility (ugh), we find the pps variables 2449 * only if the shift member is nonzero. 2450 */ 2451 if (!ik->shift) 2452 return; 2453 2454 /* 2455 * pps variables 2456 */ 2457 (void)fprintf(fp, "pps frequency: %s ppm\n", 2458 fptoa((s_fp)ntohl(ik->ppsfreq), 3)); 2459 (void)fprintf(fp, "pps stability: %s ppm\n", 2460 fptoa((s_fp)ntohl(ik->stabil), 3)); 2461 (void)fprintf(fp, "pps jitter: %g s\n", 2462 (u_long)ntohl(ik->jitter) * tscale); 2463 (void)fprintf(fp, "calibration interval: %d s\n", 2464 1 << ntohs(ik->shift)); 2465 (void)fprintf(fp, "calibration cycles: %ld\n", 2466 (u_long)ntohl(ik->calcnt)); 2467 (void)fprintf(fp, "jitter exceeded: %ld\n", 2468 (u_long)ntohl(ik->jitcnt)); 2469 (void)fprintf(fp, "stability exceeded: %ld\n", 2470 (u_long)ntohl(ik->stbcnt)); 2471 (void)fprintf(fp, "calibration errors: %ld\n", 2472 (u_long)ntohl(ik->errcnt)); 2473 } 2474