ntp_request.c revision 1.1
1/* $NetBSD: ntp_request.c,v 1.1 2009/12/13 16:55:40 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 } 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 int 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 < 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 %u\n", 588 INFO_IS_AUTH(inpkt->auth_seq), 589 info_auth_keyid, 590 ntohl(tailinpkt->keyid), mac_len)); 591#ifdef DEBUG 592 msyslog(LOG_DEBUG, 593 "process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %u\n", 594 INFO_IS_AUTH(inpkt->auth_seq), 595 info_auth_keyid, 596 ntohl(tailinpkt->keyid), 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 %d\n", recv_len)); 603 msyslog(LOG_ERR, 604 "process_private: bad pkt length %d", 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.sas.ss_len = SOCKLEN(&addr); 854#endif 855 ipl++; 856 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0) 857 continue; 858 if (IS_IPV6(srcadr)) { 859 if (pp->dstadr) 860 ip->dstadr6 = 861 (MDF_BCAST == pp->cast_flags) 862 ? SOCK_ADDR6(&pp->dstadr->bcast) 863 : SOCK_ADDR6(&pp->dstadr->sin); 864 else 865 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); 866 867 ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); 868 ip->v6_flag = 1; 869 } else { 870 if (pp->dstadr) { 871 if (!pp->processed) 872 ip->dstadr = NSRCADR(&pp->dstadr->sin); 873 else { 874 if (MDF_BCAST == pp->cast_flags) 875 ip->dstadr = NSRCADR(&pp->dstadr->bcast); 876 else if (pp->cast_flags) { 877 ip->dstadr = NSRCADR(&pp->dstadr->sin); 878 if (!ip->dstadr) 879 ip->dstadr = NSRCADR(&pp->dstadr->bcast); 880 } 881 } 882 } else 883 ip->dstadr = 0; 884 885 ip->srcadr = NSRCADR(&pp->srcadr); 886 if (client_v6_capable) 887 ip->v6_flag = 0; 888 } 889 ip->srcport = NSRCPORT(&pp->srcadr); 890 ip->flags = 0; 891 if (pp == sys_peer) 892 ip->flags |= INFO_FLAG_SYSPEER; 893 if (pp->flags & FLAG_CONFIG) 894 ip->flags |= INFO_FLAG_CONFIG; 895 if (pp->flags & FLAG_REFCLOCK) 896 ip->flags |= INFO_FLAG_REFCLOCK; 897 if (pp->flags & FLAG_PREFER) 898 ip->flags |= INFO_FLAG_PREFER; 899 if (pp->flags & FLAG_BURST) 900 ip->flags |= INFO_FLAG_BURST; 901 if (pp->status == CTL_PST_SEL_SYNCCAND) 902 ip->flags |= INFO_FLAG_SEL_CANDIDATE; 903 if (pp->status >= CTL_PST_SEL_SYSPEER) 904 ip->flags |= INFO_FLAG_SHORTLIST; 905 ip->leap = pp->leap; 906 ip->hmode = pp->hmode; 907 ip->keyid = pp->keyid; 908 ip->stratum = pp->stratum; 909 ip->ppoll = pp->ppoll; 910 ip->hpoll = pp->hpoll; 911 ip->precision = pp->precision; 912 ip->version = pp->version; 913 ip->reach = pp->reach; 914 ip->unreach = (u_char) pp->unreach; 915 ip->flash = (u_char)pp->flash; 916 ip->flash2 = (u_short) pp->flash; 917 ip->estbdelay = HTONS_FP(DTOFP(pp->delay)); 918 ip->ttl = pp->ttl; 919 ip->associd = htons(pp->associd); 920 ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay)); 921 ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp)); 922 ip->refid = pp->refid; 923 HTONL_FP(&pp->reftime, &ip->reftime); 924 HTONL_FP(&pp->aorg, &ip->org); 925 HTONL_FP(&pp->rec, &ip->rec); 926 HTONL_FP(&pp->xmt, &ip->xmt); 927 j = pp->filter_nextpt - 1; 928 for (i = 0; i < NTP_SHIFT; i++, j--) { 929 if (j < 0) 930 j = NTP_SHIFT-1; 931 ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j])); 932 DTOLFP(pp->filter_offset[j], <mp); 933 HTONL_FP(<mp, &ip->filtoffset[i]); 934 ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1) 935 - pp->filter_order[i]); 936 if (ip->order[i] >= NTP_SHIFT) 937 ip->order[i] -= NTP_SHIFT; 938 } 939 DTOLFP(pp->offset, <mp); 940 HTONL_FP(<mp, &ip->offset); 941 ip->delay = HTONS_FP(DTOFP(pp->delay)); 942 ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); 943 ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter))); 944 ip = (struct info_peer *)more_pkt(); 945 } 946 flush_pkt(); 947} 948 949 950/* 951 * peer_stats - send statistics for one or more peers 952 */ 953static void 954peer_stats ( 955 sockaddr_u *srcadr, 956 struct interface *inter, 957 struct req_pkt *inpkt 958 ) 959{ 960 register struct info_peer_list *ipl; 961 register struct peer *pp; 962 register struct info_peer_stats *ip; 963 register int items; 964 sockaddr_u addr; 965 extern struct peer *sys_peer; 966 967#ifdef DEBUG 968 if (debug) 969 printf("peer_stats: called\n"); 970#endif 971 items = INFO_NITEMS(inpkt->err_nitems); 972 ipl = (struct info_peer_list *) inpkt->data; 973 ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, 974 v6sizeof(struct info_peer_stats)); 975 while (items-- > 0 && ip != 0) { 976 memset((char *)&addr, 0, sizeof(addr)); 977 NSRCPORT(&addr) = ipl->port; 978 if (client_v6_capable && ipl->v6_flag) { 979 AF(&addr) = AF_INET6; 980 SOCK_ADDR6(&addr) = ipl->addr6; 981 } else { 982 AF(&addr) = AF_INET; 983 NSRCADR(&addr) = ipl->addr; 984 } 985#ifdef ISC_PLATFORM_HAVESALEN 986 addr.sas.ss_len = SOCKLEN(&addr); 987#endif 988 DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n", 989 stoa(&addr), ipl->port, NSRCPORT(&addr))); 990 991 ipl = (struct info_peer_list *)((char *)ipl + 992 INFO_ITEMSIZE(inpkt->mbz_itemsize)); 993 994 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == NULL) 995 continue; 996 997 DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr))); 998 999 if (IS_IPV4(&pp->srcadr)) { 1000 if (pp->dstadr) { 1001 if (!pp->processed) 1002 ip->dstadr = NSRCADR(&pp->dstadr->sin); 1003 else { 1004 if (MDF_BCAST == pp->cast_flags) 1005 ip->dstadr = NSRCADR(&pp->dstadr->bcast); 1006 else if (pp->cast_flags) { 1007 ip->dstadr = NSRCADR(&pp->dstadr->sin); 1008 if (!ip->dstadr) 1009 ip->dstadr = NSRCADR(&pp->dstadr->bcast); 1010 } 1011 } 1012 } else 1013 ip->dstadr = 0; 1014 1015 ip->srcadr = NSRCADR(&pp->srcadr); 1016 if (client_v6_capable) 1017 ip->v6_flag = 0; 1018 } else { 1019 if (pp->dstadr) 1020 ip->dstadr6 = 1021 (MDF_BCAST == pp->cast_flags) 1022 ? SOCK_ADDR6(&pp->dstadr->bcast) 1023 : SOCK_ADDR6(&pp->dstadr->sin); 1024 else 1025 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); 1026 1027 ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); 1028 ip->v6_flag = 1; 1029 } 1030 ip->srcport = NSRCPORT(&pp->srcadr); 1031 ip->flags = 0; 1032 if (pp == sys_peer) 1033 ip->flags |= INFO_FLAG_SYSPEER; 1034 if (pp->flags & FLAG_CONFIG) 1035 ip->flags |= INFO_FLAG_CONFIG; 1036 if (pp->flags & FLAG_REFCLOCK) 1037 ip->flags |= INFO_FLAG_REFCLOCK; 1038 if (pp->flags & FLAG_PREFER) 1039 ip->flags |= INFO_FLAG_PREFER; 1040 if (pp->flags & FLAG_BURST) 1041 ip->flags |= INFO_FLAG_BURST; 1042 if (pp->flags & FLAG_IBURST) 1043 ip->flags |= INFO_FLAG_IBURST; 1044 if (pp->status == CTL_PST_SEL_SYNCCAND) 1045 ip->flags |= INFO_FLAG_SEL_CANDIDATE; 1046 if (pp->status >= CTL_PST_SEL_SYSPEER) 1047 ip->flags |= INFO_FLAG_SHORTLIST; 1048 ip->flags = htons(ip->flags); 1049 ip->timereceived = htonl((u_int32)(current_time - pp->timereceived)); 1050 ip->timetosend = htonl(pp->nextdate - current_time); 1051 ip->timereachable = htonl((u_int32)(current_time - pp->timereachable)); 1052 ip->sent = htonl((u_int32)(pp->sent)); 1053 ip->processed = htonl((u_int32)(pp->processed)); 1054 ip->badauth = htonl((u_int32)(pp->badauth)); 1055 ip->bogusorg = htonl((u_int32)(pp->bogusorg)); 1056 ip->oldpkt = htonl((u_int32)(pp->oldpkt)); 1057 ip->seldisp = htonl((u_int32)(pp->seldisptoolarge)); 1058 ip->selbroken = htonl((u_int32)(pp->selbroken)); 1059 ip->candidate = pp->status; 1060 ip = (struct info_peer_stats *)more_pkt(); 1061 } 1062 flush_pkt(); 1063} 1064 1065 1066/* 1067 * sys_info - return system info 1068 */ 1069static void 1070sys_info( 1071 sockaddr_u *srcadr, 1072 struct interface *inter, 1073 struct req_pkt *inpkt 1074 ) 1075{ 1076 register struct info_sys *is; 1077 1078 is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt, 1079 v6sizeof(struct info_sys)); 1080 1081 if (sys_peer) { 1082 if (IS_IPV4(&sys_peer->srcadr)) { 1083 is->peer = NSRCADR(&sys_peer->srcadr); 1084 if (client_v6_capable) 1085 is->v6_flag = 0; 1086 } else if (client_v6_capable) { 1087 is->peer6 = SOCK_ADDR6(&sys_peer->srcadr); 1088 is->v6_flag = 1; 1089 } 1090 is->peer_mode = sys_peer->hmode; 1091 } else { 1092 is->peer = 0; 1093 if (client_v6_capable) { 1094 is->v6_flag = 0; 1095 } 1096 is->peer_mode = 0; 1097 } 1098 1099 is->leap = sys_leap; 1100 is->stratum = sys_stratum; 1101 is->precision = sys_precision; 1102 is->rootdelay = htonl(DTOFP(sys_rootdelay)); 1103 is->rootdispersion = htonl(DTOUFP(sys_rootdisp)); 1104 is->frequency = htonl(DTOFP(sys_jitter)); 1105 is->stability = htonl(DTOUFP(clock_stability)); 1106 is->refid = sys_refid; 1107 HTONL_FP(&sys_reftime, &is->reftime); 1108 1109 is->poll = sys_poll; 1110 1111 is->flags = 0; 1112 if (sys_authenticate) 1113 is->flags |= INFO_FLAG_AUTHENTICATE; 1114 if (sys_bclient) 1115 is->flags |= INFO_FLAG_BCLIENT; 1116#ifdef REFCLOCK 1117 if (cal_enable) 1118 is->flags |= INFO_FLAG_CAL; 1119#endif /* REFCLOCK */ 1120 if (kern_enable) 1121 is->flags |= INFO_FLAG_KERNEL; 1122 if (mon_enabled != MON_OFF) 1123 is->flags |= INFO_FLAG_MONITOR; 1124 if (ntp_enable) 1125 is->flags |= INFO_FLAG_NTP; 1126 if (pps_enable) 1127 is->flags |= INFO_FLAG_PPS_SYNC; 1128 if (stats_control) 1129 is->flags |= INFO_FLAG_FILEGEN; 1130 is->bdelay = HTONS_FP(DTOFP(sys_bdelay)); 1131 HTONL_UF(sys_authdelay.l_f, &is->authdelay); 1132 (void) more_pkt(); 1133 flush_pkt(); 1134} 1135 1136 1137/* 1138 * sys_stats - return system statistics 1139 */ 1140static void 1141sys_stats( 1142 sockaddr_u *srcadr, 1143 struct interface *inter, 1144 struct req_pkt *inpkt 1145 ) 1146{ 1147 register struct info_sys_stats *ss; 1148 1149 /* 1150 * Importations from the protocol module 1151 */ 1152 ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt, 1153 sizeof(struct info_sys_stats)); 1154 ss->timeup = htonl((u_int32)current_time); 1155 ss->timereset = htonl((u_int32)(current_time - sys_stattime)); 1156 ss->denied = htonl((u_int32)sys_restricted); 1157 ss->oldversionpkt = htonl((u_int32)sys_oldversion); 1158 ss->newversionpkt = htonl((u_int32)sys_newversion); 1159 ss->unknownversion = htonl((u_int32)sys_declined); 1160 ss->badlength = htonl((u_int32)sys_badlength); 1161 ss->processed = htonl((u_int32)sys_processed); 1162 ss->badauth = htonl((u_int32)sys_badauth); 1163 ss->limitrejected = htonl((u_int32)sys_limitrejected); 1164 ss->received = htonl((u_int32)sys_received); 1165 (void) more_pkt(); 1166 flush_pkt(); 1167} 1168 1169 1170/* 1171 * mem_stats - return memory statistics 1172 */ 1173static void 1174mem_stats( 1175 sockaddr_u *srcadr, 1176 struct interface *inter, 1177 struct req_pkt *inpkt 1178 ) 1179{ 1180 register struct info_mem_stats *ms; 1181 register int i; 1182 1183 /* 1184 * Importations from the peer module 1185 */ 1186 extern int peer_hash_count[NTP_HASH_SIZE]; 1187 extern int peer_free_count; 1188 extern u_long peer_timereset; 1189 extern u_long findpeer_calls; 1190 extern u_long peer_allocations; 1191 extern u_long peer_demobilizations; 1192 extern int total_peer_structs; 1193 1194 ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt, 1195 sizeof(struct info_mem_stats)); 1196 1197 ms->timereset = htonl((u_int32)(current_time - peer_timereset)); 1198 ms->totalpeermem = htons((u_short)total_peer_structs); 1199 ms->freepeermem = htons((u_short)peer_free_count); 1200 ms->findpeer_calls = htonl((u_int32)findpeer_calls); 1201 ms->allocations = htonl((u_int32)peer_allocations); 1202 ms->demobilizations = htonl((u_int32)peer_demobilizations); 1203 1204 for (i = 0; i < NTP_HASH_SIZE; i++) { 1205 if (peer_hash_count[i] > 255) 1206 ms->hashcount[i] = 255; 1207 else 1208 ms->hashcount[i] = (u_char)peer_hash_count[i]; 1209 } 1210 1211 (void) more_pkt(); 1212 flush_pkt(); 1213} 1214 1215 1216/* 1217 * io_stats - return io statistics 1218 */ 1219static void 1220io_stats( 1221 sockaddr_u *srcadr, 1222 struct interface *inter, 1223 struct req_pkt *inpkt 1224 ) 1225{ 1226 register struct info_io_stats *io; 1227 1228 /* 1229 * Importations from the io module 1230 */ 1231 extern u_long io_timereset; 1232 1233 io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt, 1234 sizeof(struct info_io_stats)); 1235 1236 io->timereset = htonl((u_int32)(current_time - io_timereset)); 1237 io->totalrecvbufs = htons((u_short) total_recvbuffs()); 1238 io->freerecvbufs = htons((u_short) free_recvbuffs()); 1239 io->fullrecvbufs = htons((u_short) full_recvbuffs()); 1240 io->lowwater = htons((u_short) lowater_additions()); 1241 io->dropped = htonl((u_int32)packets_dropped); 1242 io->ignored = htonl((u_int32)packets_ignored); 1243 io->received = htonl((u_int32)packets_received); 1244 io->sent = htonl((u_int32)packets_sent); 1245 io->notsent = htonl((u_int32)packets_notsent); 1246 io->interrupts = htonl((u_int32)handler_calls); 1247 io->int_received = htonl((u_int32)handler_pkts); 1248 1249 (void) more_pkt(); 1250 flush_pkt(); 1251} 1252 1253 1254/* 1255 * timer_stats - return timer statistics 1256 */ 1257static void 1258timer_stats( 1259 sockaddr_u *srcadr, 1260 struct interface *inter, 1261 struct req_pkt *inpkt 1262 ) 1263{ 1264 register struct info_timer_stats *ts; 1265 1266 /* 1267 * Importations from the timer module 1268 */ 1269 extern u_long timer_timereset; 1270 extern u_long timer_overflows; 1271 extern u_long timer_xmtcalls; 1272 1273 ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, inpkt, 1274 sizeof(struct info_timer_stats)); 1275 1276 ts->timereset = htonl((u_int32)(current_time - timer_timereset)); 1277 ts->alarms = htonl((u_int32)alarm_overflow); 1278 ts->overflows = htonl((u_int32)timer_overflows); 1279 ts->xmtcalls = htonl((u_int32)timer_xmtcalls); 1280 1281 (void) more_pkt(); 1282 flush_pkt(); 1283} 1284 1285 1286/* 1287 * loop_info - return the current state of the loop filter 1288 */ 1289static void 1290loop_info( 1291 sockaddr_u *srcadr, 1292 struct interface *inter, 1293 struct req_pkt *inpkt 1294 ) 1295{ 1296 register struct info_loop *li; 1297 l_fp ltmp; 1298 1299 /* 1300 * Importations from the loop filter module 1301 */ 1302 extern double last_offset; 1303 extern double drift_comp; 1304 extern int tc_counter; 1305 extern u_long sys_epoch; 1306 1307 li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt, 1308 sizeof(struct info_loop)); 1309 1310 DTOLFP(last_offset, <mp); 1311 HTONL_FP(<mp, &li->last_offset); 1312 DTOLFP(drift_comp * 1e6, <mp); 1313 HTONL_FP(<mp, &li->drift_comp); 1314 li->compliance = htonl((u_int32)(tc_counter)); 1315 li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch)); 1316 1317 (void) more_pkt(); 1318 flush_pkt(); 1319} 1320 1321 1322/* 1323 * do_conf - add a peer to the configuration list 1324 */ 1325static void 1326do_conf( 1327 sockaddr_u *srcadr, 1328 struct interface *inter, 1329 struct req_pkt *inpkt 1330 ) 1331{ 1332 static u_long soonest_ifrescan_time = 0; 1333 int items; 1334 u_int fl; 1335 struct conf_peer *cp; 1336 struct conf_peer temp_cp; 1337 sockaddr_u peeraddr; 1338 1339 /* 1340 * Do a check of everything to see that it looks 1341 * okay. If not, complain about it. Note we are 1342 * very picky here. 1343 */ 1344 items = INFO_NITEMS(inpkt->err_nitems); 1345 cp = (struct conf_peer *)inpkt->data; 1346 memset(&temp_cp, 0, sizeof(struct conf_peer)); 1347 memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1348 1349#if 0 /* paranoid checking - these are done in newpeer() */ 1350 fl = 0; 1351 while (items-- > 0 && !fl) { 1352 if (((temp_cp.version) > NTP_VERSION) 1353 || ((temp_cp.version) < NTP_OLDVERSION)) 1354 fl = 1; 1355 if (temp_cp.hmode != MODE_ACTIVE 1356 && temp_cp.hmode != MODE_CLIENT 1357 && temp_cp.hmode != MODE_BROADCAST) 1358 fl = 1; 1359 if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST | 1360 CONF_FLAG_IBURST | CONF_FLAG_SKEY)) 1361 fl = 1; 1362 cp = (struct conf_peer *) 1363 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1364 } 1365 1366 if (fl) { 1367 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1368 return; 1369 } 1370#endif /* end paranoid checking */ 1371 1372 /* 1373 * Looks okay, try it out 1374 */ 1375 items = INFO_NITEMS(inpkt->err_nitems); 1376 cp = (struct conf_peer *)inpkt->data; 1377 1378 while (items-- > 0) { 1379 memset(&temp_cp, 0, sizeof(struct conf_peer)); 1380 memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1381 ZERO_SOCK(&peeraddr); 1382 1383 fl = 0; 1384 if (temp_cp.flags & CONF_FLAG_PREFER) 1385 fl |= FLAG_PREFER; 1386 if (temp_cp.flags & CONF_FLAG_BURST) 1387 fl |= FLAG_BURST; 1388 if (temp_cp.flags & CONF_FLAG_IBURST) 1389 fl |= FLAG_IBURST; 1390#ifdef OPENSSL 1391 if (temp_cp.flags & CONF_FLAG_SKEY) 1392 fl |= FLAG_SKEY; 1393#endif /* OPENSSL */ 1394 if (client_v6_capable && temp_cp.v6_flag != 0) { 1395 AF(&peeraddr) = AF_INET6; 1396 SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; 1397 } else { 1398 AF(&peeraddr) = AF_INET; 1399 NSRCADR(&peeraddr) = temp_cp.peeraddr; 1400 /* 1401 * Make sure the address is valid 1402 */ 1403 if (!ISREFCLOCKADR(&peeraddr) && 1404 ISBADADR(&peeraddr)) { 1405 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1406 return; 1407 } 1408 1409 } 1410 NSRCPORT(&peeraddr) = htons(NTP_PORT); 1411#ifdef ISC_PLATFORM_HAVESALEN 1412 peeraddr.sas.ss_len = SOCKLEN(&peeraddr); 1413#endif 1414 1415 /* XXX W2DO? minpoll/maxpoll arguments ??? */ 1416 if (peer_config(&peeraddr, (struct interface *)0, 1417 temp_cp.hmode, temp_cp.version, temp_cp.minpoll, 1418 temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid, 1419 NULL) == 0) { 1420 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1421 return; 1422 } 1423 1424 /* 1425 * ntp_intres.c uses REQ_CONFIG/doconf() to add each 1426 * server after its name is resolved. If we have been 1427 * disconnected from the network, it may notice the 1428 * network has returned and add the first server while 1429 * the relevant interface is still disabled, awaiting 1430 * the next interface rescan. To get things moving 1431 * more quickly, trigger an interface scan now, except 1432 * if we have done so in the last half minute. 1433 */ 1434 if (soonest_ifrescan_time < current_time) { 1435 soonest_ifrescan_time = current_time + 30; 1436 timer_interfacetimeout(current_time); 1437 DPRINTF(1, ("do_conf triggering interface rescan\n")); 1438 } 1439 1440 cp = (struct conf_peer *) 1441 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1442 } 1443 1444 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1445} 1446 1447#if 0 1448/* XXX */ 1449/* 1450 * dns_a - Snarf DNS info for an association ID 1451 */ 1452static void 1453dns_a( 1454 sockaddr_u *srcadr, 1455 struct interface *inter, 1456 struct req_pkt *inpkt 1457 ) 1458{ 1459 register struct info_dns_assoc *dp; 1460 register int items; 1461 struct sockaddr_in peeraddr; 1462 1463 /* 1464 * Do a check of everything to see that it looks 1465 * okay. If not, complain about it. Note we are 1466 * very picky here. 1467 */ 1468 items = INFO_NITEMS(inpkt->err_nitems); 1469 dp = (struct info_dns_assoc *)inpkt->data; 1470 1471 /* 1472 * Looks okay, try it out 1473 */ 1474 items = INFO_NITEMS(inpkt->err_nitems); 1475 dp = (struct info_dns_assoc *)inpkt->data; 1476 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in)); 1477 peeraddr.sin_family = AF_INET; 1478 peeraddr.sin_port = htons(NTP_PORT); 1479 1480 /* 1481 * Make sure the address is valid 1482 */ 1483 if (!ISREFCLOCKADR(&peeraddr) && ISBADADR(&peeraddr)) { 1484 msyslog(LOG_ERR, "dns_a: !ISREFCLOCKADR && ISBADADR"); 1485 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1486 return; 1487 } 1488 1489 while (items-- > 0) { 1490 associd_t associd; 1491 size_t hnl; 1492 struct peer *peer; 1493 int bogon = 0; 1494 1495 associd = dp->associd; 1496 peer = findpeerbyassoc(associd); 1497 if (peer == 0 || peer->flags & FLAG_REFCLOCK) { 1498 msyslog(LOG_ERR, "dns_a: %s", 1499 (peer == 0) 1500 ? "peer == 0" 1501 : "peer->flags & FLAG_REFCLOCK"); 1502 ++bogon; 1503 } 1504 peeraddr.sin_addr.s_addr = dp->peeraddr; 1505 for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ; 1506 if (hnl >= sizeof dp->hostname) { 1507 msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld", 1508 (long)hnl, (long)sizeof dp->hostname); 1509 ++bogon; 1510 } 1511 1512 msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d", 1513 dp->hostname, 1514 stoa((sockaddr_u *)&peeraddr), associd, 1515 bogon); 1516 1517 if (bogon) { 1518 /* If it didn't work */ 1519 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1520 return; 1521 } else { 1522#if 0 1523#ifdef PUBKEY 1524 crypto_public(peer, dp->hostname); 1525#endif /* PUBKEY */ 1526#endif 1527 } 1528 1529 dp++; 1530 } 1531 1532 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1533} 1534#endif /* 0 */ 1535 1536/* 1537 * do_unconf - remove a peer from the configuration list 1538 */ 1539static void 1540do_unconf( 1541 sockaddr_u *srcadr, 1542 struct interface *inter, 1543 struct req_pkt *inpkt 1544 ) 1545{ 1546 register struct conf_unpeer *cp; 1547 struct conf_unpeer temp_cp; 1548 register int items; 1549 register struct peer *peer; 1550 sockaddr_u peeraddr; 1551 int bad, found; 1552 1553 /* 1554 * This is a bit unstructured, but I like to be careful. 1555 * We check to see that every peer exists and is actually 1556 * configured. If so, we remove them. If not, we return 1557 * an error. 1558 */ 1559 items = INFO_NITEMS(inpkt->err_nitems); 1560 cp = (struct conf_unpeer *)inpkt->data; 1561 1562 bad = 0; 1563 while (items-- > 0 && !bad) { 1564 memset(&temp_cp, 0, sizeof(temp_cp)); 1565 ZERO_SOCK(&peeraddr); 1566 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1567 if (client_v6_capable && temp_cp.v6_flag) { 1568 AF(&peeraddr) = AF_INET6; 1569 SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; 1570 } else { 1571 AF(&peeraddr) = AF_INET; 1572 NSRCADR(&peeraddr) = temp_cp.peeraddr; 1573 } 1574 SET_PORT(&peeraddr, NTP_PORT); 1575#ifdef ISC_PLATFORM_HAVESALEN 1576 peeraddr.sas.ss_len = SOCKLEN(&peeraddr); 1577#endif 1578 found = 0; 1579 peer = NULL; 1580 1581 DPRINTF(1, ("searching for %s\n", stoa(&peeraddr))); 1582 1583 while (!found) { 1584 peer = findexistingpeer(&peeraddr, peer, -1); 1585 if (!peer) 1586 break; 1587 if (peer->flags & FLAG_CONFIG) 1588 found = 1; 1589 } 1590 if (!found) 1591 bad = 1; 1592 cp = (struct conf_unpeer *) 1593 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1594 } 1595 1596 if (bad) { 1597 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1598 return; 1599 } 1600 1601 /* 1602 * Now do it in earnest. 1603 */ 1604 1605 items = INFO_NITEMS(inpkt->err_nitems); 1606 cp = (struct conf_unpeer *)inpkt->data; 1607 1608 while (items-- > 0) { 1609 memset(&temp_cp, 0, sizeof(temp_cp)); 1610 memset(&peeraddr, 0, sizeof(peeraddr)); 1611 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1612 if (client_v6_capable && temp_cp.v6_flag) { 1613 AF(&peeraddr) = AF_INET6; 1614 SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; 1615 } else { 1616 AF(&peeraddr) = AF_INET; 1617 NSRCADR(&peeraddr) = temp_cp.peeraddr; 1618 } 1619 SET_PORT(&peeraddr, NTP_PORT); 1620#ifdef ISC_PLATFORM_HAVESALEN 1621 peeraddr.sas.ss_len = SOCKLEN(&peeraddr); 1622#endif 1623 found = 0; 1624 peer = NULL; 1625 1626 while (!found) { 1627 peer = findexistingpeer(&peeraddr, peer, -1); 1628 if (!peer) 1629 break; 1630 if (peer->flags & FLAG_CONFIG) 1631 found = 1; 1632 } 1633 NTP_INSIST(found); 1634 NTP_INSIST(peer); 1635 1636 peer_clear(peer, "GONE"); 1637 unpeer(peer); 1638 1639 cp = (struct conf_unpeer *) 1640 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1641 } 1642 1643 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1644} 1645 1646 1647/* 1648 * set_sys_flag - set system flags 1649 */ 1650static void 1651set_sys_flag( 1652 sockaddr_u *srcadr, 1653 struct interface *inter, 1654 struct req_pkt *inpkt 1655 ) 1656{ 1657 setclr_flags(srcadr, inter, inpkt, 1); 1658} 1659 1660 1661/* 1662 * clr_sys_flag - clear system flags 1663 */ 1664static void 1665clr_sys_flag( 1666 sockaddr_u *srcadr, 1667 struct interface *inter, 1668 struct req_pkt *inpkt 1669 ) 1670{ 1671 setclr_flags(srcadr, inter, inpkt, 0); 1672} 1673 1674 1675/* 1676 * setclr_flags - do the grunge work of flag setting/clearing 1677 */ 1678static void 1679setclr_flags( 1680 sockaddr_u *srcadr, 1681 struct interface *inter, 1682 struct req_pkt *inpkt, 1683 u_long set 1684 ) 1685{ 1686 register u_int flags; 1687 int prev_kern_enable; 1688 1689 prev_kern_enable = kern_enable; 1690 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 1691 msyslog(LOG_ERR, "setclr_flags: err_nitems > 1"); 1692 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1693 return; 1694 } 1695 1696 flags = ((struct conf_sys_flags *)inpkt->data)->flags; 1697 flags = ntohl(flags); 1698 1699 if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | 1700 SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | 1701 SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) { 1702 msyslog(LOG_ERR, "setclr_flags: extra flags: %#x", 1703 flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | 1704 SYS_FLAG_NTP | SYS_FLAG_KERNEL | 1705 SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN | 1706 SYS_FLAG_AUTH | SYS_FLAG_CAL)); 1707 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1708 return; 1709 } 1710 1711 if (flags & SYS_FLAG_BCLIENT) 1712 proto_config(PROTO_BROADCLIENT, set, 0., NULL); 1713 if (flags & SYS_FLAG_PPS) 1714 proto_config(PROTO_PPS, set, 0., NULL); 1715 if (flags & SYS_FLAG_NTP) 1716 proto_config(PROTO_NTP, set, 0., NULL); 1717 if (flags & SYS_FLAG_KERNEL) 1718 proto_config(PROTO_KERNEL, set, 0., NULL); 1719 if (flags & SYS_FLAG_MONITOR) 1720 proto_config(PROTO_MONITOR, set, 0., NULL); 1721 if (flags & SYS_FLAG_FILEGEN) 1722 proto_config(PROTO_FILEGEN, set, 0., NULL); 1723 if (flags & SYS_FLAG_AUTH) 1724 proto_config(PROTO_AUTHENTICATE, set, 0., NULL); 1725 if (flags & SYS_FLAG_CAL) 1726 proto_config(PROTO_CAL, set, 0., NULL); 1727 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1728 1729 /* Reset the kernel ntp parameters if the kernel flag changed. */ 1730 if (prev_kern_enable && !kern_enable) 1731 loop_config(LOOP_KERN_CLEAR, 0.0); 1732 if (!prev_kern_enable && kern_enable) 1733 loop_config(LOOP_DRIFTCOMP, drift_comp); 1734} 1735 1736 1737/* 1738 * list_restrict - return the restrict list 1739 */ 1740static void 1741list_restrict( 1742 sockaddr_u *srcadr, 1743 struct interface *inter, 1744 struct req_pkt *inpkt 1745 ) 1746{ 1747 register struct info_restrict *ir; 1748 register struct restrictlist *rl; 1749 register struct restrictlist6 *rl6; 1750 1751#ifdef DEBUG 1752 if (debug > 2) 1753 printf("wants restrict list summary\n"); 1754#endif 1755 1756 ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt, 1757 v6sizeof(struct info_restrict)); 1758 1759 for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) { 1760 ir->addr = htonl(rl->addr); 1761 if (client_v6_capable) 1762 ir->v6_flag = 0; 1763 ir->mask = htonl(rl->mask); 1764 ir->count = htonl((u_int32)rl->count); 1765 ir->flags = htons(rl->flags); 1766 ir->mflags = htons(rl->mflags); 1767 ir = (struct info_restrict *)more_pkt(); 1768 } 1769 if (client_v6_capable) 1770 for (rl6 = restrictlist6; rl6 != 0 && ir != 0; rl6 = rl6->next) { 1771 ir->addr6 = rl6->addr6; 1772 ir->mask6 = rl6->mask6; 1773 ir->v6_flag = 1; 1774 ir->count = htonl((u_int32)rl6->count); 1775 ir->flags = htons(rl6->flags); 1776 ir->mflags = htons(rl6->mflags); 1777 ir = (struct info_restrict *)more_pkt(); 1778 } 1779 flush_pkt(); 1780} 1781 1782 1783 1784/* 1785 * do_resaddflags - add flags to a restrict entry (or create one) 1786 */ 1787static void 1788do_resaddflags( 1789 sockaddr_u *srcadr, 1790 struct interface *inter, 1791 struct req_pkt *inpkt 1792 ) 1793{ 1794 do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS); 1795} 1796 1797 1798 1799/* 1800 * do_ressubflags - remove flags from a restrict entry 1801 */ 1802static void 1803do_ressubflags( 1804 sockaddr_u *srcadr, 1805 struct interface *inter, 1806 struct req_pkt *inpkt 1807 ) 1808{ 1809 do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG); 1810} 1811 1812 1813/* 1814 * do_unrestrict - remove a restrict entry from the list 1815 */ 1816static void 1817do_unrestrict( 1818 sockaddr_u *srcadr, 1819 struct interface *inter, 1820 struct req_pkt *inpkt 1821 ) 1822{ 1823 do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE); 1824} 1825 1826 1827/* 1828 * do_restrict - do the dirty stuff of dealing with restrictions 1829 */ 1830static void 1831do_restrict( 1832 sockaddr_u *srcadr, 1833 struct interface *inter, 1834 struct req_pkt *inpkt, 1835 int op 1836 ) 1837{ 1838 register struct conf_restrict *cr; 1839 register int items; 1840 sockaddr_u matchaddr; 1841 sockaddr_u matchmask; 1842 int bad; 1843 1844 /* 1845 * Do a check of the flags to make sure that only 1846 * the NTPPORT flag is set, if any. If not, complain 1847 * about it. Note we are very picky here. 1848 */ 1849 items = INFO_NITEMS(inpkt->err_nitems); 1850 cr = (struct conf_restrict *)inpkt->data; 1851 1852 bad = 0; 1853 cr->flags = ntohs(cr->flags); 1854 cr->mflags = ntohs(cr->mflags); 1855 while (items-- > 0 && !bad) { 1856 if (cr->mflags & ~(RESM_NTPONLY)) 1857 bad |= 1; 1858 if (cr->flags & ~(RES_ALLFLAGS)) 1859 bad |= 2; 1860 if (cr->mask != htonl(INADDR_ANY)) { 1861 if (client_v6_capable && cr->v6_flag != 0) { 1862 if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6)) 1863 bad |= 4; 1864 } else 1865 if (cr->addr == htonl(INADDR_ANY)) 1866 bad |= 8; 1867 } 1868 cr = (struct conf_restrict *)((char *)cr + 1869 INFO_ITEMSIZE(inpkt->mbz_itemsize)); 1870 } 1871 1872 if (bad) { 1873 msyslog(LOG_ERR, "do_restrict: bad = %#x", bad); 1874 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 1875 return; 1876 } 1877 1878 /* 1879 * Looks okay, try it out 1880 */ 1881 items = INFO_NITEMS(inpkt->err_nitems); 1882 cr = (struct conf_restrict *)inpkt->data; 1883 ZERO_SOCK(&matchaddr); 1884 ZERO_SOCK(&matchmask); 1885 1886 while (items-- > 0) { 1887 if (client_v6_capable && cr->v6_flag) { 1888 AF(&matchaddr) = AF_INET6; 1889 AF(&matchmask) = AF_INET6; 1890 SOCK_ADDR6(&matchaddr) = cr->addr6; 1891 SOCK_ADDR6(&matchmask) = cr->mask6; 1892 } else { 1893 AF(&matchaddr) = AF_INET; 1894 AF(&matchmask) = AF_INET; 1895 NSRCADR(&matchaddr) = cr->addr; 1896 NSRCADR(&matchmask) = cr->mask; 1897 } 1898 hack_restrict(op, &matchaddr, &matchmask, cr->mflags, 1899 cr->flags); 1900 cr++; 1901 } 1902 1903 req_ack(srcadr, inter, inpkt, INFO_OKAY); 1904} 1905 1906 1907/* 1908 * mon_getlist - return monitor data 1909 */ 1910static void 1911mon_getlist_0( 1912 sockaddr_u *srcadr, 1913 struct interface *inter, 1914 struct req_pkt *inpkt 1915 ) 1916{ 1917 register struct info_monitor *im; 1918 register struct mon_data *md; 1919 extern struct mon_data mon_mru_list; 1920 extern int mon_enabled; 1921 1922#ifdef DEBUG 1923 if (debug > 2) 1924 printf("wants monitor 0 list\n"); 1925#endif 1926 if (!mon_enabled) { 1927 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1928 return; 1929 } 1930 im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt, 1931 v6sizeof(struct info_monitor)); 1932 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; 1933 md = md->mru_next) { 1934 im->lasttime = htonl((u_int32)((current_time - 1935 md->firsttime) / md->count)); 1936 im->firsttime = htonl((u_int32)(current_time - md->lasttime)); 1937 im->restr = htonl((u_int32)md->flags); 1938 im->count = htonl((u_int32)(md->count)); 1939 if (IS_IPV6(&md->rmtadr)) { 1940 if (!client_v6_capable) 1941 continue; 1942 im->addr6 = SOCK_ADDR6(&md->rmtadr); 1943 im->v6_flag = 1; 1944 } else { 1945 im->addr = NSRCADR(&md->rmtadr); 1946 if (client_v6_capable) 1947 im->v6_flag = 0; 1948 } 1949 im->port = md->rmtport; 1950 im->mode = md->mode; 1951 im->version = md->version; 1952 im = (struct info_monitor *)more_pkt(); 1953 } 1954 flush_pkt(); 1955} 1956 1957/* 1958 * mon_getlist - return monitor data 1959 */ 1960static void 1961mon_getlist_1( 1962 sockaddr_u *srcadr, 1963 struct interface *inter, 1964 struct req_pkt *inpkt 1965 ) 1966{ 1967 register struct info_monitor_1 *im; 1968 register struct mon_data *md; 1969 extern struct mon_data mon_mru_list; 1970 extern int mon_enabled; 1971 1972 if (!mon_enabled) { 1973 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 1974 return; 1975 } 1976 im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt, 1977 v6sizeof(struct info_monitor_1)); 1978 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; 1979 md = md->mru_next) { 1980 im->lasttime = htonl((u_int32)((current_time - 1981 md->firsttime) / md->count)); 1982 im->firsttime = htonl((u_int32)(current_time - md->lasttime)); 1983 im->restr = htonl((u_int32)md->flags); 1984 im->count = htonl((u_int32)md->count); 1985 if (IS_IPV6(&md->rmtadr)) { 1986 if (!client_v6_capable) 1987 continue; 1988 im->addr6 = SOCK_ADDR6(&md->rmtadr); 1989 im->v6_flag = 1; 1990 im->daddr6 = SOCK_ADDR6(&md->interface->sin); 1991 } else { 1992 im->addr = NSRCADR(&md->rmtadr); 1993 if (client_v6_capable) 1994 im->v6_flag = 0; 1995 if (MDF_BCAST == md->cast_flags) 1996 im->daddr = NSRCADR(&md->interface->bcast); 1997 else if (md->cast_flags) { 1998 im->daddr = NSRCADR(&md->interface->sin); 1999 if (!im->daddr) 2000 im->daddr = NSRCADR(&md->interface->bcast); 2001 } else 2002 im->daddr = 4; 2003 } 2004 im->flags = htonl(md->cast_flags); 2005 im->port = md->rmtport; 2006 im->mode = md->mode; 2007 im->version = md->version; 2008 im = (struct info_monitor_1 *)more_pkt(); 2009 } 2010 flush_pkt(); 2011} 2012 2013/* 2014 * Module entry points and the flags they correspond with 2015 */ 2016struct reset_entry { 2017 int flag; /* flag this corresponds to */ 2018 void (*handler) (void); /* routine to handle request */ 2019}; 2020 2021struct reset_entry reset_entries[] = { 2022 { RESET_FLAG_ALLPEERS, peer_all_reset }, 2023 { RESET_FLAG_IO, io_clr_stats }, 2024 { RESET_FLAG_SYS, proto_clr_stats }, 2025 { RESET_FLAG_MEM, peer_clr_stats }, 2026 { RESET_FLAG_TIMER, timer_clr_stats }, 2027 { RESET_FLAG_AUTH, reset_auth_stats }, 2028 { RESET_FLAG_CTL, ctl_clr_stats }, 2029 { 0, 0 } 2030}; 2031 2032/* 2033 * reset_stats - reset statistic counters here and there 2034 */ 2035static void 2036reset_stats( 2037 sockaddr_u *srcadr, 2038 struct interface *inter, 2039 struct req_pkt *inpkt 2040 ) 2041{ 2042 u_long flags; 2043 struct reset_entry *rent; 2044 2045 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2046 msyslog(LOG_ERR, "reset_stats: err_nitems > 1"); 2047 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2048 return; 2049 } 2050 2051 flags = ((struct reset_flags *)inpkt->data)->flags; 2052 flags = ntohl(flags); 2053 2054 if (flags & ~RESET_ALLFLAGS) { 2055 msyslog(LOG_ERR, "reset_stats: reset leaves %#lx", 2056 flags & ~RESET_ALLFLAGS); 2057 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2058 return; 2059 } 2060 2061 for (rent = reset_entries; rent->flag != 0; rent++) { 2062 if (flags & rent->flag) 2063 (rent->handler)(); 2064 } 2065 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2066} 2067 2068 2069/* 2070 * reset_peer - clear a peer's statistics 2071 */ 2072static void 2073reset_peer( 2074 sockaddr_u *srcadr, 2075 struct interface *inter, 2076 struct req_pkt *inpkt 2077 ) 2078{ 2079 struct conf_unpeer *cp; 2080 int items; 2081 struct peer *peer; 2082 sockaddr_u peeraddr; 2083 int bad; 2084 2085 /* 2086 * We check first to see that every peer exists. If not, 2087 * we return an error. 2088 */ 2089 2090 items = INFO_NITEMS(inpkt->err_nitems); 2091 cp = (struct conf_unpeer *)inpkt->data; 2092 2093 bad = 0; 2094 while (items-- > 0 && !bad) { 2095 ZERO_SOCK(&peeraddr); 2096 if (client_v6_capable && cp->v6_flag) { 2097 AF(&peeraddr) = AF_INET6; 2098 SOCK_ADDR6(&peeraddr) = cp->peeraddr6; 2099 } else { 2100 AF(&peeraddr) = AF_INET; 2101 NSRCADR(&peeraddr) = cp->peeraddr; 2102 } 2103 2104#ifdef ISC_PLATFORM_HAVESALEN 2105 peeraddr.sas.ss_len = SOCKLEN(&peeraddr); 2106#endif 2107 peer = findexistingpeer(&peeraddr, NULL, -1); 2108 if (NULL == peer) 2109 bad++; 2110 cp = (struct conf_unpeer *)((char *)cp + 2111 INFO_ITEMSIZE(inpkt->mbz_itemsize)); 2112 } 2113 2114 if (bad) { 2115 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2116 return; 2117 } 2118 2119 /* 2120 * Now do it in earnest. 2121 */ 2122 2123 items = INFO_NITEMS(inpkt->err_nitems); 2124 cp = (struct conf_unpeer *)inpkt->data; 2125 while (items-- > 0) { 2126 ZERO_SOCK(&peeraddr); 2127 if (client_v6_capable && cp->v6_flag) { 2128 AF(&peeraddr) = AF_INET6; 2129 SOCK_ADDR6(&peeraddr) = cp->peeraddr6; 2130 } else { 2131 AF(&peeraddr) = AF_INET; 2132 NSRCADR(&peeraddr) = cp->peeraddr; 2133 } 2134 SET_PORT(&peeraddr, 123); 2135#ifdef ISC_PLATFORM_HAVESALEN 2136 peeraddr.sas.ss_len = SOCKLEN(&peeraddr); 2137#endif 2138 peer = findexistingpeer(&peeraddr, NULL, -1); 2139 while (peer != NULL) { 2140 peer_reset(peer); 2141 peer = findexistingpeer(&peeraddr, peer, -1); 2142 } 2143 cp = (struct conf_unpeer *)((char *)cp + 2144 INFO_ITEMSIZE(inpkt->mbz_itemsize)); 2145 } 2146 2147 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2148} 2149 2150 2151/* 2152 * do_key_reread - reread the encryption key file 2153 */ 2154static void 2155do_key_reread( 2156 sockaddr_u *srcadr, 2157 struct interface *inter, 2158 struct req_pkt *inpkt 2159 ) 2160{ 2161 rereadkeys(); 2162 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2163} 2164 2165 2166/* 2167 * trust_key - make one or more keys trusted 2168 */ 2169static void 2170trust_key( 2171 sockaddr_u *srcadr, 2172 struct interface *inter, 2173 struct req_pkt *inpkt 2174 ) 2175{ 2176 do_trustkey(srcadr, inter, inpkt, 1); 2177} 2178 2179 2180/* 2181 * untrust_key - make one or more keys untrusted 2182 */ 2183static void 2184untrust_key( 2185 sockaddr_u *srcadr, 2186 struct interface *inter, 2187 struct req_pkt *inpkt 2188 ) 2189{ 2190 do_trustkey(srcadr, inter, inpkt, 0); 2191} 2192 2193 2194/* 2195 * do_trustkey - make keys either trustable or untrustable 2196 */ 2197static void 2198do_trustkey( 2199 sockaddr_u *srcadr, 2200 struct interface *inter, 2201 struct req_pkt *inpkt, 2202 u_long trust 2203 ) 2204{ 2205 register u_long *kp; 2206 register int items; 2207 2208 items = INFO_NITEMS(inpkt->err_nitems); 2209 kp = (u_long *)inpkt->data; 2210 while (items-- > 0) { 2211 authtrust(*kp, trust); 2212 kp++; 2213 } 2214 2215 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2216} 2217 2218 2219/* 2220 * get_auth_info - return some stats concerning the authentication module 2221 */ 2222static void 2223get_auth_info( 2224 sockaddr_u *srcadr, 2225 struct interface *inter, 2226 struct req_pkt *inpkt 2227 ) 2228{ 2229 register struct info_auth *ia; 2230 2231 /* 2232 * Importations from the authentication module 2233 */ 2234 extern u_long authnumkeys; 2235 extern int authnumfreekeys; 2236 extern u_long authkeylookups; 2237 extern u_long authkeynotfound; 2238 extern u_long authencryptions; 2239 extern u_long authdecryptions; 2240 extern u_long authkeyuncached; 2241 extern u_long authkeyexpired; 2242 2243 ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt, 2244 sizeof(struct info_auth)); 2245 2246 ia->numkeys = htonl((u_int32)authnumkeys); 2247 ia->numfreekeys = htonl((u_int32)authnumfreekeys); 2248 ia->keylookups = htonl((u_int32)authkeylookups); 2249 ia->keynotfound = htonl((u_int32)authkeynotfound); 2250 ia->encryptions = htonl((u_int32)authencryptions); 2251 ia->decryptions = htonl((u_int32)authdecryptions); 2252 ia->keyuncached = htonl((u_int32)authkeyuncached); 2253 ia->expired = htonl((u_int32)authkeyexpired); 2254 ia->timereset = htonl((u_int32)(current_time - auth_timereset)); 2255 2256 (void) more_pkt(); 2257 flush_pkt(); 2258} 2259 2260 2261 2262/* 2263 * reset_auth_stats - reset the authentication stat counters. Done here 2264 * to keep ntp-isms out of the authentication module 2265 */ 2266static void 2267reset_auth_stats(void) 2268{ 2269 /* 2270 * Importations from the authentication module 2271 */ 2272 extern u_long authkeylookups; 2273 extern u_long authkeynotfound; 2274 extern u_long authencryptions; 2275 extern u_long authdecryptions; 2276 extern u_long authkeyuncached; 2277 2278 authkeylookups = 0; 2279 authkeynotfound = 0; 2280 authencryptions = 0; 2281 authdecryptions = 0; 2282 authkeyuncached = 0; 2283 auth_timereset = current_time; 2284} 2285 2286 2287/* 2288 * req_get_traps - return information about current trap holders 2289 */ 2290static void 2291req_get_traps( 2292 sockaddr_u *srcadr, 2293 struct interface *inter, 2294 struct req_pkt *inpkt 2295 ) 2296{ 2297 register struct info_trap *it; 2298 register struct ctl_trap *tr; 2299 register int i; 2300 2301 /* 2302 * Imported from the control module 2303 */ 2304 extern struct ctl_trap ctl_trap[]; 2305 extern int num_ctl_traps; 2306 2307 if (num_ctl_traps == 0) { 2308 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2309 return; 2310 } 2311 2312 it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt, 2313 v6sizeof(struct info_trap)); 2314 2315 for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) { 2316 if (tr->tr_flags & TRAP_INUSE) { 2317 if (IS_IPV4(&tr->tr_addr)) { 2318 if (tr->tr_localaddr == any_interface) 2319 it->local_address = 0; 2320 else 2321 it->local_address 2322 = NSRCADR(&tr->tr_localaddr->sin); 2323 it->trap_address = NSRCADR(&tr->tr_addr); 2324 if (client_v6_capable) 2325 it->v6_flag = 0; 2326 } else { 2327 if (!client_v6_capable) 2328 continue; 2329 it->local_address6 2330 = SOCK_ADDR6(&tr->tr_localaddr->sin); 2331 it->trap_address6 = SOCK_ADDR6(&tr->tr_addr); 2332 it->v6_flag = 1; 2333 } 2334 it->trap_port = NSRCPORT(&tr->tr_addr); 2335 it->sequence = htons(tr->tr_sequence); 2336 it->settime = htonl((u_int32)(current_time - tr->tr_settime)); 2337 it->origtime = htonl((u_int32)(current_time - tr->tr_origtime)); 2338 it->resets = htonl((u_int32)tr->tr_resets); 2339 it->flags = htonl((u_int32)tr->tr_flags); 2340 it = (struct info_trap *)more_pkt(); 2341 } 2342 } 2343 flush_pkt(); 2344} 2345 2346 2347/* 2348 * req_set_trap - configure a trap 2349 */ 2350static void 2351req_set_trap( 2352 sockaddr_u *srcadr, 2353 struct interface *inter, 2354 struct req_pkt *inpkt 2355 ) 2356{ 2357 do_setclr_trap(srcadr, inter, inpkt, 1); 2358} 2359 2360 2361 2362/* 2363 * req_clr_trap - unconfigure a trap 2364 */ 2365static void 2366req_clr_trap( 2367 sockaddr_u *srcadr, 2368 struct interface *inter, 2369 struct req_pkt *inpkt 2370 ) 2371{ 2372 do_setclr_trap(srcadr, inter, inpkt, 0); 2373} 2374 2375 2376 2377/* 2378 * do_setclr_trap - do the grunge work of (un)configuring a trap 2379 */ 2380static void 2381do_setclr_trap( 2382 sockaddr_u *srcadr, 2383 struct interface *inter, 2384 struct req_pkt *inpkt, 2385 int set 2386 ) 2387{ 2388 register struct conf_trap *ct; 2389 register struct interface *linter; 2390 int res; 2391 sockaddr_u laddr; 2392 2393 /* 2394 * Prepare sockaddr 2395 */ 2396 ZERO_SOCK(&laddr); 2397 AF(&laddr) = AF(srcadr); 2398 SET_PORT(&laddr, NTP_PORT); 2399 2400 /* 2401 * Restrict ourselves to one item only. This eliminates 2402 * the error reporting problem. 2403 */ 2404 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2405 msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1"); 2406 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2407 return; 2408 } 2409 ct = (struct conf_trap *)inpkt->data; 2410 2411 /* 2412 * Look for the local interface. If none, use the default. 2413 */ 2414 if (ct->local_address == 0) { 2415 linter = any_interface; 2416 } else { 2417 if (IS_IPV4(&laddr)) 2418 NSRCADR(&laddr) = ct->local_address; 2419 else 2420 SOCK_ADDR6(&laddr) = ct->local_address6; 2421 linter = findinterface(&laddr); 2422 if (NULL == linter) { 2423 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2424 return; 2425 } 2426 } 2427 2428 if (IS_IPV4(&laddr)) 2429 NSRCADR(&laddr) = ct->trap_address; 2430 else 2431 SOCK_ADDR6(&laddr) = ct->trap_address6; 2432 if (ct->trap_port) 2433 NSRCPORT(&laddr) = ct->trap_port; 2434 else 2435 SET_PORT(&laddr, TRAPPORT); 2436 2437 if (set) { 2438 res = ctlsettrap(&laddr, linter, 0, 2439 INFO_VERSION(inpkt->rm_vn_mode)); 2440 } else { 2441 res = ctlclrtrap(&laddr, linter, 0); 2442 } 2443 2444 if (!res) { 2445 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2446 } else { 2447 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2448 } 2449 return; 2450} 2451 2452 2453 2454/* 2455 * set_request_keyid - set the keyid used to authenticate requests 2456 */ 2457static void 2458set_request_keyid( 2459 sockaddr_u *srcadr, 2460 struct interface *inter, 2461 struct req_pkt *inpkt 2462 ) 2463{ 2464 keyid_t keyid; 2465 2466 /* 2467 * Restrict ourselves to one item only. 2468 */ 2469 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2470 msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1"); 2471 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2472 return; 2473 } 2474 2475 keyid = ntohl(*((u_int32 *)(inpkt->data))); 2476 info_auth_keyid = keyid; 2477 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2478} 2479 2480 2481 2482/* 2483 * set_control_keyid - set the keyid used to authenticate requests 2484 */ 2485static void 2486set_control_keyid( 2487 sockaddr_u *srcadr, 2488 struct interface *inter, 2489 struct req_pkt *inpkt 2490 ) 2491{ 2492 keyid_t keyid; 2493 extern keyid_t ctl_auth_keyid; 2494 2495 /* 2496 * Restrict ourselves to one item only. 2497 */ 2498 if (INFO_NITEMS(inpkt->err_nitems) > 1) { 2499 msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1"); 2500 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2501 return; 2502 } 2503 2504 keyid = ntohl(*((u_int32 *)(inpkt->data))); 2505 ctl_auth_keyid = keyid; 2506 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2507} 2508 2509 2510 2511/* 2512 * get_ctl_stats - return some stats concerning the control message module 2513 */ 2514static void 2515get_ctl_stats( 2516 sockaddr_u *srcadr, 2517 struct interface *inter, 2518 struct req_pkt *inpkt 2519 ) 2520{ 2521 register struct info_control *ic; 2522 2523 /* 2524 * Importations from the control module 2525 */ 2526 extern u_long ctltimereset; 2527 extern u_long numctlreq; 2528 extern u_long numctlbadpkts; 2529 extern u_long numctlresponses; 2530 extern u_long numctlfrags; 2531 extern u_long numctlerrors; 2532 extern u_long numctltooshort; 2533 extern u_long numctlinputresp; 2534 extern u_long numctlinputfrag; 2535 extern u_long numctlinputerr; 2536 extern u_long numctlbadoffset; 2537 extern u_long numctlbadversion; 2538 extern u_long numctldatatooshort; 2539 extern u_long numctlbadop; 2540 extern u_long numasyncmsgs; 2541 2542 ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt, 2543 sizeof(struct info_control)); 2544 2545 ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset)); 2546 ic->numctlreq = htonl((u_int32)numctlreq); 2547 ic->numctlbadpkts = htonl((u_int32)numctlbadpkts); 2548 ic->numctlresponses = htonl((u_int32)numctlresponses); 2549 ic->numctlfrags = htonl((u_int32)numctlfrags); 2550 ic->numctlerrors = htonl((u_int32)numctlerrors); 2551 ic->numctltooshort = htonl((u_int32)numctltooshort); 2552 ic->numctlinputresp = htonl((u_int32)numctlinputresp); 2553 ic->numctlinputfrag = htonl((u_int32)numctlinputfrag); 2554 ic->numctlinputerr = htonl((u_int32)numctlinputerr); 2555 ic->numctlbadoffset = htonl((u_int32)numctlbadoffset); 2556 ic->numctlbadversion = htonl((u_int32)numctlbadversion); 2557 ic->numctldatatooshort = htonl((u_int32)numctldatatooshort); 2558 ic->numctlbadop = htonl((u_int32)numctlbadop); 2559 ic->numasyncmsgs = htonl((u_int32)numasyncmsgs); 2560 2561 (void) more_pkt(); 2562 flush_pkt(); 2563} 2564 2565 2566#ifdef KERNEL_PLL 2567/* 2568 * get_kernel_info - get kernel pll/pps information 2569 */ 2570static void 2571get_kernel_info( 2572 sockaddr_u *srcadr, 2573 struct interface *inter, 2574 struct req_pkt *inpkt 2575 ) 2576{ 2577 register struct info_kernel *ik; 2578 struct timex ntx; 2579 2580 if (!pll_control) { 2581 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2582 return; 2583 } 2584 2585 memset((char *)&ntx, 0, sizeof(ntx)); 2586 if (ntp_adjtime(&ntx) < 0) 2587 msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m"); 2588 ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt, 2589 sizeof(struct info_kernel)); 2590 2591 /* 2592 * pll variables 2593 */ 2594 ik->offset = htonl((u_int32)ntx.offset); 2595 ik->freq = htonl((u_int32)ntx.freq); 2596 ik->maxerror = htonl((u_int32)ntx.maxerror); 2597 ik->esterror = htonl((u_int32)ntx.esterror); 2598 ik->status = htons(ntx.status); 2599 ik->constant = htonl((u_int32)ntx.constant); 2600 ik->precision = htonl((u_int32)ntx.precision); 2601 ik->tolerance = htonl((u_int32)ntx.tolerance); 2602 2603 /* 2604 * pps variables 2605 */ 2606 ik->ppsfreq = htonl((u_int32)ntx.ppsfreq); 2607 ik->jitter = htonl((u_int32)ntx.jitter); 2608 ik->shift = htons(ntx.shift); 2609 ik->stabil = htonl((u_int32)ntx.stabil); 2610 ik->jitcnt = htonl((u_int32)ntx.jitcnt); 2611 ik->calcnt = htonl((u_int32)ntx.calcnt); 2612 ik->errcnt = htonl((u_int32)ntx.errcnt); 2613 ik->stbcnt = htonl((u_int32)ntx.stbcnt); 2614 2615 (void) more_pkt(); 2616 flush_pkt(); 2617} 2618#endif /* KERNEL_PLL */ 2619 2620 2621#ifdef REFCLOCK 2622/* 2623 * get_clock_info - get info about a clock 2624 */ 2625static void 2626get_clock_info( 2627 sockaddr_u *srcadr, 2628 struct interface *inter, 2629 struct req_pkt *inpkt 2630 ) 2631{ 2632 register struct info_clock *ic; 2633 register u_int32 *clkaddr; 2634 register int items; 2635 struct refclockstat clock_stat; 2636 sockaddr_u addr; 2637 l_fp ltmp; 2638 2639 ZERO_SOCK(&addr); 2640 AF(&addr) = AF_INET; 2641#ifdef ISC_PLATFORM_HAVESALEN 2642 addr.sas.ss_len = SOCKLEN(&addr); 2643#endif 2644 SET_PORT(&addr, NTP_PORT); 2645 items = INFO_NITEMS(inpkt->err_nitems); 2646 clkaddr = (u_int32 *) inpkt->data; 2647 2648 ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt, 2649 sizeof(struct info_clock)); 2650 2651 while (items-- > 0) { 2652 NSRCADR(&addr) = *clkaddr++; 2653 if (!ISREFCLOCKADR(&addr) || 2654 findexistingpeer(&addr, NULL, -1) == NULL) { 2655 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2656 return; 2657 } 2658 2659 clock_stat.kv_list = (struct ctl_var *)0; 2660 2661 refclock_control(&addr, NULL, &clock_stat); 2662 2663 ic->clockadr = NSRCADR(&addr); 2664 ic->type = clock_stat.type; 2665 ic->flags = clock_stat.flags; 2666 ic->lastevent = clock_stat.lastevent; 2667 ic->currentstatus = clock_stat.currentstatus; 2668 ic->polls = htonl((u_int32)clock_stat.polls); 2669 ic->noresponse = htonl((u_int32)clock_stat.noresponse); 2670 ic->badformat = htonl((u_int32)clock_stat.badformat); 2671 ic->baddata = htonl((u_int32)clock_stat.baddata); 2672 ic->timestarted = htonl((u_int32)clock_stat.timereset); 2673 DTOLFP(clock_stat.fudgetime1, <mp); 2674 HTONL_FP(<mp, &ic->fudgetime1); 2675 DTOLFP(clock_stat.fudgetime2, <mp); 2676 HTONL_FP(<mp, &ic->fudgetime2); 2677 ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1); 2678 ic->fudgeval2 = htonl((u_int32)clock_stat.fudgeval2); 2679 2680 free_varlist(clock_stat.kv_list); 2681 2682 ic = (struct info_clock *)more_pkt(); 2683 } 2684 flush_pkt(); 2685} 2686 2687 2688 2689/* 2690 * set_clock_fudge - get a clock's fudge factors 2691 */ 2692static void 2693set_clock_fudge( 2694 sockaddr_u *srcadr, 2695 struct interface *inter, 2696 struct req_pkt *inpkt 2697 ) 2698{ 2699 register struct conf_fudge *cf; 2700 register int items; 2701 struct refclockstat clock_stat; 2702 sockaddr_u addr; 2703 l_fp ltmp; 2704 2705 ZERO_SOCK(&addr); 2706 memset((char *)&clock_stat, 0, sizeof clock_stat); 2707 items = INFO_NITEMS(inpkt->err_nitems); 2708 cf = (struct conf_fudge *) inpkt->data; 2709 2710 while (items-- > 0) { 2711 AF(&addr) = AF_INET; 2712 NSRCADR(&addr) = cf->clockadr; 2713#ifdef ISC_PLATFORM_HAVESALEN 2714 addr.sas.ss_len = SOCKLEN(&addr); 2715#endif 2716 SET_PORT(&addr, NTP_PORT); 2717 if (!ISREFCLOCKADR(&addr) || 2718 findexistingpeer(&addr, NULL, -1) == 0) { 2719 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2720 return; 2721 } 2722 2723 switch(ntohl(cf->which)) { 2724 case FUDGE_TIME1: 2725 NTOHL_FP(&cf->fudgetime, <mp); 2726 LFPTOD(<mp, clock_stat.fudgetime1); 2727 clock_stat.haveflags = CLK_HAVETIME1; 2728 break; 2729 case FUDGE_TIME2: 2730 NTOHL_FP(&cf->fudgetime, <mp); 2731 LFPTOD(<mp, clock_stat.fudgetime2); 2732 clock_stat.haveflags = CLK_HAVETIME2; 2733 break; 2734 case FUDGE_VAL1: 2735 clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags); 2736 clock_stat.haveflags = CLK_HAVEVAL1; 2737 break; 2738 case FUDGE_VAL2: 2739 clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags); 2740 clock_stat.haveflags = CLK_HAVEVAL2; 2741 break; 2742 case FUDGE_FLAGS: 2743 clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf); 2744 clock_stat.haveflags = 2745 (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4); 2746 break; 2747 default: 2748 msyslog(LOG_ERR, "set_clock_fudge: default!"); 2749 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); 2750 return; 2751 } 2752 2753 refclock_control(&addr, &clock_stat, (struct refclockstat *)0); 2754 } 2755 2756 req_ack(srcadr, inter, inpkt, INFO_OKAY); 2757} 2758#endif 2759 2760#ifdef REFCLOCK 2761/* 2762 * get_clkbug_info - get debugging info about a clock 2763 */ 2764static void 2765get_clkbug_info( 2766 sockaddr_u *srcadr, 2767 struct interface *inter, 2768 struct req_pkt *inpkt 2769 ) 2770{ 2771 register int i; 2772 register struct info_clkbug *ic; 2773 register u_int32 *clkaddr; 2774 register int items; 2775 struct refclockbug bug; 2776 sockaddr_u addr; 2777 2778 ZERO_SOCK(&addr); 2779 AF(&addr) = AF_INET; 2780#ifdef ISC_PLATFORM_HAVESALEN 2781 addr.sas.ss_len = SOCKLEN(&addr); 2782#endif 2783 SET_PORT(&addr, NTP_PORT); 2784 items = INFO_NITEMS(inpkt->err_nitems); 2785 clkaddr = (u_int32 *) inpkt->data; 2786 2787 ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt, 2788 sizeof(struct info_clkbug)); 2789 2790 while (items-- > 0) { 2791 NSRCADR(&addr) = *clkaddr++; 2792 if (!ISREFCLOCKADR(&addr) || 2793 findexistingpeer(&addr, NULL, -1) == 0) { 2794 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2795 return; 2796 } 2797 2798 memset((char *)&bug, 0, sizeof bug); 2799 refclock_buginfo(&addr, &bug); 2800 if (bug.nvalues == 0 && bug.ntimes == 0) { 2801 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); 2802 return; 2803 } 2804 2805 ic->clockadr = NSRCADR(&addr); 2806 i = bug.nvalues; 2807 if (i > NUMCBUGVALUES) 2808 i = NUMCBUGVALUES; 2809 ic->nvalues = (u_char)i; 2810 ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1))); 2811 while (--i >= 0) 2812 ic->values[i] = htonl(bug.values[i]); 2813 2814 i = bug.ntimes; 2815 if (i > NUMCBUGTIMES) 2816 i = NUMCBUGTIMES; 2817 ic->ntimes = (u_char)i; 2818 ic->stimes = htonl(bug.stimes); 2819 while (--i >= 0) { 2820 HTONL_FP(&bug.times[i], &ic->times[i]); 2821 } 2822 2823 ic = (struct info_clkbug *)more_pkt(); 2824 } 2825 flush_pkt(); 2826} 2827#endif 2828 2829/* 2830 * receiver of interface structures 2831 */ 2832static void 2833fill_info_if_stats(void *data, interface_info_t *interface_info) 2834{ 2835 struct info_if_stats **ifsp = (struct info_if_stats **)data; 2836 struct info_if_stats *ifs = *ifsp; 2837 struct interface *interface = interface_info->interface; 2838 2839 memset(ifs, 0, sizeof(*ifs)); 2840 2841 if (IS_IPV6(&interface->sin)) { 2842 if (!client_v6_capable) { 2843 return; 2844 } 2845 ifs->v6_flag = 1; 2846 ifs->unaddr.addr6 = SOCK_ADDR6(&interface->sin); 2847 ifs->unbcast.addr6 = SOCK_ADDR6(&interface->bcast); 2848 ifs->unmask.addr6 = SOCK_ADDR6(&interface->mask); 2849 } else { 2850 ifs->v6_flag = 0; 2851 ifs->unaddr.addr = SOCK_ADDR4(&interface->sin); 2852 ifs->unbcast.addr = SOCK_ADDR4(&interface->bcast); 2853 ifs->unmask.addr = SOCK_ADDR4(&interface->mask); 2854 } 2855 ifs->v6_flag = htonl(ifs->v6_flag); 2856 strncpy(ifs->name, interface->name, sizeof(ifs->name)); 2857 ifs->family = htons(interface->family); 2858 ifs->flags = htonl(interface->flags); 2859 ifs->last_ttl = htonl(interface->last_ttl); 2860 ifs->num_mcast = htonl(interface->num_mcast); 2861 ifs->received = htonl(interface->received); 2862 ifs->sent = htonl(interface->sent); 2863 ifs->notsent = htonl(interface->notsent); 2864 ifs->scopeid = htonl(interface->scopeid); 2865 /* ifindex was always zero, now no longer in struct interface */ 2866 ifs->ifindex = 0; 2867 ifs->ifnum = htonl(interface->ifnum); 2868 ifs->uptime = htonl(current_time - interface->starttime); 2869 ifs->ignore_packets = interface->ignore_packets; 2870 ifs->peercnt = htonl(interface->peercnt); 2871 ifs->action = interface_info->action; 2872 2873 *ifsp = (struct info_if_stats *)more_pkt(); 2874} 2875 2876/* 2877 * get_if_stats - get interface statistics 2878 */ 2879static void 2880get_if_stats( 2881 sockaddr_u *srcadr, 2882 struct interface *inter, 2883 struct req_pkt *inpkt 2884 ) 2885{ 2886 struct info_if_stats *ifs; 2887 2888 DPRINTF(3, ("wants interface statistics\n")); 2889 2890 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, 2891 v6sizeof(struct info_if_stats)); 2892 2893 interface_enumerate(fill_info_if_stats, &ifs); 2894 2895 flush_pkt(); 2896} 2897 2898static void 2899do_if_reload( 2900 sockaddr_u *srcadr, 2901 struct interface *inter, 2902 struct req_pkt *inpkt 2903 ) 2904{ 2905 struct info_if_stats *ifs; 2906 2907 DPRINTF(3, ("wants interface reload\n")); 2908 2909 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, 2910 v6sizeof(struct info_if_stats)); 2911 2912 interface_update(fill_info_if_stats, &ifs); 2913 2914 flush_pkt(); 2915} 2916 2917