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