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>