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