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