Ejemplo n.º 1
0
/*
 * setup peer dstadr field keeping it in sync with the interface structures
 */
void
set_peerdstadr(struct peer *peer, struct interface *interface)
{
	if (peer->dstadr != interface) {
		if (interface != NULL &&
		    (peer->cast_flags & MDF_BCLNT) &&
		    (interface->flags & INT_MCASTIF) &&
		    peer->burst) {
			/*
			 * don't accept updates to a true multicast reception
			 * interface while a BCLNT peer is running it's
			 * unicast protocol
			 */
			return;
		}

		if (peer->dstadr != NULL)
		{
			peer->dstadr->peercnt--;
			ISC_LIST_UNLINK_TYPE(peer->dstadr->peers, peer, ilink, struct peer);
		}

		DPRINTF(4, ("set_peerdstadr(%s): change interface from %s to %s\n",
			    stoa(&peer->srcadr),
			    (peer->dstadr != NULL) ? stoa(&peer->dstadr->sin) : "<null>",
			    (interface != NULL) ? stoa(&interface->sin) : "<null>"));

		peer->dstadr = interface;

		if (peer->dstadr != NULL)
		{
			ISC_LIST_APPEND(peer->dstadr->peers, peer, ilink);
			peer->dstadr->peercnt++;
		}
	}
Ejemplo n.º 2
0
/*
 * record_raw_stats - write raw timestamps to file
 *
 * file format
 * day (MJD)
 * time (s past midnight)
 * peer ip address
 * IP address
 * t1 t2 t3 t4 timestamps
 */
void
record_raw_stats(
	sockaddr_u *srcadr,
	sockaddr_u *dstadr,
	l_fp	*t1,		/* originate timestamp */
	l_fp	*t2,		/* receive timestamp */
	l_fp	*t3,		/* transmit timestamp */
	l_fp	*t4		/* destination timestamp */
	)
{
	l_fp	now;
	u_long	day;

	if (!stats_control)
		return;

	get_systime(&now);
	filegen_setup(&rawstats, now.l_ui);
	day = now.l_ui / 86400 + MJD_1900;
	now.l_ui %= 86400;
	if (rawstats.fp != NULL) {
		fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s\n", day,
		    ulfptoa(&now, 3), stoa(srcadr), dstadr ? 
		    stoa(dstadr) : "-",	ulfptoa(t1, 9), ulfptoa(t2, 9),
		    ulfptoa(t3, 9), ulfptoa(t4, 9));
		fflush(rawstats.fp);
	}
}
Ejemplo n.º 3
0
/*
 * doconfigure - attempt to resolve names and configure the server
 */
static void
doconfigure(
	int dores
	)
{
	register struct conf_entry *ce;

#ifdef DEBUG
		if (debug > 1)
			msyslog(LOG_INFO, "Running doconfigure %s DNS",
			    dores ? "with" : "without" );
#endif

#if defined(HAVE_RES_INIT) || defined(HAVE___RES_INIT)
	if (dores)	   /* Reload /etc/resolv.conf - bug 1226 */
		res_init();
#endif
	ce = confentries;
	while (ce != NULL) {
#ifdef DEBUG
		if (debug > 1)
			msyslog(LOG_INFO,
			    "doconfigure: <%s> has peeraddr %s",
			    ce->ce_name, stoa(&ce->peer_store));
#endif
		if (dores && SOCK_UNSPEC(&ce->peer_store)) {
			if (!findhostaddr(ce)) {
#ifndef IGNORE_DNS_ERRORS
				msyslog(LOG_ERR,
					"couldn't resolve `%s', giving up on it",
					ce->ce_name);
				ce = removeentry(ce);
				continue;
#endif
			} else if (!SOCK_UNSPEC(&ce->peer_store))
				msyslog(LOG_INFO,
					"DNS %s -> %s", ce->ce_name,
					stoa(&ce->peer_store));
		}

		if (!SOCK_UNSPEC(&ce->peer_store)) {
			if (request(&ce->ce_config)) {
				ce = removeentry(ce);
				continue;
			}
			/* 
			 * Failed case.  Should bump counter and give 
			 * up.
			 */
#ifdef DEBUG
			if (debug > 1) {
				msyslog(LOG_INFO,
				    "doconfigure: request() FAILED, maybe next time.");
			}
#endif
		}
		ce = ce->ce_next;
	}
}
Ejemplo n.º 4
0
/*
 * free_peer - internal routine to free memory referred to by a struct
 *	       peer and return it to the peer free list.  If unlink is
 *	       nonzero, unlink from the various lists.
 */
static void
free_peer(
	struct peer *	p,
	int		unlink_peer
	)
{
	struct peer *	unlinked;
	int		hash;

	if (unlink_peer) {
		hash = NTP_HASH_ADDR(&p->srcadr);
		peer_hash_count[hash]--;

		UNLINK_SLIST(unlinked, peer_hash[hash], p, adr_link,
			     struct peer);
		if (NULL == unlinked) {
			peer_hash_count[hash]++;
			msyslog(LOG_ERR, "peer %s not in address table!",
				stoa(&p->srcadr));
		}

		/*
		 * Remove him from the association hash as well.
		 */
		hash = p->associd & NTP_HASH_MASK;
		assoc_hash_count[hash]--;

		UNLINK_SLIST(unlinked, assoc_hash[hash], p, aid_link,
			     struct peer);
		if (NULL == unlinked) {
			assoc_hash_count[hash]++;
			msyslog(LOG_ERR,
				"peer %s not in association ID table!",
				stoa(&p->srcadr));
		}

		/* Remove him from the overall list. */
		UNLINK_SLIST(unlinked, peer_list, p, p_link,
			     struct peer);
		if (NULL == unlinked)
			msyslog(LOG_ERR, "%s not in peer list!",
				stoa(&p->srcadr));
	}

	if (p->hostname != NULL)
		free(p->hostname);

	if (p->ident != NULL)
		free(p->ident);

	if (p->addrs != NULL)
		free(p->addrs);		/* from copy_addrinfo_list() */

	/* Add his corporeal form to peer free list */
	ZERO(*p);
	LINK_SLIST(peer_free, p, p_link);
	peer_free_count++;
}
Ejemplo n.º 5
0
/*
 * restrict_source - maintains dynamic "restrict source ..." entries as
 *		     peers come and go.
 */
