"Fossies" - the Fresh Open Source Software Archive

Member "ntp-4.2.8p15/ntpdate/ntpdate.c" (23 Jun 2020, 51566 Bytes) of package /linux/misc/ntp-4.2.8p15.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ntpdate.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.2.8p14_vs_4.2.8p15.

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