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