void
restrict_source(
	sockaddr_u *	addr,
	int		farewell,	/* 0 to add, 1 to remove */
	u_long		expire		/* 0 is infinite, valid until */
	)
{
	sockaddr_u	onesmask;
	restrict_u *	res;
	int		found_specific;

	if (!restrict_source_enabled || SOCK_UNSPEC(addr) ||
	    IS_MCAST(addr) || ISREFCLOCKADR(addr))
		return;

	REQUIRE(AF_INET == AF(addr) || AF_INET6 == AF(addr));

	SET_HOSTMASK(&onesmask, AF(addr));
	if (farewell) {
		hack_restrict(RESTRICT_REMOVE, addr, &onesmask,
			      0, 0, 0);
		DPRINTF(1, ("restrict_source: %s removed", stoa(addr)));
		return;
	}

	/*
	 * If there is a specific entry for this address, hands
	 * off, as it is condidered more specific than "restrict
	 * server ...".
	 * However, if the specific entry found is a fleeting one
	 * added by pool_xmit() before soliciting, replace it
	 * immediately regardless of the expire value to make way
	 * for the more persistent entry.
	 */
	if (IS_IPV4(addr)) {
		res = match_restrict4_addr(SRCADR(addr), SRCPORT(addr));
		INSIST(res != NULL);
		found_specific = (SRCADR(&onesmask) == res->u.v4.mask);
	} else {
		res = match_restrict6_addr(&SOCK_ADDR6(addr),
					   SRCPORT(addr));
		INSIST(res != NULL);
		found_specific = ADDR6_EQ(&res->u.v6.mask,
					  &SOCK_ADDR6(&onesmask));
	}
	if (!expire && found_specific && res->expire) {
		found_specific = 0;
		free_res(res, IS_IPV6(addr));
	}
	if (found_specific)
		return;

	hack_restrict(RESTRICT_FLAGS, addr, &onesmask,
		      restrict_source_mflags, restrict_source_flags,
		      expire);
	DPRINTF(1, ("restrict_source: %s host restriction added\n", 
		    stoa(addr)));
}
Ejemplo n.º 6
0
/*
 * setup peer dstadr field keeping it in sync with the interface
 * structures
 */
