"Fossies" - the Fresh Open Source Software Archive 
Member "ntp-4.2.8p15/ntpdate/ntpdate.c" (23 Jun 2020, 51566 Bytes) of package /linux/misc/ntp-4.2.8p15.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "ntpdate.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
4.2.8p14_vs_4.2.8p15.
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 ... */
57 struct 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 */
63 struct sock_timeval timeout = {0,1000000/TIMER_HZ};
64 #else
65 struct 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")
78 isc_boolean_t ntp_port_inuse(int af, u_short port);
79 UINT 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 */
93 static 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 */
110 s_char sys_precision; /* local clock precision (log2 s) */
111
112 /*
113 * File descriptor masks etc. for call to select
114 */
115
116 int ai_fam_templ;
117 int nbsock; /* the number of sockets used */
118 SOCKET fd[MAX_AF];
119 int fd_family[MAX_AF]; /* to remember the socket family */
120 #ifdef HAVE_POLL_H
121 struct pollfd fdmask[MAX_AF];
122 #else
123 fd_set fdmask;
124 SOCKET maxfd;
125 #endif
126 int polltest = 0;
127
128 /*
129 * Initializing flag. All async routines watch this and only do their
130 * thing when it is clear.
131 */
132 int initializing = 1;
133
134 /*
135 * Alarm flag. Set when an alarm occurs
136 */
137 volatile int alarm_flag = 0;
138
139 /*
140 * Simple query flag.
141 */
142 int simple_query = 0;
143
144 /*
145 * Unprivileged port flag.
146 */
147 int unpriv_port = 0;
148
149 /*
150 * Program name.
151 */
152 char const *progname;
153
154 /*
155 * Systemwide parameters and flags
156 */
157 int sys_samples = 0; /* number of samples/server, will be modified later */
158 u_long sys_timeout = DEFTIMEOUT; /* timeout time, in TIMER_HZ units */
159 struct server *sys_servers; /* the server list */
160 int sys_numservers = 0; /* number of servers to poll */
161 int sys_authenticate = 0; /* true when authenticating */
162 u_int32 sys_authkey = 0; /* set to authentication key in use */
163 u_long sys_authdelay = 0; /* authentication delay */
164 int sys_version = NTP_VERSION; /* version to poll with */
165
166 /*
167 * The current internal time
168 */
169 u_long current_time = 0;
170
171 /*
172 * Counter for keeping track of completed servers
173 */
174 int 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
189 const char *key_file = KEYFILE;
190 #else
191 char key_file_storage[MAX_PATH+1], *key_file ;
192 #endif /* SYS_WINNT */
193
194 /*
195 * Miscellaneous flags
196 */
197 int verbose = 0;
198 int always_step = 0;
199 int never_step = 0;
200
201 int ntpdatemain (int, char **);
202
203 static void transmit (struct server *);
204 static void receive (struct recvbuf *);
205 static void server_data (struct server *, s_fp, l_fp *, u_fp);
206 static void clock_filter (struct server *);
207 static struct server *clock_select (void);
208 static int clock_adjust (void);
209 static void addserver (char *);
210 static struct server *findserver (sockaddr_u *);
211 void timer (void);
212 static void init_alarm (void);
213 #ifndef SYS_WINNT
214 static RETSIGTYPE alarming (int);
215 #endif /* SYS_WINNT */
216 static void init_io (void);
217 static void sendpkt (sockaddr_u *, struct pkt *, int);
218 void input_handler (void);
219
220 static int l_adj_systime (l_fp *);
221 static int l_step_systime (l_fp *);
222
223 static void print_server (struct server *, FILE *);
224
225 #ifdef SYS_WINNT
226 int on = 1;
227 WORD wVersionRequested;
228 WSADATA wsaData;
229 #endif /* SYS_WINNT */
230
231 #ifdef NO_MAIN_ALLOWED
232 CALL(ntpdate,"ntpdate",ntpdatemain);
233
234 void 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
288 static 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
296 int
297 main(
298 int argc,
299 char *argv[]
300 )
301 {
302 return ntpdatemain (argc, argv);
303 }
304 #endif /* NO_MAIN_ALLOWED */
305
306 int
307 ntpdatemain (
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 */
659 static void
660 transmit(
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 */
743 static void
744 receive(
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 */
938 static void
939 server_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 */
962 static void
963 clock_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 */
1038 static struct server *
1039 clock_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 */
1260 static int
1261 clock_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 */
1320 static int
1321 is_reachable (sockaddr_u *dst)
1322 {
1323 SOCKET sockfd;
1324
1325 sockfd = socket(AF(dst), SOCK_DGRAM, 0);
1326 if (sockfd == -1) {
1327 return 0;
1328 }
1329
1330 if (connect(sockfd, &dst->sa, SOCKLEN(dst))) {
1331 closesocket(sockfd);
1332 return 0;
1333 }
1334 closesocket(sockfd);
1335 return 1;
1336 }
1337
1338
1339
1340 /* XXX ELIMINATE: merge BIG slew into adj_systime in lib/systime.c */
1341 /*
1342 * addserver - determine a server's address and allocate a new structure
1343 * for it.
1344 */
1345 static void
1346 addserver(
1347 char *serv
1348 )
1349 {
1350 register struct server *server;
1351 /* Address infos structure to store result of getaddrinfo */
1352 struct addrinfo *addrResult, *ptr;
1353 /* Address infos structure to store hints for getaddrinfo */
1354 struct addrinfo hints;
1355 /* Error variable for getaddrinfo */
1356 int error;
1357 /* Service name */
1358 char service[5];
1359 sockaddr_u addr;
1360
1361 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 */
1435 static struct server *
1436 findserver(
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 */
1486 void
1487 timer(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 */
1519 static RETSIGTYPE
1520 alarming(
1521 int sig
1522 )
1523 {
1524 alarm_flag++;
1525 }
1526 #else /* SYS_WINNT follows */
1527 void CALLBACK
1528 alarming(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
1536 static void
1537 callTimeEndPeriod(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 */
1548 static void
1549 init_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 */
1684 static void
1685 init_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 */
1845 static void
1846 sendpkt(
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 */
1892 void
1893 input_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 */
2011 static int
2012 l_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 */
2082 static int
2083 l_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 */
2147 static void
2148 print_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
2231 static ni_namelist *
2232 getnetinfoservers(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
2262 isc_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