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