void
set_peerdstadr(
	struct peer *	p,
	endpt *		dstadr
	)
{
	struct peer *	unlinked;

	if (p->dstadr == dstadr)
		return;

	/*
	 * Don't accept updates to a separate multicast receive-only
	 * endpt while a BCLNT peer is running its unicast protocol.
	 */
	if (dstadr != NULL && (FLAG_BC_VOL & p->flags) &&
	    (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
		return;
	}
	if (p->dstadr != NULL) {
		p->dstadr->peercnt--;
		UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
			     struct peer);
		msyslog(LOG_INFO, "%s local addr %s -> %s",
			stoa(&p->srcadr), latoa(p->dstadr),
			latoa(dstadr));
	}
Ejemplo n.º 7
0
/* Receive raw data */
int
recvdata(
	SOCKET rsock,
	sockaddr_u *sender,
	char *rdata,
	int rdata_length
	)
{
	GETSOCKNAME_SOCKLEN_TYPE slen;
	int recvc;

#ifdef DEBUG
	printf("sntp recvdata: Trying to receive data from...\n");
#endif
	slen = sizeof(*sender);
	recvc = recvfrom(rsock, rdata, rdata_length, 0, 
			 &sender->sa, &slen);
#ifdef DEBUG
	if (recvc > 0) {
		printf("Received %d bytes from %s:\n", recvc, stoa(sender));
		pkt_output((struct pkt *) rdata, recvc, stdout);
	} else {
		int saved_errno = errno;
		printf("recvfrom error %d (%s)\n", errno, strerror(errno));
		errno = saved_errno;
	}
#endif
	return recvc;
}
Ejemplo n.º 8
0
/*
 * record_peer_stats - write peer statistics to file
 *
 * file format:
 * day (MJD)
 * time (s past UTC midnight)
 * IP address
 * status word (hex)
 * offset
 * delay
 * dispersion
 * jitter
*/
void
record_peer_stats(
	sockaddr_u *addr,
	int	status,
	double	offset,		/* offset */
	double	delay,		/* delay */
	double	dispersion,	/* dispersion */
	double	jitter		/* jitter */
	)
{
	l_fp	now;
	u_long	day;

	if (!stats_control)
		return;

	get_systime(&now);
	filegen_setup(&peerstats, now.l_ui);
	day = now.l_ui / 86400 + MJD_1900;
	now.l_ui %= 86400;
	if (peerstats.fp != NULL) {
		fprintf(peerstats.fp,
		    "%lu %s %s %x %.9f %.9f %.9f %.9f\n", day,
		    ulfptoa(&now, 3), stoa(addr), status, offset,
		    delay, dispersion, jitter);
		fflush(peerstats.fp);
	}
}
Ejemplo n.º 9
0
/*
 * record_crypto_stats - write crypto statistics to file
 *
 * file format:
 * day (mjd)
 * time (s past midnight)
 * peer ip address
 * text message
 */
void
record_crypto_stats(
	sockaddr_u *addr,
	const char *text	/* text message */
	)
{
	l_fp	now;
	u_long	day;

	if (!stats_control)
		return;

	get_systime(&now);
	filegen_setup(&cryptostats, now.l_ui);
	day = now.l_ui / 86400 + MJD_1900;
	now.l_ui %= 86400;
	if (cryptostats.fp != NULL) {
		if (addr == NULL)
			fprintf(cryptostats.fp, "%lu %s 0.0.0.0 %s\n",
			    day, ulfptoa(&now, 3), text);
		else
			fprintf(cryptostats.fp, "%lu %s %s %s\n",
			    day, ulfptoa(&now, 3), stoa(addr), text);
		fflush(cryptostats.fp);
	}
}
Ejemplo n.º 10
0
/* Convert a sockaddr_u to a string containing the address in
 * style of inet_ntoa
 * Why not switch callers to use stoa from libntp?  No free() needed
 * in that case.
 */
char *
ss_to_str(
	sockaddr_u *saddr
	)
{
	return estrdup(stoa(saddr));
}
Ejemplo n.º 11
0
/*
 * timeout_queries() -- give up on unrequited NTP queries
 */
void
timeout_queries(void)
{
	struct timeval	start_cb;
	u_int		idx;
	sent_pkt *	head;
	sent_pkt *	spkt;
	sent_pkt *	spkt_next;
	long		age;
	int didsomething = 0;

	TRACE(3, ("timeout_queries: called to check %u items\n",
		  (unsigned)COUNTOF(fam_listheads)));

	gettimeofday_cached(base, &start_cb);
	for (idx = 0; idx < COUNTOF(fam_listheads); idx++) {
		head = fam_listheads[idx];
		for (spkt = head; spkt != NULL; spkt = spkt_next) {
			char xcst;

			didsomething = 1;
			switch (spkt->dctx->flags & CTX_xCST) {
			    case CTX_BCST:
				xcst = 'B';
				break;

			    case CTX_UCST:
				xcst = 'U';
				break;

			    default:
				INSIST(!"spkt->dctx->flags neither UCST nor BCST");
				break;
			}

			spkt_next = spkt->link;
			if (0 == spkt->stime || spkt->done)
				continue;
			age = start_cb.tv_sec - spkt->stime;
			TRACE(3, ("%s %s %cCST age %ld\n",
				  stoa(&spkt->addr),
				  spkt->dctx->name, xcst, age));
			if (age > response_timeout)
				timeout_query(spkt);
		}
	}
	// Do we care about didsomething?
	TRACE(3, ("timeout_queries: didsomething is %d, age is %ld\n",
		  didsomething, (long) (start_cb.tv_sec - start_tv.tv_sec)));
	if (start_cb.tv_sec - start_tv.tv_sec > response_timeout) {
		TRACE(3, ("timeout_queries: bail!\n"));
		event_base_loopexit(base, NULL);
		shutting_down = TRUE;
	}
}
Ejemplo n.º 12
0
/* Define a function to create the server associations */
void create_server_associations()
{
    int i;
    for (i = 0;i < simulation.num_of_servers;++i) {
	printf("%s\n", stoa(simulation.servers[i].addr));
	if (peer_config(simulation.servers[i].addr,
			ANY_INTERFACE_CHOOSE(simulation.servers[i].addr),
			MODE_CLIENT,
			NTP_VERSION,
			NTP_MINDPOLL,
			NTP_MAXDPOLL,
			0, /* peerflags */
			0, /* ttl */
			0, /* peerkey */
			(u_char *)"*" /* peerkeystr */) == 0) {
	    fprintf(stderr, "ERROR!! Could not create association for: %s",
		    stoa(simulation.servers[i].addr));
	}
    }
}
Ejemplo n.º 13
0
/* Receive raw data */
int
recvdata (
		SOCKET rsock,
		sockaddr_u *sender,
		char *rdata,
		int rdata_length
	 )
{
	struct timeval timeout_tv = { 0 };
	fd_set recv_fd;
	GETSOCKNAME_SOCKLEN_TYPE slen;
	int recvc;

#ifdef DEBUG
	printf("sntp recvdata: Trying to receive data from...\n");
#endif
	// Is the socket ready?
	FD_ZERO(&recv_fd);
	FD_SET(rsock, &recv_fd);
	
	if(ENABLED_OPT(TIMEOUT)) {
		timeout_tv.tv_sec = (int) OPT_ARG(TIMEOUT);
	} else {
		timeout_tv.tv_sec = 15; 
	}
	switch(select(rsock + 1, &recv_fd, 0, 0, &timeout_tv)) {
		case 0:
			if(ENABLED_OPT(NORMALVERBOSE))
				printf("sntp recvdata: select() reached timeout (%u sec), aborting.\n", 
				       (unsigned)timeout_tv.tv_sec);
			return SERVER_UNUSEABLE;

		case -1:
			return SERVER_UNUSEABLE;
		default:
			
			slen = sizeof(sender->sas);
			recvc = recvfrom(rsock, rdata, rdata_length, 0, 
							 &sender->sa, &slen);
#ifdef DEBUG
			if (recvc > 0) {
				printf("Received %d bytes from %s:\n", recvc, stoa(sender));

				pkt_output((struct pkt *) rdata, recvc, stdout);
			} else {
				saved_errno = errno;
				printf("recvfrom error %d (%s)\n", errno, strerror(errno));
				errno = saved_errno;
			}
#endif
	}

	return recvc;
}
Ejemplo n.º 14
0
/*
 * refclock_transmit - simulate the transmit procedure
 *
 * This routine implements the NTP transmit procedure for a reference
 * clock. This provides a mechanism to call the driver at the NTP poll
 * interval, as well as provides a reachability mechanism to detect a
 * broken radio or other madness.
 */
void
refclock_transmit(
	struct peer *peer	/* peer structure pointer */
	)
{
	u_char clktype;
	int unit;

	clktype = peer->refclktype;
	unit = peer->refclkunit;
	peer->sent++;
	get_systime(&peer->xmt);

	/*
	 * This is a ripoff of the peer transmit routine, but
	 * specialized for reference clocks. We do a little less
	 * protocol here and call the driver-specific transmit routine.
	 */
	if (peer->burst == 0) {
		u_char oreach;
#ifdef DEBUG
		if (debug)
			printf("refclock_transmit: at %ld %s\n",
			    current_time, stoa(&(peer->srcadr)));
#endif

		/*
		 * Update reachability and poll variables like the
		 * network code.
		 */
		oreach = peer->reach;
		peer->reach <<= 1;
		peer->outdate = current_time;
		if (!peer->reach) {
			if (oreach) {
				report_event(EVNT_UNREACH, peer);
				peer->timereachable = current_time;
			}
		} else {
			if (!(oreach & 0x07)) {
				clock_filter(peer, 0., 0., MAXDISPERSE);
				clock_select();
			}
			if (peer->flags & FLAG_BURST)
				peer->burst = NSTAGE;
		}
	} else {
		peer->burst--;
	}
	if (refclock_conf[clktype]->clock_poll != noentry)
		(refclock_conf[clktype]->clock_poll)(unit, peer);
	poll_update(peer, peer->hpoll);
}
Ejemplo n.º 15
0
Archivo: ntpdc.c Proyecto: pexip/os-ntp
/*
 * nntohost - convert network number to host name.  This routine enforces
 *	       the showhostnames setting.
 */
char *
nntohost(
	sockaddr_u *netnum
	)
{
	if (!showhostnames)
		return stoa(netnum);

	if (ISREFCLOCKADR(netnum))
		return refnumtoa(netnum);
	return socktohost(netnum);
}
Ejemplo n.º 16
0
/*
 * nntohost - convert network number to host name.  This routine enforces
 *	       the showhostnames setting.
 */
const char *
nntohost(
	sockaddr_u *netnum
	)
{
	if (!showhostnames || SOCK_UNSPEC(netnum))
		return stoa(netnum);
	else if (ISREFCLOCKADR(netnum))
		return refnumtoa(netnum);
	else
		return socktohost(netnum);
}
Ejemplo n.º 17
0
/* Convert a sockaddr_u to a string containing the address in
 * style of inet_ntoa
 * Why not switch callers to use stoa from libntp?  No free() needed
 * in that case.
 */
char *
ss_to_str (
    sockaddr_u *saddr
)
{
    char *	buf;

    buf = emalloc(INET6_ADDRSTRLEN);
    strncpy(buf, stoa(saddr), INET6_ADDRSTRLEN);

    return buf;
}
Ejemplo n.º 18
0
/*
 * record_raw_stats - write raw timestamps to file
 *
 * file format
 * day (MJD)
 * time (s past midnight)
 * peer ip address
 * IP address
 * t1 t2 t3 t4 timestamps
 */
void
record_raw_stats(
	sockaddr_u *srcadr,
	sockaddr_u *dstadr,
	l_fp	*t1,		/* originate timestamp */
	l_fp	*t2,		/* receive timestamp */
	l_fp	*t3,		/* transmit timestamp */
	l_fp	*t4,		/* destination timestamp */
	int	leap,
	int	version,
	int	mode,
	int	stratum,
	int	ppoll,
	int	precision,
	double	root_delay,	/* seconds */
	double	root_dispersion,/* seconds */
	u_int32	refid
	)
{
	l_fp	now;
	u_long	day;

	if (!stats_control)
		return;

	get_systime(&now);
	filegen_setup(&rawstats, now.l_ui);
	day = now.l_ui / 86400 + MJD_1900;
	now.l_ui %= 86400;
	if (rawstats.fp != NULL) {
		fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s %d %d %d %d %d %d %.6f %.6f %s\n",
		    day, ulfptoa(&now, 3),
		    stoa(srcadr), dstadr ?  stoa(dstadr) : "-",
		    ulfptoa(t1, 9), ulfptoa(t2, 9),
		    ulfptoa(t3, 9), ulfptoa(t4, 9),
		    leap, version, mode, stratum, ppoll, precision,
		    root_delay, root_dispersion, refid_str(refid, stratum));
		fflush(rawstats.fp);
	}
}
Ejemplo n.º 19
0
/*
 * refclock_receive - simulate the receive and packet procedures
 *
 * This routine simulates the NTP receive and packet procedures for a
 * reference clock. This provides a mechanism in which the ordinary NTP
 * filter, selection and combining algorithms can be used to suppress
 * misbehaving radios and to mitigate between them when more than one is
 * available for backup.
 */
