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