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