void
refclock_receive(
	struct peer *peer	/* peer structure pointer */
	)
{
	struct refclockproc *pp;

#ifdef DEBUG
	if (debug)
		printf("refclock_receive: at %lu %s\n",
		    current_time, stoa(&peer->srcadr));
#endif

	/*
	 * Do a little sanity dance and update the peer structure. Groom
	 * the median filter samples and give the data to the clock
	 * filter.
	 */
	pp = peer->procptr;
	peer->leap = pp->leap;
	if (peer->leap == LEAP_NOTINSYNC)
		return;

	peer->received++;
	peer->timereceived = current_time;
	if (!peer->reach) {
		report_event(EVNT_REACH, peer);
		peer->timereachable = current_time;
	}
	peer->reach |= 1;
	peer->reftime = pp->lastref;
	peer->org = pp->lastrec;
	peer->rootdispersion = pp->disp;
	get_systime(&peer->rec);
	if (!refclock_sample(pp))
		return;

	clock_filter(peer, pp->offset, 0., pp->jitter);
	record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
	    peer->offset, peer->delay, clock_phi * (current_time -
	    peer->epoch), peer->jitter);
	if (cal_enable && last_offset < MINDISPERSE) {
#ifdef KERNEL_PLL
		if (peer != sys_peer || pll_status & STA_PPSTIME)
#else
		if (peer != sys_peer)
#endif /* KERNEL_PLL */
			pp->fudgetime1 -= pp->offset * FUDGEFAC;
		else
			pp->fudgetime1 -= pp->fudgetime1 * FUDGEFAC;
	}
}
Ejemplo n.º 20
0
char *
socktohost(
	struct sockaddr_storage* sock
	)
{
	register char *buffer;

	LIB_GETBUF(buffer);
	if (getnameinfo((struct sockaddr *)sock, SOCKLEN(sock), buffer,
	    LIB_BUFLENGTH /* NI_MAXHOST*/, NULL, 0, 0))
		return stoa(sock);

  	return buffer;
}
Ejemplo n.º 21
0
/*
 * refclock_receive - simulate the receive and packet procedures
 *
 * This routine simulates the NTP receive and packet procedures for a
 * reference clock. This provides a mechanism in which the ordinary NTP
 * filter, selection and combining algorithms can be used to suppress
 * misbehaving radios and to mitigate between them when more than one is
 * available for backup.
 */
