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