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