void
refclock_receive(
	struct peer *peer	/* peer structure pointer */
	)
{
	struct refclockproc *pp;

#ifdef DEBUG
	if (debug)
		printf("refclock_receive: at %lu %s\n",
		    current_time, stoa(&peer->srcadr));
#endif

	/*
	 * Do a little sanity dance and update the peer structure. Groom
	 * the median filter samples and give the data to the clock
	 * filter.
	 */
	pp = peer->procptr;
	peer->leap = pp->leap;
	if (peer->leap == LEAP_NOTINSYNC)
		return;

	peer->received++;
	peer->timereceived = current_time;
	if (!peer->reach) {
		report_event(PEVNT_REACH, peer, NULL);
		peer->timereachable = current_time;
	}
	peer->reach |= 1;
	peer->reftime = pp->lastref;
	peer->aorg = pp->lastrec;
	peer->rootdisp = pp->disp;
	get_systime(&peer->dst);
	if (!refclock_sample(pp))
		return;

	clock_filter(peer, pp->offset, 0., pp->jitter);
	if (cal_enable && fabs(last_offset) < sys_mindisp && sys_peer !=
	    NULL) {
		if (sys_peer->refclktype == REFCLK_ATOM_PPS &&
		    peer->refclktype != REFCLK_ATOM_PPS)
			pp->fudgetime1 -= pp->offset * FUDGEFAC;
	}
}
Ejemplo n.º 22
0
/*
** xmt_timer_cb
*/
void
xmt_timer_cb(
	evutil_socket_t	fd,
	short		what,
	void *		ctx
	)
{
	struct timeval	start_cb;
	struct timeval	delay;
	xmt_ctx *	x;

	UNUSED_ARG(fd);
	UNUSED_ARG(ctx);
	DEBUG_INSIST(EV_TIMEOUT == what);

	if (NULL == xmt_q || shutting_down)
		return;
	gettimeofday_cached(base, &start_cb);
	if (xmt_q->sched <= start_cb.tv_sec) {
		UNLINK_HEAD_SLIST(x, xmt_q, link);
		TRACE(2, ("xmt_timer_cb: at .%6.6u -> %s\n",
			  (u_int)start_cb.tv_usec, stoa(&x->spkt->addr)));
		xmt(x);
		free(x);
		if (NULL == xmt_q)
			return;
	}
	if (xmt_q->sched <= start_cb.tv_sec) {
		event_add(ev_xmt_timer, &gap);
		TRACE(2, ("xmt_timer_cb: at .%6.6u gap %6.6u\n",
			  (u_int)start_cb.tv_usec,
			  (u_int)gap.tv_usec));
	} else {
		delay.tv_sec = xmt_q->sched - start_cb.tv_sec;
		delay.tv_usec = 0;
		event_add(ev_xmt_timer, &delay);
		TRACE(2, ("xmt_timer_cb: at .%6.6u next %ld seconds\n",
			  (u_int)start_cb.tv_usec,
			  (long)delay.tv_sec));
	}
}
Ejemplo n.º 23
0
/*
** xmt()
*/
void
xmt(
	xmt_ctx *	xctx
	)
{
	SOCKET		sock = xctx->sock;
	struct dns_ctx *dctx = xctx->spkt->dctx;
	sent_pkt *	spkt = xctx->spkt;
	sockaddr_u *	dst = &spkt->addr;
	struct timeval	tv_xmt;
	struct pkt	x_pkt;
	size_t		pkt_len;
	int		sent;

	if (0 != gettimeofday(&tv_xmt, NULL)) {
		msyslog(LOG_ERR,
			"xmt: gettimeofday() failed: %m");
		exit(1);
	}
	tv_xmt.tv_sec += JAN_1970;

	pkt_len = generate_pkt(&x_pkt, &tv_xmt, dctx->key_id,
			       dctx->key);

	sent = sendpkt(sock, dst, &x_pkt, pkt_len);
	if (sent) {
		/* Save the packet we sent... */
		memcpy(&spkt->x_pkt, &x_pkt, min(sizeof(spkt->x_pkt),
		       pkt_len));
		spkt->stime = tv_xmt.tv_sec - JAN_1970;

		TRACE(2, ("xmt: %lx.%6.6u %s %s\n", (u_long)tv_xmt.tv_sec,
			  (u_int)tv_xmt.tv_usec, dctx->name, stoa(dst)));
	} else {
		dec_pending_ntp(dctx->name, dst);
	}

	return;
}
Ejemplo n.º 24
0
/*
 * record_clock_stats - write clock statistics to file
 *
 * file format:
 * day (MJD)
 * time (s past midnight)
 * IP address
 * text message
 */
void
record_clock_stats(
	sockaddr_u *addr,
	const char *text	/* timecode string */
	)
{
	l_fp	now;
	u_long	day;

	if (!stats_control)
		return;

	get_systime(&now);
	filegen_setup(&clockstats, now.l_ui);
	day = now.l_ui / 86400 + MJD_1900;
	now.l_ui %= 86400;
	if (clockstats.fp != NULL) {
		fprintf(clockstats.fp, "%lu %s %s %s\n", day,
		    ulfptoa(&now, 3), stoa(addr), text);
		fflush(clockstats.fp);
	}
}
Ejemplo n.º 25
0
/*
 *
 * hostnameaddr()
 *
 * Formats the hostname and resulting numeric IP address into a string,
 * avoiding duplication if the "hostname" was in fact a numeric address.
 *
 */
const char *
hostnameaddr(
	const char *		hostname,
	const sockaddr_u *	addr
	)
{
	const char *	addrtxt;
	char *		result;
	int		cnt;

	addrtxt = stoa(addr);
	LIB_GETBUF(result);
	if (strcmp(hostname, addrtxt))
		cnt = snprintf(result, LIB_BUFLENGTH, "%s %s",
			       hostname, addrtxt);
	else
		cnt = snprintf(result, LIB_BUFLENGTH, "%s", addrtxt);
	if (cnt >= LIB_BUFLENGTH)
		snprintf(result, LIB_BUFLENGTH,
			 "hostnameaddr ERROR have %d (%d needed)",
			 LIB_BUFLENGTH, cnt + 1);

	return result;
}
Ejemplo n.º 26
0
/*
 * unpeer - remove peer structure from hash table and free structure
 */
