1 /* 2 * ntp_request.c - respond to information requests 3 */ 4 #ifdef HAVE_CONFIG_H 5 #include <config.h> 6 #endif 7 8 #include <sys/types.h> 9 #include <stdio.h> 10 #include <signal.h> 11 #include <sys/time.h> 12 13 #include "ntpd.h" 14 #include "ntp_io.h" 15 #include "ntp_request.h" 16 #include "ntp_control.h" 17 #include "ntp_refclock.h" 18 #include "ntp_if.h" 19 #include "ntp_stdlib.h" 20 #include "recvbuff.h" 21 22 #ifdef KERNEL_PLL 23 #include "ntp_syscall.h" 24 #endif /* KERNEL_PLL */ 25 26 /* 27 * Structure to hold request procedure information 28 */ 29 #define NOAUTH 0 30 #define AUTH 1 31 32 #define NO_REQUEST (-1) 33 34 struct req_proc { 35 short request_code; /* defined request code */ 36 short needs_auth; /* true when authentication needed */ 37 short sizeofitem; /* size of request data item */ 38 void (*handler) P((struct sockaddr_in *, struct interface *, 39 struct req_pkt *)); /* routine to handle request */ 40 }; 41 42 /* 43 * Universal request codes 44 */ 45 static struct req_proc univ_codes[] = { 46 { NO_REQUEST, NOAUTH, 0, 0 } 47 }; 48 49 static void req_ack P((struct sockaddr_in *, struct interface *, struct req_pkt *, int)); 50 static char * prepare_pkt P((struct sockaddr_in *, struct interface *, struct req_pkt *, u_int)); 51 static char * more_pkt P((void)); 52 static void flush_pkt P((void)); 53 static void peer_list P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 54 static void peer_list_sum P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 55 static void peer_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 56 static void peer_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 57 static void sys_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 58 static void sys_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 59 static void mem_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 60 static void io_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 61 static void timer_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 62 static void loop_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 63 static void do_conf P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 64 static void do_unconf P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 65 static void set_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 66 static void clr_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 67 static void setclr_flags P((struct sockaddr_in *, struct interface *, struct req_pkt *, u_long)); 68 static void list_restrict P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 69 static void do_resaddflags P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 70 static void do_ressubflags P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 71 static void do_unrestrict P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 72 static void do_restrict P((struct sockaddr_in *, struct interface *, struct req_pkt *, int)); 73 static void mon_getlist_0 P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 74 static void mon_getlist_1 P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 75 static void reset_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 76 static void reset_peer P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 77 static void do_key_reread P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 78 static void trust_key P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 79 static void untrust_key P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 80 static void do_trustkey P((struct sockaddr_in *, struct interface *, struct req_pkt *, int)); 81 static void get_auth_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 82 static void reset_auth_stats P((void)); 83 static void req_get_traps P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 84 static void req_set_trap P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 85 static void req_clr_trap P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 86 static void do_setclr_trap P((struct sockaddr_in *, struct interface *, struct req_pkt *, int)); 87 static void set_request_keyid P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 88 static void set_control_keyid P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 89 static void get_ctl_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 90 #ifdef KERNEL_PLL 91 static void get_kernel_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 92 #endif /* KERNEL_PLL */ 93 #ifdef REFCLOCK 94 static void get_clock_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 95 static void set_clock_fudge P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 96 #endif /* REFCLOCK */ 97 #ifdef REFCLOCK 98 static void get_clkbug_info P((struct sockaddr_in *, struct interface *, struct req_pkt *)); 99 #endif /* REFCLOCK */ 100 101 /* 102 * ntpd request codes 103 */ 104 static struct req_proc ntp_codes[] = { 105 { REQ_PEER_LIST, NOAUTH, 0, peer_list }, 106 { REQ_PEER_LIST_SUM, NOAUTH, 0, peer_list_sum }, 107 { REQ_PEER_INFO, NOAUTH, sizeof(struct info_peer_list), peer_info }, 108 { REQ_PEER_STATS, NOAUTH, sizeof(struct info_peer_list), peer_stats }, 109 { REQ_SYS_INFO, NOAUTH, 0, sys_info }, 110 { REQ_SYS_STATS, NOAUTH, 0, sys_stats }, 111 { REQ_IO_STATS, NOAUTH, 0, io_stats }, 112 { REQ_MEM_STATS, NOAUTH, 0, mem_stats }, 113 { REQ_LOOP_INFO, NOAUTH, 0, loop_info }, 114 { REQ_TIMER_STATS, NOAUTH, 0, timer_stats }, 115 { REQ_CONFIG, AUTH, sizeof(struct conf_peer), do_conf }, 116 { REQ_UNCONFIG, AUTH, sizeof(struct conf_unpeer), do_unconf }, 117 { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), set_sys_flag }, 118 { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), clr_sys_flag }, 119 { REQ_GET_RESTRICT, NOAUTH, 0, list_restrict }, 120 { REQ_RESADDFLAGS, AUTH, sizeof(struct conf_restrict), do_resaddflags }, 121 { REQ_RESSUBFLAGS, AUTH, sizeof(struct conf_restrict), do_ressubflags }, 122 { REQ_UNRESTRICT, AUTH, sizeof(struct conf_restrict), do_unrestrict }, 123 { REQ_MON_GETLIST, NOAUTH, 0, mon_getlist_0 }, 124 { REQ_MON_GETLIST_1, NOAUTH, 0, mon_getlist_1 }, 125 { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), reset_stats }, 126 { REQ_RESET_PEER, AUTH, sizeof(struct conf_unpeer), reset_peer }, 127 { REQ_REREAD_KEYS, AUTH, 0, do_key_reread }, 128 { REQ_TRUSTKEY, AUTH, sizeof(u_long), trust_key }, 129 { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), untrust_key }, 130 { REQ_AUTHINFO, NOAUTH, 0, get_auth_info }, 131 { REQ_TRAPS, NOAUTH, 0, req_get_traps }, 132 { REQ_ADD_TRAP, AUTH, sizeof(struct conf_trap), req_set_trap }, 133 { REQ_CLR_TRAP, AUTH, sizeof(struct conf_trap), req_clr_trap }, 134 { REQ_REQUEST_KEY, AUTH, sizeof(u_long), set_request_keyid }, 135 { REQ_CONTROL_KEY, AUTH, sizeof(u_long), set_control_keyid }, 136 { REQ_GET_CTLSTATS, NOAUTH, 0, get_ctl_stats }, 137 #ifdef KERNEL_PLL 138 { REQ_GET_KERNEL, NOAUTH, 0, get_kernel_info }, 139 #endif 140 #ifdef REFCLOCK 141 { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), get_clock_info }, 142 { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge), set_clock_fudge }, 143 { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), get_clkbug_info }, 144 #endif 145 { NO_REQUEST, NOAUTH, 0, 0 } 146 }; 147 148 149 /* 150 * Authentication keyid used to authenticate requests. Zero means we 151 * don't allow writing anything. 152 */ 153 u_long info_auth_keyid; 154 155 /* 156 * Statistic counters to keep track of requests and responses. 157 */ 158 u_long numrequests; /* number of requests we've received */ 159 u_long numresppkts; /* number of resp packets sent with data */ 160 161 u_long errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */ 162 /* by the error code */ 163 164 /* 165 * A hack. To keep the authentication module clear of ntp-ism's, we 166 * include a time reset variable for its stats here. 167 */ 168 static u_long auth_timereset; 169 170 /* 171 * Response packet used by these routines. Also some state information 172 * so that we can handle packet formatting within a common set of 173 * subroutines. Note we try to enter data in place whenever possible, 174 * but the need to set the more bit correctly means we occasionally 175 * use the extra buffer and copy. 176 */ 177 static struct resp_pkt rpkt; 178 static int reqver; 179 static int seqno; 180 static int nitems; 181 static int itemsize; 182 static int databytes; 183 static char exbuf[RESP_DATA_SIZE]; 184 static int usingexbuf; 185 static struct sockaddr_in *toaddr; 186 static struct interface *frominter; 187 188 /* 189 * init_request - initialize request data 190 */ 191 void 192 init_request (void) 193 { 194 int i; 195 196 numrequests = 0; 197 numresppkts = 0; 198 auth_timereset = 0; 199 info_auth_keyid = 0; /* by default, can't do this */ 200 201 for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++) 202 errorcounter[i] = 0; 203 } 204 205 206 /* 207 * req_ack - acknowledge request with no data 208 */ 209 static void 210 req_ack( 211 struct sockaddr_in *srcadr, 212 struct interface *inter, 213 struct req_pkt *inpkt, 214 int errcode 215 ) 216 { 217 /* 218 * fill in the fields 219 */ 220 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver); 221 rpkt.auth_seq = AUTH_SEQ(0, 0); 222 rpkt.implementation = inpkt->implementation; 223 rpkt.request = inpkt->request; 224 rpkt.err_nitems = ERR_NITEMS(errcode, 0); 225 rpkt.mbz_itemsize = MBZ_ITEMSIZE(0); 226 227 /* 228 * send packet and bump counters 229 */ 230 sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE); 231 errorcounter[errcode]++; 232 } 233 234 235 /* 236 * prepare_pkt - prepare response packet for transmission, return pointer 237 * to storage for data item. 238 */ 239 static char * 240 prepare_pkt( 241 struct sockaddr_in *srcadr, 242 struct interface *inter, 243 struct req_pkt *pkt, 244 u_int structsize 245 ) 246 { 247 #ifdef DEBUG 248 if (debug > 3) 249 printf("request: preparing pkt\n"); 250 #endif 251 252 /* 253 * Fill in the implementation, reqest and itemsize fields 254 * since these won't change. 255 */ 256 rpkt.implementation = pkt->implementation; 257 rpkt.request = pkt->request; 258 rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize); 259 260 /* 261 * Compute the static data needed to carry on. 262 */ 263 toaddr = srcadr; 264 frominter = inter; 265 seqno = 0; 266 nitems = 0; 267 itemsize = structsize; 268 databytes = 0; 269 usingexbuf = 0; 270 271 /* 272 * return the beginning of the packet buffer. 273 */ 274 return &rpkt.data[0]; 275 } 276 277 278 /* 279 * more_pkt - return a data pointer for a new item. 280 */ 281 static char * 282 more_pkt(void) 283 { 284 /* 285 * If we were using the extra buffer, send the packet. 286 */ 287 if (usingexbuf) { 288 #ifdef DEBUG 289 if (debug > 2) 290 printf("request: sending pkt\n"); 291 #endif 292 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver); 293 rpkt.auth_seq = AUTH_SEQ(0, seqno); 294 rpkt.err_nitems = htons((u_short)nitems); 295 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt, 296 RESP_HEADER_SIZE+databytes); 297 numresppkts++; 298 299 /* 300 * Copy data out of exbuf into the packet. 301 */ 302 memmove(&rpkt.data[0], exbuf, (unsigned)itemsize); 303 seqno++; 304 databytes = 0; 305 nitems = 0; 306 usingexbuf = 0; 307 } 308 309 databytes += itemsize; 310 nitems++; 311 if (databytes + itemsize <= RESP_DATA_SIZE) { 312 #ifdef DEBUG 313 if (debug > 3) 314 printf("request: giving him more data\n"); 315 #endif 316 /* 317 * More room in packet. Give him the 318 * next address. 319 */ 320 return &rpkt.data[databytes]; 321 } else { 322 /* 323 * No room in packet. Give him the extra 324 * buffer unless this was the last in the sequence. 325 */ 326 #ifdef DEBUG 327 if (debug > 3) 328 printf("request: into extra buffer\n"); 329 #endif 330 if (seqno == MAXSEQ) 331 return (char *)0; 332 else { 333 usingexbuf = 1; 334 return exbuf; 335 } 336 } 337 } 338 339 340 /* 341 * flush_pkt - we're done, return remaining information. 342 */ 343 static void 344 flush_pkt(void) 345 { 346 #ifdef DEBUG 347 if (debug > 2) 348 printf("request: flushing packet, %d items\n", nitems); 349 #endif 350 /* 351 * Must send the last packet. If nothing in here and nothing 352 * has been sent, send an error saying no data to be found. 353 */ 354 if (seqno == 0 && nitems == 0) 355 req_ack(toaddr, frominter, (struct req_pkt *)&rpkt, 356 INFO_ERR_NODATA); 357 else { 358 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver); 359 rpkt.auth_seq = AUTH_SEQ(0, seqno); 360 rpkt.err_nitems = htons((u_short)nitems); 361 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt, 362 RESP_HEADER_SIZE+databytes); 363 numresppkts++; 364 } 365 } 366 367 368 369 /* 370 * process_private - process private mode (7) packets 371 */ 372 void 373 process_private( 374 struct recvbuf *rbufp, 375 int mod_okay 376 ) 377 { 378 struct req_pkt *inpkt; 379 struct sockaddr_in *srcadr; 380 struct interface *inter; 381 struct req_proc *proc; 382 383 /* 384 * Initialize pointers, for convenience 385 */ 386 inpkt = (struct req_pkt *)&rbufp->recv_pkt; 387 srcadr = &rbufp->recv_srcadr; 388 inter = rbufp->dstadr; 389 390 #ifdef DEBUG 391 if (debug > 2) 392 printf("prepare_pkt: impl %d req %d\n", 393 inpkt->implementation, inpkt->request); 394 #endif 395 396 /* 397 * Do some sanity checks on the packet. Return a format 398 * error if it fails. 399 */ 400 if (ISRESPONSE(inpkt->rm_vn_mode) 401 || ISMORE(inpkt->rm_vn_mode) 402 || INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION 403 || INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION 404 || INFO_SEQ(inpkt->auth_seq) != 0 405 || INFO_ERR(inpkt->err_nitems) != 0 406 || INFO_MBZ(inpkt->mbz_itemsize) != 0 407 || rbufp->recv_length > REQ_LEN_MAC 408 || rbufp->recv_length < REQ_LEN_NOMAC) { 409 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 410 return; 411 } 412 413 reqver = INFO_VERSION(inpkt->rm_vn_mode); 414 415 /* 416 * Get the appropriate procedure list to search. 417 */ 418 if (inpkt->implementation == IMPL_UNIV) 419 proc = univ_codes; 420 else if (inpkt->implementation == IMPL_XNTPD) 421 proc = ntp_codes; 422 else { 423 req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL); 424 return; 425 } 426 427 428 /* 429 * Search the list for the request codes. If it isn't one 430 * we know, return an error. 431 */ 432 while (proc->request_code != NO_REQUEST) { 433 if (proc->request_code == (short) inpkt->request) 434 break; 435 proc++; 436 } 437 if (proc->request_code == NO_REQUEST) { 438 req_ack(srcadr, inter, inpkt, INFO_ERR_REQ); 439 return; 440 } 441 442 #ifdef DEBUG 443 if (debug > 3) 444 printf("found request in tables\n"); 445 #endif 446 447 /* 448 * If we need to authenticate, do so. Note that an 449 * authenticatable packet must include a mac field, must 450 * have used key info_auth_keyid and must have included 451 * a time stamp in the appropriate field. The time stamp 452 * must be within INFO_TS_MAXSKEW of the receive 453 * time stamp. 454 */ 455 if (proc->needs_auth && sys_authenticate) { 456 l_fp ftmp; 457 double dtemp; 458 459 /* 460 * If this guy is restricted from doing this, don't let him 461 * If wrong key was used, or packet doesn't have mac, return. 462 */ 463 if (!INFO_IS_AUTH(inpkt->auth_seq) || info_auth_keyid == 0 464 || ntohl(inpkt->keyid) != info_auth_keyid) { 465 #ifdef DEBUG 466 if (debug > 4) 467 printf("failed auth %d info_auth_keyid %lu pkt keyid %lu\n", 468 INFO_IS_AUTH(inpkt->auth_seq), 469 (u_long)info_auth_keyid, 470 (u_long)ntohl(inpkt->keyid)); 471 #endif 472 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); 473 return; 474 } 475 if (rbufp->recv_length > REQ_LEN_MAC) { 476 #ifdef DEBUG 477 if (debug > 4) 478 printf("bad pkt length %d\n", 479 rbufp->recv_length); 480 #endif 481 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 482 return; 483 } 484 if (!mod_okay || !authhavekey(info_auth_keyid)) { 485 #ifdef DEBUG 486 if (debug > 4) 487 printf("failed auth mod_okay %d\n", mod_okay); 488 #endif 489 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); 490 return; 491 } 492 493 /* 494 * calculate absolute time difference between xmit time stamp 495 * and receive time stamp. If too large, too bad. 496 */ 497 NTOHL_FP(&inpkt->tstamp, &ftmp); 498 L_SUB(&ftmp, &rbufp->recv_time); 499 LFPTOD(&ftmp, dtemp); 500 if (fabs(dtemp) >= INFO_TS_MAXSKEW) { 501 /* 502 * He's a loser. Tell him. 503 */ 504 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); 505 return; 506 } 507 508 /* 509 * So far so good. See if decryption works out okay. 510 */ 511 if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt, 512 REQ_LEN_NOMAC, (int)(rbufp->recv_length - REQ_LEN_NOMAC))) { 513 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); 514 return; 515 } 516 } 517 518 /* 519 * If we need data, check to see if we have some. If we 520 * don't, check to see that there is none (picky, picky). 521 */ 522 if (INFO_ITEMSIZE(inpkt->mbz_itemsize) != proc->sizeofitem) { 523 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 524 return; 525 } 526 if (proc->sizeofitem != 0) 527 if (proc->sizeofitem*INFO_NITEMS(inpkt->err_nitems) 528 > sizeof(inpkt->data)) { 529 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 530 return; 531 } 532 533 #ifdef DEBUG 534 if (debug > 3) 535 printf("process_private: all okay, into handler\n"); 536 #endif 537 538 /* 539 * Packet is okay. Call the handler to send him data. 540 */ 541 (proc->handler)(srcadr, inter, inpkt); 542 } 543 544 545 /* 546 * peer_list - send a list of the peers 547 */ 548 static void 549 peer_list( 550 struct sockaddr_in *srcadr, 551 struct interface *inter, 552 struct req_pkt *inpkt 553 ) 554 { 555 register struct info_peer_list *ip; 556 register struct peer *pp; 557 register int i; 558 559 ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt, 560 sizeof(struct info_peer_list)); 561 for (i = 0; i < HASH_SIZE && ip != 0; i++) { 562 pp = peer_hash[i]; 563 while (pp != 0 && ip != 0) { 564 ip->address = pp->srcadr.sin_addr.s_addr; 565 ip->port = pp->srcadr.sin_port; 566 ip->hmode = pp->hmode; 567 ip->flags = 0; 568 if (pp->flags & FLAG_CONFIG) 569 ip->flags |= INFO_FLAG_CONFIG; 570 if (pp == sys_peer) 571 ip->flags |= INFO_FLAG_SYSPEER; 572 if (pp->status == CTL_PST_SEL_SYNCCAND) 573 ip->flags |= INFO_FLAG_SEL_CANDIDATE; 574 if (pp->status >= CTL_PST_SEL_SYSPEER) 575 ip->flags |= INFO_FLAG_SHORTLIST; 576 ip = (struct info_peer_list *)more_pkt(); 577 pp = pp->next; 578 } 579 } 580 flush_pkt(); 581 } 582 583 584 /* 585 * peer_list_sum - return extended peer list 586 */ 587 static void 588 peer_list_sum( 589 struct sockaddr_in *srcadr, 590 struct interface *inter, 591 struct req_pkt *inpkt 592 ) 593 { 594 register struct info_peer_summary *ips; 595 register struct peer *pp; 596 register int i; 597 l_fp ltmp; 598 599 #ifdef DEBUG 600 if (debug > 2) 601 printf("wants peer list summary\n"); 602 #endif 603 604 ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt, 605 sizeof(struct info_peer_summary)); 606 for (i = 0; i < HASH_SIZE && ips != 0; i++) { 607 pp = peer_hash[i]; 608 while (pp != 0 && ips != 0) { 609 #ifdef DEBUG 610 if (debug > 3) 611 printf("sum: got one\n"); 612 #endif 613 ips->dstadr = (pp->processed) ? 614 pp->cast_flags == MDF_BCAST ? 615 pp->dstadr->bcast.sin_addr.s_addr: 616 pp->cast_flags ? 617 pp->dstadr->sin.sin_addr.s_addr ? 618 pp->dstadr->sin.sin_addr.s_addr: 619 pp->dstadr->bcast.sin_addr.s_addr: 620 1 : 5; 621 ips->srcadr = pp->srcadr.sin_addr.s_addr; 622 ips->srcport = pp->srcadr.sin_port; 623 ips->stratum = pp->stratum; 624 ips->hpoll = pp->hpoll; 625 ips->ppoll = pp->ppoll; 626 ips->reach = pp->reach; 627 ips->flags = 0; 628 if (pp == sys_peer) 629 ips->flags |= INFO_FLAG_SYSPEER; 630 if (pp->flags & FLAG_CONFIG) 631 ips->flags |= INFO_FLAG_CONFIG; 632 if (pp->flags & FLAG_REFCLOCK) 633 ips->flags |= INFO_FLAG_REFCLOCK; 634 if (pp->flags & FLAG_AUTHENABLE) 635 ips->flags |= INFO_FLAG_AUTHENABLE; 636 if (pp->flags & FLAG_PREFER) 637 ips->flags |= INFO_FLAG_PREFER; 638 if (pp->flags & FLAG_BURST) 639 ips->flags |= INFO_FLAG_BURST; 640 if (pp->status == CTL_PST_SEL_SYNCCAND) 641 ips->flags |= INFO_FLAG_SEL_CANDIDATE; 642 if (pp->status >= CTL_PST_SEL_SYSPEER) 643 ips->flags |= INFO_FLAG_SHORTLIST; 644 ips->hmode = pp->hmode; 645 ips->delay = HTONS_FP(DTOFP(pp->delay)); 646 DTOLFP(pp->offset, <mp); 647 HTONL_FP(<mp, &ips->offset); 648 ips->dispersion = HTONS_FP(DTOUFP(pp->disp)); 649 650 pp = pp->next; 651 ips = (struct info_peer_summary *)more_pkt(); 652 } 653 } 654 flush_pkt(); 655 } 656 657 658 /* 659 * peer_info - send information for one or more peers 660 */ 661 static void 662 peer_info ( 663 struct sockaddr_in *srcadr, 664 struct interface *inter, 665 struct req_pkt *inpkt 666 ) 667 { 668 register struct info_peer_list *ipl; 669 register struct peer *pp; 670 register struct info_peer *ip; 671 register int items; 672 register int i, j; 673 struct sockaddr_in addr; 674 extern struct peer *sys_peer; 675 l_fp ltmp; 676 677 memset((char *)&addr, 0, sizeof addr); 678 addr.sin_family = AF_INET; 679 items = INFO_NITEMS(inpkt->err_nitems); 680 ipl = (struct info_peer_list *) inpkt->data; 681 ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt, 682 sizeof(struct info_peer)); 683 while (items-- > 0 && ip != 0) { 684 addr.sin_port = ipl->port; 685 addr.sin_addr.s_addr = ipl->address; 686 ipl++; 687 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0) 688 continue; 689 ip->dstadr = (pp->processed) ? 690 pp->cast_flags == MDF_BCAST ? 691 pp->dstadr->bcast.sin_addr.s_addr: 692 pp->cast_flags ? 693 pp->dstadr->sin.sin_addr.s_addr ? 694 pp->dstadr->sin.sin_addr.s_addr: 695 pp->dstadr->bcast.sin_addr.s_addr: 696 2 : 6; 697 ip->srcadr = NSRCADR(&pp->srcadr); 698 ip->srcport = NSRCPORT(&pp->srcadr); 699 ip->flags = 0; 700 if (pp == sys_peer) 701 ip->flags |= INFO_FLAG_SYSPEER; 702 if (pp->flags & FLAG_CONFIG) 703 ip->flags |= INFO_FLAG_CONFIG; 704 if (pp->flags & FLAG_REFCLOCK) 705 ip->flags |= INFO_FLAG_REFCLOCK; 706 if (pp->flags & FLAG_AUTHENABLE) 707 ip->flags |= INFO_FLAG_AUTHENABLE; 708 if (pp->flags & FLAG_PREFER) 709 ip->flags |= INFO_FLAG_PREFER; 710 if (pp->flags & FLAG_BURST) 711 ip->flags |= INFO_FLAG_BURST; 712 if (pp->status == CTL_PST_SEL_SYNCCAND) 713 ip->flags |= INFO_FLAG_SEL_CANDIDATE; 714 if (pp->status >= CTL_PST_SEL_SYSPEER) 715 ip->flags |= INFO_FLAG_SHORTLIST; 716 ip->leap = pp->leap; 717 ip->hmode = pp->hmode; 718 ip->keyid = pp->keyid; 719 ip->stratum = pp->stratum; 720 ip->ppoll = pp->ppoll; 721 ip->hpoll = pp->hpoll; 722 ip->precision = pp->precision; 723 ip->version = pp->version; 724 ip->valid = pp->valid; 725 ip->reach = pp->reach; 726 ip->unreach = pp->unreach; 727 ip->flash = (u_char)pp->flash; 728 ip->flash2 = pp->flash; 729 ip->estbdelay = HTONS_FP(DTOFP(pp->estbdelay)); 730 ip->ttl = pp->ttl; 731 ip->associd = htons(pp->associd); 732 ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay)); 733 ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdispersion)); 734 ip->refid = pp->refid; 735 HTONL_FP(&pp->reftime, &ip->reftime); 736 HTONL_FP(&pp->org, &ip->org); 737 HTONL_FP(&pp->rec, &ip->rec); 738 HTONL_FP(&pp->xmt, &ip->xmt); 739 j = pp->filter_nextpt - 1; 740 for (i = 0; i < NTP_SHIFT; i++, j--) { 741 if (j < 0) 742 j = NTP_SHIFT-1; 743 ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j])); 744 DTOLFP(pp->filter_offset[j], <mp); 745 HTONL_FP(<mp, &ip->filtoffset[i]); 746 ip->order[i] = (pp->filter_nextpt+NTP_SHIFT-1) 747 - pp->filter_order[i]; 748 if (ip->order[i] >= NTP_SHIFT) 749 ip->order[i] -= NTP_SHIFT; 750 } 751 DTOLFP(pp->offset, <mp); 752 HTONL_FP(<mp, &ip->offset); 753 ip->delay = HTONS_FP(DTOFP(pp->delay)); 754 ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); 755 ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->variance))); 756 ip = (struct info_peer *)more_pkt(); 757 } 758 flush_pkt(); 759 } 760 761 762 /* 763 * peer_stats - send statistics for one or more peers 764 */ 765 static void 766 peer_stats ( 767 struct sockaddr_in *srcadr, 768 struct interface *inter, 769 struct req_pkt *inpkt 770 ) 771 { 772 register struct info_peer_list *ipl; 773 register struct peer *pp; 774 register struct info_peer_stats *ip; 775 register int items; 776 struct sockaddr_in addr; 777 extern struct peer *sys_peer; 778 779 memset((char *)&addr, 0, sizeof addr); 780 addr.sin_family = AF_INET; 781 items = INFO_NITEMS(inpkt->err_nitems); 782 ipl = (struct info_peer_list *) inpkt->data; 783 ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, 784 sizeof(struct info_peer_stats)); 785 while (items-- > 0 && ip != 0) { 786 addr.sin_port = ipl->port; 787 addr.sin_addr.s_addr = ipl->address; 788 ipl++; 789 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0) 790 continue; 791 ip->dstadr = (pp->processed) ? 792 pp->cast_flags == MDF_BCAST ? 793 pp->dstadr->bcast.sin_addr.s_addr: 794 pp->cast_flags ? 795 pp->dstadr->sin.sin_addr.s_addr ? 796 pp->dstadr->sin.sin_addr.s_addr: 797 pp->dstadr->bcast.sin_addr.s_addr: 798 3 : 7; 799 ip->srcadr = NSRCADR(&pp->srcadr); 800 ip->srcport = NSRCPORT(&pp->srcadr); 801 ip->flags = 0; 802 if (pp == sys_peer) 803 ip->flags |= INFO_FLAG_SYSPEER; 804 if (pp->flags & FLAG_CONFIG) 805 ip->flags |= INFO_FLAG_CONFIG; 806 if (pp->flags & FLAG_REFCLOCK) 807 ip->flags |= INFO_FLAG_REFCLOCK; 808 if (pp->flags & FLAG_AUTHENABLE) 809 ip->flags |= INFO_FLAG_AUTHENABLE; 810 if (pp->flags & FLAG_PREFER) 811 ip->flags |= INFO_FLAG_PREFER; 812 if (pp->flags & FLAG_BURST) 813 ip->flags |= INFO_FLAG_BURST; 814 if (pp->status == CTL_PST_SEL_SYNCCAND) 815 ip->flags |= INFO_FLAG_SEL_CANDIDATE; 816 if (pp->status >= CTL_PST_SEL_SYSPEER) 817 ip->flags |= INFO_FLAG_SHORTLIST; 818 ip->timereceived = htonl((u_int32)(current_time - pp->timereceived)); 819 ip->timetosend = htonl(pp->nextdate - current_time); 820 ip->timereachable = htonl((u_int32)(current_time - pp->timereachable)); 821 ip->sent = htonl((u_int32)(pp->sent)); 822 ip->processed = htonl((u_int32)(pp->processed)); 823 ip->badauth = htonl((u_int32)(pp->badauth)); 824 ip->bogusorg = htonl((u_int32)(pp->bogusorg)); 825 ip->oldpkt = htonl((u_int32)(pp->oldpkt)); 826 ip->seldisp = htonl((u_int32)(pp->seldisptoolarge)); 827 ip->selbroken = htonl((u_int32)(pp->selbroken)); 828 ip->candidate = pp->status; 829 ip = (struct info_peer_stats *)more_pkt(); 830 } 831 flush_pkt(); 832 } 833 834 835 /* 836 * sys_info - return system info 837 */ 838 static void 839 sys_info( 840 struct sockaddr_in *srcadr, 841 struct interface *inter, 842 struct req_pkt *inpkt 843 ) 844 { 845 register struct info_sys *is; 846 847 /* 848 * Importations from the protocol module 849 */ 850 extern u_char sys_leap; 851 extern u_char sys_stratum; 852 extern s_char sys_precision; 853 extern double sys_rootdelay; 854 extern double sys_rootdispersion; 855 extern u_int32 sys_refid; 856 extern l_fp sys_reftime; 857 extern u_char sys_poll; 858 extern struct peer *sys_peer; 859 extern int sys_bclient; 860 extern double sys_bdelay; 861 extern l_fp sys_authdelay; 862 extern double clock_stability; 863 extern double sys_error; 864 865 is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt, 866 sizeof(struct info_sys)); 867 868 if (sys_peer != 0) { 869 is->peer = NSRCADR(&sys_peer->srcadr); 870 is->peer_mode = sys_peer->hmode; 871 } else { 872 is->peer = 0; 873 is->peer_mode = 0; 874 } 875 is->leap = sys_leap; 876 is->stratum = sys_stratum; 877 is->precision = sys_precision; 878 is->rootdelay = htonl(DTOFP(sys_rootdelay)); 879 is->rootdispersion = htonl(DTOUFP(sys_rootdispersion)); 880 is->frequency = htonl(DTOFP(sys_error)); 881 is->stability = htonl(DTOUFP(clock_stability * 1e6)); 882 is->refid = sys_refid; 883 HTONL_FP(&sys_reftime, &is->reftime); 884 885 is->poll = sys_poll; 886 887 is->flags = 0; 888 if (sys_bclient) 889 is->flags |= INFO_FLAG_BCLIENT; 890 if (sys_authenticate) 891 is->flags |= INFO_FLAG_AUTHENTICATE; 892 if (kern_enable) 893 is->flags |= INFO_FLAG_KERNEL; 894 if (ntp_enable) 895 is->flags |= INFO_FLAG_NTP; 896 if (pll_control) 897 is->flags |= INFO_FLAG_PLL_SYNC; 898 if (pps_control) 899 is->flags |= INFO_FLAG_PPS_SYNC; 900 if (mon_enabled != MON_OFF) 901 is->flags |= INFO_FLAG_MONITOR; 902 if (stats_control) 903 is->flags |= INFO_FLAG_FILEGEN; 904 is->bdelay = HTONS_FP(DTOFP(sys_bdelay)); 905 HTONL_UF(sys_authdelay.l_f, &is->authdelay); 906 907 (void) more_pkt(); 908 flush_pkt(); 909 } 910 911 912 /* 913 * sys_stats - return system statistics 914 */ 915 static void 916 sys_stats( 917 struct sockaddr_in *srcadr, 918 struct interface *inter, 919 struct req_pkt *inpkt 920 ) 921 { 922 register struct info_sys_stats *ss; 923 924 /* 925 * Importations from the protocol module 926 */ 927 extern u_long sys_stattime; 928 extern u_long sys_badstratum; 929 extern u_long sys_oldversionpkt; 930 extern u_long sys_newversionpkt; 931 extern u_long sys_unknownversion; 932 extern u_long sys_badlength; 933 extern u_long sys_processed; 934 extern u_long sys_badauth; 935 extern u_long sys_limitrejected; 936 937 ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt, 938 sizeof(struct info_sys_stats)); 939 940 ss->timeup = htonl((u_int32)current_time); 941 ss->timereset = htonl((u_int32)(current_time - sys_stattime)); 942 ss->badstratum = htonl((u_int32)sys_badstratum); 943 ss->oldversionpkt = htonl((u_int32)sys_oldversionpkt); 944 ss->newversionpkt = htonl((u_int32)sys_newversionpkt); 945 ss->unknownversion = htonl((u_int32)sys_unknownversion); 946 ss->badlength = htonl((u_int32)sys_badlength); 947 ss->processed = htonl((u_int32)sys_processed); 948 ss->badauth = htonl((u_int32)sys_badauth); 949 ss->limitrejected = htonl((u_int32)sys_limitrejected); 950 (void) more_pkt(); 951 flush_pkt(); 952 } 953 954 955 /* 956 * mem_stats - return memory statistics 957 */ 958 static void 959 mem_stats( 960 struct sockaddr_in *srcadr, 961 struct interface *inter, 962 struct req_pkt *inpkt 963 ) 964 { 965 register struct info_mem_stats *ms; 966 register int i; 967 968 /* 969 * Importations from the peer module 970 */ 971 extern int peer_hash_count[HASH_SIZE]; 972 extern int peer_free_count; 973 extern u_long peer_timereset; 974 extern u_long findpeer_calls; 975 extern u_long peer_allocations; 976 extern u_long peer_demobilizations; 977 extern int total_peer_structs; 978 979 ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt, 980 sizeof(struct info_mem_stats)); 981 982 ms->timereset = htonl((u_int32)(current_time - peer_timereset)); 983 ms->totalpeermem = htons((u_short)total_peer_structs); 984 ms->freepeermem = htons((u_short)peer_free_count); 985 ms->findpeer_calls = htonl((u_int32)findpeer_calls); 986 ms->allocations = htonl((u_int32)peer_allocations); 987 ms->demobilizations = htonl((u_int32)peer_demobilizations); 988 989 for (i = 0; i < HASH_SIZE; i++) { 990 if (peer_hash_count[i] > 255) 991 ms->hashcount[i] = 255; 992 else 993 ms->hashcount[i] = (u_char)peer_hash_count[i]; 994 } 995 996 (void) more_pkt(); 997 flush_pkt(); 998 } 999 1000 1001 /* 1002 * io_stats - return io statistics 1003 */ 1004 static void 1005 io_stats( 1006 struct sockaddr_in *srcadr, 1007 struct interface *inter, 1008 struct req_pkt *inpkt 1009 ) 1010 { 1011 register struct info_io_stats *io; 1012 1013 /* 1014 * Importations from the io module 1015 */ 1016 extern u_long io_timereset; 1017 1018 io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt, 1019 sizeof(struct info_io_stats)); 1020 1021 io->timereset = htonl((u_int32)(current_time - io_timereset)); 1022 io->totalrecvbufs = htons((u_short) total_recvbuffs()); 1023 io->freerecvbufs = htons((u_short) free_recvbuffs()); 1024 io->fullrecvbufs = htons((u_short) full_recvbuffs()); 1025 io->lowwater = htons((u_short) lowater_additions()); 1026 io->dropped = htonl((u_int32)packets_dropped); 1027 io->ignored = htonl((u_int32)packets_ignored); 1028 io->received = htonl((u_int32)packets_received); 1029 io->sent = htonl((u_int32)packets_sent); 1030 io->notsent = htonl((u_int32)packets_notsent); 1031 io->interrupts = htonl((u_int32)handler_calls); 1032 io->int_received = htonl((u_int32)handler_pkts); 1033 1034 (void) more_pkt(); 1035 flush_pkt(); 1036 } 1037 1038 1039 /* 1040 * timer_stats - return timer statistics 1041 */ 1042 static void 1043 timer_stats( 1044 struct sockaddr_in *srcadr, 1045 struct interface *inter, 1046 struct req_pkt *inpkt 1047 ) 1048 { 1049 register struct info_timer_stats *ts; 1050 1051 /* 1052 * Importations from the timer module 1053 */ 1054 extern u_long timer_timereset; 1055 extern u_long timer_overflows; 1056 extern u_long timer_xmtcalls; 1057 1058 ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, inpkt, 1059 sizeof(struct info_timer_stats)); 1060 1061 ts->timereset = htonl((u_int32)(current_time - timer_timereset)); 1062 ts->alarms = htonl((u_int32)alarm_overflow); 1063 ts->overflows = htonl((u_int32)timer_overflows); 1064 ts->xmtcalls = htonl((u_int32)timer_xmtcalls); 1065 1066 (void) more_pkt(); 1067 flush_pkt(); 1068 } 1069 1070 1071 /* 1072 * loop_info - return the current state of the loop filter 1073 */ 1074 static void 1075 loop_info( 1076 struct sockaddr_in *srcadr, 1077 struct interface *inter, 1078 struct req_pkt *inpkt 1079 ) 1080 { 1081 register struct info_loop *li; 1082 l_fp ltmp; 1083 1084 /* 1085 * Importations from the loop filter module 1086 */ 1087 extern double last_offset; 1088 extern double drift_comp; 1089 extern int tc_counter; 1090 extern u_long last_time; 1091 1092 li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt, 1093 sizeof(struct info_loop)); 1094 1095 DTOLFP(last_offset, <mp); 1096 HTONL_FP(<mp, &li->last_offset); 1097 DTOLFP(drift_comp * 1e6, <mp); 1098 HTONL_FP(<mp, &li->drift_comp); 1099 li->compliance = htonl((u_int32)(tc_counter)); 1100 li->watchdog_timer = htonl((u_int32)(current_time - last_time)); 1101 1102 (void) more_pkt(); 1103 flush_pkt(); 1104 } 1105 1106 1107 /* 1108 * do_conf - add a peer to the configuration list 1109 */ 1110 static void 1111 do_conf( 1112 struct sockaddr_in *srcadr, 1113 struct interface *inter, 1114 struct req_pkt *inpkt 1115 ) 1116 { 1117 register struct conf_peer *cp; 1118 register int items; 1119 struct sockaddr_in peeraddr; 1120 int fl; 1121 1122 /* 1123 * Do a check of everything to see that it looks 1124 * okay. If not, complain about it. Note we are 1125 * very picky here. 1126 */ 1127 items = INFO_NITEMS(inpkt->err_nitems); 1128 cp = (struct conf_peer *)inpkt->data; 1129 1130 fl = 0; 1131 while (items-- > 0 && !fl) { 1132 if (((cp->version) > NTP_VERSION) 1133 || ((cp->version) < NTP_OLDVERSION)) 1134 fl = 1; 1135 if (cp->hmode != MODE_ACTIVE 1136 && cp->hmode != MODE_CLIENT 1137 && cp->hmode != MODE_BROADCAST) 1138 fl = 1; 1139 if (cp->flags & ~(CONF_FLAG_AUTHENABLE | CONF_FLAG_PREFER 1140 | CONF_FLAG_NOSELECT | CONF_FLAG_BURST | CONF_FLAG_SKEY)) 1141 fl = 1; 1142 cp++; 1143 } 1144 1145 if (fl) { 1146 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1147 return; 1148 } 1149 1150 /* 1151 * Looks okay, try it out 1152 */ 1153 items = INFO_NITEMS(inpkt->err_nitems); 1154 cp = (struct conf_peer *)inpkt->data; 1155 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in)); 1156 peeraddr.sin_family = AF_INET; 1157 peeraddr.sin_port = htons(NTP_PORT); 1158 1159 /* 1160 * Make sure the address is valid 1161 */ 1162 if ( 1163 #ifdef REFCLOCK 1164 !ISREFCLOCKADR(&peeraddr) && 1165 #endif 1166 ISBADADR(&peeraddr)) { 1167 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1168 return; 1169 } 1170 1171 while (items-- > 0) { 1172 fl = 0; 1173 if (cp->flags & CONF_FLAG_AUTHENABLE) 1174 fl |= FLAG_AUTHENABLE; 1175 if (cp->flags & CONF_FLAG_PREFER) 1176 fl |= FLAG_PREFER; 1177 if (cp->flags & CONF_FLAG_NOSELECT) 1178 fl |= FLAG_NOSELECT; 1179 if (cp->flags & CONF_FLAG_BURST) 1180 fl |= FLAG_BURST; 1181 if (cp->flags & CONF_FLAG_SKEY) 1182 fl |= FLAG_SKEY; 1183 peeraddr.sin_addr.s_addr = cp->peeraddr; 1184 /* XXX W2DO? minpoll/maxpoll arguments ??? */ 1185 if (peer_config(&peeraddr, (struct interface *)0, 1186 cp->hmode, cp->version, cp->minpoll, cp->maxpoll, 1187 fl, cp->ttl, cp->keyid) == 0) { 1188 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1189 return; 1190 } 1191 cp++; 1192 } 1193 1194 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1195 } 1196 1197 1198 /* 1199 * do_unconf - remove a peer from the configuration list 1200 */ 1201 static void 1202 do_unconf( 1203 struct sockaddr_in *srcadr, 1204 struct interface *inter, 1205 struct req_pkt *inpkt 1206 ) 1207 { 1208 register struct conf_unpeer *cp; 1209 register int items; 1210 register struct peer *peer; 1211 struct sockaddr_in peeraddr; 1212 int bad, found; 1213 1214 /* 1215 * This is a bit unstructured, but I like to be careful. 1216 * We check to see that every peer exists and is actually 1217 * configured. If so, we remove them. If not, we return 1218 * an error. 1219 */ 1220 peeraddr.sin_family = AF_INET; 1221 peeraddr.sin_port = htons(NTP_PORT); 1222 1223 items = INFO_NITEMS(inpkt->err_nitems); 1224 cp = (struct conf_unpeer *)inpkt->data; 1225 1226 bad = 0; 1227 while (items-- > 0 && !bad) { 1228 peeraddr.sin_addr.s_addr = cp->peeraddr; 1229 found = 0; 1230 peer = (struct peer *)0; 1231 while (!found) { 1232 peer = findexistingpeer(&peeraddr, peer, -1); 1233 if (peer == (struct peer *)0) 1234 break; 1235 if (peer->flags & FLAG_CONFIG) 1236 found = 1; 1237 } 1238 if (!found) 1239 bad = 1; 1240 cp++; 1241 } 1242 1243 if (bad) { 1244 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1245 return; 1246 } 1247 1248 /* 1249 * Now do it in earnest. 1250 */ 1251 1252 items = INFO_NITEMS(inpkt->err_nitems); 1253 cp = (struct conf_unpeer *)inpkt->data; 1254 while (items-- > 0) { 1255 peeraddr.sin_addr.s_addr = cp->peeraddr; 1256 peer_unconfig(&peeraddr, (struct interface *)0, -1); 1257 cp++; 1258 } 1259 1260 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1261 } 1262 1263 1264 /* 1265 * set_sys_flag - set system flags 1266 */ 1267 static void 1268 set_sys_flag( 1269 struct sockaddr_in *srcadr, 1270 struct interface *inter, 1271 struct req_pkt *inpkt 1272 ) 1273 { 1274 setclr_flags(srcadr, inter, inpkt, 1); 1275 } 1276 1277 1278 /* 1279 * clr_sys_flag - clear system flags 1280 */ 1281 static void 1282 clr_sys_flag( 1283 struct sockaddr_in *srcadr, 1284 struct interface *inter, 1285 struct req_pkt *inpkt 1286 ) 1287 { 1288 setclr_flags(srcadr, inter, inpkt, 0); 1289 } 1290 1291 1292 /* 1293 * setclr_flags - do the grunge work of flag setting/clearing 1294 */ 1295 static void 1296 setclr_flags( 1297 struct sockaddr_in *srcadr, 1298 struct interface *inter, 1299 struct req_pkt *inpkt, 1300 u_long set 1301 ) 1302 { 1303 register u_long flags; 1304 1305 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 1306 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1307 return; 1308 } 1309 1310 flags = ((struct conf_sys_flags *)inpkt->data)->flags; 1311 1312 if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_AUTHENTICATE | 1313 SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | 1314 SYS_FLAG_FILEGEN)) { 1315 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1316 return; 1317 } 1318 1319 if (flags & SYS_FLAG_BCLIENT) 1320 proto_config(PROTO_BROADCLIENT, set, 0.); 1321 if (flags & SYS_FLAG_AUTHENTICATE) 1322 proto_config(PROTO_AUTHENTICATE, set, 0.); 1323 if (flags & SYS_FLAG_NTP) 1324 proto_config(PROTO_NTP, set, 0.); 1325 if (flags & SYS_FLAG_KERNEL) 1326 proto_config(PROTO_KERNEL, set, 0.); 1327 if (flags & SYS_FLAG_MONITOR) 1328 proto_config(PROTO_MONITOR, set, 0.); 1329 if (flags & SYS_FLAG_FILEGEN) 1330 proto_config(PROTO_FILEGEN, set, 0.); 1331 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1332 } 1333 1334 1335 /* 1336 * list_restrict - return the restrict list 1337 */ 1338 static void 1339 list_restrict( 1340 struct sockaddr_in *srcadr, 1341 struct interface *inter, 1342 struct req_pkt *inpkt 1343 ) 1344 { 1345 register struct info_restrict *ir; 1346 register struct restrictlist *rl; 1347 extern struct restrictlist *restrictlist; 1348 1349 #ifdef DEBUG 1350 if (debug > 2) 1351 printf("wants peer list summary\n"); 1352 #endif 1353 1354 ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt, 1355 sizeof(struct info_restrict)); 1356 for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) { 1357 ir->addr = htonl(rl->addr); 1358 ir->mask = htonl(rl->mask); 1359 ir->count = htonl((u_int32)rl->count); 1360 ir->flags = htons(rl->flags); 1361 ir->mflags = htons(rl->mflags); 1362 ir = (struct info_restrict *)more_pkt(); 1363 } 1364 flush_pkt(); 1365 } 1366 1367 1368 1369 /* 1370 * do_resaddflags - add flags to a restrict entry (or create one) 1371 */ 1372 static void 1373 do_resaddflags( 1374 struct sockaddr_in *srcadr, 1375 struct interface *inter, 1376 struct req_pkt *inpkt 1377 ) 1378 { 1379 do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS); 1380 } 1381 1382 1383 1384 /* 1385 * do_ressubflags - remove flags from a restrict entry 1386 */ 1387 static void 1388 do_ressubflags( 1389 struct sockaddr_in *srcadr, 1390 struct interface *inter, 1391 struct req_pkt *inpkt 1392 ) 1393 { 1394 do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG); 1395 } 1396 1397 1398 /* 1399 * do_unrestrict - remove a restrict entry from the list 1400 */ 1401 static void 1402 do_unrestrict( 1403 struct sockaddr_in *srcadr, 1404 struct interface *inter, 1405 struct req_pkt *inpkt 1406 ) 1407 { 1408 do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE); 1409 } 1410 1411 1412 1413 1414 1415 /* 1416 * do_restrict - do the dirty stuff of dealing with restrictions 1417 */ 1418 static void 1419 do_restrict( 1420 struct sockaddr_in *srcadr, 1421 struct interface *inter, 1422 struct req_pkt *inpkt, 1423 int op 1424 ) 1425 { 1426 register struct conf_restrict *cr; 1427 register int items; 1428 struct sockaddr_in matchaddr; 1429 struct sockaddr_in matchmask; 1430 int bad; 1431 1432 /* 1433 * Do a check of the flags to make sure that only 1434 * the NTPPORT flag is set, if any. If not, complain 1435 * about it. Note we are very picky here. 1436 */ 1437 items = INFO_NITEMS(inpkt->err_nitems); 1438 cr = (struct conf_restrict *)inpkt->data; 1439 1440 bad = 0; 1441 while (items-- > 0 && !bad) { 1442 if (cr->mflags & ~(RESM_NTPONLY)) 1443 bad = 1; 1444 if (cr->flags & ~(RES_ALLFLAGS)) 1445 bad = 1; 1446 if (cr->addr == htonl(INADDR_ANY) && cr->mask != htonl(INADDR_ANY)) 1447 bad = 1; 1448 cr++; 1449 } 1450 1451 if (bad) { 1452 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1453 return; 1454 } 1455 1456 /* 1457 * Looks okay, try it out 1458 */ 1459 items = INFO_NITEMS(inpkt->err_nitems); 1460 cr = (struct conf_restrict *)inpkt->data; 1461 memset((char *)&matchaddr, 0, sizeof(struct sockaddr_in)); 1462 memset((char *)&matchmask, 0, sizeof(struct sockaddr_in)); 1463 matchaddr.sin_family = AF_INET; 1464 matchmask.sin_family = AF_INET; 1465 1466 while (items-- > 0) { 1467 matchaddr.sin_addr.s_addr = cr->addr; 1468 matchmask.sin_addr.s_addr = cr->mask; 1469 hack_restrict(op, &matchaddr, &matchmask, cr->mflags, 1470 cr->flags); 1471 cr++; 1472 } 1473 1474 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1475 } 1476 1477 1478 /* 1479 * mon_getlist - return monitor data 1480 */ 1481 static void 1482 mon_getlist_0( 1483 struct sockaddr_in *srcadr, 1484 struct interface *inter, 1485 struct req_pkt *inpkt 1486 ) 1487 { 1488 register struct info_monitor *im; 1489 register struct mon_data *md; 1490 extern struct mon_data mon_mru_list; 1491 extern int mon_enabled; 1492 1493 #ifdef DEBUG 1494 if (debug > 2) 1495 printf("wants monitor 0 list\n"); 1496 #endif 1497 if (!mon_enabled) { 1498 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1499 return; 1500 } 1501 1502 im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt, 1503 sizeof(struct info_monitor)); 1504 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; 1505 md = md->mru_next) { 1506 im->lasttime = htonl((u_int32)(current_time - md->lasttime)); 1507 im->firsttime = htonl((u_int32)(current_time - md->firsttime)); 1508 if (md->lastdrop) 1509 im->lastdrop = htonl((u_int32)(current_time - md->lastdrop)); 1510 else 1511 im->lastdrop = 0; 1512 im->count = htonl((u_int32)(md->count)); 1513 im->addr = md->rmtadr; 1514 im->port = md->rmtport; 1515 im->mode = md->mode; 1516 im->version = md->version; 1517 im = (struct info_monitor *)more_pkt(); 1518 } 1519 flush_pkt(); 1520 } 1521 1522 /* 1523 * mon_getlist - return monitor data 1524 */ 1525 static void 1526 mon_getlist_1( 1527 struct sockaddr_in *srcadr, 1528 struct interface *inter, 1529 struct req_pkt *inpkt 1530 ) 1531 { 1532 register struct info_monitor_1 *im; 1533 register struct mon_data *md; 1534 extern struct mon_data mon_mru_list; 1535 extern int mon_enabled; 1536 1537 #ifdef DEBUG 1538 if (debug > 2) 1539 printf("wants monitor 1 list\n"); 1540 #endif 1541 if (!mon_enabled) { 1542 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1543 return; 1544 } 1545 1546 im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt, 1547 sizeof(struct info_monitor_1)); 1548 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; 1549 md = md->mru_next) { 1550 im->lasttime = htonl((u_int32)(current_time - md->lasttime)); 1551 im->firsttime = htonl((u_int32)(current_time - md->firsttime)); 1552 if (md->lastdrop) 1553 im->lastdrop = htonl((u_int32)(current_time - md->lastdrop)); 1554 else 1555 im->lastdrop = 0; 1556 im->count = htonl((u_int32)md->count); 1557 im->addr = md->rmtadr; 1558 im->daddr = 1559 (md->cast_flags == MDF_BCAST) 1560 ? md->interface->bcast.sin_addr.s_addr 1561 : (md->cast_flags 1562 ? (md->interface->sin.sin_addr.s_addr 1563 ? md->interface->sin.sin_addr.s_addr 1564 : md->interface->bcast.sin_addr.s_addr 1565 ) 1566 : 4); 1567 im->flags = md->cast_flags; 1568 im->port = md->rmtport; 1569 im->mode = md->mode; 1570 im->version = md->version; 1571 im = (struct info_monitor_1 *)more_pkt(); 1572 } 1573 flush_pkt(); 1574 } 1575 1576 /* 1577 * Module entry points and the flags they correspond with 1578 */ 1579 struct reset_entry { 1580 int flag; /* flag this corresponds to */ 1581 void (*handler) P((void)); /* routine to handle request */ 1582 }; 1583 1584 struct reset_entry reset_entries[] = { 1585 { RESET_FLAG_ALLPEERS, peer_all_reset }, 1586 { RESET_FLAG_IO, io_clr_stats }, 1587 { RESET_FLAG_SYS, proto_clr_stats }, 1588 { RESET_FLAG_MEM, peer_clr_stats }, 1589 { RESET_FLAG_TIMER, timer_clr_stats }, 1590 { RESET_FLAG_AUTH, reset_auth_stats }, 1591 { RESET_FLAG_CTL, ctl_clr_stats }, 1592 { 0, 0 } 1593 }; 1594 1595 /* 1596 * reset_stats - reset statistic counters here and there 1597 */ 1598 static void 1599 reset_stats( 1600 struct sockaddr_in *srcadr, 1601 struct interface *inter, 1602 struct req_pkt *inpkt 1603 ) 1604 { 1605 u_long flags; 1606 struct reset_entry *rent; 1607 1608 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 1609 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1610 return; 1611 } 1612 1613 flags = ((struct reset_flags *)inpkt->data)->flags; 1614 1615 if (flags & ~RESET_ALLFLAGS) { 1616 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1617 return; 1618 } 1619 1620 for (rent = reset_entries; rent->flag != 0; rent++) { 1621 if (flags & rent->flag) 1622 (rent->handler)(); 1623 } 1624 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1625 } 1626 1627 1628 /* 1629 * reset_peer - clear a peer's statistics 1630 */ 1631 static void 1632 reset_peer( 1633 struct sockaddr_in *srcadr, 1634 struct interface *inter, 1635 struct req_pkt *inpkt 1636 ) 1637 { 1638 register struct conf_unpeer *cp; 1639 register int items; 1640 register struct peer *peer; 1641 struct sockaddr_in peeraddr; 1642 int bad; 1643 1644 /* 1645 * We check first to see that every peer exists. If not, 1646 * we return an error. 1647 */ 1648 peeraddr.sin_family = AF_INET; 1649 peeraddr.sin_port = htons(NTP_PORT); 1650 1651 items = INFO_NITEMS(inpkt->err_nitems); 1652 cp = (struct conf_unpeer *)inpkt->data; 1653 1654 bad = 0; 1655 while (items-- > 0 && !bad) { 1656 peeraddr.sin_addr.s_addr = cp->peeraddr; 1657 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1); 1658 if (peer == (struct peer *)0) 1659 bad++; 1660 cp++; 1661 } 1662 1663 if (bad) { 1664 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1665 return; 1666 } 1667 1668 /* 1669 * Now do it in earnest. 1670 */ 1671 1672 items = INFO_NITEMS(inpkt->err_nitems); 1673 cp = (struct conf_unpeer *)inpkt->data; 1674 while (items-- > 0) { 1675 peeraddr.sin_addr.s_addr = cp->peeraddr; 1676 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1); 1677 while (peer != 0) { 1678 peer_reset(peer); 1679 peer = findexistingpeer(&peeraddr, (struct peer *)peer, -1); 1680 } 1681 cp++; 1682 } 1683 1684 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1685 } 1686 1687 1688 /* 1689 * do_key_reread - reread the encryption key file 1690 */ 1691 static void 1692 do_key_reread( 1693 struct sockaddr_in *srcadr, 1694 struct interface *inter, 1695 struct req_pkt *inpkt 1696 ) 1697 { 1698 rereadkeys(); 1699 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1700 } 1701 1702 1703 /* 1704 * trust_key - make one or more keys trusted 1705 */ 1706 static void 1707 trust_key( 1708 struct sockaddr_in *srcadr, 1709 struct interface *inter, 1710 struct req_pkt *inpkt 1711 ) 1712 { 1713 do_trustkey(srcadr, inter, inpkt, 1); 1714 } 1715 1716 1717 /* 1718 * untrust_key - make one or more keys untrusted 1719 */ 1720 static void 1721 untrust_key( 1722 struct sockaddr_in *srcadr, 1723 struct interface *inter, 1724 struct req_pkt *inpkt 1725 ) 1726 { 1727 do_trustkey(srcadr, inter, inpkt, 0); 1728 } 1729 1730 1731 /* 1732 * do_trustkey - make keys either trustable or untrustable 1733 */ 1734 static void 1735 do_trustkey( 1736 struct sockaddr_in *srcadr, 1737 struct interface *inter, 1738 struct req_pkt *inpkt, 1739 int trust 1740 ) 1741 { 1742 register u_long *kp; 1743 register int items; 1744 1745 items = INFO_NITEMS(inpkt->err_nitems); 1746 kp = (u_long *)inpkt->data; 1747 while (items-- > 0) { 1748 authtrust(*kp, trust); 1749 kp++; 1750 } 1751 1752 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1753 } 1754 1755 1756 /* 1757 * get_auth_info - return some stats concerning the authentication module 1758 */ 1759 static void 1760 get_auth_info( 1761 struct sockaddr_in *srcadr, 1762 struct interface *inter, 1763 struct req_pkt *inpkt 1764 ) 1765 { 1766 register struct info_auth *ia; 1767 1768 /* 1769 * Importations from the authentication module 1770 */ 1771 extern u_long authnumkeys; 1772 extern int authnumfreekeys; 1773 extern u_long authkeylookups; 1774 extern u_long authkeynotfound; 1775 extern u_long authencryptions; 1776 extern u_long authdecryptions; 1777 extern u_long authkeyuncached; 1778 extern u_long authkeyexpired; 1779 1780 ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt, 1781 sizeof(struct info_auth)); 1782 1783 ia->numkeys = htonl((u_int32)authnumkeys); 1784 ia->numfreekeys = htonl((u_int32)authnumfreekeys); 1785 ia->keylookups = htonl((u_int32)authkeylookups); 1786 ia->keynotfound = htonl((u_int32)authkeynotfound); 1787 ia->encryptions = htonl((u_int32)authencryptions); 1788 ia->decryptions = htonl((u_int32)authdecryptions); 1789 ia->keyuncached = htonl((u_int32)authkeyuncached); 1790 ia->expired = htonl((u_int32)authkeyexpired); 1791 ia->timereset = htonl((u_int32)(current_time - auth_timereset)); 1792 1793 (void) more_pkt(); 1794 flush_pkt(); 1795 } 1796 1797 1798 1799 /* 1800 * reset_auth_stats - reset the authentication stat counters. Done here 1801 * to keep ntp-isms out of the authentication module 1802 */ 1803 static void 1804 reset_auth_stats(void) 1805 { 1806 /* 1807 * Importations from the authentication module 1808 */ 1809 extern u_long authkeylookups; 1810 extern u_long authkeynotfound; 1811 extern u_long authencryptions; 1812 extern u_long authdecryptions; 1813 extern u_long authkeyuncached; 1814 1815 authkeylookups = 0; 1816 authkeynotfound = 0; 1817 authencryptions = 0; 1818 authdecryptions = 0; 1819 authkeyuncached = 0; 1820 auth_timereset = current_time; 1821 } 1822 1823 1824 /* 1825 * req_get_traps - return information about current trap holders 1826 */ 1827 static void 1828 req_get_traps( 1829 struct sockaddr_in *srcadr, 1830 struct interface *inter, 1831 struct req_pkt *inpkt 1832 ) 1833 { 1834 register struct info_trap *it; 1835 register struct ctl_trap *tr; 1836 register int i; 1837 1838 /* 1839 * Imported from the control module 1840 */ 1841 extern struct ctl_trap ctl_trap[]; 1842 extern int num_ctl_traps; 1843 1844 if (num_ctl_traps == 0) { 1845 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1846 return; 1847 } 1848 1849 it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt, 1850 sizeof(struct info_trap)); 1851 1852 for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) { 1853 if (tr->tr_flags & TRAP_INUSE) { 1854 if (tr->tr_localaddr == any_interface) 1855 it->local_address = 0; 1856 else 1857 it->local_address 1858 = NSRCADR(&tr->tr_localaddr->sin); 1859 it->trap_address = NSRCADR(&tr->tr_addr); 1860 it->trap_port = NSRCPORT(&tr->tr_addr); 1861 it->sequence = htons(tr->tr_sequence); 1862 it->settime = htonl((u_int32)(current_time - tr->tr_settime)); 1863 it->origtime = htonl((u_int32)(current_time - tr->tr_origtime)); 1864 it->resets = htonl((u_int32)tr->tr_resets); 1865 it->flags = htonl((u_int32)tr->tr_flags); 1866 it = (struct info_trap *)more_pkt(); 1867 } 1868 } 1869 flush_pkt(); 1870 } 1871 1872 1873 /* 1874 * req_set_trap - configure a trap 1875 */ 1876 static void 1877 req_set_trap( 1878 struct sockaddr_in *srcadr, 1879 struct interface *inter, 1880 struct req_pkt *inpkt 1881 ) 1882 { 1883 do_setclr_trap(srcadr, inter, inpkt, 1); 1884 } 1885 1886 1887 1888 /* 1889 * req_clr_trap - unconfigure a trap 1890 */ 1891 static void 1892 req_clr_trap( 1893 struct sockaddr_in *srcadr, 1894 struct interface *inter, 1895 struct req_pkt *inpkt 1896 ) 1897 { 1898 do_setclr_trap(srcadr, inter, inpkt, 0); 1899 } 1900 1901 1902 1903 /* 1904 * do_setclr_trap - do the grunge work of (un)configuring a trap 1905 */ 1906 static void 1907 do_setclr_trap( 1908 struct sockaddr_in *srcadr, 1909 struct interface *inter, 1910 struct req_pkt *inpkt, 1911 int set 1912 ) 1913 { 1914 register struct conf_trap *ct; 1915 register struct interface *linter; 1916 int res; 1917 struct sockaddr_in laddr; 1918 1919 /* 1920 * Prepare sockaddr_in structure 1921 */ 1922 memset((char *)&laddr, 0, sizeof laddr); 1923 laddr.sin_family = AF_INET; 1924 laddr.sin_port = ntohs(NTP_PORT); 1925 1926 /* 1927 * Restrict ourselves to one item only. This eliminates 1928 * the error reporting problem. 1929 */ 1930 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 1931 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1932 return; 1933 } 1934 ct = (struct conf_trap *)inpkt->data; 1935 1936 /* 1937 * Look for the local interface. If none, use the default. 1938 */ 1939 if (ct->local_address == 0) { 1940 linter = any_interface; 1941 } else { 1942 laddr.sin_addr.s_addr = ct->local_address; 1943 linter = findinterface(&laddr); 1944 if (linter == NULL) { 1945 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1946 return; 1947 } 1948 } 1949 1950 laddr.sin_addr.s_addr = ct->trap_address; 1951 if (ct->trap_port != 0) 1952 laddr.sin_port = ct->trap_port; 1953 else 1954 laddr.sin_port = htons(TRAPPORT); 1955 1956 if (set) { 1957 res = ctlsettrap(&laddr, linter, 0, 1958 INFO_VERSION(inpkt->rm_vn_mode)); 1959 } else { 1960 res = ctlclrtrap(&laddr, linter, 0); 1961 } 1962 1963 if (!res) { 1964 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1965 } else { 1966 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1967 } 1968 return; 1969 } 1970 1971 1972 1973 /* 1974 * set_request_keyid - set the keyid used to authenticate requests 1975 */ 1976 static void 1977 set_request_keyid( 1978 struct sockaddr_in *srcadr, 1979 struct interface *inter, 1980 struct req_pkt *inpkt 1981 ) 1982 { 1983 u_long keyid; 1984 1985 /* 1986 * Restrict ourselves to one item only. 1987 */ 1988 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 1989 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1990 return; 1991 } 1992 1993 keyid = ntohl(*((u_int32 *)(inpkt->data))); 1994 info_auth_keyid = keyid; 1995 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1996 } 1997 1998 1999 2000 /* 2001 * set_control_keyid - set the keyid used to authenticate requests 2002 */ 2003 static void 2004 set_control_keyid( 2005 struct sockaddr_in *srcadr, 2006 struct interface *inter, 2007 struct req_pkt *inpkt 2008 ) 2009 { 2010 u_long keyid; 2011 extern u_long ctl_auth_keyid; 2012 2013 /* 2014 * Restrict ourselves to one item only. 2015 */ 2016 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2017 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2018 return; 2019 } 2020 2021 keyid = ntohl(*((u_int32 *)(inpkt->data))); 2022 ctl_auth_keyid = keyid; 2023 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2024 } 2025 2026 2027 2028 /* 2029 * get_ctl_stats - return some stats concerning the control message module 2030 */ 2031 static void 2032 get_ctl_stats( 2033 struct sockaddr_in *srcadr, 2034 struct interface *inter, 2035 struct req_pkt *inpkt 2036 ) 2037 { 2038 register struct info_control *ic; 2039 2040 /* 2041 * Importations from the control module 2042 */ 2043 extern u_long ctltimereset; 2044 extern u_long numctlreq; 2045 extern u_long numctlbadpkts; 2046 extern u_long numctlresponses; 2047 extern u_long numctlfrags; 2048 extern u_long numctlerrors; 2049 extern u_long numctltooshort; 2050 extern u_long numctlinputresp; 2051 extern u_long numctlinputfrag; 2052 extern u_long numctlinputerr; 2053 extern u_long numctlbadoffset; 2054 extern u_long numctlbadversion; 2055 extern u_long numctldatatooshort; 2056 extern u_long numctlbadop; 2057 extern u_long numasyncmsgs; 2058 2059 ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt, 2060 sizeof(struct info_control)); 2061 2062 ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset)); 2063 ic->numctlreq = htonl((u_int32)numctlreq); 2064 ic->numctlbadpkts = htonl((u_int32)numctlbadpkts); 2065 ic->numctlresponses = htonl((u_int32)numctlresponses); 2066 ic->numctlfrags = htonl((u_int32)numctlfrags); 2067 ic->numctlerrors = htonl((u_int32)numctlerrors); 2068 ic->numctltooshort = htonl((u_int32)numctltooshort); 2069 ic->numctlinputresp = htonl((u_int32)numctlinputresp); 2070 ic->numctlinputfrag = htonl((u_int32)numctlinputfrag); 2071 ic->numctlinputerr = htonl((u_int32)numctlinputerr); 2072 ic->numctlbadoffset = htonl((u_int32)numctlbadoffset); 2073 ic->numctlbadversion = htonl((u_int32)numctlbadversion); 2074 ic->numctldatatooshort = htonl((u_int32)numctldatatooshort); 2075 ic->numctlbadop = htonl((u_int32)numctlbadop); 2076 ic->numasyncmsgs = htonl((u_int32)numasyncmsgs); 2077 2078 (void) more_pkt(); 2079 flush_pkt(); 2080 } 2081 2082 2083 #ifdef KERNEL_PLL 2084 /* 2085 * get_kernel_info - get kernel pll/pps information 2086 */ 2087 static void 2088 get_kernel_info( 2089 struct sockaddr_in *srcadr, 2090 struct interface *inter, 2091 struct req_pkt *inpkt 2092 ) 2093 { 2094 register struct info_kernel *ik; 2095 struct timex ntx; 2096 2097 if (!pll_control) { 2098 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2099 return; 2100 } 2101 2102 memset((char *)&ntx, 0, sizeof(ntx)); 2103 if (ntp_adjtime(&ntx) < 0) 2104 msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m"); 2105 ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt, 2106 sizeof(struct info_kernel)); 2107 2108 /* 2109 * pll variables 2110 */ 2111 ik->offset = htonl((u_int32)ntx.offset); 2112 ik->freq = htonl((u_int32)ntx.freq); 2113 ik->maxerror = htonl((u_int32)ntx.maxerror); 2114 ik->esterror = htonl((u_int32)ntx.esterror); 2115 ik->status = htons(ntx.status); 2116 ik->constant = htonl((u_int32)ntx.constant); 2117 ik->precision = htonl((u_int32)ntx.precision); 2118 ik->tolerance = htonl((u_int32)ntx.tolerance); 2119 2120 /* 2121 * pps variables 2122 */ 2123 ik->ppsfreq = htonl((u_int32)ntx.ppsfreq); 2124 ik->jitter = htonl((u_int32)ntx.jitter); 2125 ik->shift = htons(ntx.shift); 2126 ik->stabil = htonl((u_int32)ntx.stabil); 2127 ik->jitcnt = htonl((u_int32)ntx.jitcnt); 2128 ik->calcnt = htonl((u_int32)ntx.calcnt); 2129 ik->errcnt = htonl((u_int32)ntx.errcnt); 2130 ik->stbcnt = htonl((u_int32)ntx.stbcnt); 2131 2132 (void) more_pkt(); 2133 flush_pkt(); 2134 } 2135 #endif /* KERNEL_PLL */ 2136 2137 2138 #ifdef REFCLOCK 2139 /* 2140 * get_clock_info - get info about a clock 2141 */ 2142 static void 2143 get_clock_info( 2144 struct sockaddr_in *srcadr, 2145 struct interface *inter, 2146 struct req_pkt *inpkt 2147 ) 2148 { 2149 register struct info_clock *ic; 2150 register u_int32 *clkaddr; 2151 register int items; 2152 struct refclockstat clock_stat; 2153 struct sockaddr_in addr; 2154 l_fp ltmp; 2155 2156 memset((char *)&addr, 0, sizeof addr); 2157 addr.sin_family = AF_INET; 2158 addr.sin_port = htons(NTP_PORT); 2159 items = INFO_NITEMS(inpkt->err_nitems); 2160 clkaddr = (u_int32 *) inpkt->data; 2161 2162 ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt, 2163 sizeof(struct info_clock)); 2164 2165 while (items-- > 0) { 2166 addr.sin_addr.s_addr = *clkaddr++; 2167 if (!ISREFCLOCKADR(&addr) || 2168 findexistingpeer(&addr, (struct peer *)0, -1) == 0) { 2169 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2170 return; 2171 } 2172 2173 clock_stat.kv_list = (struct ctl_var *)0; 2174 2175 refclock_control(&addr, (struct refclockstat *)0, &clock_stat); 2176 2177 ic->clockadr = addr.sin_addr.s_addr; 2178 ic->type = clock_stat.type; 2179 ic->flags = clock_stat.flags; 2180 ic->lastevent = clock_stat.lastevent; 2181 ic->currentstatus = clock_stat.currentstatus; 2182 ic->polls = htonl((u_int32)clock_stat.polls); 2183 ic->noresponse = htonl((u_int32)clock_stat.noresponse); 2184 ic->badformat = htonl((u_int32)clock_stat.badformat); 2185 ic->baddata = htonl((u_int32)clock_stat.baddata); 2186 ic->timestarted = htonl((u_int32)clock_stat.timereset); 2187 DTOLFP(clock_stat.fudgetime1, <mp); 2188 HTONL_FP(<mp, &ic->fudgetime1); 2189 DTOLFP(clock_stat.fudgetime1, <mp); 2190 HTONL_FP(<mp, &ic->fudgetime2); 2191 ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1); 2192 ic->fudgeval2 = htonl((u_int32)clock_stat.fudgeval2); 2193 2194 free_varlist(clock_stat.kv_list); 2195 2196 ic = (struct info_clock *)more_pkt(); 2197 } 2198 flush_pkt(); 2199 } 2200 2201 2202 2203 /* 2204 * set_clock_fudge - get a clock's fudge factors 2205 */ 2206 static void 2207 set_clock_fudge( 2208 struct sockaddr_in *srcadr, 2209 struct interface *inter, 2210 struct req_pkt *inpkt 2211 ) 2212 { 2213 register struct conf_fudge *cf; 2214 register int items; 2215 struct refclockstat clock_stat; 2216 struct sockaddr_in addr; 2217 l_fp ltmp; 2218 2219 memset((char *)&addr, 0, sizeof addr); 2220 memset((char *)&clock_stat, 0, sizeof clock_stat); 2221 addr.sin_family = AF_INET; 2222 addr.sin_port = htons(NTP_PORT); 2223 items = INFO_NITEMS(inpkt->err_nitems); 2224 cf = (struct conf_fudge *) inpkt->data; 2225 2226 while (items-- > 0) { 2227 addr.sin_addr.s_addr = cf->clockadr; 2228 if (!ISREFCLOCKADR(&addr) || 2229 findexistingpeer(&addr, (struct peer *)0, -1) == 0) { 2230 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2231 return; 2232 } 2233 2234 switch(ntohl(cf->which)) { 2235 case FUDGE_TIME1: 2236 NTOHL_FP(&cf->fudgetime, <mp); 2237 LFPTOD(<mp, clock_stat.fudgetime1); 2238 clock_stat.haveflags = CLK_HAVETIME1; 2239 break; 2240 case FUDGE_TIME2: 2241 NTOHL_FP(&cf->fudgetime, <mp); 2242 LFPTOD(<mp, clock_stat.fudgetime2); 2243 clock_stat.haveflags = CLK_HAVETIME2; 2244 break; 2245 case FUDGE_VAL1: 2246 clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags); 2247 clock_stat.haveflags = CLK_HAVEVAL1; 2248 break; 2249 case FUDGE_VAL2: 2250 clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags); 2251 clock_stat.haveflags = CLK_HAVEVAL2; 2252 break; 2253 case FUDGE_FLAGS: 2254 clock_stat.flags = (u_char) ntohl(cf->fudgeval_flags) & 0xf; 2255 clock_stat.haveflags = 2256 (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4); 2257 break; 2258 default: 2259 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2260 return; 2261 } 2262 2263 refclock_control(&addr, &clock_stat, (struct refclockstat *)0); 2264 } 2265 2266 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2267 } 2268 #endif 2269 2270 #ifdef REFCLOCK 2271 /* 2272 * get_clkbug_info - get debugging info about a clock 2273 */ 2274 static void 2275 get_clkbug_info( 2276 struct sockaddr_in *srcadr, 2277 struct interface *inter, 2278 struct req_pkt *inpkt 2279 ) 2280 { 2281 register int i; 2282 register struct info_clkbug *ic; 2283 register u_int32 *clkaddr; 2284 register int items; 2285 struct refclockbug bug; 2286 struct sockaddr_in addr; 2287 2288 memset((char *)&addr, 0, sizeof addr); 2289 addr.sin_family = AF_INET; 2290 addr.sin_port = htons(NTP_PORT); 2291 items = INFO_NITEMS(inpkt->err_nitems); 2292 clkaddr = (u_int32 *) inpkt->data; 2293 2294 ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt, 2295 sizeof(struct info_clkbug)); 2296 2297 while (items-- > 0) { 2298 addr.sin_addr.s_addr = *clkaddr++; 2299 if (!ISREFCLOCKADR(&addr) || 2300 findexistingpeer(&addr, (struct peer *)0, -1) == 0) { 2301 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2302 return; 2303 } 2304 2305 memset((char *)&bug, 0, sizeof bug); 2306 refclock_buginfo(&addr, &bug); 2307 if (bug.nvalues == 0 && bug.ntimes == 0) { 2308 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2309 return; 2310 } 2311 2312 ic->clockadr = addr.sin_addr.s_addr; 2313 i = bug.nvalues; 2314 if (i > NUMCBUGVALUES) 2315 i = NUMCBUGVALUES; 2316 ic->nvalues = (u_char)i; 2317 ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1))); 2318 while (--i >= 0) 2319 ic->values[i] = htonl(bug.values[i]); 2320 2321 i = bug.ntimes; 2322 if (i > NUMCBUGTIMES) 2323 i = NUMCBUGTIMES; 2324 ic->ntimes = (u_char)i; 2325 ic->stimes = htonl(bug.stimes); 2326 while (--i >= 0) { 2327 HTONL_FP(&bug.times[i], &ic->times[i]); 2328 } 2329 2330 ic = (struct info_clkbug *)more_pkt(); 2331 } 2332 flush_pkt(); 2333 } 2334 #endif 2335