File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / ntpdate / ntpdate.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>