void
unpeer(
	struct peer *peer_to_remove
	)
{
	int hash;
#ifdef OPENSSL
	char	statstr[NTP_MAXSTRLEN]; /* statistics for filegen */

	if (peer_to_remove->flags & FLAG_SKEY) {
		sprintf(statstr, "unpeer %d flash %x reach %03o flags %04x",
		    peer_to_remove->associd, peer_to_remove->flash,
		    peer_to_remove->reach, peer_to_remove->flags);
		record_crypto_stats(&peer_to_remove->srcadr, statstr);
#ifdef DEBUG
		if (debug)
			printf("peer: %s\n", statstr);
#endif
	}
#endif /* OPENSSL */
#ifdef DEBUG
	if (debug)
		printf("demobilize %u %d %d\n", peer_to_remove->associd,
		    peer_associations, peer_preempt);
#endif
	set_peerdstadr(peer_to_remove, NULL);

	/* XXXMEMLEAK? peer_clear->crypto allocation */

	hash = NTP_HASH_ADDR(&peer_to_remove->srcadr);
	peer_hash_count[hash]--;
	peer_demobilizations++;
	peer_associations--;
	if (peer_to_remove->flags & FLAG_PREEMPT)
		peer_preempt--;
#ifdef REFCLOCK
	/*
	 * If this peer is actually a clock, shut it down first
	 */
	if (peer_to_remove->flags & FLAG_REFCLOCK)
		refclock_unpeer(peer_to_remove);
#endif
	peer_to_remove->action = 0;	/* disable timeout actions */
	if (peer_hash[hash] == peer_to_remove)
		peer_hash[hash] = peer_to_remove->next;
	else {
		register struct peer *peer;

		peer = peer_hash[hash];
		while (peer != 0 && peer->next != peer_to_remove)
		    peer = peer->next;
		
		if (peer == 0) {
			peer_hash_count[hash]++;
			msyslog(LOG_ERR, "peer struct for %s not in table!",
				stoa(&peer->srcadr));
		} else {
			peer->next = peer_to_remove->next;
		}
	}

	/*
	 * Remove him from the association hash as well.
	 */
	hash = peer_to_remove->associd & NTP_HASH_MASK;
	assoc_hash_count[hash]--;
	if (assoc_hash[hash] == peer_to_remove)
		assoc_hash[hash] = peer_to_remove->ass_next;
	else {
		register struct peer *peer;

		peer = assoc_hash[hash];
		while (peer != 0 && peer->ass_next != peer_to_remove)
		    peer = peer->ass_next;
		
		if (peer == 0) {
			assoc_hash_count[hash]++;
			msyslog(LOG_ERR,
				"peer struct for %s not in association table!",
				stoa(&peer->srcadr));
		} else {
			peer->ass_next = peer_to_remove->ass_next;
		}
	}
	peer_to_remove->next = peer_free;
	peer_free = peer_to_remove;
	peer_free_count++;
}
Ejemplo n.º 27
0
/*
 * refclock_newpeer - initialize and start a reference clock
 *
 * This routine allocates and initializes the interface structure which
 * supports a reference clock in the form of an ordinary NTP peer. A
 * driver-specific support routine completes the initialization, if
 * used. Default peer variables which identify the clock and establish
 * its reference ID and stratum are set here. It returns one if success
 * and zero if the clock address is invalid or already running,
 * insufficient resources are available or the driver declares a bum
 * rap.
 */
int
refclock_newpeer(
	struct peer *peer	/* peer structure pointer */
	)
{
	struct refclockproc *pp;
	u_char clktype;
	int unit;

	/*
	 * Check for valid clock address. If already running, shut it
	 * down first.
	 */
	if (!ISREFCLOCKADR(&peer->srcadr)) {
		msyslog(LOG_ERR,
			"refclock_newpeer: clock address %s invalid",
			stoa(&peer->srcadr));
		return (0);
	}
	clktype = (u_char)REFCLOCKTYPE(&peer->srcadr);
	unit = REFCLOCKUNIT(&peer->srcadr);
	if (clktype >= num_refclock_conf ||
		refclock_conf[clktype]->clock_start == noentry) {
		msyslog(LOG_ERR,
			"refclock_newpeer: clock type %d invalid\n",
			clktype);
		return (0);
	}

	/*
	 * Allocate and initialize interface structure
	 */
	pp = emalloc(sizeof(*pp));
	memset(pp, 0, sizeof(*pp));
	peer->procptr = pp;

	/*
	 * Initialize structures
	 */
	peer->refclktype = clktype;
	peer->refclkunit = (u_char)unit;
	peer->flags |= FLAG_REFCLOCK;
	peer->leap = LEAP_NOTINSYNC;
	peer->stratum = STRATUM_REFCLOCK;
	peer->ppoll = peer->maxpoll;
	pp->type = clktype;
	pp->timestarted = current_time;

	/*
	 * Set peer.pmode based on the hmode. For appearances only.
	 */
	switch (peer->hmode) {
	case MODE_ACTIVE:
		peer->pmode = MODE_PASSIVE;
		break;

	default:
		peer->pmode = MODE_SERVER;
		break;
	}

	/*
	 * Do driver dependent initialization. The above defaults
	 * can be wiggled, then finish up for consistency.
	 */
	if (!((refclock_conf[clktype]->clock_start)(unit, peer))) {
		refclock_unpeer(peer);
		return (0);
	}
	peer->refid = pp->refid;
	return (1);
}
Ejemplo n.º 28
0
/* Receive data from broadcast. Couldn't finish that. Need to do some digging
 * here, especially for protocol independence and IPv6 multicast */
