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