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