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 */ 41 static int client_v6_capable = 0; /* the client can handle longer messages */ 42 43 #define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type)) 44 45 struct 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 */ 57 static struct req_proc univ_codes[] = { 58 { NO_REQUEST, NOAUTH, 0, 0 } 59 }; 60 61 static void req_ack P((struct sockaddr_storage *, struct interface *, struct req_pkt *, int)); 62 static char * prepare_pkt P((struct sockaddr_storage *, struct interface *, struct req_pkt *, u_int)); 63 static char * more_pkt P((void)); 64 static void flush_pkt P((void)); 65 static void peer_list P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 66 static void peer_list_sum P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 67 static void peer_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 68 static void peer_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 69 static void sys_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 70 static void sys_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 71 static void mem_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 72 static void io_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 73 static void timer_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 74 static void loop_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 75 static void do_conf P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 76 static void do_unconf P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 77 static void set_sys_flag P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 78 static void clr_sys_flag P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 79 static void setclr_flags P((struct sockaddr_storage *, struct interface *, struct req_pkt *, u_long)); 80 static void list_restrict P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 81 static void do_resaddflags P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 82 static void do_ressubflags P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 83 static void do_unrestrict P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 84 static void do_restrict P((struct sockaddr_storage *, struct interface *, struct req_pkt *, int)); 85 static void mon_getlist_0 P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 86 static void mon_getlist_1 P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 87 static void reset_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 88 static void reset_peer P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 89 static void do_key_reread P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 90 static void trust_key P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 91 static void untrust_key P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 92 static void do_trustkey P((struct sockaddr_storage *, struct interface *, struct req_pkt *, u_long)); 93 static void get_auth_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 94 static void reset_auth_stats P((void)); 95 static void req_get_traps P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 96 static void req_set_trap P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 97 static void req_clr_trap P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 98 static void do_setclr_trap P((struct sockaddr_storage *, struct interface *, struct req_pkt *, int)); 99 static void set_request_keyid P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 100 static void set_control_keyid P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 101 static void get_ctl_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 102 #ifdef KERNEL_PLL 103 static void get_kernel_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 104 #endif /* KERNEL_PLL */ 105 #ifdef REFCLOCK 106 static void get_clock_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 107 static void set_clock_fudge P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 108 #endif /* REFCLOCK */ 109 #ifdef REFCLOCK 110 static void get_clkbug_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *)); 111 #endif /* REFCLOCK */ 112 113 /* 114 * ntpd request codes 115 */ 116 static 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 */ 182 keyid_t info_auth_keyid; 183 184 /* 185 * Statistic counters to keep track of requests and responses. 186 */ 187 u_long numrequests; /* number of requests we've received */ 188 u_long numresppkts; /* number of resp packets sent with data */ 189 190 u_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 */ 197 static 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 */ 206 static struct resp_pkt rpkt; 207 static int reqver; 208 static int seqno; 209 static int nitems; 210 static int itemsize; 211 static int databytes; 212 static char exbuf[RESP_DATA_SIZE]; 213 static int usingexbuf; 214 static struct sockaddr_storage *toaddr; 215 static struct interface *frominter; 216 217 /* 218 * init_request - initialize request data 219 */ 220 void 221 init_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 */ 238 static void 239 req_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 */ 268 static char * 269 prepare_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 */ 310 static char * 311 more_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 */ 372 static void 373 flush_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 */ 401 void 402 process_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 */ 639 static void 640 peer_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 */ 696 static void 697 peer_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 */ 792 static void 793 peer_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 */ 917 static void 918 peer_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 */ 1014 static void 1015 sys_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 */ 1104 static void 1105 sys_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 */ 1137 static void 1138 mem_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 */ 1183 static void 1184 io_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 */ 1221 static void 1222 timer_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 */ 1253 static void 1254 loop_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 */ 1289 static void 1290 do_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 */ 1398 static void 1399 dns_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 */ 1493 static void 1494 do_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 */ 1586 static void 1587 set_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 */ 1600 static void 1601 clr_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 */ 1614 static void 1615 setclr_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 */ 1667 static void 1668 list_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 */ 1714 static void 1715 do_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 */ 1729 static void 1730 do_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 */ 1743 static void 1744 do_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 */ 1760 static void 1761 do_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 */ 1838 static void 1839 mon_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 */ 1887 static void 1888 mon_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 */ 1941 struct reset_entry { 1942 int flag; /* flag this corresponds to */ 1943 void (*handler) P((void)); /* routine to handle request */ 1944 }; 1945 1946 struct 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 */ 1960 static void 1961 reset_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 */ 1996 static void 1997 reset_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 */ 2077 static void 2078 do_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 */ 2092 static void 2093 trust_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 */ 2106 static void 2107 untrust_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 */ 2120 static void 2121 do_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 */ 2145 static void 2146 get_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 */ 2189 static void 2190 reset_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 */ 2213 static void 2214 req_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 */ 2273 static void 2274 req_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 */ 2288 static void 2289 req_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 */ 2303 static void 2304 do_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 */ 2380 static void 2381 set_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 */ 2408 static void 2409 set_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 */ 2437 static void 2438 get_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 */ 2493 static void 2494 get_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 */ 2548 static void 2549 get_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 */ 2617 static void 2618 set_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 */ 2691 static void 2692 get_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