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