int 
recv_bcst_data (
	SOCKET rsock,
	char *rdata,
	int rdata_len,
	sockaddr_u *sas,
	sockaddr_u *ras
	)
{
	char *buf;
	int btrue = 1;
	int recv_bytes = 0;
	int rdy_socks;
	GETSOCKNAME_SOCKLEN_TYPE ss_len;
	struct timeval timeout_tv;
	fd_set bcst_fd;
#ifdef MCAST
	struct ip_mreq mdevadr;
	TYPEOF_IP_MULTICAST_LOOP mtrue = 1;
#endif
#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
	struct ipv6_mreq mdevadr6;
#endif

	setsockopt(rsock, SOL_SOCKET, SO_REUSEADDR, &btrue, sizeof(btrue));
	if (IS_IPV4(sas)) {
		if (bind(rsock, &sas->sa, SOCKLEN(sas)) < 0) {
			if (ENABLED_OPT(NORMALVERBOSE))
				printf("sntp recv_bcst_data: Couldn't bind() address %s:%d.\n",
				       stoa(sas), SRCPORT(sas));
		}

#ifdef MCAST
		if (setsockopt(rsock, IPPROTO_IP, IP_MULTICAST_LOOP, &mtrue, sizeof(mtrue)) < 0) {
			/* some error message regarding setting up multicast loop */
			return BROADCAST_FAILED;
		}
		mdevadr.imr_multiaddr.s_addr = NSRCADR(sas); 
		mdevadr.imr_interface.s_addr = htonl(INADDR_ANY);
		if (mdevadr.imr_multiaddr.s_addr == ~(unsigned)0) {
			if (ENABLED_OPT(NORMALVERBOSE)) {
				printf("sntp recv_bcst_data: %s:%d is not a broad-/multicast address, aborting...\n",
				       stoa(sas), SRCPORT(sas));
			}
			return BROADCAST_FAILED;
		}
		if (setsockopt(rsock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mdevadr, sizeof(mdevadr)) < 0) {
			if (ENABLED_OPT(NORMALVERBOSE)) {
				buf = ss_to_str(sas);
				printf("sntp recv_bcst_data: Couldn't add IP membership for %s\n", buf);
				free(buf);
			}
		}
#endif	/* MCAST */
	}
#ifdef ISC_PLATFORM_HAVEIPV6
	else if (IS_IPV6(sas)) {
		if (bind(rsock, &sas->sa, SOCKLEN(sas)) < 0) {
			if (ENABLED_OPT(NORMALVERBOSE))
				printf("sntp recv_bcst_data: Couldn't bind() address.\n");
		}
#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
		if (setsockopt(rsock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &btrue, sizeof (btrue)) < 0) {
			/* some error message regarding setting up multicast loop */
			return BROADCAST_FAILED;
		}
		memset(&mdevadr6, 0, sizeof(mdevadr6));
		mdevadr6.ipv6mr_multiaddr = SOCK_ADDR6(sas);
		if (!IN6_IS_ADDR_MULTICAST(&mdevadr6.ipv6mr_multiaddr)) {
			if (ENABLED_OPT(NORMALVERBOSE)) {
				buf = ss_to_str(sas); 
				printf("sntp recv_bcst_data: %s is not a broad-/multicast address, aborting...\n", buf);
				free(buf);
			}
			return BROADCAST_FAILED;
		}
		if (setsockopt(rsock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
			       &mdevadr6, sizeof(mdevadr6)) < 0) {
			if (ENABLED_OPT(NORMALVERBOSE)) {
				buf = ss_to_str(sas); 
				printf("sntp recv_bcst_data: Couldn't join group for %s\n", buf);
				free(buf);
			}
		}
#endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
	}
#endif	/* ISC_PLATFORM_HAVEIPV6 */
	FD_ZERO(&bcst_fd);
	FD_SET(rsock, &bcst_fd);
	if (ENABLED_OPT(TIMEOUT)) 
		timeout_tv.tv_sec = (int) atol(OPT_ARG(TIMEOUT));
	else 
		timeout_tv.tv_sec = 68; /* ntpd broadcasts every 64s */
	timeout_tv.tv_usec = 0;
	rdy_socks = select(rsock + 1, &bcst_fd, 0, 0, &timeout_tv);
	switch (rdy_socks) {
	case -1: 
		if (ENABLED_OPT(NORMALVERBOSE)) 
			perror("sntp recv_bcst_data: select()");
		return BROADCAST_FAILED;
		break;
	case 0:
		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recv_bcst_data: select() reached timeout (%u sec), aborting.\n", 
			       (unsigned)timeout_tv.tv_sec);
		return BROADCAST_FAILED;
		break;
	default:
		ss_len = sizeof(*ras);
		recv_bytes = recvfrom(rsock, rdata, rdata_len, 0, &ras->sa, &ss_len);
		break;
	}
	if (recv_bytes == -1) {
		if (ENABLED_OPT(NORMALVERBOSE))
			perror("sntp recv_bcst_data: recvfrom:");
		recv_bytes = BROADCAST_FAILED;
	}
#ifdef MCAST
	if (IS_IPV4(sas)) 
		setsockopt(rsock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &btrue, sizeof(btrue));
#endif
#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
	if (IS_IPV6(sas))
		setsockopt(rsock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &btrue, sizeof(btrue));
#endif
	return recv_bytes;
}
Ejemplo n.º 29
0
const char *
socktohost(
	const sockaddr_u *sock
	)
{
	const char		svc[] = "ntp";
	char *			pbuf;
	char *			pliar;
	int			gni_flags;
	struct addrinfo		hints;
	struct addrinfo *	alist;
	struct addrinfo *	ai;
	sockaddr_u		addr;
	size_t			octets;
	int			a_info;

	/* reverse the address to purported DNS name */
	LIB_GETBUF(pbuf);
	gni_flags = NI_DGRAM | NI_NAMEREQD;
	if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH,
			NULL, 0, gni_flags))
		return stoa(sock);	/* use address */

	TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf));

	/*
	 * Resolve the reversed name and make sure the reversed address
	 * is among the results.
	 */
	ZERO(hints);
	hints.ai_family = AF(sock);
	hints.ai_protocol = IPPROTO_UDP;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = 0;
	alist = NULL;

	a_info = getaddrinfo(pbuf, svc, &hints, &alist);
	if (a_info == EAI_NONAME
#ifdef EAI_NODATA
	    || a_info == EAI_NODATA
#endif
	   ) {
		hints.ai_flags = AI_CANONNAME;
#ifdef AI_ADDRCONFIG
		hints.ai_flags |= AI_ADDRCONFIG;
#endif
		a_info = getaddrinfo(pbuf, svc, &hints, &alist);	
	}
