Annotation of embedaddon/ntp/ntpdate/ntpdate.c, revision 1.1.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>