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