#ifdef AI_ADDRCONFIG
	/* Some older implementations don't like AI_ADDRCONFIG. */
	if (a_info == EAI_BADFLAGS) {
		hints.ai_flags &= ~AI_ADDRCONFIG;
		a_info = getaddrinfo(pbuf, svc, &hints, &alist);	
	}
#endif
	if (a_info)
		goto forward_fail;

	NTP_INSIST(alist != NULL);

	for (ai = alist; ai != NULL; ai = ai->ai_next) {
		/*
		 * Make a convenience sockaddr_u copy from ai->ai_addr
		 * because casting from sockaddr * to sockaddr_u * is
		 * risking alignment problems on platforms where
		 * sockaddr_u has stricter alignment than sockaddr,
		 * such as sparc.
		 */
		ZERO_SOCK(&addr);
		octets = min(sizeof(addr), ai->ai_addrlen);
		memcpy(&addr, ai->ai_addr, octets);
		if (SOCK_EQ(sock, &addr))
			break;
	}
	freeaddrinfo(alist);

	if (ai != NULL)
		return pbuf;	/* forward check passed */

    forward_fail:
	TRACE(1, ("%s forward check lookup fail: %s\n", pbuf,
		  gai_strerror(a_info)));
	LIB_GETBUF(pliar);
	snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf);

	return pliar;
}
Ejemplo n.º 30
0
/* Define a function to simulate a server.
 * This function processes the sent packet according to the server script,
 * creates a reply packet and pushes the reply packet onto the event queue
 */
int simulate_server(
    sockaddr_u *serv_addr,		/* Address of the server */
    struct interface *inter,		/* Interface on which the reply should
					   be inserted */
    struct pkt *rpkt			/* Packet sent to the server that
					   needs to be processed. */
)
{
    struct pkt xpkt;	       /* Packet to be transmitted back
				  to the client */
    struct recvbuf rbuf;       /* Buffer for the received packet */
    Event *e;		       /* Packet receive event */
    server_info *server;       /* Pointer to the server being simulated */
    script_info *curr_script;  /* Current script being processed */
    int i;
    double d1, d2, d3;	       /* Delays while the packet is enroute */
    double t1, t2, t3, t4;     /* The four timestamps in the packet */

    memset(&xpkt, 0, sizeof(xpkt));
    memset(&rbuf, 0, sizeof(rbuf));

    /* Search for the server with the desired address */
    server = NULL;
    for (i = 0; i < simulation.num_of_servers; ++i) {
	fprintf(stderr,"Checking address: %s\n", stoa(simulation.servers[i].addr));
	if (memcmp(simulation.servers[i].addr, serv_addr, 
		   sizeof(*serv_addr)) == 0) { 
	    server = &simulation.servers[i];
	    break;
	}
    }

    fprintf(stderr, "Received packet for: %s\n", stoa(serv_addr));
    if (server == NULL)
	abortsim("Server with specified address not found!!!");
    
    /* Get the current script for the server */
    curr_script = server->curr_script;

    /* Create a server reply packet. 
     * Masquerade the reply as a stratum-1 server with a GPS clock
     */
    xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION,
                                     MODE_SERVER);
    xpkt.stratum = STRATUM_TO_PKT(((u_char)1));
    memcpy(&xpkt.refid, "GPS", 4);
    xpkt.ppoll = rpkt->ppoll;
    xpkt.precision = rpkt->precision;
    xpkt.rootdelay = 0;
    xpkt.rootdisp = 0;

    /* TIMESTAMP CALCULATIONS
	    t1				 t4
	     \				/
	  d1  \			       / d3
	       \		      /
	       t2 ----------------- t3
			 d2
    */
    /* Compute the delays */
    d1 = poisson(curr_script->prop_delay, curr_script->jitter);
    d2 = poisson(curr_script->proc_delay, 0);
    d3 = poisson(curr_script->prop_delay, curr_script->jitter);

    /* Note: In the transmitted packet: 
     * 1. t1 and t4 are times in the client according to the local clock.
     * 2. t2 and t3 are server times according to the simulated server.
     * Compute t1, t2, t3 and t4
     * Note: This function is called at time t1. 
     */

    LFPTOD(&rpkt->xmt, t1);
    t2 = server->server_time + d1;
    t3 = server->server_time + d1 + d2;
    t4 = t1 + d1 + d2 + d3;

    /* Save the timestamps */
    xpkt.org = rpkt->xmt;     
    DTOLFP(t2, &xpkt.rec);
    DTOLFP(t3, &xpkt.xmt);
    xpkt.reftime = xpkt.xmt;



    /* Ok, we are done with the packet. Now initialize the receive buffer for
     * the packet.
     */
    rbuf.receiver = receive;   /* Function to call to process the packet */
    rbuf.recv_length = LEN_PKT_NOMAC;
    rbuf.recv_pkt = xpkt;
    rbuf.used = 1;

    memcpy(&rbuf.srcadr, serv_addr, sizeof(rbuf.srcadr));
    memcpy(&rbuf.recv_srcadr, serv_addr, sizeof(rbuf.recv_srcadr));
    if ((rbuf.dstadr = malloc(sizeof(*rbuf.dstadr))) == NULL)
	abortsim("malloc failed in simulate_server");
    memcpy(rbuf.dstadr, inter, sizeof(*rbuf.dstadr));
    /* rbuf.link = NULL; */

    /* Create a packet event and insert it onto the event_queue at the 
     * arrival time (t4) of the packet at the client 
     */
    e = event(t4, PACKET);
    e->rcv_buf = rbuf;
    enqueue(event_queue, e);
    

    /* Check if the time of the script has expired. If yes, delete the script.
     * If not, re-enqueue the script onto the server script queue 
     */
    if (curr_script->duration > simulation.sim_time && 
	!empty(server->script)) {
	printf("Hello\n");
	/* 
	 * For some reason freeing up the curr_script memory kills the
	 * simulation. Further debugging is needed to determine why.
	 * free_node(curr_script);
	 */
	curr_script = dequeue(server->script);
    }

    return (0);
}