1 /* 2 * ntpdate - set the time of day by polling one or more NTP servers 3 */ 4 5 #ifdef HAVE_CONFIG_H 6 # include <config.h> 7 #endif 8 9 #ifdef HAVE_NETINFO 10 #include <netinfo/ni.h> 11 #endif 12 13 #include "ntp_machine.h" 14 #include "ntp_fp.h" 15 #include "ntp.h" 16 #include "ntp_io.h" 17 #include "ntp_unixtime.h" 18 #include "ntpdate.h" 19 #include "ntp_string.h" 20 #include "ntp_syslog.h" 21 #include "ntp_select.h" 22 #include "ntp_stdlib.h" 23 24 /* Don't include ISC's version of IPv6 variables and structures */ 25 #define ISC_IPV6_H 1 26 #include "isc/net.h" 27 #include "isc/result.h" 28 #include "isc/sockaddr.h" 29 30 #ifdef HAVE_UNISTD_H 31 # include <unistd.h> 32 #endif 33 34 #include <stdio.h> 35 #include <signal.h> 36 #include <ctype.h> 37 #ifdef HAVE_POLL_H 38 # include <poll.h> 39 #endif 40 #ifndef SYS_WINNT 41 # ifdef HAVE_SYS_SIGNAL_H 42 # include <sys/signal.h> 43 # else 44 # include <signal.h> 45 # endif 46 # ifdef HAVE_SYS_IOCTL_H 47 # include <sys/ioctl.h> 48 # endif 49 #endif /* SYS_WINNT */ 50 #ifdef HAVE_SYS_RESOURCE_H 51 # include <sys/resource.h> 52 #endif /* HAVE_SYS_RESOURCE_H */ 53 54 #include <arpa/inet.h> 55 56 #ifdef SYS_VXWORKS 57 # include "ioLib.h" 58 # include "sockLib.h" 59 # include "timers.h" 60 61 /* select wants a zero structure ... */ 62 struct timeval timeout = {0,0}; 63 #elif defined(SYS_WINNT) 64 /* 65 * Windows does not abort a select select call if SIGALRM goes off 66 * so a 200 ms timeout is needed 67 */ 68 struct timeval timeout = {0,1000000/TIMER_HZ}; 69 #else 70 struct timeval timeout = {60,0}; 71 #endif 72 73 #ifdef HAVE_NETINFO 74 #include <netinfo/ni.h> 75 #endif 76 77 #include "recvbuff.h" 78 79 #ifdef SYS_WINNT 80 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT 81 #define EAFNOSUPPORT WSAEAFNOSUPPORT 82 #define EPFNOSUPPORT WSAEPFNOSUPPORT 83 #define TARGET_RESOLUTION 1 /* Try for 1-millisecond accuracy 84 on Windows NT timers. */ 85 #pragma comment(lib, "winmm") 86 isc_boolean_t ntp_port_inuse(int af, u_short port); 87 UINT wTimerRes; 88 #endif /* SYS_WINNT */ 89 90 /* 91 * Scheduling priority we run at 92 */ 93 #ifndef SYS_VXWORKS 94 # define NTPDATE_PRIO (-12) 95 #else 96 # define NTPDATE_PRIO (100) 97 #endif 98 99 #if defined(HAVE_TIMER_SETTIME) || defined (HAVE_TIMER_CREATE) 100 /* POSIX TIMERS - vxWorks doesn't have itimer - casey */ 101 static timer_t ntpdate_timerid; 102 #endif 103 104 /* 105 * Compatibility stuff for Version 2 106 */ 107 #define NTP_MAXSKW 0x28f /* 0.01 sec in fp format */ 108 #define NTP_MINDIST 0x51f /* 0.02 sec in fp format */ 109 #define PEER_MAXDISP (64*FP_SECOND) /* maximum dispersion (fp 64) */ 110 #define NTP_INFIN 15 /* max stratum, infinity a la Bellman-Ford */ 111 #define NTP_MAXWGT (8*FP_SECOND) /* maximum select weight 8 seconds */ 112 #define NTP_MAXLIST 5 /* maximum select list size */ 113 #define PEER_SHIFT 8 /* 8 suitable for crystal time base */ 114 115 /* 116 * for get_systime() 117 */ 118 s_char sys_precision; /* local clock precision (log2 s) */ 119 120 /* 121 * Debugging flag 122 */ 123 volatile int debug = 0; 124 125 /* 126 * File descriptor masks etc. for call to select 127 */ 128 129 int ai_fam_templ; 130 int nbsock; /* the number of sockets used */ 131 SOCKET fd[MAX_AF]; 132 int fd_family[MAX_AF]; /* to remember the socket family */ 133 #ifdef HAVE_POLL_H 134 struct pollfd fdmask[MAX_AF]; 135 #else 136 fd_set fdmask; 137 SOCKET maxfd; 138 #endif 139 int polltest = 0; 140 141 /* 142 * Initializing flag. All async routines watch this and only do their 143 * thing when it is clear. 144 */ 145 int initializing = 1; 146 147 /* 148 * Alarm flag. Set when an alarm occurs 149 */ 150 volatile int alarm_flag = 0; 151 152 /* 153 * Simple query flag. 154 */ 155 int simple_query = 0; 156 157 /* 158 * Unprivileged port flag. 159 */ 160 int unpriv_port = 0; 161 162 /* 163 * Program name. 164 */ 165 char *progname; 166 167 /* 168 * Systemwide parameters and flags 169 */ 170 int sys_samples = DEFSAMPLES; /* number of samples/server */ 171 u_long sys_timeout = DEFTIMEOUT; /* timeout time, in TIMER_HZ units */ 172 struct server *sys_servers; /* the server list */ 173 int sys_numservers = 0; /* number of servers to poll */ 174 int sys_authenticate = 0; /* true when authenticating */ 175 u_int32 sys_authkey = 0; /* set to authentication key in use */ 176 u_long sys_authdelay = 0; /* authentication delay */ 177 int sys_version = NTP_VERSION; /* version to poll with */ 178 179 /* 180 * The current internal time 181 */ 182 u_long current_time = 0; 183 184 /* 185 * Counter for keeping track of completed servers 186 */ 187 int complete_servers = 0; 188 189 /* 190 * File of encryption keys 191 */ 192 193 #ifndef KEYFILE 194 # ifndef SYS_WINNT 195 #define KEYFILE "/etc/ntp.keys" 196 # else 197 #define KEYFILE "%windir%\\ntp.keys" 198 # endif /* SYS_WINNT */ 199 #endif /* KEYFILE */ 200 201 #ifndef SYS_WINNT 202 const char *key_file = KEYFILE; 203 #else 204 char key_file_storage[MAX_PATH+1], *key_file ; 205 #endif /* SYS_WINNT */ 206 207 /* 208 * Miscellaneous flags 209 */ 210 int verbose = 0; 211 int always_step = 0; 212 int never_step = 0; 213 214 int ntpdatemain P((int, char **)); 215 216 static void transmit P((struct server *)); 217 static void receive P((struct recvbuf *)); 218 static void server_data P((struct server *, s_fp, l_fp *, u_fp)); 219 static void clock_filter P((struct server *)); 220 static struct server *clock_select P((void)); 221 static int clock_adjust P((void)); 222 static void addserver P((char *)); 223 static struct server *findserver P((struct sockaddr_storage *)); 224 void timer P((void)); 225 static void init_alarm P((void)); 226 #ifndef SYS_WINNT 227 static RETSIGTYPE alarming P((int)); 228 #endif /* SYS_WINNT */ 229 static void init_io P((void)); 230 static void sendpkt P((struct sockaddr_storage *, struct pkt *, int)); 231 void input_handler P((void)); 232 233 static int l_adj_systime P((l_fp *)); 234 static int l_step_systime P((l_fp *)); 235 236 static void printserver P((struct server *, FILE *)); 237 238 #ifdef SYS_WINNT 239 int on = 1; 240 WORD wVersionRequested; 241 WSADATA wsaData; 242 HANDLE TimerThreadHandle = NULL; 243 #endif /* SYS_WINNT */ 244 245 #ifdef NO_MAIN_ALLOWED 246 CALL(ntpdate,"ntpdate",ntpdatemain); 247 248 void clear_globals() 249 { 250 /* 251 * Debugging flag 252 */ 253 debug = 0; 254 255 ntp_optind = 0; 256 /* 257 * Initializing flag. All async routines watch this and only do their 258 * thing when it is clear. 259 */ 260 initializing = 1; 261 262 /* 263 * Alarm flag. Set when an alarm occurs 264 */ 265 alarm_flag = 0; 266 267 /* 268 * Simple query flag. 269 */ 270 simple_query = 0; 271 272 /* 273 * Unprivileged port flag. 274 */ 275 unpriv_port = 0; 276 277 /* 278 * Systemwide parameters and flags 279 */ 280 sys_numservers = 0; /* number of servers to poll */ 281 sys_authenticate = 0; /* true when authenticating */ 282 sys_authkey = 0; /* set to authentication key in use */ 283 sys_authdelay = 0; /* authentication delay */ 284 sys_version = NTP_VERSION; /* version to poll with */ 285 286 /* 287 * The current internal time 288 */ 289 current_time = 0; 290 291 /* 292 * Counter for keeping track of completed servers 293 */ 294 complete_servers = 0; 295 verbose = 0; 296 always_step = 0; 297 never_step = 0; 298 } 299 #endif 300 301 #ifdef HAVE_NETINFO 302 static ni_namelist *getnetinfoservers P((void)); 303 #endif 304 305 /* 306 * Main program. Initialize us and loop waiting for I/O and/or 307 * timer expiries. 308 */ 309 #ifndef NO_MAIN_ALLOWED 310 int 311 main( 312 int argc, 313 char *argv[] 314 ) 315 { 316 return ntpdatemain (argc, argv); 317 } 318 #endif /* NO_MAIN_ALLOWED */ 319 320 int 321 ntpdatemain ( 322 int argc, 323 char *argv[] 324 ) 325 { 326 int was_alarmed; 327 int tot_recvbufs; 328 struct recvbuf *rbuf; 329 l_fp tmp; 330 int errflg; 331 int c; 332 int nfound; 333 334 #ifdef HAVE_NETINFO 335 ni_namelist *netinfoservers; 336 #endif 337 #ifdef SYS_WINNT 338 HANDLE process_handle; 339 340 wVersionRequested = MAKEWORD(1,1); 341 if (WSAStartup(wVersionRequested, &wsaData)) { 342 netsyslog(LOG_ERR, "No useable winsock.dll: %m"); 343 exit(1); 344 } 345 346 key_file = key_file_storage; 347 348 if (!ExpandEnvironmentStrings(KEYFILE, key_file, MAX_PATH)) 349 { 350 msyslog(LOG_ERR, "ExpandEnvironmentStrings(KEYFILE) failed: %m\n"); 351 } 352 #endif /* SYS_WINNT */ 353 354 #ifdef NO_MAIN_ALLOWED 355 clear_globals(); 356 #endif 357 358 359 /* Check to see if we have IPv6. Otherwise force the -4 flag */ 360 if (isc_net_probeipv6() != ISC_R_SUCCESS) { 361 ai_fam_templ = AF_INET; 362 } 363 364 errflg = 0; 365 progname = argv[0]; 366 syslogit = 0; 367 368 /* 369 * Decode argument list 370 */ 371 while ((c = ntp_getopt(argc, argv, "46a:bBde:k:o:p:qst:uv")) != EOF) 372 switch (c) 373 { 374 case '4': 375 ai_fam_templ = AF_INET; 376 break; 377 case '6': 378 ai_fam_templ = AF_INET6; 379 break; 380 case 'a': 381 c = atoi(ntp_optarg); 382 sys_authenticate = 1; 383 sys_authkey = c; 384 break; 385 case 'b': 386 always_step++; 387 never_step = 0; 388 break; 389 case 'B': 390 never_step++; 391 always_step = 0; 392 break; 393 case 'd': 394 ++debug; 395 break; 396 case 'e': 397 if (!atolfp(ntp_optarg, &tmp) 398 || tmp.l_ui != 0) { 399 (void) fprintf(stderr, 400 "%s: encryption delay %s is unlikely\n", 401 progname, ntp_optarg); 402 errflg++; 403 } else { 404 sys_authdelay = tmp.l_uf; 405 } 406 break; 407 case 'k': 408 key_file = ntp_optarg; 409 break; 410 case 'o': 411 sys_version = atoi(ntp_optarg); 412 break; 413 case 'p': 414 c = atoi(ntp_optarg); 415 if (c <= 0 || c > NTP_SHIFT) { 416 (void) fprintf(stderr, 417 "%s: number of samples (%d) is invalid\n", 418 progname, c); 419 errflg++; 420 } else { 421 sys_samples = c; 422 } 423 break; 424 case 'q': 425 simple_query = 1; 426 break; 427 case 's': 428 syslogit = 1; 429 break; 430 case 't': 431 if (!atolfp(ntp_optarg, &tmp)) { 432 (void) fprintf(stderr, 433 "%s: timeout %s is undecodeable\n", 434 progname, ntp_optarg); 435 errflg++; 436 } else { 437 sys_timeout = ((LFPTOFP(&tmp) * TIMER_HZ) 438 + 0x8000) >> 16; 439 if (sys_timeout == 0) 440 sys_timeout = 1; 441 } 442 break; 443 case 'v': 444 verbose = 1; 445 break; 446 case 'u': 447 unpriv_port = 1; 448 break; 449 case '?': 450 ++errflg; 451 break; 452 default: 453 break; 454 } 455 456 if (errflg) { 457 (void) fprintf(stderr, 458 "usage: %s [-46bBdqsuv] [-a key#] [-e delay] [-k file] [-p samples] [-o version#] [-t timeo] server ...\n", 459 progname); 460 exit(2); 461 } 462 463 if (debug || simple_query) { 464 #ifdef HAVE_SETVBUF 465 static char buf[BUFSIZ]; 466 #ifdef SYS_WINNT 467 /* Win32 does not implement line buffering */ 468 setvbuf(stdout, NULL, _IONBF, BUFSIZ); 469 #else 470 setvbuf(stdout, buf, _IOLBF, BUFSIZ); 471 #endif /* SYS_WINNT */ 472 #else 473 setlinebuf(stdout); 474 #endif 475 } 476 477 /* 478 * Logging. Open the syslog if we have to 479 */ 480 if (syslogit) { 481 #if !defined (SYS_WINNT) && !defined (SYS_VXWORKS) && !defined SYS_CYGWIN32 482 # ifndef LOG_DAEMON 483 openlog("ntpdate", LOG_PID); 484 # else 485 486 # ifndef LOG_NTP 487 # define LOG_NTP LOG_DAEMON 488 # endif 489 openlog("ntpdate", LOG_PID | LOG_NDELAY, LOG_NTP); 490 if (debug) 491 setlogmask(LOG_UPTO(LOG_DEBUG)); 492 else 493 setlogmask(LOG_UPTO(LOG_INFO)); 494 # endif /* LOG_DAEMON */ 495 #endif /* SYS_WINNT */ 496 } 497 498 if (debug || verbose) 499 msyslog(LOG_NOTICE, "%s", Version); 500 501 /* 502 * Add servers we are going to be polling 503 */ 504 #ifdef HAVE_NETINFO 505 netinfoservers = getnetinfoservers(); 506 #endif 507 508 for ( ; ntp_optind < argc; ntp_optind++) 509 addserver(argv[ntp_optind]); 510 511 #ifdef HAVE_NETINFO 512 if (netinfoservers) { 513 if ( netinfoservers->ni_namelist_len && 514 *netinfoservers->ni_namelist_val ) { 515 u_int servercount = 0; 516 while (servercount < netinfoservers->ni_namelist_len) { 517 if (debug) msyslog(LOG_DEBUG, 518 "Adding time server %s from NetInfo configuration.", 519 netinfoservers->ni_namelist_val[servercount]); 520 addserver(netinfoservers->ni_namelist_val[servercount++]); 521 } 522 } 523 ni_namelist_free(netinfoservers); 524 free(netinfoservers); 525 } 526 #endif 527 528 if (sys_numservers == 0) { 529 msyslog(LOG_ERR, "no servers can be used, exiting"); 530 exit(1); 531 } 532 533 /* 534 * Initialize the time of day routines and the I/O subsystem 535 */ 536 if (sys_authenticate) { 537 init_auth(); 538 if (!authreadkeys(key_file)) { 539 msyslog(LOG_ERR, "no key file <%s>, exiting", key_file); 540 exit(1); 541 } 542 authtrust(sys_authkey, 1); 543 if (!authistrusted(sys_authkey)) { 544 msyslog(LOG_ERR, "authentication key %lu unknown", 545 (unsigned long) sys_authkey); 546 exit(1); 547 } 548 } 549 init_io(); 550 init_alarm(); 551 552 /* 553 * Set the priority. 554 */ 555 #ifdef SYS_VXWORKS 556 taskPrioritySet( taskIdSelf(), NTPDATE_PRIO); 557 #endif 558 #if defined(HAVE_ATT_NICE) 559 nice (NTPDATE_PRIO); 560 #endif 561 #if defined(HAVE_BSD_NICE) 562 (void) setpriority(PRIO_PROCESS, 0, NTPDATE_PRIO); 563 #endif 564 #ifdef SYS_WINNT 565 process_handle = GetCurrentProcess(); 566 if (!SetPriorityClass(process_handle, (DWORD) REALTIME_PRIORITY_CLASS)) { 567 msyslog(LOG_ERR, "SetPriorityClass failed: %m"); 568 } 569 #endif /* SYS_WINNT */ 570 571 572 573 initializing = 0; 574 was_alarmed = 0; 575 576 while (complete_servers < sys_numservers) { 577 #ifdef HAVE_POLL_H 578 struct pollfd* rdfdes; 579 rdfdes = fdmask; 580 #else 581 fd_set rdfdes; 582 rdfdes = fdmask; 583 #endif 584 585 if (alarm_flag) { /* alarmed? */ 586 was_alarmed = 1; 587 alarm_flag = 0; 588 } 589 tot_recvbufs = full_recvbuffs(); /* get received buffers */ 590 591 if (!was_alarmed && tot_recvbufs == 0) { 592 /* 593 * Nothing to do. Wait for something. 594 */ 595 #ifdef HAVE_POLL_H 596 nfound = poll(rdfdes, (unsigned int)nbsock, timeout.tv_sec * 1000); 597 598 #else 599 nfound = select(maxfd, &rdfdes, (fd_set *)0, 600 (fd_set *)0, &timeout); 601 #endif 602 if (nfound > 0) 603 input_handler(); 604 else if (nfound == SOCKET_ERROR) 605 { 606 #ifndef SYS_WINNT 607 if (errno != EINTR) 608 #else 609 if (WSAGetLastError() != WSAEINTR) 610 #endif 611 netsyslog(LOG_ERR, 612 #ifdef HAVE_POLL_H 613 "poll() error: %m" 614 #else 615 "select() error: %m" 616 #endif 617 ); 618 } else if (errno != 0) { 619 #ifndef SYS_VXWORKS 620 netsyslog(LOG_DEBUG, 621 #ifdef HAVE_POLL_H 622 "poll(): nfound = %d, error: %m", 623 #else 624 "select(): nfound = %d, error: %m", 625 #endif 626 nfound); 627 #endif 628 } 629 if (alarm_flag) { /* alarmed? */ 630 was_alarmed = 1; 631 alarm_flag = 0; 632 } 633 tot_recvbufs = full_recvbuffs(); /* get received buffers */ 634 } 635 636 /* 637 * Out here, signals are unblocked. Call receive 638 * procedure for each incoming packet. 639 */ 640 rbuf = get_full_recv_buffer(); 641 while (rbuf != NULL) 642 { 643 receive(rbuf); 644 freerecvbuf(rbuf); 645 rbuf = get_full_recv_buffer(); 646 } 647 648 /* 649 * Call timer to process any timeouts 650 */ 651 if (was_alarmed) { 652 timer(); 653 was_alarmed = 0; 654 } 655 656 /* 657 * Go around again 658 */ 659 } 660 661 /* 662 * When we get here we've completed the polling of all servers. 663 * Adjust the clock, then exit. 664 */ 665 #ifdef SYS_WINNT 666 WSACleanup(); 667 #endif 668 #ifdef SYS_VXWORKS 669 close (fd); 670 timer_delete(ntpdate_timerid); 671 #endif 672 673 return clock_adjust(); 674 } 675 676 677 /* 678 * transmit - transmit a packet to the given server, or mark it completed. 679 * This is called by the timeout routine and by the receive 680 * procedure. 681 */ 682 static void 683 transmit( 684 register struct server *server 685 ) 686 { 687 struct pkt xpkt; 688 689 if (debug) 690 printf("transmit(%s)\n", stoa(&(server->srcadr))); 691 692 if (server->filter_nextpt < server->xmtcnt) { 693 l_fp ts; 694 /* 695 * Last message to this server timed out. Shift 696 * zeros into the filter. 697 */ 698 L_CLR(&ts); 699 server_data(server, 0, &ts, 0); 700 } 701 702 if ((int)server->filter_nextpt >= sys_samples) { 703 /* 704 * Got all the data we need. Mark this guy 705 * completed and return. 706 */ 707 server->event_time = 0; 708 complete_servers++; 709 return; 710 } 711 712 /* 713 * If we're here, send another message to the server. Fill in 714 * the packet and let 'er rip. 715 */ 716 xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, 717 sys_version, MODE_CLIENT); 718 xpkt.stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); 719 xpkt.ppoll = NTP_MINPOLL; 720 xpkt.precision = NTPDATE_PRECISION; 721 xpkt.rootdelay = htonl(NTPDATE_DISTANCE); 722 xpkt.rootdispersion = htonl(NTPDATE_DISP); 723 xpkt.refid = htonl(NTPDATE_REFID); 724 L_CLR(&xpkt.reftime); 725 L_CLR(&xpkt.org); 726 L_CLR(&xpkt.rec); 727 728 /* 729 * Determine whether to authenticate or not. If so, 730 * fill in the extended part of the packet and do it. 731 * If not, just timestamp it and send it away. 732 */ 733 if (sys_authenticate) { 734 int len; 735 736 xpkt.exten[0] = htonl(sys_authkey); 737 get_systime(&server->xmt); 738 L_ADDUF(&server->xmt, sys_authdelay); 739 HTONL_FP(&server->xmt, &xpkt.xmt); 740 len = authencrypt(sys_authkey, (u_int32 *)&xpkt, LEN_PKT_NOMAC); 741 sendpkt(&(server->srcadr), &xpkt, (int)(LEN_PKT_NOMAC + len)); 742 743 if (debug > 1) 744 printf("transmit auth to %s\n", 745 stoa(&(server->srcadr))); 746 } else { 747 get_systime(&(server->xmt)); 748 HTONL_FP(&server->xmt, &xpkt.xmt); 749 sendpkt(&(server->srcadr), &xpkt, LEN_PKT_NOMAC); 750 751 if (debug > 1) 752 printf("transmit to %s\n", stoa(&(server->srcadr))); 753 } 754 755 /* 756 * Update the server timeout and transmit count 757 */ 758 server->event_time = current_time + sys_timeout; 759 server->xmtcnt++; 760 } 761 762 763 /* 764 * receive - receive and process an incoming frame 765 */ 766 static void 767 receive( 768 struct recvbuf *rbufp 769 ) 770 { 771 register struct pkt *rpkt; 772 register struct server *server; 773 register s_fp di; 774 l_fp t10, t23, tmp; 775 l_fp org; 776 l_fp rec; 777 l_fp ci; 778 int has_mac; 779 int is_authentic; 780 781 if (debug) 782 printf("receive(%s)\n", stoa(&rbufp->recv_srcadr)); 783 /* 784 * Check to see if the packet basically looks like something 785 * intended for us. 786 */ 787 if (rbufp->recv_length == LEN_PKT_NOMAC) 788 has_mac = 0; 789 else if (rbufp->recv_length >= LEN_PKT_NOMAC) 790 has_mac = 1; 791 else { 792 if (debug) 793 printf("receive: packet length %d\n", 794 rbufp->recv_length); 795 return; /* funny length packet */ 796 } 797 798 rpkt = &(rbufp->recv_pkt); 799 if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION || 800 PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) { 801 return; 802 } 803 804 if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER 805 && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) 806 || rpkt->stratum >= STRATUM_UNSPEC) { 807 if (debug) 808 printf("receive: mode %d stratum %d\n", 809 PKT_MODE(rpkt->li_vn_mode), rpkt->stratum); 810 return; 811 } 812 813 /* 814 * So far, so good. See if this is from a server we know. 815 */ 816 server = findserver(&(rbufp->recv_srcadr)); 817 if (server == NULL) { 818 if (debug) 819 printf("receive: server not found\n"); 820 return; 821 } 822 823 /* 824 * Decode the org timestamp and make sure we're getting a response 825 * to our last request. 826 */ 827 NTOHL_FP(&rpkt->org, &org); 828 if (!L_ISEQU(&org, &server->xmt)) { 829 if (debug) 830 printf("receive: pkt.org and peer.xmt differ\n"); 831 return; 832 } 833 834 /* 835 * Check out the authenticity if we're doing that. 836 */ 837 if (!sys_authenticate) 838 is_authentic = 1; 839 else { 840 is_authentic = 0; 841 842 if (debug > 3) 843 printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n", 844 (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey, 845 (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt, 846 LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC))); 847 848 if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey && 849 authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC, 850 (int)(rbufp->recv_length - LEN_PKT_NOMAC))) 851 is_authentic = 1; 852 if (debug) 853 printf("receive: authentication %s\n", 854 is_authentic ? "passed" : "failed"); 855 } 856 server->trust <<= 1; 857 if (!is_authentic) 858 server->trust |= 1; 859 860 /* 861 * Looks good. Record info from the packet. 862 */ 863 server->leap = PKT_LEAP(rpkt->li_vn_mode); 864 server->stratum = PKT_TO_STRATUM(rpkt->stratum); 865 server->precision = rpkt->precision; 866 server->rootdelay = ntohl(rpkt->rootdelay); 867 server->rootdispersion = ntohl(rpkt->rootdispersion); 868 server->refid = rpkt->refid; 869 NTOHL_FP(&rpkt->reftime, &server->reftime); 870 NTOHL_FP(&rpkt->rec, &rec); 871 NTOHL_FP(&rpkt->xmt, &server->org); 872 873 /* 874 * Make sure the server is at least somewhat sane. If not, try 875 * again. 876 */ 877 if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) { 878 transmit(server); 879 return; 880 } 881 882 /* 883 * Calculate the round trip delay (di) and the clock offset (ci). 884 * We use the equations (reordered from those in the spec): 885 * 886 * d = (t2 - t3) - (t1 - t0) 887 * c = ((t2 - t3) + (t1 - t0)) / 2 888 */ 889 t10 = server->org; /* pkt.xmt == t1 */ 890 L_SUB(&t10, &rbufp->recv_time); /* recv_time == t0*/ 891 892 t23 = rec; /* pkt.rec == t2 */ 893 L_SUB(&t23, &org); /* pkt->org == t3 */ 894 895 /* now have (t2 - t3) and (t0 - t1). Calculate (ci) and (di) */ 896 /* 897 * Calculate (ci) = ((t1 - t0) / 2) + ((t2 - t3) / 2) 898 * For large offsets this may prevent an overflow on '+' 899 */ 900 ci = t10; 901 L_RSHIFT(&ci); 902 tmp = t23; 903 L_RSHIFT(&tmp); 904 L_ADD(&ci, &tmp); 905 906 /* 907 * Calculate di in t23 in full precision, then truncate 908 * to an s_fp. 909 */ 910 L_SUB(&t23, &t10); 911 di = LFPTOFP(&t23); 912 913 if (debug > 3) 914 printf("offset: %s, delay %s\n", lfptoa(&ci, 6), fptoa(di, 5)); 915 916 di += (FP_SECOND >> (-(int)NTPDATE_PRECISION)) 917 + (FP_SECOND >> (-(int)server->precision)) + NTP_MAXSKW; 918 919 if (di <= 0) { /* value still too raunchy to use? */ 920 L_CLR(&ci); 921 di = 0; 922 } else { 923 di = max(di, NTP_MINDIST); 924 } 925 926 /* 927 * Shift this data in, then transmit again. 928 */ 929 server_data(server, (s_fp) di, &ci, 0); 930 transmit(server); 931 } 932 933 934 /* 935 * server_data - add a sample to the server's filter registers 936 */ 937 static void 938 server_data( 939 register struct server *server, 940 s_fp d, 941 l_fp *c, 942 u_fp e 943 ) 944 { 945 u_short i; 946 947 i = server->filter_nextpt; 948 if (i < NTP_SHIFT) { 949 server->filter_delay[i] = d; 950 server->filter_offset[i] = *c; 951 server->filter_soffset[i] = LFPTOFP(c); 952 server->filter_error[i] = e; 953 server->filter_nextpt = (u_short)(i + 1); 954 } 955 } 956 957 958 /* 959 * clock_filter - determine a server's delay, dispersion and offset 960 */ 961 static void 962 clock_filter( 963 register struct server *server 964 ) 965 { 966 register int i, j; 967 int ord[NTP_SHIFT]; 968 969 /* 970 * Sort indices into increasing delay order 971 */ 972 for (i = 0; i < sys_samples; i++) 973 ord[i] = i; 974 975 for (i = 0; i < (sys_samples-1); i++) { 976 for (j = i+1; j < sys_samples; j++) { 977 if (server->filter_delay[ord[j]] == 0) 978 continue; 979 if (server->filter_delay[ord[i]] == 0 980 || (server->filter_delay[ord[i]] 981 > server->filter_delay[ord[j]])) { 982 register int tmp; 983 984 tmp = ord[i]; 985 ord[i] = ord[j]; 986 ord[j] = tmp; 987 } 988 } 989 } 990 991 /* 992 * Now compute the dispersion, and assign values to delay and 993 * offset. If there are no samples in the register, delay and 994 * offset go to zero and dispersion is set to the maximum. 995 */ 996 if (server->filter_delay[ord[0]] == 0) { 997 server->delay = 0; 998 L_CLR(&server->offset); 999 server->soffset = 0; 1000 server->dispersion = PEER_MAXDISP; 1001 } else { 1002 register s_fp d; 1003 1004 server->delay = server->filter_delay[ord[0]]; 1005 server->offset = server->filter_offset[ord[0]]; 1006 server->soffset = LFPTOFP(&server->offset); 1007 server->dispersion = 0; 1008 for (i = 1; i < sys_samples; i++) { 1009 if (server->filter_delay[ord[i]] == 0) 1010 d = PEER_MAXDISP; 1011 else { 1012 d = server->filter_soffset[ord[i]] 1013 - server->filter_soffset[ord[0]]; 1014 if (d < 0) 1015 d = -d; 1016 if (d > PEER_MAXDISP) 1017 d = PEER_MAXDISP; 1018 } 1019 /* 1020 * XXX This *knows* PEER_FILTER is 1/2 1021 */ 1022 server->dispersion += (u_fp)(d) >> i; 1023 } 1024 } 1025 /* 1026 * We're done 1027 */ 1028 } 1029 1030 1031 /* 1032 * clock_select - select the pick-of-the-litter clock from the samples 1033 * we've got. 1034 */ 1035 static struct server * 1036 clock_select(void) 1037 { 1038 register struct server *server; 1039 register int i; 1040 register int nlist; 1041 register s_fp d; 1042 register int j; 1043 register int n; 1044 s_fp local_threshold; 1045 struct server *server_list[NTP_MAXCLOCK]; 1046 u_fp server_badness[NTP_MAXCLOCK]; 1047 struct server *sys_server; 1048 1049 /* 1050 * This first chunk of code is supposed to go through all 1051 * servers we know about to find the NTP_MAXLIST servers which 1052 * are most likely to succeed. We run through the list 1053 * doing the sanity checks and trying to insert anyone who 1054 * looks okay. We are at all times aware that we should 1055 * only keep samples from the top two strata and we only need 1056 * NTP_MAXLIST of them. 1057 */ 1058 nlist = 0; /* none yet */ 1059 for (server = sys_servers; server != NULL; server = server->next_server) { 1060 if (server->delay == 0) { 1061 if (debug) 1062 printf("%s: Server dropped: no data\n", ntoa(&server->srcadr)); 1063 continue; /* no data */ 1064 } 1065 if (server->stratum > NTP_INFIN) { 1066 if (debug) 1067 printf("%s: Server dropped: strata too high\n", ntoa(&server->srcadr)); 1068 continue; /* stratum no good */ 1069 } 1070 if (server->delay > NTP_MAXWGT) { 1071 if (debug) 1072 printf("%s: Server dropped: server too far away\n", 1073 ntoa(&server->srcadr)); 1074 continue; /* too far away */ 1075 } 1076 if (server->leap == LEAP_NOTINSYNC) { 1077 if (debug) 1078 printf("%s: Server dropped: Leap not in sync\n", ntoa(&server->srcadr)); 1079 continue; /* he's in trouble */ 1080 } 1081 if (!L_ISHIS(&server->org, &server->reftime)) { 1082 if (debug) 1083 printf("%s: Server dropped: server is very broken\n", 1084 ntoa(&server->srcadr)); 1085 continue; /* very broken host */ 1086 } 1087 if ((server->org.l_ui - server->reftime.l_ui) 1088 >= NTP_MAXAGE) { 1089 if (debug) 1090 printf("%s: Server dropped: Server has gone too long without sync\n", 1091 ntoa(&server->srcadr)); 1092 continue; /* too long without sync */ 1093 } 1094 if (server->trust != 0) { 1095 if (debug) 1096 printf("%s: Server dropped: Server is untrusted\n", 1097 ntoa(&server->srcadr)); 1098 continue; 1099 } 1100 1101 /* 1102 * This one seems sane. Find where he belongs 1103 * on the list. 1104 */ 1105 d = server->dispersion + server->dispersion; 1106 for (i = 0; i < nlist; i++) 1107 if (server->stratum <= server_list[i]->stratum) 1108 break; 1109 for ( ; i < nlist; i++) { 1110 if (server->stratum < server_list[i]->stratum) 1111 break; 1112 if (d < (s_fp) server_badness[i]) 1113 break; 1114 } 1115 1116 /* 1117 * If i points past the end of the list, this 1118 * guy is a loser, else stick him in. 1119 */ 1120 if (i >= NTP_MAXLIST) 1121 continue; 1122 for (j = nlist; j > i; j--) 1123 if (j < NTP_MAXLIST) { 1124 server_list[j] = server_list[j-1]; 1125 server_badness[j] 1126 = server_badness[j-1]; 1127 } 1128 1129 server_list[i] = server; 1130 server_badness[i] = d; 1131 if (nlist < NTP_MAXLIST) 1132 nlist++; 1133 } 1134 1135 /* 1136 * Got the five-or-less best. Cut the list where the number of 1137 * strata exceeds two. 1138 */ 1139 j = 0; 1140 for (i = 1; i < nlist; i++) 1141 if (server_list[i]->stratum > server_list[i-1]->stratum) 1142 if (++j == 2) { 1143 nlist = i; 1144 break; 1145 } 1146 1147 /* 1148 * Whew! What we should have by now is 0 to 5 candidates for 1149 * the job of syncing us. If we have none, we're out of luck. 1150 * If we have one, he's a winner. If we have more, do falseticker 1151 * detection. 1152 */ 1153 1154 if (nlist == 0) 1155 sys_server = 0; 1156 else if (nlist == 1) { 1157 sys_server = server_list[0]; 1158 } else { 1159 /* 1160 * Re-sort by stratum, bdelay estimate quality and 1161 * server.delay. 1162 */ 1163 for (i = 0; i < nlist-1; i++) 1164 for (j = i+1; j < nlist; j++) { 1165 if (server_list[i]->stratum 1166 < server_list[j]->stratum) 1167 break; /* already sorted by stratum */ 1168 if (server_list[i]->delay 1169 < server_list[j]->delay) 1170 continue; 1171 server = server_list[i]; 1172 server_list[i] = server_list[j]; 1173 server_list[j] = server; 1174 } 1175 1176 /* 1177 * Calculate the fixed part of the dispersion limit 1178 */ 1179 local_threshold = (FP_SECOND >> (-(int)NTPDATE_PRECISION)) 1180 + NTP_MAXSKW; 1181 1182 /* 1183 * Now drop samples until we're down to one. 1184 */ 1185 while (nlist > 1) { 1186 for (n = 0; n < nlist; n++) { 1187 server_badness[n] = 0; 1188 for (j = 0; j < nlist; j++) { 1189 if (j == n) /* with self? */ 1190 continue; 1191 d = server_list[j]->soffset 1192 - server_list[n]->soffset; 1193 if (d < 0) /* absolute value */ 1194 d = -d; 1195 /* 1196 * XXX This code *knows* that 1197 * NTP_SELECT is 3/4 1198 */ 1199 for (i = 0; i < j; i++) 1200 d = (d>>1) + (d>>2); 1201 server_badness[n] += d; 1202 } 1203 } 1204 1205 /* 1206 * We now have an array of nlist badness 1207 * coefficients. Find the badest. Find 1208 * the minimum precision while we're at 1209 * it. 1210 */ 1211 i = 0; 1212 n = server_list[0]->precision;; 1213 for (j = 1; j < nlist; j++) { 1214 if (server_badness[j] >= server_badness[i]) 1215 i = j; 1216 if (n > server_list[j]->precision) 1217 n = server_list[j]->precision; 1218 } 1219 1220 /* 1221 * i is the index of the server with the worst 1222 * dispersion. If his dispersion is less than 1223 * the threshold, stop now, else delete him and 1224 * continue around again. 1225 */ 1226 if ( (s_fp) server_badness[i] < (local_threshold 1227 + (FP_SECOND >> (-n)))) 1228 break; 1229 for (j = i + 1; j < nlist; j++) 1230 server_list[j-1] = server_list[j]; 1231 nlist--; 1232 } 1233 1234 /* 1235 * What remains is a list of less than 5 servers. Take 1236 * the best. 1237 */ 1238 sys_server = server_list[0]; 1239 } 1240 1241 /* 1242 * That's it. Return our server. 1243 */ 1244 return sys_server; 1245 } 1246 1247 1248 /* 1249 * clock_adjust - process what we've received, and adjust the time 1250 * if we got anything decent. 1251 */ 1252 static int 1253 clock_adjust(void) 1254 { 1255 register struct server *sp, *server; 1256 s_fp absoffset; 1257 int dostep; 1258 1259 for (sp = sys_servers; sp != NULL; sp = sp->next_server) 1260 clock_filter(sp); 1261 server = clock_select(); 1262 1263 if (debug || simple_query) { 1264 for (sp = sys_servers; sp != NULL; sp = sp->next_server) 1265 printserver(sp, stdout); 1266 } 1267 1268 if (server == 0) { 1269 msyslog(LOG_ERR, 1270 "no server suitable for synchronization found"); 1271 return(1); 1272 } 1273 1274 if (always_step) { 1275 dostep = 1; 1276 } else if (never_step) { 1277 dostep = 0; 1278 } else { 1279 absoffset = server->soffset; 1280 if (absoffset < 0) 1281 absoffset = -absoffset; 1282 dostep = (absoffset >= NTPDATE_THRESHOLD || absoffset < 0); 1283 } 1284 1285 if (dostep) { 1286 if (simple_query || debug || l_step_systime(&server->offset)){ 1287 msyslog(LOG_NOTICE, "step time server %s offset %s sec", 1288 stoa(&server->srcadr), 1289 lfptoa(&server->offset, 6)); 1290 } 1291 } else { 1292 #if !defined SYS_WINNT && !defined SYS_CYGWIN32 1293 if (simple_query || l_adj_systime(&server->offset)) { 1294 msyslog(LOG_NOTICE, "adjust time server %s offset %s sec", 1295 stoa(&server->srcadr), 1296 lfptoa(&server->offset, 6)); 1297 } 1298 #else 1299 /* The NT SetSystemTimeAdjustment() call achieves slewing by 1300 * changing the clock frequency. This means that we cannot specify 1301 * it to slew the clock by a definite amount and then stop like 1302 * the Unix adjtime() routine. We can technically adjust the clock 1303 * frequency, have ntpdate sleep for a while, and then wake 1304 * up and reset the clock frequency, but this might cause some 1305 * grief if the user attempts to run ntpd immediately after 1306 * ntpdate and the socket is in use. 1307 */ 1308 printf("\nThe -b option is required by ntpdate on Windows NT platforms\n"); 1309 exit(1); 1310 #endif /* SYS_WINNT */ 1311 } 1312 return(0); 1313 } 1314 1315 1316 /* 1317 * is_unreachable - check to see if we have a route to given destination 1318 * (non-blocking). 1319 */ 1320 static int 1321 is_reachable (struct sockaddr_storage *dst) 1322 { 1323 SOCKET sockfd; 1324 1325 sockfd = socket(dst->ss_family, SOCK_DGRAM, 0); 1326 if (sockfd == -1) { 1327 return 0; 1328 } 1329 1330 if(connect(sockfd, (struct sockaddr *)dst, SOCKLEN(dst))) { 1331 closesocket(sockfd); 1332 return 0; 1333 } 1334 closesocket(sockfd); 1335 return 1; 1336 } 1337 1338 1339 1340 /* XXX ELIMINATE: merge BIG slew into adj_systime in lib/systime.c */ 1341 /* 1342 * addserver - determine a server's address and allocate a new structure 1343 * for it. 1344 */ 1345 static void 1346 addserver( 1347 char *serv 1348 ) 1349 { 1350 register struct server *server; 1351 /* Address infos structure to store result of getaddrinfo */ 1352 struct addrinfo *addrResult, *ptr; 1353 /* Address infos structure to store hints for getaddrinfo */ 1354 struct addrinfo hints; 1355 /* Error variable for getaddrinfo */ 1356 int error; 1357 /* Service name */ 1358 char service[5]; 1359 strcpy(service, "ntp"); 1360 1361 /* Get host address. Looking for UDP datagram connection. */ 1362 memset(&hints, 0, sizeof(hints)); 1363 hints.ai_family = ai_fam_templ; 1364 hints.ai_socktype = SOCK_DGRAM; 1365 1366 #ifdef DEBUG 1367 if (debug) 1368 printf("Looking for host %s and service %s\n", serv, service); 1369 #endif 1370 1371 error = getaddrinfo(serv, service, &hints, &addrResult); 1372 if (error != 0) { 1373 /* Conduct more refined error analysis */ 1374 if (error == EAI_FAIL || error == EAI_AGAIN){ 1375 /* Name server is unusable. Exit after failing on the 1376 first server, in order to shorten the timeout caused 1377 by waiting for resolution of several servers */ 1378 fprintf(stderr, "Name server cannot be used, exiting"); 1379 msyslog(LOG_ERR, "name server cannot be used, reason: %s\n", gai_strerror(error)); 1380 exit(1); 1381 } 1382 fprintf(stderr, "Error : %s\n", gai_strerror(error)); 1383 msyslog(LOG_ERR, "can't find host %s\n", serv); 1384 return; 1385 } 1386 #ifdef DEBUG 1387 else if (debug) { 1388 fprintf(stderr, "host found : %s\n", stohost((struct sockaddr_storage*)addrResult->ai_addr)); 1389 } 1390 #endif 1391 1392 /* We must get all returned server in case the first one fails */ 1393 for (ptr = addrResult; ptr != NULL; ptr = ptr->ai_next) { 1394 if (is_reachable ((struct sockaddr_storage *)ptr->ai_addr)) { 1395 server = (struct server *)emalloc(sizeof(struct server)); 1396 memset((char *)server, 0, sizeof(struct server)); 1397 1398 memset(&(server->srcadr), 0, sizeof(struct sockaddr_storage)); 1399 memcpy(&(server->srcadr), ptr->ai_addr, ptr->ai_addrlen); 1400 server->event_time = ++sys_numservers; 1401 if (sys_servers == NULL) 1402 sys_servers = server; 1403 else { 1404 struct server *sp; 1405 1406 for (sp = sys_servers; sp->next_server != NULL; 1407 sp = sp->next_server) ; 1408 sp->next_server = server; 1409 } 1410 } 1411 } 1412 1413 freeaddrinfo(addrResult); 1414 } 1415 1416 1417 /* 1418 * findserver - find a server in the list given its address 1419 * ***(For now it isn't totally AF-Independant, to check later..) 1420 */ 1421 static struct server * 1422 findserver( 1423 struct sockaddr_storage *addr 1424 ) 1425 { 1426 struct server *server; 1427 struct server *mc_server; 1428 isc_sockaddr_t laddr; 1429 isc_sockaddr_t saddr; 1430 1431 if(addr->ss_family == AF_INET) { 1432 isc_sockaddr_fromin( &laddr, &((struct sockaddr_in*)addr)->sin_addr, 0); 1433 } 1434 else { 1435 isc_sockaddr_fromin6(&laddr, &((struct sockaddr_in6*)addr)->sin6_addr, 0); 1436 } 1437 1438 1439 mc_server = NULL; 1440 if (htons(((struct sockaddr_in*)addr)->sin_port) != NTP_PORT) 1441 return 0; 1442 1443 for (server = sys_servers; server != NULL; 1444 server = server->next_server) { 1445 1446 if(server->srcadr.ss_family == AF_INET) { 1447 isc_sockaddr_fromin(&saddr, &((struct sockaddr_in*)&server->srcadr)->sin_addr, 0); 1448 } 1449 else { 1450 isc_sockaddr_fromin6(&saddr, &((struct sockaddr_in6*)&server->srcadr)->sin6_addr, 0); 1451 } 1452 if (isc_sockaddr_eqaddr(&laddr, &saddr) == ISC_TRUE) 1453 return server; 1454 1455 if(addr->ss_family == server->srcadr.ss_family) { 1456 if (isc_sockaddr_ismulticast(&saddr) == ISC_TRUE) 1457 mc_server = server; 1458 } 1459 } 1460 1461 if (mc_server != NULL) { 1462 1463 struct server *sp; 1464 1465 if (mc_server->event_time != 0) { 1466 mc_server->event_time = 0; 1467 complete_servers++; 1468 } 1469 1470 server = (struct server *)emalloc(sizeof(struct server)); 1471 memset((char *)server, 0, sizeof(struct server)); 1472 1473 memcpy(&server->srcadr, addr, sizeof(struct sockaddr_storage)); 1474 1475 server->event_time = ++sys_numservers; 1476 1477 for (sp = sys_servers; sp->next_server != NULL; 1478 sp = sp->next_server) ; 1479 sp->next_server = server; 1480 transmit(server); 1481 } 1482 return NULL; 1483 } 1484 1485 1486 /* 1487 * timer - process a timer interrupt 1488 */ 1489 void 1490 timer(void) 1491 { 1492 struct server *server; 1493 1494 /* 1495 * Bump the current idea of the time 1496 */ 1497 current_time++; 1498 1499 /* 1500 * Search through the server list looking for guys 1501 * who's event timers have expired. Give these to 1502 * the transmit routine. 1503 */ 1504 for (server = sys_servers; server != NULL; 1505 server = server->next_server) { 1506 if (server->event_time != 0 1507 && server->event_time <= current_time) 1508 transmit(server); 1509 } 1510 } 1511 1512 1513 /* 1514 * The code duplication in the following subroutine sucks, but 1515 * we need to appease ansi2knr. 1516 */ 1517 1518 #ifndef SYS_WINNT 1519 /* 1520 * alarming - record the occurance of an alarm interrupt 1521 */ 1522 static RETSIGTYPE 1523 alarming( 1524 int sig 1525 ) 1526 { 1527 alarm_flag++; 1528 } 1529 #else 1530 void CALLBACK 1531 alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) 1532 { 1533 alarm_flag++; 1534 } 1535 #endif /* SYS_WINNT */ 1536 1537 1538 #ifdef SYS_WINNT 1539 static void 1540 callTimeEndPeriod(void) 1541 { 1542 timeEndPeriod( wTimerRes ); 1543 wTimerRes = 0; 1544 } 1545 #endif /* SYS_WINNT */ 1546 1547 1548 /* 1549 * init_alarm - set up the timer interrupt 1550 */ 1551 static void 1552 init_alarm(void) 1553 { 1554 #ifndef SYS_WINNT 1555 # ifndef HAVE_TIMER_SETTIME 1556 struct itimerval itimer; 1557 # else 1558 struct itimerspec ntpdate_itimer; 1559 # endif 1560 #else 1561 TIMECAPS tc; 1562 UINT wTimerID; 1563 # endif /* SYS_WINNT */ 1564 #if defined SYS_CYGWIN32 || defined SYS_WINNT 1565 HANDLE hToken; 1566 TOKEN_PRIVILEGES tkp; 1567 DWORD dwUser = 0; 1568 #endif /* SYS_WINNT */ 1569 1570 alarm_flag = 0; 1571 1572 #ifndef SYS_WINNT 1573 # if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) 1574 alarm_flag = 0; 1575 /* this code was put in as setitimer() is non existant this us the 1576 * POSIX "equivalents" setup - casey 1577 */ 1578 /* ntpdate_timerid is global - so we can kill timer later */ 1579 if (timer_create (CLOCK_REALTIME, NULL, &ntpdate_timerid) == 1580 # ifdef SYS_VXWORKS 1581 ERROR 1582 # else 1583 -1 1584 # endif 1585 ) 1586 { 1587 fprintf (stderr, "init_alarm(): timer_create (...) FAILED\n"); 1588 return; 1589 } 1590 1591 /* TIMER_HZ = (5) 1592 * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) 1593 * seconds from now and they continue on every 1/TIMER_HZ seconds. 1594 */ 1595 (void) signal_no_reset(SIGALRM, alarming); 1596 ntpdate_itimer.it_interval.tv_sec = ntpdate_itimer.it_value.tv_sec = 0; 1597 ntpdate_itimer.it_interval.tv_nsec = 1000000000/TIMER_HZ; 1598 ntpdate_itimer.it_value.tv_nsec = 1000000000/(TIMER_HZ<<1); 1599 timer_settime(ntpdate_timerid, 0 /* !TIMER_ABSTIME */, &ntpdate_itimer, NULL); 1600 # else 1601 /* 1602 * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) 1603 * seconds from now and they continue on every 1/TIMER_HZ seconds. 1604 */ 1605 (void) signal_no_reset(SIGALRM, alarming); 1606 itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0; 1607 itimer.it_interval.tv_usec = 1000000/TIMER_HZ; 1608 itimer.it_value.tv_usec = 1000000/(TIMER_HZ<<1); 1609 1610 setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); 1611 # endif 1612 #if defined SYS_CYGWIN32 1613 /* 1614 * Get privileges needed for fiddling with the clock 1615 */ 1616 1617 /* get the current process token handle */ 1618 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { 1619 msyslog(LOG_ERR, "OpenProcessToken failed: %m"); 1620 exit(1); 1621 } 1622 /* get the LUID for system-time privilege. */ 1623 LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); 1624 tkp.PrivilegeCount = 1; /* one privilege to set */ 1625 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 1626 /* get set-time privilege for this process. */ 1627 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); 1628 /* cannot test return value of AdjustTokenPrivileges. */ 1629 if (GetLastError() != ERROR_SUCCESS) 1630 msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); 1631 #endif 1632 #else /* SYS_WINNT */ 1633 _tzset(); 1634 1635 /* 1636 * Get privileges needed for fiddling with the clock 1637 */ 1638 1639 /* get the current process token handle */ 1640 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { 1641 msyslog(LOG_ERR, "OpenProcessToken failed: %m"); 1642 exit(1); 1643 } 1644 /* get the LUID for system-time privilege. */ 1645 LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); 1646 tkp.PrivilegeCount = 1; /* one privilege to set */ 1647 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 1648 /* get set-time privilege for this process. */ 1649 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); 1650 /* cannot test return value of AdjustTokenPrivileges. */ 1651 if (GetLastError() != ERROR_SUCCESS) 1652 msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); 1653 1654 /* 1655 * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds 1656 * Under Win/NT, expiry of timer interval leads to invocation 1657 * of a callback function (on a different thread) rather than 1658 * generating an alarm signal 1659 */ 1660 1661 /* determine max and min resolution supported */ 1662 if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { 1663 msyslog(LOG_ERR, "timeGetDevCaps failed: %m"); 1664 exit(1); 1665 } 1666 wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax); 1667 /* establish the minimum timer resolution that we'll use */ 1668 timeBeginPeriod(wTimerRes); 1669 atexit(callTimeEndPeriod); 1670 1671 /* start the timer event */ 1672 wTimerID = timeSetEvent( 1673 (UINT) (1000/TIMER_HZ), /* Delay */ 1674 wTimerRes, /* Resolution */ 1675 (LPTIMECALLBACK) alarming, /* Callback function */ 1676 (DWORD) dwUser, /* User data */ 1677 TIME_PERIODIC); /* Event type (periodic) */ 1678 if (wTimerID == 0) { 1679 msyslog(LOG_ERR, "timeSetEvent failed: %m"); 1680 exit(1); 1681 } 1682 #endif /* SYS_WINNT */ 1683 } 1684 1685 1686 1687 1688 /* 1689 * We do asynchronous input using the SIGIO facility. A number of 1690 * recvbuf buffers are preallocated for input. In the signal 1691 * handler we poll to see if the socket is ready and read the 1692 * packets from it into the recvbuf's along with a time stamp and 1693 * an indication of the source host and the interface it was received 1694 * through. This allows us to get as accurate receive time stamps 1695 * as possible independent of other processing going on. 1696 * 1697 * We allocate a number of recvbufs equal to the number of servers 1698 * plus 2. This should be plenty. 1699 */ 1700 1701 1702 /* 1703 * init_io - initialize I/O data and open socket 1704 */ 1705 static void 1706 init_io(void) 1707 { 1708 struct addrinfo *res, *ressave; 1709 struct addrinfo hints; 1710 char service[5]; 1711 int optval = 1; 1712 int check_ntp_port_in_use = !debug && !simple_query && !unpriv_port; 1713 1714 /* 1715 * Init buffer free list and stat counters 1716 */ 1717 init_recvbuff(sys_numservers + 2); 1718 1719 /* 1720 * Open the socket 1721 */ 1722 1723 strcpy(service, "ntp"); 1724 1725 /* 1726 * Init hints addrinfo structure 1727 */ 1728 memset(&hints, 0, sizeof(hints)); 1729 hints.ai_family = ai_fam_templ; 1730 hints.ai_flags = AI_PASSIVE; 1731 hints.ai_socktype = SOCK_DGRAM; 1732 1733 if(getaddrinfo(NULL, service, &hints, &res) != 0) { 1734 msyslog(LOG_ERR, "getaddrinfo() failed: %m"); 1735 exit(1); 1736 /*NOTREACHED*/ 1737 } 1738 1739 #ifdef SYS_WINNT 1740 if (check_ntp_port_in_use && ntp_port_inuse(AF_INET, NTP_PORT)){ 1741 netsyslog(LOG_ERR, "the NTP socket is in use, exiting: %m"); 1742 exit(1); 1743 } 1744 #endif 1745 1746 /* Remember the address of the addrinfo structure chain */ 1747 ressave = res; 1748 1749 /* 1750 * For each structure returned, open and bind socket 1751 */ 1752 for(nbsock = 0; (nbsock < MAX_AF) && res ; res = res->ai_next) { 1753 /* create a datagram (UDP) socket */ 1754 fd[nbsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 1755 if (fd[nbsock] == SOCKET_ERROR) { 1756 #ifndef SYS_WINNT 1757 if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT || 1758 errno == EPFNOSUPPORT) 1759 #else 1760 int err = WSAGetLastError(); 1761 if (err == WSAEPROTONOSUPPORT || err == WSAEAFNOSUPPORT || 1762 err == WSAEPFNOSUPPORT) 1763 #endif 1764 continue; 1765 netsyslog(LOG_ERR, "socket() failed: %m"); 1766 exit(1); 1767 /*NOTREACHED*/ 1768 } 1769 /* set socket to reuse address */ 1770 if (setsockopt(fd[nbsock], SOL_SOCKET, SO_REUSEADDR, (void*) &optval, sizeof(optval)) < 0) { 1771 netsyslog(LOG_ERR, "setsockopt() SO_REUSEADDR failed: %m"); 1772 exit(1); 1773 /*NOTREACHED*/ 1774 } 1775 #ifdef IPV6_V6ONLY 1776 /* Restricts AF_INET6 socket to IPv6 communications (see RFC 2553bis-03) */ 1777 if (res->ai_family == AF_INET6) 1778 if (setsockopt(fd[nbsock], IPPROTO_IPV6, IPV6_V6ONLY, (void*) &optval, sizeof(optval)) < 0) { 1779 netsyslog(LOG_ERR, "setsockopt() IPV6_V6ONLY failed: %m"); 1780 exit(1); 1781 /*NOTREACHED*/ 1782 } 1783 #endif 1784 1785 /* Remember the socket family in fd_family structure */ 1786 fd_family[nbsock] = res->ai_family; 1787 1788 /* 1789 * bind the socket to the NTP port 1790 */ 1791 if (check_ntp_port_in_use) { 1792 if (bind(fd[nbsock], res->ai_addr, SOCKLEN(res->ai_addr)) < 0) { 1793 #ifndef SYS_WINNT 1794 if (errno == EADDRINUSE) 1795 #else 1796 if (WSAGetLastError() == WSAEADDRINUSE) 1797 #endif /* SYS_WINNT */ 1798 netsyslog(LOG_ERR, "the NTP socket is in use, exiting"); 1799 else 1800 netsyslog(LOG_ERR, "bind() fails: %m"); 1801 exit(1); 1802 } 1803 } 1804 1805 #ifdef HAVE_POLL_H 1806 fdmask[nbsock].fd = fd[nbsock]; 1807 fdmask[nbsock].events = POLLIN; 1808 #else 1809 FD_SET(fd[nbsock], &fdmask); 1810 if (maxfd < fd[nbsock]+1) { 1811 maxfd = fd[nbsock]+1; 1812 } 1813 #endif 1814 1815 /* 1816 * set non-blocking, 1817 */ 1818 #ifndef SYS_WINNT 1819 # ifdef SYS_VXWORKS 1820 { 1821 int on = TRUE; 1822 1823 if (ioctl(fd[nbsock],FIONBIO, &on) == ERROR) { 1824 netsyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m"); 1825 exit(1); 1826 } 1827 } 1828 # else /* not SYS_VXWORKS */ 1829 # if defined(O_NONBLOCK) 1830 if (fcntl(fd[nbsock], F_SETFL, O_NONBLOCK) < 0) { 1831 netsyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails: %m"); 1832 exit(1); 1833 /*NOTREACHED*/ 1834 } 1835 # else /* not O_NONBLOCK */ 1836 # if defined(FNDELAY) 1837 if (fcntl(fd[nbsock], F_SETFL, FNDELAY) < 0) { 1838 netsyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails: %m"); 1839 exit(1); 1840 /*NOTREACHED*/ 1841 } 1842 # else /* FNDELAY */ 1843 # include "Bletch: Need non blocking I/O" 1844 # endif /* FNDELAY */ 1845 # endif /* not O_NONBLOCK */ 1846 # endif /* SYS_VXWORKS */ 1847 #else /* SYS_WINNT */ 1848 if (ioctlsocket(fd[nbsock], FIONBIO, (u_long *) &on) == SOCKET_ERROR) { 1849 netsyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m"); 1850 exit(1); 1851 } 1852 #endif /* SYS_WINNT */ 1853 nbsock++; 1854 } 1855 freeaddrinfo(ressave); 1856 } 1857 1858 /* 1859 * sendpkt - send a packet to the specified destination 1860 */ 1861 static void 1862 sendpkt( 1863 struct sockaddr_storage *dest, 1864 struct pkt *pkt, 1865 int len 1866 ) 1867 { 1868 int i; 1869 int cc; 1870 SOCKET sock = INVALID_SOCKET; 1871 1872 #ifdef SYS_WINNT 1873 DWORD err; 1874 #endif /* SYS_WINNT */ 1875 1876 /* Find a local family compatible socket to send ntp packet to ntp server */ 1877 for(i = 0; (i < MAX_AF); i++) { 1878 if(dest->ss_family == fd_family[i]) { 1879 sock = fd[i]; 1880 break; 1881 } 1882 } 1883 1884 if ( sock == INVALID_SOCKET ) { 1885 netsyslog(LOG_ERR, "cannot find family compatible socket to send ntp packet"); 1886 exit(1); 1887 /*NOTREACHED*/ 1888 } 1889 1890 cc = sendto(sock, (char *)pkt, len, 0, (struct sockaddr *)dest, 1891 SOCKLEN(dest)); 1892 1893 if (cc == SOCKET_ERROR) { 1894 #ifndef SYS_WINNT 1895 if (errno != EWOULDBLOCK && errno != ENOBUFS) 1896 #else 1897 err = WSAGetLastError(); 1898 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS) 1899 #endif /* SYS_WINNT */ 1900 netsyslog(LOG_ERR, "sendto(%s): %m", stohost(dest)); 1901 } 1902 } 1903 1904 1905 /* 1906 * input_handler - receive packets asynchronously 1907 */ 1908 void 1909 input_handler(void) 1910 { 1911 register int n; 1912 register struct recvbuf *rb; 1913 struct timeval tvzero; 1914 int fromlen; 1915 l_fp ts; 1916 int i; 1917 #ifdef HAVE_POLL_H 1918 struct pollfd fds[MAX_AF]; 1919 #else 1920 fd_set fds; 1921 #endif 1922 int fdc = 0; 1923 1924 /* 1925 * Do a poll to see if we have data 1926 */ 1927 for (;;) { 1928 tvzero.tv_sec = tvzero.tv_usec = 0; 1929 #ifdef HAVE_POLL_H 1930 memcpy(fds, fdmask, sizeof(fdmask)); 1931 n = poll(fds, (unsigned int)nbsock, tvzero.tv_sec * 1000); 1932 1933 /* 1934 * Determine which socket received data 1935 */ 1936 1937 for(i=0; i < nbsock; i++) { 1938 if(fds[i].revents & POLLIN) { 1939 fdc = fd[i]; 1940 break; 1941 } 1942 } 1943 1944 #else 1945 fds = fdmask; 1946 n = select(maxfd, &fds, (fd_set *)0, (fd_set *)0, &tvzero); 1947 1948 /* 1949 * Determine which socket received data 1950 */ 1951 1952 for(i=0; i < nbsock; i++) { 1953 if(FD_ISSET(fd[i], &fds)) { 1954 fdc = fd[i]; 1955 break; 1956 } 1957 } 1958 1959 #endif 1960 1961 /* 1962 * If nothing to do, just return. If an error occurred, 1963 * complain and return. If we've got some, freeze a 1964 * timestamp. 1965 */ 1966 if (n == 0) 1967 return; 1968 else if (n == -1) { 1969 if (errno != EINTR) 1970 netsyslog(LOG_ERR, 1971 #ifdef HAVE_POLL_H 1972 "poll() error: %m" 1973 #else 1974 "select() error: %m" 1975 #endif 1976 ); 1977 return; 1978 } 1979 get_systime(&ts); 1980 1981 /* 1982 * Get a buffer and read the frame. If we 1983 * haven't got a buffer, or this is received 1984 * on the wild card socket, just dump the packet. 1985 */ 1986 if (initializing || free_recvbuffs() == 0) { 1987 char buf[100]; 1988 1989 1990 #ifndef SYS_WINNT 1991 (void) read(fdc, buf, sizeof buf); 1992 #else 1993 /* NT's _read does not operate on nonblocking sockets 1994 * either recvfrom or ReadFile() has to be used here. 1995 * ReadFile is used in [ntpd]ntp_intres() and ntpdc, 1996 * just to be different use recvfrom() here 1997 */ 1998 recvfrom(fdc, buf, sizeof(buf), 0, (struct sockaddr *)0, NULL); 1999 #endif /* SYS_WINNT */ 2000 continue; 2001 } 2002 2003 rb = get_free_recv_buffer(); 2004 2005 fromlen = sizeof(struct sockaddr_storage); 2006 rb->recv_length = recvfrom(fdc, (char *)&rb->recv_pkt, 2007 sizeof(rb->recv_pkt), 0, 2008 (struct sockaddr *)&rb->recv_srcadr, &fromlen); 2009 if (rb->recv_length == -1) { 2010 freerecvbuf(rb); 2011 continue; 2012 } 2013 2014 /* 2015 * Got one. Mark how and when it got here, 2016 * put it on the full list. 2017 */ 2018 rb->recv_time = ts; 2019 add_full_recv_buffer(rb); 2020 } 2021 } 2022 2023 2024 #if !defined SYS_WINNT && !defined SYS_CYGWIN32 2025 /* 2026 * adj_systime - do a big long slew of the system time 2027 */ 2028 static int 2029 l_adj_systime( 2030 l_fp *ts 2031 ) 2032 { 2033 struct timeval adjtv, oadjtv; 2034 int isneg = 0; 2035 l_fp offset; 2036 #ifndef STEP_SLEW 2037 l_fp overshoot; 2038 #endif 2039 2040 /* 2041 * Take the absolute value of the offset 2042 */ 2043 offset = *ts; 2044 if (L_ISNEG(&offset)) { 2045 isneg = 1; 2046 L_NEG(&offset); 2047 } 2048 2049 #ifndef STEP_SLEW 2050 /* 2051 * Calculate the overshoot. XXX N.B. This code *knows* 2052 * ADJ_OVERSHOOT is 1/2. 2053 */ 2054 overshoot = offset; 2055 L_RSHIFTU(&overshoot); 2056 if (overshoot.l_ui != 0 || (overshoot.l_uf > ADJ_MAXOVERSHOOT)) { 2057 overshoot.l_ui = 0; 2058 overshoot.l_uf = ADJ_MAXOVERSHOOT; 2059 } 2060 L_ADD(&offset, &overshoot); 2061 #endif 2062 TSTOTV(&offset, &adjtv); 2063 2064 if (isneg) { 2065 adjtv.tv_sec = -adjtv.tv_sec; 2066 adjtv.tv_usec = -adjtv.tv_usec; 2067 } 2068 2069 if (adjtv.tv_usec != 0 && !debug) { 2070 if (adjtime(&adjtv, &oadjtv) < 0) { 2071 msyslog(LOG_ERR, "Can't adjust the time of day: %m"); 2072 return 0; 2073 } 2074 } 2075 return 1; 2076 } 2077 #endif /* SYS_WINNT */ 2078 2079 2080 /* 2081 * This fuction is not the same as lib/systime step_systime!!! 2082 */ 2083 static int 2084 l_step_systime( 2085 l_fp *ts 2086 ) 2087 { 2088 double dtemp; 2089 2090 #ifdef SLEWALWAYS 2091 #ifdef STEP_SLEW 2092 l_fp ftmp; 2093 int isneg; 2094 int n; 2095 2096 if (debug) return 1; 2097 /* 2098 * Take the absolute value of the offset 2099 */ 2100 ftmp = *ts; 2101 if (L_ISNEG(&ftmp)) { 2102 L_NEG(&ftmp); 2103 isneg = 1; 2104 } else 2105 isneg = 0; 2106 2107 if (ftmp.l_ui >= 3) { /* Step it and slew - we might win */ 2108 LFPTOD(ts, dtemp); 2109 n = step_systime(dtemp); 2110 if (!n) 2111 return n; 2112 if (isneg) 2113 ts->l_ui = ~0; 2114 else 2115 ts->l_ui = ~0; 2116 } 2117 /* 2118 * Just add adjustment into the current offset. The update 2119 * routine will take care of bringing the system clock into 2120 * line. 2121 */ 2122 #endif 2123 if (debug) 2124 return 1; 2125 #ifdef FORCE_NTPDATE_STEP 2126 LFPTOD(ts, dtemp); 2127 return step_systime(dtemp); 2128 #else 2129 l_adj_systime(ts); 2130 return 1; 2131 #endif 2132 #else /* SLEWALWAYS */ 2133 if (debug) 2134 return 1; 2135 LFPTOD(ts, dtemp); 2136 return step_systime(dtemp); 2137 #endif /* SLEWALWAYS */ 2138 } 2139 2140 2141 /* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c */ 2142 /* 2143 * printserver - print detail information for a server 2144 */ 2145 static void 2146 printserver( 2147 register struct server *pp, 2148 FILE *fp 2149 ) 2150 { 2151 register int i; 2152 char junk[5]; 2153 char *str; 2154 2155 if (!debug) { 2156 (void) fprintf(fp, "server %s, stratum %d, offset %s, delay %s\n", 2157 stoa(&pp->srcadr), pp->stratum, 2158 lfptoa(&pp->offset, 6), fptoa((s_fp)pp->delay, 5)); 2159 return; 2160 } 2161 2162 (void) fprintf(fp, "server %s, port %d\n", 2163 stoa(&pp->srcadr), ntohs(((struct sockaddr_in*)&(pp->srcadr))->sin_port)); 2164 2165 (void) fprintf(fp, "stratum %d, precision %d, leap %c%c, trust %03o\n", 2166 pp->stratum, pp->precision, 2167 pp->leap & 0x2 ? '1' : '0', 2168 pp->leap & 0x1 ? '1' : '0', 2169 pp->trust); 2170 2171 if (pp->stratum == 1) { 2172 junk[4] = 0; 2173 memmove(junk, (char *)&pp->refid, 4); 2174 str = junk; 2175 } else { 2176 str = stoa(&pp->srcadr); 2177 } 2178 (void) fprintf(fp, 2179 "refid [%s], delay %s, dispersion %s\n", 2180 str, fptoa((s_fp)pp->delay, 5), 2181 ufptoa(pp->dispersion, 5)); 2182 2183 (void) fprintf(fp, "transmitted %d, in filter %d\n", 2184 pp->xmtcnt, pp->filter_nextpt); 2185 2186 (void) fprintf(fp, "reference time: %s\n", 2187 prettydate(&pp->reftime)); 2188 (void) fprintf(fp, "originate timestamp: %s\n", 2189 prettydate(&pp->org)); 2190 (void) fprintf(fp, "transmit timestamp: %s\n", 2191 prettydate(&pp->xmt)); 2192 2193 (void) fprintf(fp, "filter delay: "); 2194 for (i = 0; i < NTP_SHIFT; i++) { 2195 (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5)); 2196 if (i == (NTP_SHIFT>>1)-1) 2197 (void) fprintf(fp, "\n "); 2198 } 2199 (void) fprintf(fp, "\n"); 2200 2201 (void) fprintf(fp, "filter offset:"); 2202 for (i = 0; i < PEER_SHIFT; i++) { 2203 (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6)); 2204 if (i == (PEER_SHIFT>>1)-1) 2205 (void) fprintf(fp, "\n "); 2206 } 2207 (void) fprintf(fp, "\n"); 2208 2209 (void) fprintf(fp, "delay %s, dispersion %s\n", 2210 fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5)); 2211 2212 (void) fprintf(fp, "offset %s\n\n", 2213 lfptoa(&pp->offset, 6)); 2214 } 2215 2216 #if !defined(HAVE_VSPRINTF) 2217 int 2218 vsprintf( 2219 char *str, 2220 const char *fmt, 2221 va_list ap 2222 ) 2223 { 2224 FILE f; 2225 int len; 2226 2227 f._flag = _IOWRT+_IOSTRG; 2228 f._ptr = str; 2229 f._cnt = 32767; 2230 len = _doprnt(fmt, ap, &f); 2231 *f._ptr = 0; 2232 return (len); 2233 } 2234 #endif 2235 2236 #if 0 2237 /* override function in library since SA_RESTART makes ALL syscalls restart */ 2238 #ifdef SA_RESTART 2239 void 2240 signal_no_reset( 2241 int sig, 2242 void (*func)() 2243 ) 2244 { 2245 int n; 2246 struct sigaction vec; 2247 2248 vec.sa_handler = func; 2249 sigemptyset(&vec.sa_mask); 2250 vec.sa_flags = 0; 2251 2252 while (1) 2253 { 2254 n = sigaction(sig, &vec, NULL); 2255 if (n == -1 && errno == EINTR) 2256 continue; 2257 break; 2258 } 2259 if (n == -1) 2260 { 2261 perror("sigaction"); 2262 exit(1); 2263 } 2264 } 2265 #endif 2266 #endif 2267 2268 #ifdef HAVE_NETINFO 2269 static ni_namelist * 2270 getnetinfoservers(void) 2271 { 2272 ni_status status; 2273 void *domain; 2274 ni_id confdir; 2275 ni_namelist *namelist = (ni_namelist*)malloc(sizeof(ni_namelist)); 2276 2277 /* Find a time server in NetInfo */ 2278 if ((status = ni_open(NULL, ".", &domain)) != NI_OK) return NULL; 2279 2280 while (status = ni_pathsearch(domain, &confdir, NETINFO_CONFIG_DIR) == NI_NODIR) { 2281 void *next_domain; 2282 if (ni_open(domain, "..", &next_domain) != NI_OK) break; 2283 ni_free(domain); 2284 domain = next_domain; 2285 } 2286 if (status != NI_OK) return NULL; 2287 2288 NI_INIT(namelist); 2289 if (ni_lookupprop(domain, &confdir, "server", namelist) != NI_OK) { 2290 ni_namelist_free(namelist); 2291 free(namelist); 2292 return NULL; 2293 } 2294 2295 return(namelist); 2296 } 2297 #endif 2298 2299 #ifdef SYS_WINNT 2300 isc_boolean_t ntp_port_inuse(int af, u_short port) 2301 { 2302 /* 2303 * Check if NTP socket is already in use on this system 2304 * This is only for Windows Systems, as they tend not to fail on the real bind() below 2305 */ 2306 2307 SOCKET checksocket; 2308 struct sockaddr_in checkservice; 2309 checksocket = socket(af, SOCK_DGRAM, 0); 2310 if (checksocket == INVALID_SOCKET) { 2311 return (ISC_TRUE); 2312 } 2313 2314 checkservice.sin_family = (short) AF_INET; 2315 checkservice.sin_addr.s_addr = INADDR_LOOPBACK; 2316 checkservice.sin_port = htons(port); 2317 2318 if (bind(checksocket, (struct sockaddr *)&checkservice, 2319 sizeof(checkservice)) == SOCKET_ERROR) { 2320 if ( WSAGetLastError() == WSAEADDRINUSE ){ 2321 closesocket(checksocket); 2322 return (ISC_TRUE); 2323 } 2324 } 2325 closesocket(checksocket); 2326 return (ISC_FALSE); 2327 } 2328 #endif 2329