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. Needs to reload data pointer and 1761 * item counter. (Talos-CAN-0052) 1762 */ 1763 ZERO_SOCK(&matchaddr); 1764 ZERO_SOCK(&matchmask); 1765 items = INFO_NITEMS(inpkt->err_nitems); 1766 datap = inpkt->u.data; 1767 1768 while (items-- > 0) { 1769 memcpy(&cr, datap, item_sz); 1770 cr.flags = ntohs(cr.flags); 1771 cr.mflags = ntohs(cr.mflags); 1772 if (client_v6_capable && cr.v6_flag) { 1773 AF(&matchaddr) = AF_INET6; 1774 AF(&matchmask) = AF_INET6; 1775 SOCK_ADDR6(&matchaddr) = cr.addr6; 1776 SOCK_ADDR6(&matchmask) = cr.mask6; 1777 } else { 1778 AF(&matchaddr) = AF_INET; 1779 AF(&matchmask) = AF_INET; 1780 NSRCADR(&matchaddr) = cr.addr; 1781 NSRCADR(&matchmask) = cr.mask; 1782 } 1783 hack_restrict(op, &matchaddr, &matchmask, cr.mflags, 1784 cr.flags, 0); 1785 datap += item_sz; 1786 } 1787 1788 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1789 } 1790 1791 1792 /* 1793 * mon_getlist - return monitor data 1794 */ 1795 static void 1796 mon_getlist( 1797 sockaddr_u *srcadr, 1798 endpt *inter, 1799 struct req_pkt *inpkt 1800 ) 1801 { 1802 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1803 } 1804 1805 1806 /* 1807 * Module entry points and the flags they correspond with 1808 */ 1809 struct reset_entry { 1810 int flag; /* flag this corresponds to */ 1811 void (*handler)(void); /* routine to handle request */ 1812 }; 1813 1814 struct reset_entry reset_entries[] = { 1815 { RESET_FLAG_ALLPEERS, peer_all_reset }, 1816 { RESET_FLAG_IO, io_clr_stats }, 1817 { RESET_FLAG_SYS, proto_clr_stats }, 1818 { RESET_FLAG_MEM, peer_clr_stats }, 1819 { RESET_FLAG_TIMER, timer_clr_stats }, 1820 { RESET_FLAG_AUTH, reset_auth_stats }, 1821 { RESET_FLAG_CTL, ctl_clr_stats }, 1822 { 0, 0 } 1823 }; 1824 1825 /* 1826 * reset_stats - reset statistic counters here and there 1827 */ 1828 static void 1829 reset_stats( 1830 sockaddr_u *srcadr, 1831 endpt *inter, 1832 struct req_pkt *inpkt 1833 ) 1834 { 1835 struct reset_flags *rflags; 1836 u_long flags; 1837 struct reset_entry *rent; 1838 1839 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 1840 msyslog(LOG_ERR, "reset_stats: err_nitems > 1"); 1841 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1842 return; 1843 } 1844 1845 rflags = (struct reset_flags *)&inpkt->u; 1846 flags = ntohl(rflags->flags); 1847 1848 if (flags & ~RESET_ALLFLAGS) { 1849 msyslog(LOG_ERR, "reset_stats: reset leaves %#lx", 1850 flags & ~RESET_ALLFLAGS); 1851 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1852 return; 1853 } 1854 1855 for (rent = reset_entries; rent->flag != 0; rent++) { 1856 if (flags & rent->flag) 1857 (*rent->handler)(); 1858 } 1859 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1860 } 1861 1862 1863 /* 1864 * reset_peer - clear a peer's statistics 1865 */ 1866 static void 1867 reset_peer( 1868 sockaddr_u *srcadr, 1869 endpt *inter, 1870 struct req_pkt *inpkt 1871 ) 1872 { 1873 u_short items; 1874 size_t item_sz; 1875 char * datap; 1876 struct conf_unpeer cp; 1877 struct peer * p; 1878 sockaddr_u peeraddr; 1879 int bad; 1880 1881 /* 1882 * We check first to see that every peer exists. If not, 1883 * we return an error. 1884 */ 1885 1886 items = INFO_NITEMS(inpkt->err_nitems); 1887 item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); 1888 datap = inpkt->u.data; 1889 if (item_sz > sizeof(cp)) { 1890 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1891 return; 1892 } 1893 1894 bad = FALSE; 1895 while (items-- > 0 && !bad) { 1896 ZERO(cp); 1897 memcpy(&cp, datap, item_sz); 1898 ZERO_SOCK(&peeraddr); 1899 if (client_v6_capable && cp.v6_flag) { 1900 AF(&peeraddr) = AF_INET6; 1901 SOCK_ADDR6(&peeraddr) = cp.peeraddr6; 1902 } else { 1903 AF(&peeraddr) = AF_INET; 1904 NSRCADR(&peeraddr) = cp.peeraddr; 1905 } 1906 1907 #ifdef ISC_PLATFORM_HAVESALEN 1908 peeraddr.sa.sa_len = SOCKLEN(&peeraddr); 1909 #endif 1910 p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0); 1911 if (NULL == p) 1912 bad++; 1913 datap += item_sz; 1914 } 1915 1916 if (bad) { 1917 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1918 return; 1919 } 1920 1921 /* 1922 * Now do it in earnest. Needs to reload data pointer and item 1923 * counter. (Talos-CAN-0052) 1924 */ 1925 1926 items = INFO_NITEMS(inpkt->err_nitems); 1927 datap = inpkt->u.data; 1928 while (items-- > 0) { 1929 ZERO(cp); 1930 memcpy(&cp, datap, item_sz); 1931 ZERO_SOCK(&peeraddr); 1932 if (client_v6_capable && cp.v6_flag) { 1933 AF(&peeraddr) = AF_INET6; 1934 SOCK_ADDR6(&peeraddr) = cp.peeraddr6; 1935 } else { 1936 AF(&peeraddr) = AF_INET; 1937 NSRCADR(&peeraddr) = cp.peeraddr; 1938 } 1939 SET_PORT(&peeraddr, 123); 1940 #ifdef ISC_PLATFORM_HAVESALEN 1941 peeraddr.sa.sa_len = SOCKLEN(&peeraddr); 1942 #endif 1943 p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0); 1944 while (p != NULL) { 1945 peer_reset(p); 1946 p = findexistingpeer(&peeraddr, NULL, p, -1, 0); 1947 } 1948 datap += item_sz; 1949 } 1950 1951 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1952 } 1953 1954 1955 /* 1956 * do_key_reread - reread the encryption key file 1957 */ 1958 static void 1959 do_key_reread( 1960 sockaddr_u *srcadr, 1961 endpt *inter, 1962 struct req_pkt *inpkt 1963 ) 1964 { 1965 rereadkeys(); 1966 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1967 } 1968 1969 1970 /* 1971 * trust_key - make one or more keys trusted 1972 */ 1973 static void 1974 trust_key( 1975 sockaddr_u *srcadr, 1976 endpt *inter, 1977 struct req_pkt *inpkt 1978 ) 1979 { 1980 do_trustkey(srcadr, inter, inpkt, 1); 1981 } 1982 1983 1984 /* 1985 * untrust_key - make one or more keys untrusted 1986 */ 1987 static void 1988 untrust_key( 1989 sockaddr_u *srcadr, 1990 endpt *inter, 1991 struct req_pkt *inpkt 1992 ) 1993 { 1994 do_trustkey(srcadr, inter, inpkt, 0); 1995 } 1996 1997 1998 /* 1999 * do_trustkey - make keys either trustable or untrustable 2000 */ 2001 static void 2002 do_trustkey( 2003 sockaddr_u *srcadr, 2004 endpt *inter, 2005 struct req_pkt *inpkt, 2006 u_long trust 2007 ) 2008 { 2009 register u_long *kp; 2010 register int items; 2011 2012 items = INFO_NITEMS(inpkt->err_nitems); 2013 kp = (u_long *)&inpkt->u; 2014 while (items-- > 0) { 2015 authtrust(*kp, trust); 2016 kp++; 2017 } 2018 2019 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2020 } 2021 2022 2023 /* 2024 * get_auth_info - return some stats concerning the authentication module 2025 */ 2026 static void 2027 get_auth_info( 2028 sockaddr_u *srcadr, 2029 endpt *inter, 2030 struct req_pkt *inpkt 2031 ) 2032 { 2033 register struct info_auth *ia; 2034 2035 ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt, 2036 sizeof(struct info_auth)); 2037 2038 ia->numkeys = htonl((u_int32)authnumkeys); 2039 ia->numfreekeys = htonl((u_int32)authnumfreekeys); 2040 ia->keylookups = htonl((u_int32)authkeylookups); 2041 ia->keynotfound = htonl((u_int32)authkeynotfound); 2042 ia->encryptions = htonl((u_int32)authencryptions); 2043 ia->decryptions = htonl((u_int32)authdecryptions); 2044 ia->keyuncached = htonl((u_int32)authkeyuncached); 2045 ia->expired = htonl((u_int32)authkeyexpired); 2046 ia->timereset = htonl((u_int32)(current_time - auth_timereset)); 2047 2048 (void) more_pkt(); 2049 flush_pkt(); 2050 } 2051 2052 2053 2054 /* 2055 * reset_auth_stats - reset the authentication stat counters. Done here 2056 * to keep ntp-isms out of the authentication module 2057 */ 2058 void 2059 reset_auth_stats(void) 2060 { 2061 authkeylookups = 0; 2062 authkeynotfound = 0; 2063 authencryptions = 0; 2064 authdecryptions = 0; 2065 authkeyuncached = 0; 2066 auth_timereset = current_time; 2067 } 2068 2069 2070 /* 2071 * req_get_traps - return information about current trap holders 2072 */ 2073 static void 2074 req_get_traps( 2075 sockaddr_u *srcadr, 2076 endpt *inter, 2077 struct req_pkt *inpkt 2078 ) 2079 { 2080 struct info_trap *it; 2081 struct ctl_trap *tr; 2082 size_t i; 2083 2084 if (num_ctl_traps == 0) { 2085 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2086 return; 2087 } 2088 2089 it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt, 2090 v6sizeof(struct info_trap)); 2091 2092 for (i = 0, tr = ctl_traps; i < COUNTOF(ctl_traps); i++, tr++) { 2093 if (tr->tr_flags & TRAP_INUSE) { 2094 if (IS_IPV4(&tr->tr_addr)) { 2095 if (tr->tr_localaddr == any_interface) 2096 it->local_address = 0; 2097 else 2098 it->local_address 2099 = NSRCADR(&tr->tr_localaddr->sin); 2100 it->trap_address = NSRCADR(&tr->tr_addr); 2101 if (client_v6_capable) 2102 it->v6_flag = 0; 2103 } else { 2104 if (!client_v6_capable) 2105 continue; 2106 it->local_address6 2107 = SOCK_ADDR6(&tr->tr_localaddr->sin); 2108 it->trap_address6 = SOCK_ADDR6(&tr->tr_addr); 2109 it->v6_flag = 1; 2110 } 2111 it->trap_port = NSRCPORT(&tr->tr_addr); 2112 it->sequence = htons(tr->tr_sequence); 2113 it->settime = htonl((u_int32)(current_time - tr->tr_settime)); 2114 it->origtime = htonl((u_int32)(current_time - tr->tr_origtime)); 2115 it->resets = htonl((u_int32)tr->tr_resets); 2116 it->flags = htonl((u_int32)tr->tr_flags); 2117 it = (struct info_trap *)more_pkt(); 2118 } 2119 } 2120 flush_pkt(); 2121 } 2122 2123 2124 /* 2125 * req_set_trap - configure a trap 2126 */ 2127 static void 2128 req_set_trap( 2129 sockaddr_u *srcadr, 2130 endpt *inter, 2131 struct req_pkt *inpkt 2132 ) 2133 { 2134 do_setclr_trap(srcadr, inter, inpkt, 1); 2135 } 2136 2137 2138 2139 /* 2140 * req_clr_trap - unconfigure a trap 2141 */ 2142 static void 2143 req_clr_trap( 2144 sockaddr_u *srcadr, 2145 endpt *inter, 2146 struct req_pkt *inpkt 2147 ) 2148 { 2149 do_setclr_trap(srcadr, inter, inpkt, 0); 2150 } 2151 2152 2153 2154 /* 2155 * do_setclr_trap - do the grunge work of (un)configuring a trap 2156 */ 2157 static void 2158 do_setclr_trap( 2159 sockaddr_u *srcadr, 2160 endpt *inter, 2161 struct req_pkt *inpkt, 2162 int set 2163 ) 2164 { 2165 register struct conf_trap *ct; 2166 register endpt *linter; 2167 int res; 2168 sockaddr_u laddr; 2169 2170 /* 2171 * Prepare sockaddr 2172 */ 2173 ZERO_SOCK(&laddr); 2174 AF(&laddr) = AF(srcadr); 2175 SET_PORT(&laddr, NTP_PORT); 2176 2177 /* 2178 * Restrict ourselves to one item only. This eliminates 2179 * the error reporting problem. 2180 */ 2181 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2182 msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1"); 2183 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2184 return; 2185 } 2186 ct = (struct conf_trap *)&inpkt->u; 2187 2188 /* 2189 * Look for the local interface. If none, use the default. 2190 */ 2191 if (ct->local_address == 0) { 2192 linter = any_interface; 2193 } else { 2194 if (IS_IPV4(&laddr)) 2195 NSRCADR(&laddr) = ct->local_address; 2196 else 2197 SOCK_ADDR6(&laddr) = ct->local_address6; 2198 linter = findinterface(&laddr); 2199 if (NULL == linter) { 2200 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2201 return; 2202 } 2203 } 2204 2205 if (IS_IPV4(&laddr)) 2206 NSRCADR(&laddr) = ct->trap_address; 2207 else 2208 SOCK_ADDR6(&laddr) = ct->trap_address6; 2209 if (ct->trap_port) 2210 NSRCPORT(&laddr) = ct->trap_port; 2211 else 2212 SET_PORT(&laddr, TRAPPORT); 2213 2214 if (set) { 2215 res = ctlsettrap(&laddr, linter, 0, 2216 INFO_VERSION(inpkt->rm_vn_mode)); 2217 } else { 2218 res = ctlclrtrap(&laddr, linter, 0); 2219 } 2220 2221 if (!res) { 2222 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2223 } else { 2224 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2225 } 2226 return; 2227 } 2228 2229 2230 2231 /* 2232 * set_request_keyid - set the keyid used to authenticate requests 2233 */ 2234 static void 2235 set_request_keyid( 2236 sockaddr_u *srcadr, 2237 endpt *inter, 2238 struct req_pkt *inpkt 2239 ) 2240 { 2241 keyid_t *pkeyid; 2242 2243 /* 2244 * Restrict ourselves to one item only. 2245 */ 2246 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2247 msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1"); 2248 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2249 return; 2250 } 2251 2252 pkeyid = (keyid_t *)&inpkt->u; 2253 info_auth_keyid = ntohl(*pkeyid); 2254 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2255 } 2256 2257 2258 2259 /* 2260 * set_control_keyid - set the keyid used to authenticate requests 2261 */ 2262 static void 2263 set_control_keyid( 2264 sockaddr_u *srcadr, 2265 endpt *inter, 2266 struct req_pkt *inpkt 2267 ) 2268 { 2269 keyid_t *pkeyid; 2270 2271 /* 2272 * Restrict ourselves to one item only. 2273 */ 2274 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2275 msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1"); 2276 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2277 return; 2278 } 2279 2280 pkeyid = (keyid_t *)&inpkt->u; 2281 ctl_auth_keyid = ntohl(*pkeyid); 2282 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2283 } 2284 2285 2286 2287 /* 2288 * get_ctl_stats - return some stats concerning the control message module 2289 */ 2290 static void 2291 get_ctl_stats( 2292 sockaddr_u *srcadr, 2293 endpt *inter, 2294 struct req_pkt *inpkt 2295 ) 2296 { 2297 register struct info_control *ic; 2298 2299 ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt, 2300 sizeof(struct info_control)); 2301 2302 ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset)); 2303 ic->numctlreq = htonl((u_int32)numctlreq); 2304 ic->numctlbadpkts = htonl((u_int32)numctlbadpkts); 2305 ic->numctlresponses = htonl((u_int32)numctlresponses); 2306 ic->numctlfrags = htonl((u_int32)numctlfrags); 2307 ic->numctlerrors = htonl((u_int32)numctlerrors); 2308 ic->numctltooshort = htonl((u_int32)numctltooshort); 2309 ic->numctlinputresp = htonl((u_int32)numctlinputresp); 2310 ic->numctlinputfrag = htonl((u_int32)numctlinputfrag); 2311 ic->numctlinputerr = htonl((u_int32)numctlinputerr); 2312 ic->numctlbadoffset = htonl((u_int32)numctlbadoffset); 2313 ic->numctlbadversion = htonl((u_int32)numctlbadversion); 2314 ic->numctldatatooshort = htonl((u_int32)numctldatatooshort); 2315 ic->numctlbadop = htonl((u_int32)numctlbadop); 2316 ic->numasyncmsgs = htonl((u_int32)numasyncmsgs); 2317 2318 (void) more_pkt(); 2319 flush_pkt(); 2320 } 2321 2322 2323 #ifdef KERNEL_PLL 2324 /* 2325 * get_kernel_info - get kernel pll/pps information 2326 */ 2327 static void 2328 get_kernel_info( 2329 sockaddr_u *srcadr, 2330 endpt *inter, 2331 struct req_pkt *inpkt 2332 ) 2333 { 2334 register struct info_kernel *ik; 2335 struct timex ntx; 2336 2337 if (!pll_control) { 2338 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2339 return; 2340 } 2341 2342 ZERO(ntx); 2343 if (ntp_adjtime(&ntx) < 0) 2344 msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m"); 2345 ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt, 2346 sizeof(struct info_kernel)); 2347 2348 /* 2349 * pll variables 2350 */ 2351 ik->offset = htonl((u_int32)ntx.offset); 2352 ik->freq = htonl((u_int32)ntx.freq); 2353 ik->maxerror = htonl((u_int32)ntx.maxerror); 2354 ik->esterror = htonl((u_int32)ntx.esterror); 2355 ik->status = htons(ntx.status); 2356 ik->constant = htonl((u_int32)ntx.constant); 2357 ik->precision = htonl((u_int32)ntx.precision); 2358 ik->tolerance = htonl((u_int32)ntx.tolerance); 2359 2360 /* 2361 * pps variables 2362 */ 2363 ik->ppsfreq = htonl((u_int32)ntx.ppsfreq); 2364 ik->jitter = htonl((u_int32)ntx.jitter); 2365 ik->shift = htons(ntx.shift); 2366 ik->stabil = htonl((u_int32)ntx.stabil); 2367 ik->jitcnt = htonl((u_int32)ntx.jitcnt); 2368 ik->calcnt = htonl((u_int32)ntx.calcnt); 2369 ik->errcnt = htonl((u_int32)ntx.errcnt); 2370 ik->stbcnt = htonl((u_int32)ntx.stbcnt); 2371 2372 (void) more_pkt(); 2373 flush_pkt(); 2374 } 2375 #endif /* KERNEL_PLL */ 2376 2377 2378 #ifdef REFCLOCK 2379 /* 2380 * get_clock_info - get info about a clock 2381 */ 2382 static void 2383 get_clock_info( 2384 sockaddr_u *srcadr, 2385 endpt *inter, 2386 struct req_pkt *inpkt 2387 ) 2388 { 2389 register struct info_clock *ic; 2390 register u_int32 *clkaddr; 2391 register int items; 2392 struct refclockstat clock_stat; 2393 sockaddr_u addr; 2394 l_fp ltmp; 2395 2396 ZERO_SOCK(&addr); 2397 AF(&addr) = AF_INET; 2398 #ifdef ISC_PLATFORM_HAVESALEN 2399 addr.sa.sa_len = SOCKLEN(&addr); 2400 #endif 2401 SET_PORT(&addr, NTP_PORT); 2402 items = INFO_NITEMS(inpkt->err_nitems); 2403 clkaddr = &inpkt->u.u32[0]; 2404 2405 ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt, 2406 sizeof(struct info_clock)); 2407 2408 while (items-- > 0) { 2409 NSRCADR(&addr) = *clkaddr++; 2410 if (!ISREFCLOCKADR(&addr) || NULL == 2411 findexistingpeer(&addr, NULL, NULL, -1, 0)) { 2412 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2413 return; 2414 } 2415 2416 clock_stat.kv_list = (struct ctl_var *)0; 2417 2418 refclock_control(&addr, NULL, &clock_stat); 2419 2420 ic->clockadr = NSRCADR(&addr); 2421 ic->type = clock_stat.type; 2422 ic->flags = clock_stat.flags; 2423 ic->lastevent = clock_stat.lastevent; 2424 ic->currentstatus = clock_stat.currentstatus; 2425 ic->polls = htonl((u_int32)clock_stat.polls); 2426 ic->noresponse = htonl((u_int32)clock_stat.noresponse); 2427 ic->badformat = htonl((u_int32)clock_stat.badformat); 2428 ic->baddata = htonl((u_int32)clock_stat.baddata); 2429 ic->timestarted = htonl((u_int32)clock_stat.timereset); 2430 DTOLFP(clock_stat.fudgetime1, <mp); 2431 HTONL_FP(<mp, &ic->fudgetime1); 2432 DTOLFP(clock_stat.fudgetime2, <mp); 2433 HTONL_FP(<mp, &ic->fudgetime2); 2434 ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1); 2435 ic->fudgeval2 = htonl(clock_stat.fudgeval2); 2436 2437 free_varlist(clock_stat.kv_list); 2438 2439 ic = (struct info_clock *)more_pkt(); 2440 } 2441 flush_pkt(); 2442 } 2443 2444 2445 2446 /* 2447 * set_clock_fudge - get a clock's fudge factors 2448 */ 2449 static void 2450 set_clock_fudge( 2451 sockaddr_u *srcadr, 2452 endpt *inter, 2453 struct req_pkt *inpkt 2454 ) 2455 { 2456 register struct conf_fudge *cf; 2457 register int items; 2458 struct refclockstat clock_stat; 2459 sockaddr_u addr; 2460 l_fp ltmp; 2461 2462 ZERO(addr); 2463 ZERO(clock_stat); 2464 items = INFO_NITEMS(inpkt->err_nitems); 2465 cf = (struct conf_fudge *)&inpkt->u; 2466 2467 while (items-- > 0) { 2468 AF(&addr) = AF_INET; 2469 NSRCADR(&addr) = cf->clockadr; 2470 #ifdef ISC_PLATFORM_HAVESALEN 2471 addr.sa.sa_len = SOCKLEN(&addr); 2472 #endif 2473 SET_PORT(&addr, NTP_PORT); 2474 if (!ISREFCLOCKADR(&addr) || NULL == 2475 findexistingpeer(&addr, NULL, NULL, -1, 0)) { 2476 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2477 return; 2478 } 2479 2480 switch(ntohl(cf->which)) { 2481 case FUDGE_TIME1: 2482 NTOHL_FP(&cf->fudgetime, <mp); 2483 LFPTOD(<mp, clock_stat.fudgetime1); 2484 clock_stat.haveflags = CLK_HAVETIME1; 2485 break; 2486 case FUDGE_TIME2: 2487 NTOHL_FP(&cf->fudgetime, <mp); 2488 LFPTOD(<mp, clock_stat.fudgetime2); 2489 clock_stat.haveflags = CLK_HAVETIME2; 2490 break; 2491 case FUDGE_VAL1: 2492 clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags); 2493 clock_stat.haveflags = CLK_HAVEVAL1; 2494 break; 2495 case FUDGE_VAL2: 2496 clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags); 2497 clock_stat.haveflags = CLK_HAVEVAL2; 2498 break; 2499 case FUDGE_FLAGS: 2500 clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf); 2501 clock_stat.haveflags = 2502 (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4); 2503 break; 2504 default: 2505 msyslog(LOG_ERR, "set_clock_fudge: default!"); 2506 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2507 return; 2508 } 2509 2510 refclock_control(&addr, &clock_stat, (struct refclockstat *)0); 2511 } 2512 2513 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2514 } 2515 #endif 2516 2517 #ifdef REFCLOCK 2518 /* 2519 * get_clkbug_info - get debugging info about a clock 2520 */ 2521 static void 2522 get_clkbug_info( 2523 sockaddr_u *srcadr, 2524 endpt *inter, 2525 struct req_pkt *inpkt 2526 ) 2527 { 2528 register int i; 2529 register struct info_clkbug *ic; 2530 register u_int32 *clkaddr; 2531 register int items; 2532 struct refclockbug bug; 2533 sockaddr_u addr; 2534 2535 ZERO_SOCK(&addr); 2536 AF(&addr) = AF_INET; 2537 #ifdef ISC_PLATFORM_HAVESALEN 2538 addr.sa.sa_len = SOCKLEN(&addr); 2539 #endif 2540 SET_PORT(&addr, NTP_PORT); 2541 items = INFO_NITEMS(inpkt->err_nitems); 2542 clkaddr = (u_int32 *)&inpkt->u; 2543 2544 ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt, 2545 sizeof(struct info_clkbug)); 2546 2547 while (items-- > 0) { 2548 NSRCADR(&addr) = *clkaddr++; 2549 if (!ISREFCLOCKADR(&addr) || NULL == 2550 findexistingpeer(&addr, NULL, NULL, -1, 0)) { 2551 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2552 return; 2553 } 2554 2555 ZERO(bug); 2556 refclock_buginfo(&addr, &bug); 2557 if (bug.nvalues == 0 && bug.ntimes == 0) { 2558 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2559 return; 2560 } 2561 2562 ic->clockadr = NSRCADR(&addr); 2563 i = bug.nvalues; 2564 if (i > NUMCBUGVALUES) 2565 i = NUMCBUGVALUES; 2566 ic->nvalues = (u_char)i; 2567 ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1))); 2568 while (--i >= 0) 2569 ic->values[i] = htonl(bug.values[i]); 2570 2571 i = bug.ntimes; 2572 if (i > NUMCBUGTIMES) 2573 i = NUMCBUGTIMES; 2574 ic->ntimes = (u_char)i; 2575 ic->stimes = htonl(bug.stimes); 2576 while (--i >= 0) { 2577 HTONL_FP(&bug.times[i], &ic->times[i]); 2578 } 2579 2580 ic = (struct info_clkbug *)more_pkt(); 2581 } 2582 flush_pkt(); 2583 } 2584 #endif 2585 2586 /* 2587 * receiver of interface structures 2588 */ 2589 static void 2590 fill_info_if_stats(void *data, interface_info_t *interface_info) 2591 { 2592 struct info_if_stats **ifsp = (struct info_if_stats **)data; 2593 struct info_if_stats *ifs = *ifsp; 2594 endpt *ep = interface_info->ep; 2595 2596 ZERO(*ifs); 2597 2598 if (IS_IPV6(&ep->sin)) { 2599 if (!client_v6_capable) { 2600 return; 2601 } 2602 ifs->v6_flag = 1; 2603 ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin); 2604 ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast); 2605 ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask); 2606 } else { 2607 ifs->v6_flag = 0; 2608 ifs->unaddr.addr = SOCK_ADDR4(&ep->sin); 2609 ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast); 2610 ifs->unmask.addr = SOCK_ADDR4(&ep->mask); 2611 } 2612 ifs->v6_flag = htonl(ifs->v6_flag); 2613 strlcpy(ifs->name, ep->name, sizeof(ifs->name)); 2614 ifs->family = htons(ep->family); 2615 ifs->flags = htonl(ep->flags); 2616 ifs->last_ttl = htonl(ep->last_ttl); 2617 ifs->num_mcast = htonl(ep->num_mcast); 2618 ifs->received = htonl(ep->received); 2619 ifs->sent = htonl(ep->sent); 2620 ifs->notsent = htonl(ep->notsent); 2621 ifs->ifindex = htonl(ep->ifindex); 2622 /* scope no longer in endpt, in in6_addr typically */ 2623 ifs->scopeid = ifs->ifindex; 2624 ifs->ifnum = htonl(ep->ifnum); 2625 ifs->uptime = htonl(current_time - ep->starttime); 2626 ifs->ignore_packets = ep->ignore_packets; 2627 ifs->peercnt = htonl(ep->peercnt); 2628 ifs->action = interface_info->action; 2629 2630 *ifsp = (struct info_if_stats *)more_pkt(); 2631 } 2632 2633 /* 2634 * get_if_stats - get interface statistics 2635 */ 2636 static void 2637 get_if_stats( 2638 sockaddr_u *srcadr, 2639 endpt *inter, 2640 struct req_pkt *inpkt 2641 ) 2642 { 2643 struct info_if_stats *ifs; 2644 2645 DPRINTF(3, ("wants interface statistics\n")); 2646 2647 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, 2648 v6sizeof(struct info_if_stats)); 2649 2650 interface_enumerate(fill_info_if_stats, &ifs); 2651 2652 flush_pkt(); 2653 } 2654 2655 static void 2656 do_if_reload( 2657 sockaddr_u *srcadr, 2658 endpt *inter, 2659 struct req_pkt *inpkt 2660 ) 2661 { 2662 struct info_if_stats *ifs; 2663 2664 DPRINTF(3, ("wants interface reload\n")); 2665 2666 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, 2667 v6sizeof(struct info_if_stats)); 2668 2669 interface_update(fill_info_if_stats, &ifs); 2670 2671 flush_pkt(); 2672 } 2673 2674