Annotation of embedaddon/ntp/ntpdate/ntptimeset.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * ntptimeset - get/set the time via ntp
                      3:  *
                      4:  * GOAL:
                      5:  * The goal of ntptime is to set the current time on system startup
                      6:  * to the best possible time using the network very wisely. It is assumed
                      7:  * that after a resonable time has been sett then ntp daemon will
                      8:  * maintain it.
                      9:  *
                     10:  * PROBLEM DOMAIN:
                     11:  * We have three sets of issues related to acheiving the goal. The first
                     12:  * issue is using the network when normal traffic is happening or when
                     13:  * the entire network world is recovering from a campus wide power failure
                     14:  * and is restarting. The second issue is the class of machine whether it
                     15:  * is a user's office workstation being handled by an uneducated user or
                     16:  * a server computer being handled by a trained operations staff. The third
                     17:  * issue is whether the ratio of people to computers and whether the 
                     18:  * environment is stable and viable or not.
                     19:  *
                     20:  * NETWORK USAGE:
                     21:  * The first issue of using the network wisely is a question of whether
                     22:  * the network load and time server load and state are normal. If things
                     23:  * are normal ntptime can do what ntpdate does of sending out 4 packets
                     24:  * quickly to each server (new transmit done with each ack). However
                     25:  * if network or time load is high then this scheme will simply contribute
                     26:  * to problems. Given we have minimal state, we simply weight lost packets
                     27:  * significantly and make sure we throttle output as much as possible
                     28:  * without performance lost for quick startups.
                     29:  *
                     30:  * TRAINING AND KNOWLEDGE:
                     31:  * The second issue of uneducated user of a office workstation versus a
                     32:  * trained operation staff of a server machine translates into simply an
                     33:  * issue of untrained and trained users.
                     34:  * 
                     35:  * The training issue implies that for the sake of the users involved in the
                     36:  * handling of their office workstation, problems and options should be
                     37:  * communicated simply and effectively and not in terse expert related
                     38:  * descriptions without possible options to be taken. The operator's training
                     39:  * and education enables them to deal with either type of communication and
                     40:  * control.
                     41:  *
                     42:  * AUTOMATION AND MANUAL CONTROL:
                     43:  * The last issue boils down to a design problem. If the design tends to go
                     44:  * into a manual mode when the environment is non-viable then one person
                     45:  * handling many computers all at the same time will be heavily impacted. On
                     46:  * the other hand, if the design tends to be automatic and does not indicate
                     47:  * a way for the user to take over control then the computer will be
                     48:  * unavailable for the user until the proble is resolved by someone else or
                     49:  * the user.
                     50:  *
                     51:  * NOTE: Please do not have this program print out every minute some line,
                     52:  *       of output. If this happens and the environment is in trouble then
                     53:  *       many pages of paper on many different machines will be filled up.
                     54:  *       Save some tress in your lifetime.
                     55:  * 
                     56:  * CONCLUSION:
                     57:  * The behavior of the program derived from these three issues should be
                     58:  * that during normal situations it quickly sets the time and allow the
                     59:  * system to startup.
                     60:  *
                     61:  * However during abnormal conditions as detected by unresponsive servers,
                     62:  * out-of-sync or bad responses and other detections, it should print out
                     63:  * a simple but clear message and continue in a mellow way to get the best
                     64:  * possible time. It may never get the time and if so should also indicate
                     65:  * this.
                     66:  *
                     67:  * Rudy Nedved
                     68:  * 18-May-1993
                     69:  *
                     70:  ****************************************************************
                     71:  *
                     72:  * Much of the above is confusing or no longer relevant.  For example,
                     73:  * it is rare these days for a machine's console to be a printing terminal,
                     74:  * so the comment about saving trees doesn't mean much.  Nonetheless,
                     75:  * the basic principles still stand:
                     76:  *
                     77:  * - Work automatically, without human control or intervention.  To
                     78:  *   this end, we use the same configuration file as ntpd itself, so
                     79:  *   you don't have to specify servers or other information on the
                     80:  *   command line.  We also recognize that sometimes we won't be able
                     81:  *   to contact any servers, and give up in that event instead of
                     82:  *   hanging forever.
                     83:  *
                     84:  * - Behave in a sane way, both internally and externally, even in the
                     85:  *   face of insane conditions.  That means we back off quickly when
                     86:  *   we don't hear a response, to avoid network congestion.  Like
                     87:  *   ntpd, we verify responses from several servers before accepting
                     88:  *   the new time data.
                     89:  *
                     90:  *   However, we don't assume that the local clock is right, or even
                     91:  *   close, because it might not be at boot time, and we want to catch
                     92:  *   and correct that situation.  This behaviour has saved us in several
                     93:  *   instances.  On HP-UX 9.0x, there used to be a bug in adjtimed which
                     94:  *   would cause the time to be set to some wild value, making the machine
                     95:  *   essentially unusable (we use Kerberos authentication pervasively,
                     96:  *   and it requires workstations and servers to have a time within five
                     97:  *   minutes of the Kerberos server).  We also have problems on PC's
                     98:  *   running both Linux and some Microsoft OS -- they tend to disagree
                     99:  *   on what the BIOS clock should say, and who should update it, and
                    100:  *   when.  On those systems, we not only run ntptimeset at boot, we
                    101:  *   also reset the BIOS clock based on the result, so the correct
                    102:  *   time will be retained across reboots.
                    103:  *
                    104:  * For these reasons, and others, we have continued to use this tool
                    105:  * rather than ntpdate.  It is run automatically at boot time on every
                    106:  * workstation and server in our facility.
                    107:  *
                    108:  * In the past, we called this program 'ntptime'.  Unfortunately, the
                    109:  * ntp v4 distribution also includes a program with that name.  In
                    110:  * order to avoid confusion, we have renamed our program 'ntptimeset',
                    111:  * which more accurately describes what it does.
                    112:  *
                    113:  * Jeffrey T. Hutzelman (N3NHS) <jhutz+@cmu.edu>
                    114:  * School of Computer Science - Research Computing Facility
                    115:  * Carnegie Mellon University - Pittsburgh, PA
                    116:  * 16-Aug-1999
                    117:  *
                    118:  */
                    119: 
                    120: #ifdef HAVE_CONFIG_H
                    121: # include <config.h>
                    122: #endif
                    123: 
                    124: #include "ntp_machine.h"
                    125: #include "ntp_fp.h"
                    126: #include "ntp.h"
                    127: #include "ntp_io.h"
                    128: #include "iosignal.h"
                    129: #include "ntp_unixtime.h"
                    130: #include "ntpdate.h"
                    131: #include "ntp_string.h"
                    132: #include "ntp_syslog.h"
                    133: #include "ntp_select.h"
                    134: #include "ntp_stdlib.h"
                    135: 
                    136: #ifdef HAVE_UNISTD_H
                    137: # include <unistd.h>
                    138: #endif
                    139: 
                    140: #include <stdio.h>
                    141: #include <signal.h>
                    142: #include <ctype.h>
                    143: #ifndef SYS_WINNT
                    144: # ifdef HAVE_SYS_SIGNAL_H
                    145: #  include <sys/signal.h>
                    146: # else
                    147: #  include <signal.h>
                    148: # endif
                    149: # include <sys/ioctl.h>
                    150: #endif /* SYS_WINNT */
                    151: 
                    152: #ifdef HAVE_SYS_RESOURCE_H
                    153: # include <sys/resource.h>
                    154: #endif /* HAVE_SYS_RESOURCE_H */
                    155: 
                    156: #ifdef SYS_VXWORKS
                    157: # include "ioLib.h"
                    158: # include "sockLib.h"
                    159: # include "timers.h"
                    160: #endif
                    161: 
                    162: #include "recvbuff.h"
                    163: 
                    164: #ifdef SYS_WINNT
                    165: # define TARGET_RESOLUTION 1  /* Try for 1-millisecond accuracy
                    166:                                on Windows NT timers. */
                    167: #pragma comment(lib, "winmm")
                    168: #endif /* SYS_WINNT */
                    169: 
                    170: /*
                    171:  * Scheduling priority we run at
                    172:  */
                    173: #ifndef SYS_VXWORKS
                    174: # define       NTPDATE_PRIO    (-12)
                    175: #else
                    176: # define       NTPDATE_PRIO    (100)
                    177: #endif
                    178: 
                    179: #if defined(HAVE_TIMER_SETTIME) || defined (HAVE_TIMER_CREATE)
                    180: /* POSIX TIMERS - vxWorks doesn't have itimer - casey */
                    181: static timer_t ntpdate_timerid;
                    182: #endif
                    183: 
                    184: /*
                    185:  * Compatibility stuff for Version 2
                    186:  */
                    187: #define NTP_MAXSKW     0x28f   /* 0.01 sec in fp format */
                    188: #define NTP_MINDIST 0x51f      /* 0.02 sec in fp format */
                    189: #define NTP_INFIN      15      /* max stratum, infinity a la Bellman-Ford */
                    190: #define NTP_MAXWGT     (8*FP_SECOND)   /* maximum select weight 8 seconds */
                    191: #define NTP_MAXLIST 5  /* maximum select list size */
                    192: #define PEER_SHIFT     8       /* 8 suitable for crystal time base */
                    193: 
                    194: /*
                    195:  * Debugging flag
                    196:  */
                    197: volatile int debug = 0;
                    198: 
                    199: /*
                    200:  * File descriptor masks etc. for call to select
                    201:  */
                    202: int fd;
                    203: fd_set fdmask;
                    204: 
                    205: /*
                    206:  * Initializing flag.  All async routines watch this and only do their
                    207:  * thing when it is clear.
                    208:  */
                    209: int initializing = 1;
                    210: 
                    211: /*
                    212:  * Alarm flag. Set when an alarm occurs
                    213:  */
                    214: volatile int alarm_flag = 0;
                    215: 
                    216: /*
                    217:  * Set the time if valid time determined
                    218:  */
                    219: int set_time = 0;
                    220: 
                    221: /*
                    222:  * transmission rate control
                    223:  */
                    224: #define        MINTRANSMITS    (3)     /* minimum total packets per server */
                    225: #define        MAXXMITCOUNT    (2)     /* maximum packets per time interrupt */
                    226: 
                    227: /*
                    228:  * time setting constraints
                    229:  */
                    230: #define        DESIREDDISP     (4*FP_SECOND)   /* desired dispersion, (fp 4) */
                    231: int max_period = DEFMAXPERIOD;
                    232: int min_servers = DEFMINSERVERS;
                    233: int min_valid = DEFMINVALID;
                    234: 
                    235: /*
                    236:  * counters related to time setting constraints
                    237:  */
                    238: int contacted = 0;             /* # of servers we have sent to */
                    239: int responding = 0;            /* servers responding */
                    240: int validcount = 0;            /* servers with valid time */
                    241: int valid_n_low = 0;           /* valid time servers with low dispersion */
                    242: 
                    243: /*
                    244:  * Unpriviledged port flag.
                    245:  */
                    246: int unpriv_port = 0;
                    247: 
                    248: /*
                    249:  * Program name.
                    250:  */
                    251: char *progname;
                    252: 
                    253: /*
                    254:  * Systemwide parameters and flags
                    255:  */
                    256: struct server **sys_servers;   /* the server list */
                    257: int sys_numservers = 0;        /* number of servers to poll */
                    258: int sys_authenticate = 0;      /* true when authenticating */
                    259: u_int32 sys_authkey = 0;       /* set to authentication key in use */
                    260: u_long sys_authdelay = 0;      /* authentication delay */
                    261: 
                    262: /*
                    263:  * The current internal time
                    264:  */
                    265: u_long current_time = 0;
                    266: 
                    267: /*
                    268:  * File of encryption keys
                    269:  */
                    270: 
                    271: #ifndef KEYFILE
                    272: # ifndef SYS_WINNT
                    273: #define KEYFILE        "/etc/ntp.keys"
                    274: # else
                    275: #define KEYFILE        "%windir%\\ntp.keys"
                    276: # endif /* SYS_WINNT */
                    277: #endif /* KEYFILE */
                    278: 
                    279: #ifndef SYS_WINNT
                    280: const char *key_file = KEYFILE;
                    281: #else
                    282: char key_file_storage[MAX_PATH+1], *key_file ;
                    283: #endif  /* SYS_WINNT */
                    284: 
                    285: /*
                    286:  * total packet counts
                    287:  */
                    288: u_long total_xmit = 0;
                    289: u_long total_recv = 0;
                    290: 
                    291: /*
                    292:  * Miscellaneous flags
                    293:  */
                    294: int verbose = 0;
                    295: #define        HORRIBLEOK      3       /* how many packets to let out */
                    296: int horrible = 0;      /* how many packets we drop for testing */
                    297: int secondhalf = 0;    /* second half of timeout period */
                    298: int printmsg = 0;      /* print time response analysis */
                    299: 
                    300: /*
                    301:  * The half time and finish time in internal time
                    302:  */
                    303: u_long half_time = 0;
                    304: u_long finish_time = 0;
                    305: 
                    306: 
                    307: int    ntptimesetmain  P((int argc, char *argv[]));
                    308: static void    analysis        P((int final));
                    309: static int     have_enough     P((void));
                    310: static void    transmit        P((register struct server *server));
                    311: static void    receive         P((struct recvbuf *rbufp));
                    312: static void    clock_filter P((register struct server *server, s_fp d, l_fp *c));
                    313: static void    clock_count     P((void));
                    314: static struct server *clock_select P((void));
                    315: static void    set_local_clock P((void));
                    316: static struct server *findserver P((struct sockaddr_in *addr));
                    317: static void    timer           P((void));
                    318: #ifndef SYS_WINNT
                    319: static RETSIGTYPE      alarming        P((int sig));
                    320: #endif /* SYS_WINNT */
                    321: static void    init_alarm      P((void));
                    322: static void    init_io         P((void));
                    323: static int     sendpkt         P((struct sockaddr_in *dest, struct pkt *pkt, int len));
                    324:        void    input_handler   P((l_fp *xts));
                    325: static void    printserver     P((register struct server *pp, FILE *fp));
                    326: #if !defined(HAVE_VSPRINTF)
                    327: int    vsprintf        P((char *str, const char *fmt, va_list ap));
                    328: #endif
                    329: 
                    330: #ifdef HAVE_SIGNALED_IO
                    331: extern  void    wait_for_signal P((void));
                    332: extern  void    unblock_io_and_alarm P((void));
                    333: extern  void    block_io_and_alarm P((void));
                    334: #endif
                    335: 
                    336: 
                    337: #ifdef NO_MAIN_ALLOWED
                    338: CALL(ntptimeset,"ntptimeset",ntptimesetmain);
                    339: 
                    340: void clear_globals()
                    341: {
                    342:   /*
                    343:    * Debugging flag
                    344:    */
                    345:   debug = 0;
                    346: 
                    347:   ntp_optind = 0;
                    348: 
                    349:   /*
                    350:    * Initializing flag.  All async routines watch this and only do their
                    351:    * thing when it is clear.
                    352:    */
                    353:   initializing = 1;
                    354: 
                    355:   /*
                    356:    * Alarm flag.  Set when an alarm occurs
                    357:    */
                    358:   alarm_flag = 0;
                    359: 
                    360:   /*
                    361:    * Unpriviledged port flag.
                    362:    */
                    363:   unpriv_port = 0;
                    364: 
                    365:   /*
                    366:    * Systemwide parameters and flags
                    367:    */
                    368:   sys_numservers = 0;    /* number of servers to poll */
                    369:   sys_authenticate = 0;   /* true when authenticating */
                    370:   sys_authkey = 0;        /* set to authentication key in use */
                    371:   sys_authdelay = 0;   /* authentication delay */
                    372: 
                    373:   /*
                    374:    * The current internal time
                    375:    */
                    376:   current_time = 0;
                    377: 
                    378:   verbose = 0;
                    379: }
                    380: #endif /* NO_MAIN_ALLOWED */
                    381: 
                    382: /*
                    383:  * Main program.  Initialize us and loop waiting for I/O and/or
                    384:  * timer expiries.
                    385:  */
                    386: #ifndef NO_MAIN_ALLOWED
                    387: int
                    388: main(
                    389:        int argc,
                    390:        char *argv[]
                    391:        )
                    392: {
                    393:        return ntptimesetmain(argc, argv);
                    394: }
                    395: #endif /* NO_MAIN_ALLOWED */
                    396:           
                    397: 
                    398: int
                    399: ntptimesetmain(
                    400:        int argc,
                    401:        char *argv[]
                    402:        )
                    403: {
                    404:        int was_alarmed;
                    405:        int tot_recvbufs;
                    406:        struct recvbuf *rbuf;
                    407:        l_fp tmp;
                    408:        int errflg;
                    409:        int c;
                    410:        extern char *ntp_optarg;
                    411:        extern int ntp_optind;
                    412:        int ltmp;
                    413:        char *cfgpath;
                    414: 
                    415: #ifdef SYS_WINNT
                    416:        HANDLE process_handle;
                    417: 
                    418:        wVersionRequested = MAKEWORD(1,1);
                    419:        if (WSAStartup(wVersionRequested, &wsaData)) {
                    420:                msyslog(LOG_ERR, "No useable winsock.dll: %m");
                    421:                exit(1);
                    422:        }
                    423: #endif /* SYS_WINNT */
                    424: 
                    425: #ifdef NO_MAIN_ALLOWED
                    426:        clear_globals();
                    427: #endif
                    428: 
                    429:        errflg = 0;
                    430:        cfgpath = 0;
                    431:        progname = argv[0];
                    432:        syslogit = 0;
                    433: 
                    434:        /*
                    435:         * Decode argument list
                    436:         */
                    437:        while ((c = ntp_getopt(argc, argv, "a:c:de:slt:uvHS:V:")) != EOF)
                    438:                switch (c)
                    439:                {
                    440:                case 'a':
                    441:                        c = atoi(ntp_optarg);
                    442:                        sys_authenticate = 1;
                    443:                        sys_authkey = c;
                    444:                        break;
                    445:                case 'c':
                    446:                        cfgpath = ntp_optarg;
                    447:                        break;
                    448:                case 'd':
                    449:                        ++debug;
                    450:                        break;
                    451:                case 'e':
                    452:                        if (!atolfp(ntp_optarg, &tmp)
                    453:                            || tmp.l_ui != 0) {
                    454:                                (void) fprintf(stderr,
                    455:                                    "%s: encryption delay %s is unlikely\n",
                    456:                                    progname, ntp_optarg);
                    457:                                errflg++;
                    458:                        } else {
                    459:                                sys_authdelay = tmp.l_uf;
                    460:                        }
                    461:                        break;
                    462:                case 's':
                    463:                        set_time = 1;
                    464:                        break;
                    465:                case 'l':
                    466:                        syslogit = 1;
                    467:                        break;
                    468:                case 't':
                    469:                        ltmp = atoi(ntp_optarg);
                    470:                        if (ltmp <= 0) {
                    471:                            (void) fprintf(stderr,
                    472:                                "%s: maximum time period (%d) is invalid\n",
                    473:                                progname, ltmp);
                    474:                            errflg++;
                    475:                        }
                    476:                        else
                    477:                            max_period = ltmp;
                    478:                        break;
                    479:                case 'u':
                    480:                        unpriv_port = 1;
                    481:                        break;
                    482:                case 'v':
                    483:                        ++verbose;
                    484:                        break;
                    485:                case 'H':
                    486:                        horrible++;
                    487:                        break;
                    488:                case 'S':
                    489:                        ltmp = atoi(ntp_optarg);
                    490:                        if (ltmp <= 0) {
                    491:                            (void) fprintf(stderr,
                    492:                                "%s: minimum responding (%d) is invalid\n",
                    493:                                progname, ltmp);
                    494:                            errflg++;
                    495:                        }
                    496:                        else
                    497:                            min_servers = ltmp;
                    498:                        break;
                    499:                case 'V':
                    500:                        ltmp = atoi(ntp_optarg);
                    501:                        if (ltmp <= 0) {
                    502:                            (void) fprintf(stderr,
                    503:                                "%s: minimum valid (%d) is invalid\n",
                    504:                                progname, ltmp);
                    505:                            errflg++;
                    506:                        }
                    507:                        else
                    508:                            min_valid = ltmp;
                    509:                        break;
                    510:                case '?':
                    511:                        ++errflg;
                    512:                        break;
                    513:                default:
                    514:                        break;
                    515:                }
                    516: 
                    517:        
                    518:        if (errflg || ntp_optind < argc) {
                    519:                fprintf(stderr,"usage: %s [switches...]\n",progname);
                    520:                fprintf(stderr,"  -v       (verbose)\n");
                    521:                fprintf(stderr,"  -c path  (set config file path)\n");
                    522:                fprintf(stderr,"  -a key   (authenticate using key)\n");
                    523:                fprintf(stderr,"  -e delay (authentication delay)\n");
                    524:                fprintf(stderr,"  -S num   (# of servers that must respond)\n");
                    525:                fprintf(stderr,"  -V num   (# of servers that must valid)\n");
                    526:                fprintf(stderr,"  -s       (set the time based if okay)\n");
                    527:                fprintf(stderr,"  -t secs  (time period before ending)\n");
                    528:                fprintf(stderr,"  -l       (use syslog facility)\n");
                    529:                fprintf(stderr,"  -u       (use unprivileged port)\n");
                    530:                fprintf(stderr,"  -H       (drop packets for debugging)\n");
                    531:                fprintf(stderr,"  -d       (debug output)\n");
                    532:                exit(2);
                    533:        }
                    534: 
                    535:        /*
                    536:         * Logging.  Open the syslog if we have to
                    537:         */
                    538:        if (syslogit) {
                    539: #if !defined (SYS_WINNT) && !defined (SYS_VXWORKS) && !defined SYS_CYGWIN32
                    540: # ifndef       LOG_DAEMON
                    541:                openlog("ntptimeset", LOG_PID);
                    542: # else
                    543: 
                    544: #  ifndef      LOG_NTP
                    545: #      define  LOG_NTP LOG_DAEMON
                    546: #  endif
                    547:                openlog("ntptimeset", LOG_PID | LOG_NDELAY, LOG_NTP);
                    548:                if (debug)
                    549:                        setlogmask(LOG_UPTO(LOG_DEBUG));
                    550:                else
                    551:                        setlogmask(LOG_UPTO(LOG_INFO));
                    552: # endif /* LOG_DAEMON */
                    553: #endif /* SYS_WINNT */
                    554:        }
                    555: 
                    556:        if (debug || verbose)
                    557:                msyslog(LOG_INFO, "%s", Version);
                    558: 
                    559:        if (horrible)
                    560:                msyslog(LOG_INFO, "Dropping %d out of %d packets",
                    561:                        horrible,horrible+HORRIBLEOK);
                    562:        /*
                    563:         * Add servers we are going to be polling
                    564:         */
                    565:        loadservers(cfgpath);
                    566: 
                    567:        if (sys_numservers < min_servers) {
                    568:                msyslog(LOG_ERR, "Found %d servers, require %d servers",
                    569:                        sys_numservers,min_servers);
                    570:                exit(2);
                    571:        }
                    572: 
                    573:        /*
                    574:         * determine when we will end at least
                    575:         */
                    576:        finish_time = max_period * TIMER_HZ;
                    577:        half_time = finish_time >> 1;
                    578: 
                    579:        /*
                    580:         * Initialize the time of day routines and the I/O subsystem
                    581:         */
                    582:        if (sys_authenticate) {
                    583:                init_auth();
                    584: #ifdef SYS_WINNT
                    585:                if (!key_file) key_file = KEYFILE;
                    586:                if (!ExpandEnvironmentStrings(key_file, key_file_storage, MAX_PATH))
                    587:                {
                    588:                        msyslog(LOG_ERR, "ExpandEnvironmentStrings(%s) failed: %m\n",
                    589:                                key_file);
                    590:                } else {
                    591:                        key_file = key_file_storage;
                    592:                }
                    593: #endif /* SYS_WINNT */
                    594: 
                    595:                if (!authreadkeys(key_file)) {
                    596:                        msyslog(LOG_ERR, "no key file, exiting");
                    597:                        exit(1);
                    598:                }
                    599:                if (!authistrusted(sys_authkey)) {
                    600:                        char buf[10];
                    601: 
                    602:                        (void) sprintf(buf, "%lu", (unsigned long)sys_authkey);
                    603:                        msyslog(LOG_ERR, "authentication key %s unknown", buf);
                    604:                        exit(1);
                    605:                }
                    606:        }
                    607:        init_io();
                    608:        init_alarm();
                    609: 
                    610:        /*
                    611:         * Set the priority.
                    612:         */
                    613: #ifdef SYS_VXWORKS
                    614:        taskPrioritySet( taskIdSelf(), NTPDATE_PRIO);
                    615: #endif
                    616: #if defined(HAVE_ATT_NICE)
                    617:        nice (NTPDATE_PRIO);
                    618: #endif
                    619: #if defined(HAVE_BSD_NICE)
                    620:        (void) setpriority(PRIO_PROCESS, 0, NTPDATE_PRIO);
                    621: #endif
                    622: #ifdef SYS_WINNT
                    623:        process_handle = GetCurrentProcess();
                    624:        if (!SetPriorityClass(process_handle, (DWORD) REALTIME_PRIORITY_CLASS)) {
                    625:                msyslog(LOG_ERR, "SetPriorityClass failed: %m");
                    626:        }
                    627: #endif /* SYS_WINNT */
                    628: 
                    629:        initializing = 0;
                    630: 
                    631:        /*
                    632:         * Use select() on all on all input fd's for unlimited
                    633:         * time.  select() will terminate on SIGALARM or on the
                    634:         * reception of input.  Using select() means we can't do
                    635:         * robust signal handling and we get a potential race
                    636:         * between checking for alarms and doing the select().
                    637:         * Mostly harmless, I think.
                    638:         * Keep going until we have enough information, or time is up.
                    639:         */
                    640:        /* On VMS, I suspect that select() can't be interrupted
                    641:         * by a "signal" either, so I take the easy way out and
                    642:         * have select() time out after one second.
                    643:         * System clock updates really aren't time-critical,
                    644:         * and - lacking a hardware reference clock - I have
                    645:         * yet to learn about anything else that is.
                    646:         */
                    647:        was_alarmed = 0;
                    648:        while (finish_time > current_time) {
                    649: #if !defined(HAVE_SIGNALED_IO) 
                    650:                fd_set rdfdes;
                    651:                int nfound;
                    652: #elif defined(HAVE_SIGNALED_IO)
                    653:                block_io_and_alarm();
                    654: #endif
                    655: 
                    656:                tot_recvbufs = full_recvbuffs();        /* get received buffers */
                    657:                if (printmsg) {
                    658:                        printmsg = 0;
                    659:                        analysis(0);
                    660:                }
                    661:                if (alarm_flag) {               /* alarmed? */
                    662:                        was_alarmed = 1;
                    663:                        alarm_flag = 0;
                    664:                }
                    665: 
                    666:                if (!was_alarmed && tot_recvbufs > 0) {
                    667:                        /*
                    668:                         * Nothing to do.  Wait for something.
                    669:                         */
                    670: #ifndef HAVE_SIGNALED_IO
                    671:                        rdfdes = fdmask;
                    672: # if defined(VMS) || defined(SYS_VXWORKS)
                    673:                        /* make select() wake up after one second */
                    674:                        {
                    675:                                struct timeval t1;
                    676: 
                    677:                                t1.tv_sec = 1; t1.tv_usec = 0;
                    678:                                nfound = select(fd+1, &rdfdes, (fd_set *)0,
                    679:                                                (fd_set *)0, &t1);
                    680:                        }
                    681: # else
                    682:                        nfound = select(fd+1, &rdfdes, (fd_set *)0,
                    683:                                        (fd_set *)0, (struct timeval *)0);
                    684: # endif /* VMS */
                    685:                        if (nfound > 0) {
                    686:                                l_fp ts;
                    687:                                get_systime(&ts);
                    688:                                (void)input_handler(&ts);
                    689:                        }
                    690:                        else if (nfound == -1 && errno != EINTR)
                    691:                                msyslog(LOG_ERR, "select() error: %m");
                    692:                        else if (debug) {
                    693: # if !defined SYS_VXWORKS && !defined SYS_CYGWIN32 /* to unclutter log */
                    694:                                msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
                    695: # endif
                    696:                        }
                    697: #else /* HAVE_SIGNALED_IO */
                    698:                         
                    699:                        wait_for_signal();
                    700: #endif /* HAVE_SIGNALED_IO */
                    701:                        if (alarm_flag)         /* alarmed? */
                    702:                        {
                    703:                                was_alarmed = 1;
                    704:                                alarm_flag = 0;
                    705:                        }
                    706:                        tot_recvbufs = full_recvbuffs();  /* get received buffers */
                    707:                }
                    708: #ifdef HAVE_SIGNALED_IO
                    709:                unblock_io_and_alarm();
                    710: #endif /* HAVE_SIGNALED_IO */
                    711: 
                    712:                /*
                    713:                 * Out here, signals are unblocked.  Call timer routine
                    714:                 * to process expiry.
                    715:                 */
                    716:                if (was_alarmed)
                    717:                {
                    718:                        timer();
                    719:                        was_alarmed = 0;
                    720:                }
                    721: 
                    722:                /*
                    723:                 * Call the data procedure to handle each received
                    724:                 * packet.
                    725:                 */
                    726:                rbuf = get_full_recv_buffer();
                    727:                while (rbuf != NULL)
                    728:                {
                    729:                        receive(rbuf);
                    730:                        freerecvbuf(rbuf);
                    731:                        rbuf = get_full_recv_buffer();
                    732:                }
                    733: 
                    734:                /*
                    735:                 * Do we have enough information to stop now?
                    736:                 */
                    737:                if (have_enough())
                    738:                        break;  /* time to end */
                    739: 
                    740:                /*
                    741:                 * Go around again
                    742:                 */
                    743:        }
                    744: 
                    745:        /*
                    746:         * adjust the clock and exit accordingly
                    747:         */
                    748:        set_local_clock();
                    749: 
                    750:        /*
                    751:         * if we get here then we are in trouble
                    752:         */
                    753:        return(1);
                    754: }
                    755: 
                    756: 
                    757: /*
                    758:  * analysis - print a message indicating what is happening with time service
                    759:  *           must mimic have_enough() procedure.
                    760:  */
                    761: static void
                    762: analysis(
                    763:        int final
                    764:        )
                    765: {
                    766:        if (contacted < sys_numservers) {
                    767:                printf("%d servers of %d have been probed with %d packets\n",
                    768:                       contacted,sys_numservers,MINTRANSMITS);
                    769:                return;
                    770:        }
                    771:        if (!responding) {
                    772:                printf("No response from any of %d servers, network problem?\n",
                    773:                       sys_numservers);
                    774:                return;
                    775:        }
                    776:        else if (responding < min_servers) {
                    777:                printf("%d servers out of %d responding, need at least %d.\n",
                    778:                       responding, sys_numservers, min_servers);
                    779:                return;
                    780:        }
                    781:        if (!validcount) {
                    782:                printf("%d servers responding but none have valid time\n",
                    783:                       responding);
                    784:                return;
                    785:        }
                    786:        else if (validcount < min_valid) {
                    787:                printf("%d servers responding, %d are valid, need %d valid\n",
                    788:                       responding,validcount,min_valid);
                    789:                return;
                    790:        }
                    791:        if (!final && valid_n_low != validcount) {
                    792:                printf("%d valid servers but only %d have low dispersion\n",
                    793:                       validcount,valid_n_low);
                    794:                return;
                    795:        }
                    796: }
                    797: 
                    798: 
                    799: /* have_enough - see if we have enough information to terminate probing
                    800:  */
                    801: static int
                    802: have_enough(void)
                    803: {
                    804:        /* have we contacted all servers yet? */
                    805:        if (contacted < sys_numservers)
                    806:                return 0;       /* no...try some more */
                    807: 
                    808:        /* have we got at least minimum servers responding? */
                    809:        if (responding < min_servers)
                    810:                return 0;       /* no...try some more */
                    811: 
                    812:        /* count the clocks */
                    813:        (void) clock_count();
                    814: 
                    815:        /* have we got at least minimum valid clocks? */
                    816:        if (validcount <= 0 || validcount < min_valid)
                    817:                return 0;       /* no...try some more */
                    818: 
                    819:        /* do we have all valid servers with low dispersion */
                    820:        if (!secondhalf && valid_n_low != validcount)
                    821:                return 0;
                    822: 
                    823:        /* if we get into the secondhalf then we ignore dispersion */
                    824: 
                    825:        /* all conditions have been met...end */
                    826:        return 1;
                    827: }
                    828: 
                    829: 
                    830: /*
                    831:  * transmit - transmit a packet to the given server, or mark it completed.
                    832:  *           This is called by the timeout routine and by the receive
                    833:  *           procedure.
                    834:  */
                    835: static void
                    836: transmit(
                    837:        register struct server *server
                    838:        )
                    839: {
                    840:        struct pkt xpkt;
                    841:        int timeout;
                    842: 
                    843:        if (debug > 2)
                    844:                printf("transmit(%s)\n", ntoa(&server->srcadr));
                    845: 
                    846:        if ((server->reach & 01) == 0) {
                    847:                l_fp ts;
                    848:                /*
                    849:                 * Last message to this server timed out.  Shift
                    850:                 * zeros into the filter.
                    851:                 */
                    852:                L_CLR(&ts);
                    853:                clock_filter(server, 0, &ts);
                    854:        }
                    855: 
                    856:        /*
                    857:         * shift reachable register over
                    858:         */
                    859:        server->reach <<= 1;
                    860: 
                    861:        /*
                    862:         * If we're here, send another message to the server.  Fill in
                    863:         * the packet and let 'er rip.
                    864:         */
                    865:        xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
                    866:                server->version, MODE_CLIENT);
                    867:        xpkt.stratum = STRATUM_TO_PKT(STRATUM_UNSPEC);
                    868:        xpkt.ppoll = NTP_MINPOLL;
                    869:        xpkt.precision = NTPDATE_PRECISION;
                    870:        xpkt.rootdelay = htonl(NTPDATE_DISTANCE);
                    871:        xpkt.rootdispersion = htonl(NTPDATE_DISP);
                    872:        xpkt.refid = htonl(NTPDATE_REFID);
                    873:        L_CLR(&xpkt.reftime);
                    874:        L_CLR(&xpkt.org);
                    875:        L_CLR(&xpkt.rec);
                    876: 
                    877:        /*
                    878:         * Determine whether to authenticate or not.  If so,
                    879:         * fill in the extended part of the packet and do it.
                    880:         * If not, just timestamp it and send it away.
                    881:         */
                    882:        if (sys_authenticate) {
                    883:                int len;
                    884: 
                    885:                xpkt.exten[0] = htonl(sys_authkey);
                    886:                get_systime(&server->xmt);
                    887:                L_ADDUF(&server->xmt, sys_authdelay);
                    888:                HTONL_FP(&server->xmt, &xpkt.xmt);
                    889:                len = authencrypt(sys_authkey, (u_int32 *)&xpkt, LEN_PKT_NOMAC);
                    890:                if (sendpkt(&(server->srcadr), &xpkt, (int)(LEN_PKT_NOMAC + len))) {
                    891:                        if (debug > 1)
                    892:                                printf("failed transmit auth to %s\n",
                    893:                                    ntoa(&(server->srcadr)));
                    894:                        return;
                    895:                }
                    896: 
                    897:                if (debug > 1)
                    898:                        printf("transmit auth to %s\n",
                    899:                            ntoa(&(server->srcadr)));
                    900:        } else {
                    901:                get_systime(&(server->xmt));
                    902:                HTONL_FP(&server->xmt, &xpkt.xmt);
                    903:                if (sendpkt(&(server->srcadr), &xpkt, LEN_PKT_NOMAC)) {
                    904:                        if (debug > 1)
                    905:                                printf("failed transmit to %s\n", 
                    906:                                    ntoa(&(server->srcadr)));
                    907:                        return;
                    908:                }
                    909: 
                    910:                if (debug > 1)
                    911:                        printf("transmit to %s\n", ntoa(&(server->srcadr)));
                    912:        }
                    913: 
                    914:        /*
                    915:         * count transmits, record contacted count and set transmit time
                    916:         */
                    917:        if (++server->xmtcnt == MINTRANSMITS)
                    918:            contacted++;
                    919:        server->last_xmit = current_time;
                    920: 
                    921:        /*
                    922:         * determine timeout for this packet. The more packets we send
                    923:         * to the host, the slower we get. If the host indicates that
                    924:         * it is not "sane" then we expect even less.
                    925:         */
                    926:        if (server->xmtcnt < MINTRANSMITS) {
                    927:            /* we have not sent enough */
                    928:            timeout = TIMER_HZ;         /* 1 second probe */
                    929:        }
                    930:        else if (server->rcvcnt <= 0) {
                    931:            /* we have heard nothing */
                    932:            if (secondhalf)
                    933:                timeout = TIMER_HZ<<4;  /* 16 second probe */
                    934:            else
                    935:                timeout = TIMER_HZ<<3;  /* 8 second probe */
                    936:        }
                    937:        else {
                    938:            /* if we have low dispersion then probe infrequently */
                    939:            if (server->dispersion <= DESIREDDISP)
                    940:                timeout = TIMER_HZ<<4;  /* 16 second probe */
                    941:            /* if the server is not in sync then let it alone */
                    942:            else if (server->leap == LEAP_NOTINSYNC)
                    943:                timeout = TIMER_HZ<<4;  /* 16 second probe */
                    944:            /* if the server looks broken ignore it */
                    945:            else if (server->org.l_ui < server->reftime.l_ui)
                    946:                timeout = TIMER_HZ<<5;  /* 32 second probe */
                    947:            else if (secondhalf)
                    948:                timeout = TIMER_HZ<<2;  /* 4 second probe */
                    949:            else
                    950:                timeout = TIMER_HZ<<1;  /* 2 second probe */
                    951:        }
                    952: 
                    953:        /*
                    954:         * set next transmit time based on timeout
                    955:         */
                    956:        server->event_time = current_time + timeout;
                    957: }
                    958: 
                    959: 
                    960: /*
                    961:  * receive - receive and process an incoming frame
                    962:  */
                    963: static void
                    964: receive(
                    965:        struct recvbuf *rbufp
                    966:        )
                    967: {
                    968:        register struct pkt *rpkt;
                    969:        register struct server *server;
                    970:        register s_fp di;
                    971:        l_fp t10, t23;
                    972:        l_fp org;
                    973:        l_fp rec;
                    974:        l_fp ci;
                    975:        int has_mac;
                    976:        int is_authentic;
                    977: 
                    978:        if (debug > 2)
                    979:                printf("receive(%s)\n", ntoa(&rbufp->srcadr));
                    980:        /*
                    981:         * Check to see if the packet basically looks like something
                    982:         * intended for us.
                    983:         */
                    984:        if (rbufp->recv_length == LEN_PKT_NOMAC)
                    985:                has_mac = 0;
                    986:        else if (rbufp->recv_length >= LEN_PKT_NOMAC)
                    987:                has_mac = 1;
                    988:        else {
                    989:                if (debug > 2)
                    990:                        printf("receive: packet length %d\n",
                    991:                            rbufp->recv_length);
                    992:                return;         /* funny length packet */
                    993:        }
                    994: 
                    995:        rpkt = &(rbufp->recv_pkt);
                    996:        if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION ||
                    997:            PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) {
                    998:                if (debug > 1)
                    999:                        printf("receive: bad version %d\n",
                   1000:                               PKT_VERSION(rpkt->li_vn_mode));
                   1001:                return;
                   1002:        }
                   1003: 
                   1004:        if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER
                   1005:            && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE)
                   1006:            || rpkt->stratum >=STRATUM_UNSPEC) {
                   1007:                if (debug > 1)
                   1008:                        printf("receive: mode %d stratum %d\n",
                   1009:                            PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
                   1010:                return;
                   1011:        }
                   1012:        
                   1013:        /*
                   1014:         * So far, so good.  See if this is from a server we know.
                   1015:         */
                   1016:        server = findserver(&(rbufp->srcadr));
                   1017:        if (server == NULL) {
                   1018:                if (debug > 1)
                   1019:                        printf("receive: server not found\n");
                   1020:                return;
                   1021:        }
                   1022: 
                   1023:        /*
                   1024:         * Decode the org timestamp and make sure we're getting a response
                   1025:         * to our last request.
                   1026:         */
                   1027:        NTOHL_FP(&rpkt->org, &org);
                   1028:        if (!L_ISEQU(&org, &server->xmt)) {
                   1029:                if (debug > 1)
                   1030:                        printf("receive: pkt.org and peer.xmt differ\n");
                   1031:                return;
                   1032:        }
                   1033:        
                   1034:        /*
                   1035:         * Check out the authenticity if we're doing that.
                   1036:         */
                   1037:        if (!sys_authenticate)
                   1038:                is_authentic = 1;
                   1039:        else {
                   1040:                is_authentic = 0;
                   1041: 
                   1042:                if (debug > 3)
                   1043:                        printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n",
                   1044:                           (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey,
                   1045:                           (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt,
                   1046:                                LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC)));
                   1047: 
                   1048:                if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey &&
                   1049:                        authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC,
                   1050:                        (int)(rbufp->recv_length - LEN_PKT_NOMAC)))
                   1051:                        is_authentic = 1;
                   1052:                if (debug)
                   1053:                        printf("receive: authentication %s\n",
                   1054:                           is_authentic ? "passed" : "failed");
                   1055:        }
                   1056:        server->trust <<= 1;
                   1057:        if (!is_authentic)
                   1058:                server->trust |= 1;
                   1059:        
                   1060:        /*
                   1061:         * Looks good.  Record info from the packet.
                   1062:         */
                   1063:        server->leap = PKT_LEAP(rpkt->li_vn_mode);
                   1064:        server->stratum = PKT_TO_STRATUM(rpkt->stratum);
                   1065:        server->precision = rpkt->precision;
                   1066:        server->rootdelay = ntohl(rpkt->rootdelay);
                   1067:        server->rootdispersion = ntohl(rpkt->rootdispersion);
                   1068:        server->refid = rpkt->refid;
                   1069:        NTOHL_FP(&rpkt->reftime, &server->reftime);
                   1070:        NTOHL_FP(&rpkt->rec, &rec);
                   1071:        NTOHL_FP(&rpkt->xmt, &server->org);
                   1072: 
                   1073:        /*
                   1074:         * count this guy as responding
                   1075:         */
                   1076:        server->reach |= 1;
                   1077:        if (server->rcvcnt++ == 0)
                   1078:                responding++;
                   1079: 
                   1080:        /*
                   1081:         * Make sure the server is at least somewhat sane.  If not, ignore
                   1082:         * it for later.
                   1083:         */
                   1084:        if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) {
                   1085:                if (debug > 1)
                   1086:                        printf("receive: pkt insane\n");
                   1087:                return;
                   1088:        }
                   1089: 
                   1090:        /*
                   1091:         * Calculate the round trip delay (di) and the clock offset (ci).
                   1092:         * We use the equations (reordered from those in the spec):
                   1093:         *
                   1094:         * d = (t2 - t3) - (t1 - t0)
                   1095:         * c = ((t2 - t3) + (t1 - t0)) / 2
                   1096:         */
                   1097:        t10 = server->org;              /* pkt.xmt == t1 */
                   1098:        L_SUB(&t10, &rbufp->recv_time); /* recv_time == t0*/
                   1099: 
                   1100:        t23 = rec;                      /* pkt.rec == t2 */
                   1101:        L_SUB(&t23, &org);              /* pkt->org == t3 */
                   1102: 
                   1103:        /* now have (t2 - t3) and (t0 - t1).  Calculate (ci) and (di) */
                   1104:        ci = t10;
                   1105:        L_ADD(&ci, &t23);
                   1106:        L_RSHIFT(&ci);
                   1107: 
                   1108:        /*
                   1109:         * Calculate di in t23 in full precision, then truncate
                   1110:         * to an s_fp.
                   1111:         */
                   1112:        L_SUB(&t23, &t10);
                   1113:        di = LFPTOFP(&t23);
                   1114: 
                   1115:        if (debug > 3)
                   1116:                printf("offset: %s, delay %s\n", lfptoa(&ci, 6), fptoa(di, 5));
                   1117: 
                   1118:        di += (FP_SECOND >> (-(int)NTPDATE_PRECISION))
                   1119:            + (FP_SECOND >> (-(int)server->precision)) + NTP_MAXSKW;
                   1120: 
                   1121:        if (di <= 0) {          /* value still too raunchy to use? */
                   1122:                L_CLR(&ci);
                   1123:                di = 0;
                   1124:        } else {
                   1125:                di = max(di, NTP_MINDIST);
                   1126:        }
                   1127: 
                   1128: 
                   1129:        /*
                   1130:         * This one is valid.  Give it to clock_filter(),
                   1131:         */
                   1132:        clock_filter(server, di, &ci);
                   1133:        if (debug > 1)
                   1134:                printf("receive from %s\n", ntoa(&rbufp->srcadr));
                   1135: 
                   1136:        /*
                   1137:         * See if we should goes the transmission. If not return now
                   1138:         * otherwise have the next event time be shortened
                   1139:         */
                   1140:        if (server->stratum <= NTP_INFIN)
                   1141:            return;     /* server does not have a stratum */
                   1142:        if (server->leap == LEAP_NOTINSYNC)
                   1143:            return;     /* just booted server or out of sync */
                   1144:        if (!L_ISHIS(&server->org, &server->reftime))
                   1145:            return;     /* broken host */
                   1146:        if (server->trust != 0)
                   1147:            return;     /* can not trust it */
                   1148: 
                   1149:        if (server->dispersion < DESIREDDISP)
                   1150:            return;     /* we have the desired dispersion */
                   1151: 
                   1152:        server->event_time -= (TIMER_HZ+1);
                   1153: }
                   1154: 
                   1155: 
                   1156: /*
                   1157:  * clock_filter - add clock sample, determine a server's delay, dispersion
                   1158:  *                and offset
                   1159:  */
                   1160: static void
                   1161: clock_filter(
                   1162:        register struct server *server,
                   1163:        s_fp di,
                   1164:        l_fp *c
                   1165:        )
                   1166: {
                   1167:        register int i, j;
                   1168:        int ord[NTP_SHIFT];
                   1169: 
                   1170:        /*
                   1171:         * Insert sample and increment nextpt
                   1172:         */
                   1173: 
                   1174:        i = server->filter_nextpt;
                   1175:        server->filter_delay[i] = di;
                   1176:        server->filter_offset[i] = *c;
                   1177:        server->filter_soffset[i] = LFPTOFP(c);
                   1178:        server->filter_nextpt++;
                   1179:        if (server->filter_nextpt >= NTP_SHIFT)
                   1180:                server->filter_nextpt = 0;
                   1181: 
                   1182:        /*
                   1183:         * Sort indices into increasing delay order
                   1184:         */
                   1185:        for (i = 0; i < NTP_SHIFT; i++)
                   1186:                ord[i] = i;
                   1187:        
                   1188:        for (i = 0; i < (NTP_SHIFT-1); i++) {
                   1189:                for (j = i+1; j < NTP_SHIFT; j++) {
                   1190:                        if (server->filter_delay[ord[j]] == 0)
                   1191:                                continue;
                   1192:                        if (server->filter_delay[ord[i]] == 0
                   1193:                            || (server->filter_delay[ord[i]]
                   1194:                            > server->filter_delay[ord[j]])) {
                   1195:                                register int tmp;
                   1196: 
                   1197:                                tmp = ord[i];
                   1198:                                ord[i] = ord[j];
                   1199:                                ord[j] = tmp;
                   1200:                        }
                   1201:                }
                   1202:        }
                   1203: 
                   1204:        /*
                   1205:         * Now compute the dispersion, and assign values to delay and
                   1206:         * offset.  If there are no samples in the register, delay and
                   1207:         * offset go to zero and dispersion is set to the maximum.
                   1208:         */
                   1209:        if (server->filter_delay[ord[0]] == 0) {
                   1210:                server->delay = 0;
                   1211:                L_CLR(&server->offset);
                   1212:                server->soffset = 0;
                   1213:                server->dispersion = PEER_MAXDISP;
                   1214:        } else {
                   1215:                register s_fp d;
                   1216: 
                   1217:                server->delay = server->filter_delay[ord[0]];
                   1218:                server->offset = server->filter_offset[ord[0]];
                   1219:                server->soffset = LFPTOFP(&server->offset);
                   1220:                server->dispersion = 0;
                   1221:                for (i = 1; i < NTP_SHIFT; i++) {
                   1222:                        if (server->filter_delay[ord[i]] == 0)
                   1223:                                d = PEER_MAXDISP;
                   1224:                        else {
                   1225:                                d = server->filter_soffset[ord[i]]
                   1226:                                    - server->filter_soffset[ord[0]];
                   1227:                                if (d < 0)
                   1228:                                        d = -d;
                   1229:                                if (d > PEER_MAXDISP)
                   1230:                                        d = PEER_MAXDISP;
                   1231:                        }
                   1232:                        /*
                   1233:                         * XXX This *knows* PEER_FILTER is 1/2
                   1234:                         */
                   1235:                        server->dispersion += (u_fp)(d) >> i;
                   1236:                }
                   1237:        }
                   1238:        /*
                   1239:         * We're done
                   1240:         */
                   1241: }
                   1242: 
                   1243: 
                   1244: /* clock_count - count the clock sources we have
                   1245:  */
                   1246: static void
                   1247: clock_count(void)
                   1248: {
                   1249:        register struct server *server;
                   1250:        register int n;
                   1251: 
                   1252:        /* reset counts */
                   1253:        validcount = valid_n_low = 0;
                   1254: 
                   1255:        /* go through the list of servers and count the clocks we believe
                   1256:         * and that have low dispersion
                   1257:         */
                   1258:        for (n = 0; n < sys_numservers; n++) {
                   1259:                server = sys_servers[n];
                   1260:                if (server->delay == 0) {
                   1261:                        continue;       /* no data */
                   1262:                }
                   1263:                if (server->stratum > NTP_INFIN) {
                   1264:                        continue;       /* stratum no good */
                   1265:                }
                   1266:                if (server->delay > NTP_MAXWGT) {
                   1267:                        continue;       /* too far away */
                   1268:                }
                   1269:                if (server->leap == LEAP_NOTINSYNC)
                   1270:                        continue;       /* he's in trouble */
                   1271:                if (!L_ISHIS(&server->org, &server->reftime)) {
                   1272:                        continue;       /* very broken host */
                   1273:                }
                   1274:                if ((server->org.l_ui - server->reftime.l_ui) >= NTP_MAXAGE) {
                   1275:                        continue;       /* too long without sync */
                   1276:                }
                   1277:                if (server->trust != 0) {
                   1278:                        continue;
                   1279:                }
                   1280: 
                   1281:                /*
                   1282:                 * This one is a valid time source..
                   1283:                 */
                   1284:                validcount++;
                   1285: 
                   1286:                /*
                   1287:                 * See if this one has a okay low dispersion
                   1288:                 */
                   1289:                if (server->dispersion <= DESIREDDISP)
                   1290:                    valid_n_low++;
                   1291:        }
                   1292: 
                   1293:        if (debug > 1)
                   1294:                printf("have %d, valid %d, low %d\n",
                   1295:                        responding, validcount, valid_n_low);
                   1296: }
                   1297: 
                   1298: 
                   1299: /*
                   1300:  * clock_select - select the pick-of-the-litter clock from the samples
                   1301:  *               we've got.
                   1302:  */
                   1303: static struct server *
                   1304: clock_select(void)
                   1305: {
                   1306:        register struct server *server;
                   1307:        register int i;
                   1308:        register int nlist;
                   1309:        register s_fp d;
                   1310:        register int j;
                   1311:        register int n;
                   1312:        s_fp local_threshold;
                   1313:        struct server *server_list[NTP_MAXCLOCK];
                   1314:        u_fp server_badness[NTP_MAXCLOCK];
                   1315:        struct server *sys_server;
                   1316: 
                   1317:        /*
                   1318:         * This first chunk of code is supposed to go through all
                   1319:         * servers we know about to find the NTP_MAXLIST servers which
                   1320:         * are most likely to succeed.  We run through the list
                   1321:         * doing the sanity checks and trying to insert anyone who
                   1322:         * looks okay.  We are at all times aware that we should
                   1323:         * only keep samples from the top two strata and we only need
                   1324:         * NTP_MAXLIST of them.
                   1325:         */
                   1326:        nlist = 0;      /* none yet */
                   1327:        for (n = 0; n < sys_numservers; n++) {
                   1328:                server = sys_servers[n];
                   1329:                if (server->delay == 0)
                   1330:                        continue;       /* no data */
                   1331:                if (server->stratum > NTP_INFIN)
                   1332:                        continue;       /* stratum no good */
                   1333:                if (server->delay > NTP_MAXWGT) {
                   1334:                        continue;       /* too far away */
                   1335:                }
                   1336:                if (server->leap == LEAP_NOTINSYNC)
                   1337:                        continue;       /* he's in trouble */
                   1338:                if (!L_ISHIS(&server->org, &server->reftime)) {
                   1339:                        continue;       /* very broken host */
                   1340:                }
                   1341:                if ((server->org.l_ui - server->reftime.l_ui)
                   1342:                    >= NTP_MAXAGE) {
                   1343:                        continue;       /* too long without sync */
                   1344:                }
                   1345:                if (server->trust != 0) {
                   1346:                        continue;
                   1347:                }
                   1348: 
                   1349:                /*
                   1350:                 * This one seems sane.  Find where he belongs
                   1351:                 * on the list.
                   1352:                 */
                   1353:                d = server->dispersion + server->dispersion;
                   1354:                for (i = 0; i < nlist; i++)
                   1355:                        if (server->stratum <= server_list[i]->stratum)
                   1356:                                break;
                   1357:                for ( ; i < nlist; i++) {
                   1358:                        if (server->stratum < server_list[i]->stratum)
                   1359:                                break;
                   1360:                        if (d < (s_fp) server_badness[i])
                   1361:                                break;
                   1362:                }
                   1363: 
                   1364:                /*
                   1365:                 * If i points past the end of the list, this
                   1366:                 * guy is a loser, else stick him in.
                   1367:                 */
                   1368:                if (i >= NTP_MAXLIST)
                   1369:                        continue;
                   1370:                for (j = nlist; j > i; j--)
                   1371:                        if (j < NTP_MAXLIST) {
                   1372:                                server_list[j] = server_list[j-1];
                   1373:                                server_badness[j]
                   1374:                                    = server_badness[j-1];
                   1375:                        }
                   1376: 
                   1377:                server_list[i] = server;
                   1378:                server_badness[i] = d;
                   1379:                if (nlist < NTP_MAXLIST)
                   1380:                        nlist++;
                   1381:        }
                   1382: 
                   1383:        /*
                   1384:         * Got the five-or-less best.  Cut the list where the number of
                   1385:         * strata exceeds two.
                   1386:         */
                   1387:        j = 0;
                   1388:        for (i = 1; i < nlist; i++)
                   1389:                if (server_list[i]->stratum > server_list[i-1]->stratum)
                   1390:                        if (++j == 2) {
                   1391:                                nlist = i;
                   1392:                                break;
                   1393:                        }
                   1394: 
                   1395:        /*
                   1396:         * Whew!  What we should have by now is 0 to 5 candidates for
                   1397:         * the job of syncing us.  If we have none, we're out of luck.
                   1398:         * If we have one, he's a winner.  If we have more, do falseticker
                   1399:         * detection.
                   1400:         */
                   1401: 
                   1402:        if (nlist == 0)
                   1403:                sys_server = 0;
                   1404:        else if (nlist == 1) {
                   1405:                sys_server = server_list[0];
                   1406:        } else {
                   1407:                /*
                   1408:                 * Re-sort by stratum, bdelay estimate quality and
                   1409:                 * server.delay.
                   1410:                 */
                   1411:                for (i = 0; i < nlist-1; i++)
                   1412:                        for (j = i+1; j < nlist; j++) {
                   1413:                                if (server_list[i]->stratum
                   1414:                                    < server_list[j]->stratum)
                   1415:                                        break;  /* already sorted by stratum */
                   1416:                                if (server_list[i]->delay
                   1417:                                    < server_list[j]->delay)
                   1418:                                        continue;
                   1419:                                server = server_list[i];
                   1420:                                server_list[i] = server_list[j];
                   1421:                                server_list[j] = server;
                   1422:                        }
                   1423:                
                   1424:                /*
                   1425:                 * Calculate the fixed part of the dispersion limit
                   1426:                 */
                   1427:                local_threshold = (FP_SECOND >> (-(int)NTPDATE_PRECISION))
                   1428:                    + NTP_MAXSKW;
                   1429: 
                   1430:                /*
                   1431:                 * Now drop samples until we're down to one.
                   1432:                 */
                   1433:                while (nlist > 1) {
                   1434:                        for (n = 0; n < nlist; n++) {
                   1435:                                server_badness[n] = 0;
                   1436:                                for (j = 0; j < nlist; j++) {
                   1437:                                        if (j == n)     /* with self? */
                   1438:                                                continue;
                   1439:                                        d = server_list[j]->soffset
                   1440:                                            - server_list[n]->soffset;
                   1441:                                        if (d < 0)      /* absolute value */
                   1442:                                                d = -d;
                   1443:                                        /*
                   1444:                                         * XXX This code *knows* that
                   1445:                                         * NTP_SELECT is 3/4
                   1446:                                         */
                   1447:                                        for (i = 0; i < j; i++)
                   1448:                                                d = (d>>1) + (d>>2);
                   1449:                                        server_badness[n] += d;
                   1450:                                }
                   1451:                        }
                   1452: 
                   1453:                        /*
                   1454:                         * We now have an array of nlist badness
                   1455:                         * coefficients.  Find the badest.  Find
                   1456:                         * the minimum precision while we're at
                   1457:                         * it.
                   1458:                         */
                   1459:                        i = 0;
                   1460:                        n = server_list[0]->precision;;
                   1461:                        for (j = 1; j < nlist; j++) {
                   1462:                                if (server_badness[j] >= server_badness[i])
                   1463:                                        i = j;
                   1464:                                if (n > server_list[j]->precision)
                   1465:                                        n = server_list[j]->precision;
                   1466:                        }
                   1467:                        
                   1468:                        /*
                   1469:                         * i is the index of the server with the worst
                   1470:                         * dispersion.  If his dispersion is less than
                   1471:                         * the threshold, stop now, else delete him and
                   1472:                         * continue around again.
                   1473:                         */
                   1474:                        if (server_badness[i] < (local_threshold
                   1475:                                                 + (FP_SECOND >> (-n))))
                   1476:                                break;
                   1477:                        for (j = i + 1; j < nlist; j++)
                   1478:                                server_list[j-1] = server_list[j];
                   1479:                        nlist--;
                   1480:                }
                   1481: 
                   1482:                /*
                   1483:                 * What remains is a list of less than 5 servers.  Take
                   1484:                 * the best.
                   1485:                 */
                   1486:                sys_server = server_list[0];
                   1487:        }
                   1488: 
                   1489:        /*
                   1490:         * That's it.  Return our server.
                   1491:         */
                   1492:        return sys_server;
                   1493: }
                   1494: 
                   1495: 
                   1496: /*
                   1497:  * set_local_clock -- handle setting the local clock or displaying info.
                   1498:  */
                   1499: static void
                   1500: set_local_clock(void)
                   1501: {
                   1502:        register int i;
                   1503:        register struct server *server;
                   1504:        time_t tmp;
                   1505:        double dtemp;
                   1506: 
                   1507:        /*
                   1508:         * if setting time then print final analysis
                   1509:         */
                   1510:        if (set_time)
                   1511:            analysis(1);
                   1512: 
                   1513:        /*
                   1514:         * pick a clock
                   1515:         */
                   1516:        server = clock_select();
                   1517: 
                   1518:        /*
                   1519:         * do some display of information
                   1520:         */
                   1521:        if (debug || verbose) {
                   1522:                for (i = 0; i < sys_numservers; i++)
                   1523:                        printserver(sys_servers[i], stdout);
                   1524:                if (debug)
                   1525:                        printf("packets sent %ld, received %ld\n",
                   1526:                                total_xmit, total_recv);
                   1527:        }
                   1528: 
                   1529:        /*
                   1530:         * see if we have a server to set the time with
                   1531:         */
                   1532:        if (server == 0) {
                   1533:            if (!set_time || verbose)
                   1534:                fprintf(stdout,"No servers available to sync time with\n");
                   1535:            exit(1);
                   1536:        }
                   1537: 
                   1538:        /*
                   1539:         * we have a valid and selected time to use!!!!!
                   1540:         */
                   1541: 
                   1542:        /*
                   1543:         * if we are not setting the time then display offset and exit
                   1544:         */
                   1545:        if (!set_time) {
                   1546:                fprintf(stdout,
                   1547:                        "Your clock is off by %s seconds. (%s) [%ld/%ld]\n",
                   1548:                        lfptoa(&server->offset, 7),
                   1549:                        ntoa(&server->srcadr),
                   1550:                        total_xmit, total_recv);
                   1551:                exit(0);
                   1552:        }
                   1553: 
                   1554:        /*
                   1555:         * set the clock
                   1556:         * XXX: Examine the more flexible approach used by ntpdate.
                   1557:         * Note that a design consideration here is that we sometimes
                   1558:         * _want_ to step the clock by a _huge_ amount in either
                   1559:         * direction, because the local clock is completely bogus.
                   1560:         * This condition must be recognized and dealt with, so
                   1561:         * that we always get a good time when this completes.
                   1562:         * -- jhutz+@cmu.edu, 16-Aug-1999
                   1563:         */
                   1564:        LFPTOD(&server->offset, dtemp);
                   1565:        step_systime(dtemp);
                   1566:        time(&tmp);
                   1567:        fprintf(stdout,"Time set to %.20s [%s %s %ld/%ld]\n",
                   1568:                ctime(&tmp)+4,
                   1569:                ntoa(&server->srcadr),
                   1570:                lfptoa(&server->offset, 7),
                   1571:                total_xmit, total_recv);
                   1572:        exit(0);
                   1573: }
                   1574: 
                   1575: 
                   1576: /*
                   1577:  * findserver - find a server in the list given its address
                   1578:  */
                   1579: static struct server *
                   1580: findserver(
                   1581:        struct sockaddr_in *addr
                   1582:        )
                   1583: {
                   1584:        register int i;
                   1585:        register u_int32 netnum;
                   1586: 
                   1587:        if (htons(addr->sin_port) != NTP_PORT)
                   1588:                return 0;
                   1589:        netnum = addr->sin_addr.s_addr;
                   1590: 
                   1591:        for (i = 0; i < sys_numservers; i++) {
                   1592:                if (netnum == sys_servers[i]->srcadr.sin_addr.s_addr)
                   1593:                        return sys_servers[i];
                   1594:        }
                   1595:        return 0;
                   1596: }
                   1597: 
                   1598: 
                   1599: /*
                   1600:  * timer - process a timer interrupt
                   1601:  */
                   1602: static void
                   1603: timer(void)
                   1604: {
                   1605:        register int k;
                   1606: 
                   1607:        /*
                   1608:         * Bump the current idea of the time
                   1609:         */
                   1610:        current_time++;
                   1611: 
                   1612:        /*
                   1613:         * see if we have reached half time
                   1614:         */
                   1615:        if (current_time >= half_time && !secondhalf) {
                   1616:            secondhalf++;
                   1617:            if (debug)
                   1618:                printf("\nSecond Half of Timeout!\n");
                   1619:            printmsg++;
                   1620:        }
                   1621: 
                   1622:        /*
                   1623:         * We only want to send a few packets per transmit interrupt
                   1624:         * to throttle things
                   1625:         */
                   1626:        for(k = 0;k < MAXXMITCOUNT;k++) {
                   1627:            register int i, oldi;
                   1628:            register u_long oldxtime;
                   1629: 
                   1630:            /*
                   1631:             * We want to send a packet out for a server that has an
                   1632:             * expired event time. However to be mellow about this, we only
                   1633:             * use one expired event timer and to avoid starvation we use
                   1634:             * the one with the oldest last transmit time.
                   1635:             */
                   1636:            oldi = -1;
                   1637:            oldxtime = 0;
                   1638:            for (i = 0; i < sys_numservers; i++) {
                   1639:                if (sys_servers[i]->event_time <= current_time) {
                   1640:                    if (oldi < 0 || oldxtime > sys_servers[i]->last_xmit) {
                   1641:                        oldxtime = sys_servers[i]->last_xmit;
                   1642:                        oldi = i;
                   1643:                    }
                   1644:                }
                   1645:            }
                   1646:            if (oldi >= 0)
                   1647:                transmit(sys_servers[oldi]);
                   1648:            else
                   1649:                break;  /* no expired event */
                   1650:        } /* end of transmit loop */
                   1651: }
                   1652: 
                   1653: 
                   1654: #ifndef SYS_WINNT
                   1655: /*
                   1656:  * alarming - record the occurance of an alarm interrupt
                   1657:  */
                   1658: static RETSIGTYPE
                   1659: alarming(
                   1660:        int sig
                   1661:        )
                   1662: #else
                   1663: void CALLBACK 
                   1664: alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
                   1665: #endif /* SYS_WINNT */
                   1666: {
                   1667:        alarm_flag++;
                   1668: }
                   1669: 
                   1670: 
                   1671: /*
                   1672:  * init_alarm - set up the timer interrupt
                   1673:  */
                   1674: static void
                   1675: init_alarm(void)
                   1676: {
                   1677: #ifndef SYS_WINNT
                   1678: # ifndef HAVE_TIMER_SETTIME
                   1679:        struct itimerval itimer;
                   1680: # else
                   1681:        struct itimerspec ntpdate_itimer;
                   1682: # endif
                   1683: #else
                   1684:        TIMECAPS tc;
                   1685:        UINT wTimerRes, wTimerID;
                   1686: # endif /* SYS_WINNT */
                   1687: #if defined SYS_CYGWIN32 || defined SYS_WINNT
                   1688:        HANDLE hToken;
                   1689:        TOKEN_PRIVILEGES tkp;
                   1690:        DWORD dwUser = 0;
                   1691: #endif /* SYS_WINNT */
                   1692: 
                   1693:        alarm_flag = 0;
                   1694: 
                   1695: #ifndef SYS_WINNT
                   1696: # if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME)
                   1697:        alarm_flag = 0;
                   1698:        /* this code was put in as setitimer() is non existant this us the
                   1699:         * POSIX "equivalents" setup - casey
                   1700:         */
                   1701:        /* ntpdate_timerid is global - so we can kill timer later */
                   1702:        if (timer_create (CLOCK_REALTIME, NULL, &ntpdate_timerid) ==
                   1703: #  ifdef SYS_VXWORKS
                   1704:                ERROR
                   1705: #  else
                   1706:                -1
                   1707: #  endif
                   1708:                )
                   1709:        {
                   1710:                fprintf (stderr, "init_alarm(): timer_create (...) FAILED\n");
                   1711:                return;
                   1712:        }
                   1713: 
                   1714:        /*      TIMER_HZ = (5)
                   1715:         * Set up the alarm interrupt.  The first comes 1/(2*TIMER_HZ)
                   1716:         * seconds from now and they continue on every 1/TIMER_HZ seconds.
                   1717:         */
                   1718:        (void) signal_no_reset(SIGALRM, alarming);
                   1719:        ntpdate_itimer.it_interval.tv_sec = ntpdate_itimer.it_value.tv_sec = 0;
                   1720:        ntpdate_itimer.it_interval.tv_nsec = 1000000000/TIMER_HZ;
                   1721:        ntpdate_itimer.it_value.tv_nsec = 1000000000/(TIMER_HZ<<1);
                   1722:        timer_settime(ntpdate_timerid, 0 /* !TIMER_ABSTIME */, &ntpdate_itimer, NULL);
                   1723: # else
                   1724:        /*
                   1725:         * Set up the alarm interrupt.  The first comes 1/(2*TIMER_HZ)
                   1726:         * seconds from now and they continue on every 1/TIMER_HZ seconds.
                   1727:         */
                   1728:        (void) signal_no_reset(SIGALRM, alarming);
                   1729:        itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0;
                   1730:        itimer.it_interval.tv_usec = 1000000/TIMER_HZ;
                   1731:        itimer.it_value.tv_usec = 1000000/(TIMER_HZ<<1);
                   1732:        setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
                   1733: # endif
                   1734: #if defined SYS_CYGWIN32
                   1735:        /*
                   1736:         * Get previleges needed for fiddling with the clock
                   1737:         */
                   1738: 
                   1739:        /* get the current process token handle */
                   1740:        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
                   1741:                msyslog(LOG_ERR, "OpenProcessToken failed: %m");
                   1742:                exit(1);
                   1743:        }
                   1744:        /* get the LUID for system-time privilege. */
                   1745:        LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
                   1746:        tkp.PrivilegeCount = 1;  /* one privilege to set */
                   1747:        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                   1748:        /* get set-time privilege for this process. */
                   1749:        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);
                   1750:        /* cannot test return value of AdjustTokenPrivileges. */
                   1751:        if (GetLastError() != ERROR_SUCCESS)
                   1752:                msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
                   1753: #endif
                   1754: #else  /* SYS_WINNT */
                   1755:        _tzset();
                   1756: 
                   1757:        /*
                   1758:         * Get previleges needed for fiddling with the clock
                   1759:         */
                   1760: 
                   1761:        /* get the current process token handle */
                   1762:        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
                   1763:                msyslog(LOG_ERR, "OpenProcessToken failed: %m");
                   1764:                exit(1);
                   1765:        }
                   1766:        /* get the LUID for system-time privilege. */
                   1767:        LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
                   1768:        tkp.PrivilegeCount = 1;  /* one privilege to set */
                   1769:        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                   1770:        /* get set-time privilege for this process. */
                   1771:        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);
                   1772:        /* cannot test return value of AdjustTokenPrivileges. */
                   1773:        if (GetLastError() != ERROR_SUCCESS)
                   1774:                msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
                   1775: 
                   1776:        /*
                   1777:         * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds
                   1778:         * Under Win/NT, expiry of timer interval leads to invocation
                   1779:         * of a callback function (on a different thread) rather than
                   1780:         * generating an alarm signal
                   1781:         */
                   1782: 
                   1783:        /* determine max and min resolution supported */
                   1784:        if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
                   1785:                msyslog(LOG_ERR, "timeGetDevCaps failed: %m");
                   1786:                exit(1);
                   1787:        }
                   1788:        wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
                   1789:        /* establish the minimum timer resolution that we'll use */
                   1790:        timeBeginPeriod(wTimerRes);
                   1791: 
                   1792:        /* start the timer event */
                   1793:        wTimerID = timeSetEvent(
                   1794:                (UINT) (1000/TIMER_HZ),    /* Delay */
                   1795:                wTimerRes,                       /* Resolution */
                   1796:                (LPTIMECALLBACK) alarming, /* Callback function */
                   1797:                (DWORD) dwUser,          /* User data */
                   1798:                TIME_PERIODIC);          /* Event type (periodic) */
                   1799:        if (wTimerID == 0) {
                   1800:                msyslog(LOG_ERR, "timeSetEvent failed: %m");
                   1801:                exit(1);
                   1802:        }
                   1803: #endif /* SYS_WINNT */
                   1804: }
                   1805: 
                   1806: 
                   1807: /*
                   1808:  * init_io - initialize I/O data and open socket
                   1809:  */
                   1810: static void
                   1811: init_io(void)
                   1812: {
                   1813: #ifdef SYS_WINNT
                   1814:        WORD wVersionRequested;
                   1815:        WSADATA wsaData;
                   1816:        init_transmitbuff();
                   1817: #endif /* SYS_WINNT */
                   1818: 
                   1819:        /*
                   1820:         * Init buffer free list and stat counters
                   1821:         */
                   1822:        init_recvbuff(sys_numservers + 2);
                   1823: 
                   1824: #if defined(HAVE_SIGNALED_IO)
                   1825:        set_signal();
                   1826: #endif
                   1827: 
                   1828: #ifdef SYS_WINNT
                   1829:        wVersionRequested = MAKEWORD(1,1);
                   1830:        if (WSAStartup(wVersionRequested, &wsaData))
                   1831:        {
                   1832:                msyslog(LOG_ERR, "No useable winsock.dll: %m");
                   1833:                exit(1);
                   1834:        }
                   1835: #endif /* SYS_WINNT */
                   1836: 
                   1837:        BLOCKIO();
                   1838: 
                   1839:        /* create a datagram (UDP) socket */
                   1840:        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                   1841:                msyslog(LOG_ERR, "socket() failed: %m");
                   1842:                exit(1);
                   1843:                /*NOTREACHED*/
                   1844:        }
                   1845: 
                   1846:        /*
                   1847:         * bind the socket to the NTP port
                   1848:         */
                   1849:        if (!debug && set_time && !unpriv_port) {
                   1850:                struct sockaddr_in addr;
                   1851: 
                   1852:                memset((char *)&addr, 0, sizeof addr);
                   1853:                addr.sin_family = AF_INET;
                   1854:                addr.sin_port = htons(NTP_PORT);
                   1855:                addr.sin_addr.s_addr = htonl(INADDR_ANY);
                   1856:                if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                   1857: #ifndef SYS_WINNT
                   1858:                        if (errno == EADDRINUSE)
                   1859: #else
                   1860:                        if (WSAGetLastError() == WSAEADDRINUSE)
                   1861: #endif
                   1862:                                msyslog(LOG_ERR,
                   1863:                                    "the NTP socket is in use, exiting");
                   1864:                        else
                   1865:                                msyslog(LOG_ERR, "bind() fails: %m");
                   1866:                        exit(1);
                   1867:                }
                   1868:        }
                   1869: 
                   1870:        FD_ZERO(&fdmask);
                   1871:        FD_SET(fd, &fdmask);
                   1872: 
                   1873:        /*
                   1874:         * set non-blocking,
                   1875:         */
                   1876: 
                   1877: #ifdef USE_FIONBIO
                   1878:        /* in vxWorks we use FIONBIO, but the others are defined for old systems, so
                   1879:         * all hell breaks loose if we leave them defined
                   1880:         */
                   1881: #undef O_NONBLOCK
                   1882: #undef FNDELAY
                   1883: #undef O_NDELAY
                   1884: #endif
                   1885: 
                   1886: #if defined(O_NONBLOCK) /* POSIX */
                   1887:        if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
                   1888:        {
                   1889:                msyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails: %m");
                   1890:                exit(1);
                   1891:                /*NOTREACHED*/
                   1892:        }
                   1893: #elif defined(FNDELAY)
                   1894:        if (fcntl(fd, F_SETFL, FNDELAY) < 0)
                   1895:        {
                   1896:                msyslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
                   1897:                exit(1);
                   1898:                /*NOTREACHED*/
                   1899:        }
                   1900: #elif defined(O_NDELAY) /* generally the same as FNDELAY */
                   1901:        if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
                   1902:        {
                   1903:                msyslog(LOG_ERR, "fcntl(O_NDELAY) fails: %m");
                   1904:                exit(1);
                   1905:                /*NOTREACHED*/
                   1906:        }
                   1907: #elif defined(FIONBIO)
                   1908:        if (
                   1909: # if defined(VMS)
                   1910:                (ioctl(fd,FIONBIO,&1) < 0)
                   1911: # elif defined(SYS_WINNT)
                   1912:                (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
                   1913: # else
                   1914:                (ioctl(fd,FIONBIO,&on) < 0)
                   1915: # endif
                   1916:           )
                   1917:        {
                   1918:                msyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m");
                   1919:                exit(1);
                   1920:                /*NOTREACHED*/
                   1921:        }
                   1922: #elif defined(FIOSNBIO)
                   1923:        if (ioctl(fd,FIOSNBIO,&on) < 0)
                   1924:        {
                   1925:                msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails: %m");
                   1926:                exit(1);
                   1927:                /*NOTREACHED*/
                   1928:        }
                   1929: #else
                   1930: # include "Bletch: Need non-blocking I/O!"
                   1931: #endif
                   1932: 
                   1933: #ifdef HAVE_SIGNALED_IO
                   1934:        init_socket_sig(fd);
                   1935: #endif /* not HAVE_SIGNALED_IO */
                   1936: 
                   1937:        UNBLOCKIO();
                   1938: }
                   1939: 
                   1940: 
                   1941: /*
                   1942:  * sendpkt - send a packet to the specified destination
                   1943:  */
                   1944: static int
                   1945: sendpkt(
                   1946:        struct sockaddr_in *dest,
                   1947:        struct pkt *pkt,
                   1948:        int len
                   1949:        )
                   1950: {
                   1951:        int cc;
                   1952:        static int horriblecnt = 0;
                   1953: #ifdef SYS_WINNT
                   1954:        DWORD err;
                   1955: #endif /* SYS_WINNT */
                   1956: 
                   1957:        total_xmit++;   /* count it */
                   1958: 
                   1959:        if (horrible) {
                   1960:            if (++horriblecnt > HORRIBLEOK) {
                   1961:                if (debug > 3)
                   1962:                        printf("dropping send (%s)\n", ntoa(dest));
                   1963:                if (horriblecnt >= HORRIBLEOK+horrible)
                   1964:                    horriblecnt = 0;
                   1965:                return 0;
                   1966:            }
                   1967:        }
                   1968: 
                   1969: 
                   1970:        cc = sendto(fd, (char *)pkt, (size_t)len, 0, (struct sockaddr *)dest,
                   1971:            sizeof(struct sockaddr_in));
                   1972: #ifndef SYS_WINNT
                   1973:        if (cc == -1) {
                   1974:                if (errno != EWOULDBLOCK && errno != ENOBUFS)
                   1975: #else
                   1976:        if (cc == SOCKET_ERROR) {
                   1977:                err = WSAGetLastError();
                   1978:                if (err != WSAEWOULDBLOCK && err != WSAENOBUFS)
                   1979: #endif /* SYS_WINNT */
                   1980:                        msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest));
                   1981:                return -1;
                   1982:        }
                   1983:        return 0;
                   1984: }
                   1985: 
                   1986: 
                   1987: /*
                   1988:  * input_handler - receive packets asynchronously
                   1989:  */
                   1990: void
                   1991: input_handler(l_fp *xts)
                   1992: {
                   1993:        register int n;
                   1994:        register struct recvbuf *rb;
                   1995:        struct timeval tvzero;
                   1996:        int fromlen;
                   1997:        fd_set fds;
                   1998:        l_fp ts;
                   1999:        ts = *xts; /* we ignore xts, but make the compiler happy */
                   2000: 
                   2001:        /*
                   2002:         * Do a poll to see if we have data
                   2003:         */
                   2004:        for (;;) {
                   2005:                fds = fdmask;
                   2006:                tvzero.tv_sec = tvzero.tv_usec = 0;
                   2007:                n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);
                   2008: 
                   2009:                /*
                   2010:                 * If nothing to do, just return.  If an error occurred,
                   2011:                 * complain and return.  If we've got some, freeze a
                   2012:                 * timestamp.
                   2013:                 */
                   2014:                if (n == 0)
                   2015:                        return;
                   2016:                else if (n == -1) {
                   2017:                        if (errno != EINTR) {
                   2018:                                msyslog(LOG_ERR, "select() error: %m");
                   2019:                        }
                   2020:                        return;
                   2021:                }
                   2022:                get_systime(&ts);
                   2023: 
                   2024:                /*
                   2025:                 * Get a buffer and read the frame.  If we
                   2026:                 * haven't got a buffer, or this is received
                   2027:                 * on the wild card socket, just dump the packet.
                   2028:                 */
                   2029:                if (initializing || free_recvbuffs == 0) {
                   2030:                        char buf[100];
                   2031: 
                   2032: #ifndef SYS_WINNT
                   2033:                        (void) read(fd, buf, sizeof buf);
                   2034: #else
                   2035:                        /* NT's _read does not operate on nonblocking sockets
                   2036:                         * either recvfrom or ReadFile() has to be used here.
                   2037:                         * ReadFile is used in [ntpd]ntp_intres() and ntpdc,
                   2038:                         * just to be different use recvfrom() here
                   2039:                         */
                   2040:                        recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)0, NULL);
                   2041: #endif /* SYS_WINNT */
                   2042:                        continue;
                   2043:                }
                   2044: 
                   2045:                rb = get_free_recv_buffer();
                   2046: 
                   2047:                fromlen = sizeof(struct sockaddr_in);
                   2048:                rb->recv_length = recvfrom(fd, (char *)&rb->recv_pkt,
                   2049:                    sizeof(rb->recv_pkt), 0,
                   2050:                    (struct sockaddr *)&rb->srcadr, &fromlen);
                   2051:                if (rb->recv_length == -1) {
                   2052:                        freerecvbuf(rb);
                   2053:                        continue;
                   2054:                }
                   2055: 
                   2056:                /*
                   2057:                 * Got one.  Mark how and when it got here,
                   2058:                 * put it on the full list.
                   2059:                 */
                   2060:                rb->recv_time = ts;
                   2061:                add_full_recv_buffer(rb);
                   2062:                total_recv++;   /* count it */
                   2063:        }
                   2064: }
                   2065: 
                   2066: 
                   2067: /* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c */
                   2068: /*
                   2069:  * printserver - print detail information for a server
                   2070:  */
                   2071: static void
                   2072: printserver(
                   2073:        register struct server *pp,
                   2074:        FILE *fp
                   2075:        )
                   2076: {
                   2077:        register int i;
                   2078:        char junk[5];
                   2079:        char *str;
                   2080: 
                   2081:        if (!debug) {
                   2082:            (void) fprintf(fp,
                   2083:                "%-15s %d/%d %03o v%d s%d offset %9s delay %s disp %s\n",
                   2084:                ntoa(&pp->srcadr),
                   2085:                pp->xmtcnt,pp->rcvcnt,pp->reach,
                   2086:                pp->version,pp->stratum,
                   2087:                lfptoa(&pp->offset, 6), ufptoa(pp->delay, 5),
                   2088:                ufptoa(pp->dispersion, 4));
                   2089:            return;
                   2090:        }
                   2091: 
                   2092:        (void) fprintf(fp, "server %s, port %d\n",
                   2093:                           ntoa(&pp->srcadr), ntohs(pp->srcadr.sin_port));
                   2094: 
                   2095:        (void) fprintf(fp, "stratum %d, precision %d, leap %c%c, trust %03o\n",
                   2096:                           pp->stratum, pp->precision,
                   2097:                           pp->leap & 0x2 ? '1' : '0',
                   2098:                           pp->leap & 0x1 ? '1' : '0',
                   2099:                           pp->trust);
                   2100: 
                   2101:        if (pp->stratum == 1) {
                   2102:                junk[4] = 0;
                   2103:                memmove(junk, (char *)&pp->refid, 4);
                   2104:                str = junk;
                   2105:        } else {
                   2106:                str = numtoa(pp->refid);
                   2107:        }
                   2108:        (void) fprintf(fp,
                   2109:                           "refid [%s], delay %s, dispersion %s\n",
                   2110:                           str, fptoa((s_fp)pp->delay, 5),
                   2111:                           ufptoa(pp->dispersion, 5));
                   2112: 
                   2113:        (void) fprintf(fp, "transmitted %d, received %d, reachable %03o\n",
                   2114:            pp->xmtcnt, pp->rcvcnt, pp->reach);
                   2115: 
                   2116:        (void) fprintf(fp, "reference time:    %s\n",
                   2117:                           prettydate(&pp->reftime));
                   2118:        (void) fprintf(fp, "originate timestamp: %s\n",
                   2119:                           prettydate(&pp->org));
                   2120:        (void) fprintf(fp, "transmit timestamp:  %s\n",
                   2121:                           prettydate(&pp->xmt));
                   2122: 
                   2123:        (void) fprintf(fp, "filter delay: ");
                   2124:        for (i = 0; i < NTP_SHIFT; i++) {
                   2125:                (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5));
                   2126:                if (i == (NTP_SHIFT>>1)-1)
                   2127:                        (void) fprintf(fp, "\n        ");
                   2128:        }
                   2129:        (void) fprintf(fp, "\n");
                   2130: 
                   2131:        (void) fprintf(fp, "filter offset:");
                   2132:        for (i = 0; i < PEER_SHIFT; i++) {
                   2133:                (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6));
                   2134:                if (i == (PEER_SHIFT>>1)-1)
                   2135:                        (void) fprintf(fp, "\n        ");
                   2136:        }
                   2137:        (void) fprintf(fp, "\n");
                   2138: 
                   2139:        (void) fprintf(fp, "delay %s, dispersion %s\n",
                   2140:                           fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5));
                   2141: 
                   2142:        (void) fprintf(fp, "offset %s\n\n",
                   2143:                           lfptoa(&pp->offset, 6));
                   2144: }
                   2145: 
                   2146: #if !defined(HAVE_VSPRINTF)
                   2147: int
                   2148: vsprintf(
                   2149:        char *str,
                   2150:        const char *fmt,
                   2151:        va_list ap
                   2152:        )
                   2153: {
                   2154:        FILE f;
                   2155:        int len;
                   2156: 
                   2157:        f._flag = _IOWRT+_IOSTRG;
                   2158:        f._ptr = str;
                   2159:        f._cnt = 32767;
                   2160:        len = _doprnt(fmt, ap, &f);
                   2161:        *f._ptr = 0;
                   2162:        return (len);
                   2163: }
                   2164: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>