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