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