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