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