diff --git a/SOURCES/ntp-4.2.6p4-htmldoc.patch b/SOURCES/ntp-4.2.6p4-htmldoc.patch
index 6a082c9..8558224 100644
--- a/SOURCES/ntp-4.2.6p4-htmldoc.patch
+++ b/SOURCES/ntp-4.2.6p4-htmldoc.patch
@@ -48,8 +48,8 @@ diff -up ntp-4.2.6p5/html/keygen.html.htmldoc ntp-4.2.6p5/html/keygen.html
  
 diff -up ntp-4.2.6p5/html/ntpd.html.htmldoc ntp-4.2.6p5/html/ntpd.html
 --- ntp-4.2.6p5/html/ntpd.html.htmldoc	2011-07-11 04:18:26.000000000 +0200
-+++ ntp-4.2.6p5/html/ntpd.html	2015-02-23 12:11:24.719093119 +0100
-@@ -35,11 +35,11 @@
++++ ntp-4.2.6p5/html/ntpd.html	2017-03-22 11:08:46.864272061 +0100
+@@ -35,12 +35,12 @@
  		<tt>ntpd [ -46aAbdDgLnNqx ] [ -c <i>conffile</i> ] [ -f <i>driftfile</i> ] [ -i <i>jaildir</i> ] [ -I <i>iface</i> ] [ -k <i>keyfile</i> ] [ -l <i>logfile</i> ] [ -p <i>pidfile</i> ] [ -P <i>priority</i> ] [ -r <i>broadcastdelay</i> ] [ -s <i>statsdir</i> ] [ -t <i>key</i> ] [ -u <i>user</i>[:<i>group</i>] ] [ -U <i>interface_update_interval</i> ] [ -v <i>variable</i> ] [ -V <i>variable</i> ]</tt>
  		<h4 id="descr">Description</h4>
  		<p>The <tt>ntpd</tt> program is an operating system daemon that synchronises the system clock with remote NTP&nbsp;time servers or local reference clocks. It is a complete implementation of the Network Time Protocol (NTP) version 4, but also retains compatibility with version 3, as defined by RFC-1305, and version 1 and 2, as defined by RFC-1059 and RFC-1119, respectively. The program can operate in any of several modes, as described on the <a href="assoc.html">Association Management</a> page, and with both symmetric key and public key cryptography, as described on the <a href="manyopt.html">Authentication Options</a> page.</p>
@@ -59,10 +59,12 @@ diff -up ntp-4.2.6p5/html/ntpd.html.htmldoc ntp-4.2.6p5/html/ntpd.html
  		<h4 id="time">Setting the Time and Frequency</h4>
  		<p>The <tt>ntpd</tt> program operates by exchanging messages with one or more servers at designated intervals ranging from about one minute to about 17 minutes. When started, the program requires several exchanges while the algorithms accumulate and groom the data before setting the clock. The initial delay to set the clock can be reduced using options on the <a href="confopt.html">Server Options</a> page.</p>
 -		<p>Most compters today incorporate a time-of-year (TOY) chip to maintain the time during periods when the power is off. When the machine is booted, the chip is used to initialize the operating system time. In case there is no TOY chip or the TOY&nbsp;time is more than 1000 s from the server&nbsp;time, <tt>ntpd</tt> assumes something must be terribly wrong and exits with a panic message to the system operator. With the <tt>-g</tt> option the clock will be initially set to the server time regardless of the chip time. However, once the clock has been set, an error greater than 1000 s will cause <tt>ntpd</tt> to exit anyway.</p>
+-		<p>Under ordinary conditions, <tt>ntpd</tt> slews the clock so that the time is effectively continuous and never runs backwards. If due to extreme network congestion an error spike exceeds the <i>step threshold</i>, by default 128 ms, the spike is discarded. However, if the error persists for more than the <i>stepout threshold</i>, by default 900 s, the system clock is stepped to the correct value. In practice the need for a step has is extremely rare and almost always the result of a hardware failure. With the <tt>-x</tt> option the step threshold is increased to 600 s. Other options are available using the <tt>tinker</tt> command on the <a href="miscopt.html">Miscellaneous Options</a> page.</p>
 +		<p>Most computers today incorporate a time-of-year (TOY) chip to maintain the time during periods when the power is off. When the machine is booted, the chip is used to initialize the operating system time. In case there is no TOY chip or the TOY&nbsp;time is more than 1000 s from the server&nbsp;time, <tt>ntpd</tt> assumes something must be terribly wrong and exits with a panic message to the system operator. With the <tt>-g</tt> option the clock will be initially set to the server time regardless of the chip time. However, once the clock has been set, an error greater than 1000 s will cause <tt>ntpd</tt> to exit anyway.</p>
- 		<p>Under ordinary conditions, <tt>ntpd</tt> slews the clock so that the time is effectively continuous and never runs backwards. If due to extreme network congestion an error spike exceeds the <i>step threshold</i>, by default 128 ms, the spike is discarded. However, if the error persists for more than the <i>stepout threshold</i>, by default 900 s, the system clock is stepped to the correct value. In practice the need for a step has is extremely rare and almost always the result of a hardware failure. With the <tt>-x</tt> option the step threshold is increased to 600 s. Other options are available using the <tt>tinker</tt> command on the <a href="miscopt.html">Miscellaneous Options</a> page.</p>
++		<p>Under ordinary conditions, <tt>ntpd</tt> slews the clock so that the time is effectively continuous and never runs backwards. If due to extreme network congestion an error spike exceeds the <i>step threshold</i>, by default 128 ms, the spike is discarded. However, if the error persists for more than the <i>stepout threshold</i>, by default 900 s, the system clock is stepped to the correct value. In practice the need for a step is extremely rare and is almost always the result of a hardware failure. With the <tt>-x</tt> option the step threshold is increased to 600 s. Other options are available using the <tt>tinker</tt> command on the <a href="miscopt.html">Miscellaneous Options</a> page.</p>
  		<p>The issues should be carefully considered before using these options. The maximum slew rate possible is limited to 500 parts-per-million (PPM) by the Unix kernel. As a result, the clock can take 2000 s for each second the clock is outside the acceptable range. During this interval the clock will not be consistent with any other network clock and the system cannot be used for distributed applications that require correctly synchronized network time.</p>
  		<p>The frequency file, usually called <tt>ntp.drift</tt>, contains the latest estimate  of clock frequency. If this file does not exist when <tt>ntpd</tt> is started, it enters a special mode designed to measure the particular frequency directly. The measurement takes 15 minutes, after which the frequency is set and <tt>ntpd</tt> resumes normal mode where the time and frequency are continuously adjusted. The frequency file is updated at intervals of an hour or more depending on the measured clock stability.</p>
+ 		<h4 id="modes">Operating Modes</h4>
 @@ -70,7 +70,7 @@
  			tally the leap warning bits of surviving servers and reference clocks.
  			When a majority of the survivors show warning, a leap is programmed
diff --git a/SOURCES/ntp-4.2.6p5-cve-2017-6462.patch b/SOURCES/ntp-4.2.6p5-cve-2017-6462.patch
new file mode 100644
index 0000000..a7e4a24
--- /dev/null
+++ b/SOURCES/ntp-4.2.6p5-cve-2017-6462.patch
@@ -0,0 +1,47 @@
+2017-02-12 13:46:35+01:00, perlinger@ntp.org
+  [Sec 3388] NTP-01-014: Buffer Overflow in DPTS Clock
+
+diff -up ntp-4.2.6p5/ntpd/refclock_datum.c.cve-2017-6462 ntp-4.2.6p5/ntpd/refclock_datum.c
+--- ntp-4.2.6p5/ntpd/refclock_datum.c.cve-2017-6462	2009-12-09 08:36:36.000000000 +0100
++++ ntp-4.2.6p5/ntpd/refclock_datum.c	2017-03-22 13:34:48.851357820 +0100
+@@ -584,7 +584,7 @@ datum_pts_receive(
+ 	struct recvbuf *rbufp
+ 	)
+ {
+-	int i;
++	int i, nb;
+ 	l_fp tstmp;
+ 	struct datum_pts_unit *datum_pts;
+ 	char *dpt;
+@@ -623,22 +623,23 @@ datum_pts_receive(
+ 	** received to reduce the jitter.
+ 	*/
+ 
+-	if (datum_pts->nbytes == 0) {
++	nb = datum_pts->nbytes;
++	if (nb == 0) {
+ 		datum_pts->lastrec = rbufp->recv_time;
+ 	}
+ 
+ 	/*
+ 	** Increment our count to the number of bytes received so far. Return if we
+ 	** haven't gotten all seven bytes yet.
++	** [Sec 3388] make sure we do not overrun the buffer.
++	** TODO: what to do with excessive bytes, if we ever get them?
+ 	*/
+-
+-	for (i=0; i<dpend; i++) {
+-		datum_pts->retbuf[datum_pts->nbytes+i] = dpt[i];
++	for (i=0; (i < dpend) && (nb < sizeof(datum_pts->retbuf)); i++, nb++) {
++		datum_pts->retbuf[nb] = dpt[i];
+ 	}
+-
+-	datum_pts->nbytes += dpend;
+-
+-	if (datum_pts->nbytes != 7) {
++	datum_pts->nbytes = nb;
++	
++	if (nb < 7) {
+ 		return;
+ 	}
+ 
diff --git a/SOURCES/ntp-4.2.6p5-cve-2017-6463.patch b/SOURCES/ntp-4.2.6p5-cve-2017-6463.patch
new file mode 100644
index 0000000..4067582
--- /dev/null
+++ b/SOURCES/ntp-4.2.6p5-cve-2017-6463.patch
@@ -0,0 +1,30 @@
+2017-02-12 11:08:16+01:00, perlinger@ntp.org
+  [Sec 3387] NTP-01-012: Authenticated DoS via Malicious Config Option
+
+diff -up ntp-4.2.6p5/ntpd/ntp_config.c.cve-2017-6463 ntp-4.2.6p5/ntpd/ntp_config.c
+--- ntp-4.2.6p5/ntpd/ntp_config.c.cve-2017-6463	2017-03-22 14:28:51.342870650 +0100
++++ ntp-4.2.6p5/ntpd/ntp_config.c	2017-03-22 15:20:44.970380429 +0100
+@@ -1264,7 +1264,8 @@ destroy_address_node(
+ 	struct address_node *my_node
+ 	)
+ {
+-	NTP_REQUIRE(NULL != my_node);
++	if (NULL == my_node)
++		return;
+ 	NTP_REQUIRE(NULL != my_node->address);
+ 
+ 	free(my_node->address);
+@@ -3563,10 +3564,10 @@ config_unpeers(
+ 	     curr_unpeer = next_node(curr_unpeer)) {
+ 
+ 		/*
+-		 * Either AssocID will be zero, and we unpeer by name/
+-		 * address addr, or it is nonzero and addr NULL.
++		 * If we have no address attached, assume we have to
++		 * unpeer by AssocID.
+ 		 */
+-		if (curr_unpeer->assocID) {
++		if (!curr_unpeer->addr) {
+ 			peer = findpeerbyassoc((u_int)curr_unpeer->assocID);
+ 			if (peer != NULL) {
+ 				peer_clear(peer, "GONE");
diff --git a/SOURCES/ntp-4.2.6p5-cve-2017-6464.patch b/SOURCES/ntp-4.2.6p5-cve-2017-6464.patch
new file mode 100644
index 0000000..6725c83
--- /dev/null
+++ b/SOURCES/ntp-4.2.6p5-cve-2017-6464.patch
@@ -0,0 +1,86 @@
+2017-02-12 09:49:29+01:00, perlinger@ntp.org
+  [Sec 3389] NTP-01-016: Denial of Service via Malformed Config
+
+diff -up ntp-4.2.6p5/ntpd/ntp_config.c.cve-2017-6464 ntp-4.2.6p5/ntpd/ntp_config.c
+--- ntp-4.2.6p5/ntpd/ntp_config.c.cve-2017-6464	2017-03-22 12:54:11.257454635 +0100
++++ ntp-4.2.6p5/ntpd/ntp_config.c	2017-03-22 12:57:06.919024166 +0100
+@@ -311,6 +311,9 @@ void ntpd_set_tod_using(const char *);
+ static u_int32 get_pfxmatch(const char **, struct masks *);
+ static u_int32 get_match(const char *, struct masks *);
+ static u_int32 get_logmask(const char *);
++static int/*BOOL*/ is_refclk_addr(const struct address_node * addr);
++
++
+ static int getnetnum(const char *num,sockaddr_u *addr, int complain,
+ 		     enum gnn_type a_type);
+ static int get_multiple_netnums(const char *num, sockaddr_u *addr,
+@@ -1342,7 +1344,10 @@ create_peer_node(
+ 			break;
+ 
+ 		case T_Ttl:
+-			if (my_node->ttl >= MAX_TTL) {
++			if (is_refclk_addr(addr)) {
++				msyslog(LOG_ERR, "'ttl' does not apply for refclocks");
++				errflag = 1;
++			} else if (option->value.i < 0 || option->value.i >= MAX_TTL) {
+ 				msyslog(LOG_ERR, "ttl: invalid argument");
+ 				errflag = 1;
+ 			}
+@@ -1351,7 +1355,12 @@ create_peer_node(
+ 			break;
+ 
+ 		case T_Mode:
+-			my_node->ttl = option->value.i;
++			if (is_refclk_addr(addr)) {
++				my_node->ttl = option->value.i;
++			} else {
++				msyslog(LOG_ERR, "'mode' does not apply for network peers");
++				errflag = 1;
++			}
+ 			break;
+ 
+		case T_Key:
+@@ -2674,6 +2685,16 @@ apply_enable_disable(
+ 	}
+ }
+ 
++/* Hack to disambiguate 'server' statements for refclocks and network peers.
++ * Please note the qualification 'hack'. It's just that.
++ */
++static int/*BOOL*/
++is_refclk_addr(
++	const struct address_node * addr
++	)
++{
++	return addr && addr->address && !strncmp(addr->address, "127.127.", 8);
++}
+ 
+ static void
+ config_system_opts(
+diff -up ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2017-6464 ntp-4.2.6p5/ntpd/ntp_proto.c
+--- ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2017-6464	2017-03-22 12:54:11.270454677 +0100
++++ ntp-4.2.6p5/ntpd/ntp_proto.c	2017-03-22 12:54:11.279454706 +0100
+@@ -3017,8 +3017,9 @@ peer_xmit(
+ 			}
+ 		}
+ 		peer->t21_bytes = sendlen;
+-		sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl],
+-		    &xpkt, sendlen);
++		sendpkt(&peer->srcadr, peer->dstadr,
++			sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl],
++			&xpkt, sendlen);
+ 		peer->sent++;
+ 		peer->throttle += (1 << peer->minpoll) - 2;
+ 
+@@ -3330,8 +3331,9 @@ peer_xmit(
+ 		exit (-1);
+ 	}
+ 	peer->t21_bytes = sendlen;
+-	sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt,
+-	    sendlen);
++	sendpkt(&peer->srcadr, peer->dstadr,
++		sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl],
++		&xpkt, sendlen);
+ 	peer->sent++;
+ 	peer->throttle += (1 << peer->minpoll) - 2;
+ 
diff --git a/SOURCES/ntp-4.2.6p5-defreqkey.patch b/SOURCES/ntp-4.2.6p5-defreqkey.patch
new file mode 100644
index 0000000..07f3062
--- /dev/null
+++ b/SOURCES/ntp-4.2.6p5-defreqkey.patch
@@ -0,0 +1,14 @@
+diff -up ntp-4.2.6p5/ntpd/ntp_config.c.defreqkey ntp-4.2.6p5/ntpd/ntp_config.c
+--- ntp-4.2.6p5/ntpd/ntp_config.c.defreqkey	2017-04-13 15:29:13.287254279 +0200
++++ ntp-4.2.6p5/ntpd/ntp_config.c	2017-04-13 15:40:49.776307282 +0200
+@@ -1870,8 +1870,8 @@ config_auth(
+ 			exit(1);
+ 		}
+ 
+-		req_keytype = NID_md5;
+-		req_hashlen = 16;
++		req_keytype = NID_sha1;
++		req_hashlen = 20;
+ 		MD5auth_setkey(req_keyid, req_keytype, rankey, sizeof(rankey));
+ 		authtrust(req_keyid, 1);
+ 	}
diff --git a/SOURCES/ntp-4.2.6p5-staunsync.patch b/SOURCES/ntp-4.2.6p5-staunsync.patch
new file mode 100644
index 0000000..8a8e279
--- /dev/null
+++ b/SOURCES/ntp-4.2.6p5-staunsync.patch
@@ -0,0 +1,16 @@
+diff -up ntp-4.2.6p5/ntpd/ntp_loopfilter.c.staunsync ntp-4.2.6p5/ntpd/ntp_loopfilter.c
+--- ntp-4.2.6p5/ntpd/ntp_loopfilter.c.staunsync	2017-09-20 10:38:35.776437535 +0200
++++ ntp-4.2.6p5/ntpd/ntp_loopfilter.c	2017-09-20 10:40:47.240562306 +0200
+@@ -935,9 +935,9 @@ loop_config(
+ 		pll_control = 1;
+ 		memset(&ntv, 0, sizeof(ntv));
+ 		ntv.modes = MOD_BITS;
+-		ntv.status = STA_PLL;
+-		ntv.maxerror = MAXDISPERSE;
+-		ntv.esterror = MAXDISPERSE;
++		ntv.status = STA_PLL | STA_UNSYNC;
++		ntv.maxerror = MAXDISPERSE * 1e6;
++		ntv.esterror = MAXDISPERSE * 1e6;
+ 		ntv.constant = sys_poll;
+ #ifdef SIGSYS
+ 		/*
diff --git a/SOURCES/ntp-4.2.6p5-tsyncdriver.patch b/SOURCES/ntp-4.2.6p5-tsyncdriver.patch
new file mode 100644
index 0000000..0a225cc
--- /dev/null
+++ b/SOURCES/ntp-4.2.6p5-tsyncdriver.patch
@@ -0,0 +1,1091 @@
+diff -up ntp-4.2.6p5/config.h.in.tsyncdriver ntp-4.2.6p5/config.h.in
+--- ntp-4.2.6p5/config.h.in.tsyncdriver	2011-12-25 00:32:51.000000000 +0100
++++ ntp-4.2.6p5/config.h.in	2017-09-19 11:01:08.267218957 +0200
+@@ -159,6 +159,9 @@
+ /* Zyfer GPStarplus */
+ #undef CLOCK_ZYFER
+ 
++/* Spectracom TSYNC PCI */
++#undef CLOCK_TSYNCPCI
++
+ /* Enable ntpd debugging code? */
+ #undef DEBUG
+ 
+diff -up ntp-4.2.6p5/configure.tsyncdriver ntp-4.2.6p5/configure
+--- ntp-4.2.6p5/configure.tsyncdriver	2011-12-25 00:31:17.000000000 +0100
++++ ntp-4.2.6p5/configure	2017-09-19 11:01:08.334221167 +0200
+@@ -22827,6 +22827,7 @@ esac
+ $as_echo "$ans" >&6; }
+ 
+ 
++$as_echo "#define CLOCK_TSYNCPCI 1" >>confdefs.h
+ 
+ 
+ 
+diff -up ntp-4.2.6p5/html/drivers/driver45.html.tsyncdriver ntp-4.2.6p5/html/drivers/driver45.html
+--- ntp-4.2.6p5/html/drivers/driver45.html.tsyncdriver	2017-09-19 11:01:08.269219023 +0200
++++ ntp-4.2.6p5/html/drivers/driver45.html	2017-09-19 11:01:08.269219023 +0200
+@@ -0,0 +1,32 @@
++<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
++
++<html>
++
++  <head>
++    <meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
++    <title>Spectracom TSYNC PCI</title>
++    <link href="scripts/style.css" type="text/css" rel="stylesheet">
++  </head>
++
++  <body>
++    <h3>Spectracom TSYNC PCI</h3>
++<p>Last update:
++  <!-- #BeginDate format:En2m -->26-Mar-2012  05:10<!-- #EndDate -->
++  UTC</p>
++    <hr>
++    <h4>Synopsis</h4>
++    Address: 127.127.45.<i>u</i><br>
++    Reference ID: one of <tt>GPS</tt>, <tt>IRIG</tt>, <tt>HVQ</tt>, <tt>FREQ</tt>, <tt>ACTS</tt>, <tt>PPS</tt>, <tt>PTP</tt>, <tt>ACT</tt>, <tt>USR</tt>, <tt>LOCL</tt><br>
++    Driver ID: <tt>Spectracom TSYNC PCI</tt><br>
++    Driver Port: <tt>/dev/tsyncpci<i>u</i></tt>
++    Features: <tt>(none)</tt>
++    <h4>Description</h4>
++    <p>This driver supports the <a
++	href="http://www.spectracomcorp.com/ProductsServices/TimingSynchronization/BuslevelTiming">Spectracom TSYNC PCI</a> receiver.</p>
++    <h4>Additional Information</h4>
++    <p><a href="../refclock.html">Reference Clock Drivers</a></p>
++    <hr>
++    <script type="text/javascript" language="javascript" src="scripts/footer.txt"></script>
++  </body>
++
++</html>
+diff -up ntp-4.2.6p5/html/refclock.html.tsyncdriver ntp-4.2.6p5/html/refclock.html
+--- ntp-4.2.6p5/html/refclock.html.tsyncdriver	2009-12-09 08:36:36.000000000 +0100
++++ ntp-4.2.6p5/html/refclock.html	2017-09-19 11:01:08.269219023 +0200
+@@ -82,9 +82,10 @@
+ 			<li class="inline"><a href="drivers/driver42.html">Type 42</a> Zyfer GPStarplus Receiver</li>
+ 			<li class="inline"><a href="drivers/driver43.html">Type 43</a> RIPE NCC interface for Trimble Palisade</li>
+ 			<li class="inline"><a href="drivers/driver44.html">Type 44</a> NeoClock4X - DCF77 / TDF serial line</li>
++			<li class="inline"><a href="drivers/driver45.html">Type 45</a> Spectracom TSYNC PCI</li>
+ 		</ul>
+ 		<hr>
+ 		<script type="text/javascript" language="javascript" src="scripts/footer.txt"></script>
+ 	</body>
+ 
+-</html>
+\ No newline at end of file
++</html>
+diff -up ntp-4.2.6p5/include/ntp.h.tsyncdriver ntp-4.2.6p5/include/ntp.h
+--- ntp-4.2.6p5/include/ntp.h.tsyncdriver	2017-09-19 11:01:08.246218264 +0200
++++ ntp-4.2.6p5/include/ntp.h	2017-09-19 11:01:08.269219023 +0200
+@@ -525,7 +525,8 @@ struct peer {
+ #define REFCLK_ZYFER		42	/* Zyfer GPStarplus receiver  */
+ #define REFCLK_RIPENCC		43	/* RIPE NCC Trimble driver */
+ #define REFCLK_NEOCLOCK4X	44	/* NeoClock4X DCF77 or TDF receiver */
+-#define REFCLK_MAX		44	/* NeoClock4X DCF77 or TDF receiver */
++#define REFCLK_TSYNCPCI		45	/* Spectracom TSYNC PCI timing board */
++#define REFCLK_MAX		45	/* Spectracom TSYNC PCI timing board */
+ 
+ 
+ /*
+diff -up ntp-4.2.6p5/libntp/clocktypes.c.tsyncdriver ntp-4.2.6p5/libntp/clocktypes.c
+--- ntp-4.2.6p5/libntp/clocktypes.c.tsyncdriver	2009-12-09 08:36:37.000000000 +0100
++++ ntp-4.2.6p5/libntp/clocktypes.c	2017-09-19 11:01:08.270219055 +0200
+@@ -100,6 +100,8 @@ struct clktype clktypes[] = {
+ 	  "GPS_RIPENCC" },
+ 	{ REFCLK_NEOCLOCK4X,	"NeoClock4X DCF77 / TDF receiver (44)",
+ 	  "NEOCLK4X"},
++	{ REFCLK_TSYNCPCI,	"Spectracom TSYNC PCI timing board (45)",
++	  "PCI_TSYNC"},
+ 	{ -1,			"", "" }
+ };
+ 
+diff -up ntp-4.2.6p5/ntpd/Makefile.in.tsyncdriver ntp-4.2.6p5/ntpd/Makefile.in
+--- ntp-4.2.6p5/ntpd/Makefile.in.tsyncdriver	2011-12-25 00:31:11.000000000 +0100
++++ ntp-4.2.6p5/ntpd/Makefile.in	2017-09-19 11:01:08.270219055 +0200
+@@ -97,6 +97,7 @@ am_libntpd_a_OBJECTS = ntp_control.$(OBJ
+ 	refclock_tpro.$(OBJEXT) refclock_true.$(OBJEXT) \
+ 	refclock_tt560.$(OBJEXT) refclock_ulink.$(OBJEXT) \
+ 	refclock_wwv.$(OBJEXT) refclock_wwvb.$(OBJEXT) \
++	refclock_tsyncpci.$(OBJEXT) \
+ 	refclock_zyfer.$(OBJEXT) $(am__objects_1)
+ libntpd_a_OBJECTS = $(am_libntpd_a_OBJECTS)
+ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \
+@@ -499,6 +500,7 @@ libntpd_a_SOURCES = \
+ 	refclock_wwv.c		\
+ 	refclock_wwvb.c		\
+ 	refclock_zyfer.c	\
++	refclock_tsyncpci.c	\
+ 	$(NULL)
+ 
+ all: $(BUILT_SOURCES)
+@@ -734,6 +736,7 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_wwv.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_wwvb.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_zyfer.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refclock_tsyncpci.Po@am__quote@
+ 
+ .c.o:
+ @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+diff -up ntp-4.2.6p5/ntpd/ntp_control.c.tsyncdriver ntp-4.2.6p5/ntpd/ntp_control.c
+--- ntp-4.2.6p5/ntpd/ntp_control.c.tsyncdriver	2017-09-19 11:01:08.266218923 +0200
++++ ntp-4.2.6p5/ntpd/ntp_control.c	2017-09-19 11:01:08.270219055 +0200
+@@ -419,6 +419,7 @@ static u_char clocktypes[] = {
+ 	CTL_SST_TS_UHF,		/* REFCLK_ZYFER (42) */
+ 	CTL_SST_TS_UHF,		/* REFCLK_RIPENCC (43) */
+ 	CTL_SST_TS_UHF,		/* REFCLK_NEOCLOCK4X (44) */
++	CTL_SST_TS_UHF,		/* REFCLK_TSYNCPCI (45) */
+ };
+ 
+ 
+diff -up ntp-4.2.6p5/ntpd/refclock_conf.c.tsyncdriver ntp-4.2.6p5/ntpd/refclock_conf.c
+--- ntp-4.2.6p5/ntpd/refclock_conf.c.tsyncdriver	2011-01-04 02:57:27.000000000 +0100
++++ ntp-4.2.6p5/ntpd/refclock_conf.c	2017-09-19 11:01:08.270219055 +0200
+@@ -258,6 +258,12 @@ extern	struct refclock	refclock_neoclock
+ #define	refclock_neoclock4x	refclock_none
+ #endif
+ 
++#ifdef CLOCK_TSYNCPCI
++extern struct refclock refclock_tsyncpci;
++#else
++#define refclock_tsyncpci refclock_none
++#endif
++
+ /*
+  * Order is clock_start(), clock_shutdown(), clock_poll(),
+  * clock_control(), clock_init(), clock_buginfo, clock_flags;
+@@ -309,7 +315,8 @@ struct refclock * const refclock_conf[]
+ 	&refclock_tt560,	/* 41 REFCLK_TT560 */
+ 	&refclock_zyfer,	/* 42 REFCLK_ZYFER */
+ 	&refclock_ripencc,	/* 43 REFCLK_RIPENCC */
+-	&refclock_neoclock4x    /* 44 REFCLK_NEOCLOCK4X */
++	&refclock_neoclock4x,	/* 44 REFCLK_NEOCLOCK4X */
++	&refclock_tsyncpci	/* 45 REFCLK_TSYNCPCI */
+ };
+ 
+ u_char num_refclock_conf = sizeof(refclock_conf)/sizeof(struct refclock *);
+diff -up ntp-4.2.6p5/ntpd/refclock_tsyncpci.c.tsyncdriver ntp-4.2.6p5/ntpd/refclock_tsyncpci.c
+--- ntp-4.2.6p5/ntpd/refclock_tsyncpci.c.tsyncdriver	2017-09-19 11:01:08.271219088 +0200
++++ ntp-4.2.6p5/ntpd/refclock_tsyncpci.c	2017-09-19 11:04:55.261709585 +0200
+@@ -0,0 +1,922 @@
++/*******************************************************************************
++*
++*  Module  : refclock_tsyncpci.c
++*  Date    : 09/08/08
++*  Purpose : Implements a reference clock driver for the NTP daemon.  This
++*            reference clock driver provides a means to communicate with
++*            the Spectracom TSYNC PCI timing devices and use them as a time
++*            source.
++*
++*  (C) Copyright 2008 Spectracom Corporation
++*
++*  This software is provided by Spectracom Corporation 'as is' and
++*  any express or implied warranties, including, but not limited to, the
++*  implied warranties of merchantability and fitness for a particular purpose
++*  are disclaimed.  In no event shall Spectracom Corporation be liable
++*  for any direct, indirect, incidental, special, exemplary, or consequential
++*  damages (including, but not limited to, procurement of substitute goods
++*  or services; loss of use, data, or profits; or business interruption)
++*  however caused and on any theory of liability, whether in contract, strict
++*  liability, or tort (including negligence or otherwise) arising in any way
++*  out of the use of this software, even if advised of the possibility of
++*  such damage.
++*
++*  This software is released for distribution according to the NTP copyright
++*  and license contained in html/copyright.html of NTP source.
++*
++*******************************************************************************/
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#if defined(REFCLOCK) && defined(CLOCK_TSYNCPCI)
++
++#include <asm/ioctl.h>
++#ifdef HAVE_SYS_IOCTL_H
++# include <sys/ioctl.h>
++#endif
++
++#include <stdio.h>
++#include <ctype.h>
++#include <netinet/in.h>
++
++
++#include "ntpd.h"
++#include "ntp_io.h"
++#include "ntp_refclock.h"
++#include "ntp_unixtime.h"
++#include "ntp_stdlib.h"
++#include "ntp_calendar.h"
++
++
++/*******************************************************************************
++**
++** This driver supports the Spectracom TSYNC PCI GPS receiver.  It requires
++** that the tsyncpci.o device driver be installed and loaded.
++**
++*******************************************************************************/
++
++#define TSYNC_PCI_REVISION "1.11"
++
++/*
++** TPRO interface definitions
++*/
++#define DEVICE      "/dev/tsyncpci"             /* device name */
++#define PRECISION   (-20)                       /* precision assumed (1 us) */
++#define DESCRIPTION "Spectracom TSYNC-PCI"      /* WRU */
++
++#define SECONDS_1900_TO_1970 (2208988800U)
++
++#define TSYNC_REF_IID               (0x2500)    // SS CAI, REF IID
++#define TSYNC_REF_DEST_ID           (0x0001)    // KTS Firmware
++#define TSYNC_REF_IN_PYLD_OFF       (0)
++#define TSYNC_REF_IN_LEN            (0)
++#define TSYNC_REF_OUT_PYLD_OFF      (0)
++#define TSYNC_REF_OUT_LEN           (8)
++#define TSYNC_REF_MAX_OUT_LEN       (16)
++#define TSYNC_REF_PYLD_LEN          (TSYNC_REF_IN_LEN +                     \
++                                     TSYNC_REF_MAX_OUT_LEN)
++#define TSYNC_REF_LEN               (4)
++#define TSYNC_REF_LOCAL             ("LOCL")
++
++#define TSYNC_TMSCL_IID              (0x2301)    // CS CAI, TIMESCALE IID
++#define TSYNC_TMSCL_DEST_ID          (0x0001)    // KTS Firmware
++#define TSYNC_TMSCL_IN_PYLD_OFF      (0)
++#define TSYNC_TMSCL_IN_LEN           (0)
++#define TSYNC_TMSCL_OUT_PYLD_OFF     (0)
++#define TSYNC_TMSCL_OUT_LEN          (4)
++#define TSYNC_TMSCL_MAX_OUT_LEN      (12)
++#define TSYNC_TMSCL_PYLD_LEN         (TSYNC_TMSCL_IN_LEN +                    \
++                                     TSYNC_TMSCL_MAX_OUT_LEN)
++
++#define TSYNC_LEAP_IID              (0x2307)    // CS CAI, LEAP SEC IID
++#define TSYNC_LEAP_DEST_ID          (0x0001)    // KTS Firmware
++#define TSYNC_LEAP_IN_PYLD_OFF      (0)
++#define TSYNC_LEAP_IN_LEN           (0)
++#define TSYNC_LEAP_OUT_PYLD_OFF     (0)
++#define TSYNC_LEAP_OUT_LEN          (28)
++#define TSYNC_LEAP_MAX_OUT_LEN      (36)
++#define TSYNC_LEAP_PYLD_LEN         (TSYNC_LEAP_IN_LEN +                    \
++                                     TSYNC_LEAP_MAX_OUT_LEN)
++
++// These define the base date/time of the system clock.  The system time will
++// be tracked as the number of seconds from this date/time.
++#define TSYNC_TIME_BASE_YEAR        (1970) // earliest acceptable year
++#define TSYNC_SECS_PER_MIN          (60)
++#define TSYNC_MINS_PER_HR           (60)
++#define TSYNC_HRS_PER_DAY           (24)
++#define TSYNC_DAYS_PER_YR           (365)
++#define TSYNC_DAYS_PER_LYR          (366)
++#define TSYNC_SECS_PER_HR           (TSYNC_MINS_PER_HR  * TSYNC_SECS_PER_MIN)
++#define TSYNC_SECS_PER_DAY          (TSYNC_HRS_PER_DAY  * TSYNC_SECS_PER_HR)
++#define TSYNC_SECS_PER_YR           (TSYNC_DAYS_PER_YR  * TSYNC_SECS_PER_DAY)
++#define TSYNC_SECS_PER_LYR          (TSYNC_DAYS_PER_LYR * TSYNC_SECS_PER_DAY)
++
++
++#define TSYNC_LCL_STRATUM           (0)
++
++/*
++** TSYNC Time Scales type
++*/
++typedef enum
++{
++    TIME_SCALE_UTC    = 0,   // Universal Coordinated Time
++    TIME_SCALE_TAI    = 1,   // International Atomic Time
++    TIME_SCALE_GPS    = 2,   // Global Positioning System
++    TIME_SCALE_LOCAL  = 3,   // UTC w/local rules for time zone and DST
++    NUM_TIME_SCALES   = 4,   // Number of time scales
++
++    TIME_SCALE_MAX    = 15   // Maximum number of timescales
++
++} TIME_SCALE;
++
++/*
++** TSYNC Board Object
++*/
++typedef struct BoardObj {
++
++  int            file_descriptor;
++  unsigned short devid;
++  unsigned short options;
++  unsigned char  firmware[5];
++  unsigned char  FPGA[5];
++  unsigned char  driver[7];
++
++} BoardObj;
++
++/*
++** TSYNC Time Object
++*/
++typedef struct TimeObj {
++
++  unsigned char  syncOption;  /* -M option */
++  unsigned int   secsDouble;  /* seconds floating pt */
++  unsigned char  seconds;     /* seconds whole num */
++  unsigned char  minutes;
++  unsigned char  hours;
++  unsigned short days;
++  unsigned short year;
++  unsigned short flags;      /* bit 2 SYNC, bit 1 TCODE; all others 0 */
++
++} TimeObj;
++
++/*
++** NTP Time Object
++*/
++typedef struct NtpTimeObj {
++
++    TimeObj        timeObj;
++    struct timeval tv;
++    unsigned int   refId;
++
++} NtpTimeObj;
++/*
++** TSYNC Supervisor Reference Object
++*/
++typedef struct ReferenceObj {
++
++    char time[TSYNC_REF_LEN];
++    char pps[TSYNC_REF_LEN];
++
++} ReferenceObj;
++
++/*
++** TSYNC Seconds Time Object
++*/
++typedef struct SecTimeObj
++{
++    unsigned int seconds;
++    unsigned int ns;
++}
++SecTimeObj;
++
++/*
++** TSYNC DOY Time Object
++*/
++typedef struct DoyTimeObj
++{
++    unsigned int year;
++    unsigned int doy;
++    unsigned int hour;
++    unsigned int minute;
++    unsigned int second;
++    unsigned int ns;
++}
++DoyTimeObj;
++
++/*
++** TSYNC Leap Second Object
++*/
++typedef struct LeapSecondObj
++{
++    int        offset;
++    DoyTimeObj utcDate;
++}
++LeapSecondObj;
++
++/*
++ * structures for ioctl interactions with driver
++ */
++#define DI_PAYLOADS_STARTER_LENGTH 4
++typedef struct ioctl_trans_di {
++
++    // input parameters
++    uint16_t        dest;
++    uint16_t        iid;
++
++    uint32_t        inPayloadOffset;
++    uint32_t        inLength;
++    uint32_t        outPayloadOffset;
++    uint32_t        maxOutLength;
++
++    // output parameters
++    uint32_t        actualOutLength;
++    int32_t         status;
++
++    // Input and output
++
++    // The payloads field MUST be last in ioctl_trans_di.
++    uint8_t         payloads[DI_PAYLOADS_STARTER_LENGTH];
++
++}ioctl_trans_di;
++
++/*
++ * structure for looking up a reference ID from a reference name
++ */
++typedef struct
++{
++    const char* pRef;           // KTS Reference Name
++    const char* pRefId;         // NTP Reference ID
++
++} RefIdLookup;
++
++/*
++ * unit control structure
++ */
++typedef struct  {
++    uint32_t refPrefer;         // Reference prefer flag
++    uint32_t refId;             // Host peer reference ID
++    uint8_t  refStratum;        // Host peer reference stratum
++
++} TsyncUnit;
++
++/*
++**  Function prototypes
++*/
++static void tsync_poll     (int unit, struct peer *);
++static void tsync_shutdown (int, struct peer *);
++static int  tsync_start    (int, struct peer *);
++
++/*
++**  Helper functions
++*/
++static void ApplyTimeOffset    (DoyTimeObj* pDt, int off);
++static void SecTimeFromDoyTime (SecTimeObj* pSt, DoyTimeObj* pDt);
++static void DoyTimeFromSecTime (DoyTimeObj* pDt, SecTimeObj* pSt);
++
++/*
++**  Transfer vector
++*/
++struct refclock refclock_tsyncpci = {
++    tsync_start,    /* start up driver */
++    tsync_shutdown, /* shut down driver */
++    tsync_poll,     /* transmit poll message */
++    noentry,        /* not used (old tsync_control) */
++    noentry,        /* initialize driver (not used) */
++    noentry,        /* not used (old tsync_buginfo) */
++    NOFLAGS         /* not used */
++};
++
++/*
++ * Reference ID lookup table
++ */
++static RefIdLookup RefIdLookupTbl[] =
++{
++    {"gps",  "GPS"},
++    {"ir",   "IRIG"},
++    {"hvq",  "HVQ"},
++    {"frq",  "FREQ"},
++    {"mdm",  "ACTS"},
++    {"epp",  "PPS"},
++    {"ptp",  "PTP"},
++    {"asc",  "ATC"},
++    {"hst0", "USER"},
++    {"hst",  TSYNC_REF_LOCAL},
++    {"self", TSYNC_REF_LOCAL},
++    {NULL,   NULL}
++};
++
++/*******************************************************************************
++**          IOCTL DEFINITIONS
++*******************************************************************************/
++#define IOCTL_TPRO_ID            't'
++#define IOCTL_TPRO_OPEN          _IOWR(IOCTL_TPRO_ID, 0,  BoardObj)
++#define IOCTL_TPRO_GET_NTP_TIME  _IOWR(IOCTL_TPRO_ID, 25, NtpTimeObj)
++#define IOCTL_TSYNC_GET          _IOWR(IOCTL_TPRO_ID, 26, ioctl_trans_di)
++
++/******************************************************************************
++ *
++ * Function:    tsync_start()
++ * Description: Used to intialize the Spectracom TSYNC reference driver.
++ *
++ * Parameters:
++ *     IN:  unit - not used.
++ *         *peer - pointer to this reference clock's peer structure
++ *     Returns: 0 - unsuccessful
++ *              1 - successful
++ *
++*******************************************************************************/
++static int tsync_start(int unit, struct peer *peer)
++{
++    struct refclockproc *pp;
++    TsyncUnit           *up;
++
++
++    /*
++    **  initialize reference clock and peer parameters
++    */
++    pp                = peer->procptr;
++    pp->clockdesc     = DESCRIPTION;
++    pp->io.clock_recv = noentry;
++    pp->io.srcclock   = (caddr_t)peer;
++    pp->io.datalen    = 0;
++    peer->precision   = PRECISION;
++
++    // Allocate and initialize unit structure
++    if (!(up = (TsyncUnit*)emalloc(sizeof(TsyncUnit))))
++    {
++        return (0);
++    }
++
++    // Store reference preference
++    up->refPrefer = peer->flags & FLAG_PREFER;
++
++    // Initialize reference stratum level and ID
++    up->refStratum = STRATUM_UNSPEC;
++    strncpy((char *)&up->refId, TSYNC_REF_LOCAL, TSYNC_REF_LEN);
++
++    // Attach unit structure
++    pp->unitptr = (caddr_t)up;
++
++    /* Declare our refId as local in the beginning because we do not know
++     * what our actual refid is yet.
++     */
++    strncpy((char *)&pp->refid, TSYNC_REF_LOCAL, TSYNC_REF_LEN);
++
++    return (1);
++
++} /* End - tsync_start() */
++
++/*******************************************************************************
++**
++** Function:    tsync_shutdown()
++** Description: Handles anything related to shutting down the reference clock
++**              driver. Nothing at this point in time.
++**
++** Parameters:
++**     IN:  unit - not used.
++**         *peer - pointer to this reference clock's peer structure
++**     Returns: none.
++**
++*******************************************************************************/
++static void tsync_shutdown(int unit, struct peer *peer)
++{
++
++} /* End - tsync_shutdown() */
++
++/******************************************************************************
++ *
++ * Function:    tsync_poll()
++ * Description: Retrieve time from the TSYNC device.
++ *
++ * Parameters:
++ *     IN:  unit - not used.
++ *         *peer - pointer to this reference clock's peer structure
++ *     Returns: none.
++ *
++*******************************************************************************/
++static void tsync_poll(int unit, struct peer *peer)
++{
++    char                 device[32];
++    struct refclockproc *pp;
++    struct calendar      jt;
++    TsyncUnit           *up;
++    unsigned char        synch;
++    double               seconds;
++    int                  err;
++    int                  err1;
++    int                  err2;
++    int                  err3;
++    int                  i;
++    int                  j;
++    unsigned int         itAllocationLength;
++    unsigned int         itAllocationLength1;
++    unsigned int         itAllocationLength2;
++    NtpTimeObj           TimeContext;
++    BoardObj             hBoard;
++    char                 timeRef[TSYNC_REF_LEN + 1];
++    char                 ppsRef [TSYNC_REF_LEN + 1];
++    TIME_SCALE           tmscl = TIME_SCALE_UTC;
++    LeapSecondObj        leapSec;
++    ioctl_trans_di      *it;
++    ioctl_trans_di      *it1;
++    ioctl_trans_di      *it2;
++    l_fp                 offset;
++    l_fp                 ltemp;
++    ReferenceObj *	 pRefObj;
++
++
++    /* Construct the device name */
++    sprintf(device, "%s%d", DEVICE, (int)peer->refclkunit);
++
++    printf("Polling device number %d...\n", (int)peer->refclkunit);
++
++    /* Open the TSYNC device */
++    hBoard.file_descriptor = open(device, O_RDONLY | O_NDELAY, 0777);
++
++    /* If error opening TSYNC device... */
++    if (hBoard.file_descriptor < 0)
++    {
++        msyslog(LOG_ERR, "Couldn't open device");
++        return;
++    }
++
++    /* If error while initializing the board... */
++    if (ioctl(hBoard.file_descriptor, IOCTL_TPRO_OPEN, &hBoard) < 0)
++    {
++        msyslog(LOG_ERR, "Couldn't initialize device");
++        close(hBoard.file_descriptor);
++        return;
++    }
++
++    /* Allocate memory for ioctl message */
++    itAllocationLength =
++        (sizeof(ioctl_trans_di) - DI_PAYLOADS_STARTER_LENGTH) +
++        TSYNC_REF_IN_LEN + TSYNC_REF_MAX_OUT_LEN;
++
++    it = (ioctl_trans_di*)alloca(itAllocationLength);
++    if (it == NULL) {
++        msyslog(LOG_ERR, "Couldn't allocate transaction memory - Reference");
++        return;
++    }
++
++    /* Build SS_GetRef ioctl message */
++    it->dest             = TSYNC_REF_DEST_ID;
++    it->iid              = TSYNC_REF_IID;
++    it->inPayloadOffset  = TSYNC_REF_IN_PYLD_OFF;
++    it->inLength         = TSYNC_REF_IN_LEN;
++    it->outPayloadOffset = TSYNC_REF_OUT_PYLD_OFF;
++    it->maxOutLength     = TSYNC_REF_MAX_OUT_LEN;
++    it->actualOutLength  = 0;
++    it->status           = 0;
++    memset(it->payloads, 0, TSYNC_REF_MAX_OUT_LEN);
++
++    /* Read the reference from the TSYNC-PCI device */
++    err = ioctl(hBoard.file_descriptor,
++                 IOCTL_TSYNC_GET,
++                (char *)it);
++
++    /* Allocate memory for ioctl message */
++    itAllocationLength1 =
++        (sizeof(ioctl_trans_di) - DI_PAYLOADS_STARTER_LENGTH) +
++        TSYNC_TMSCL_IN_LEN + TSYNC_TMSCL_MAX_OUT_LEN;
++
++    it1 = (ioctl_trans_di*)alloca(itAllocationLength1);
++    if (it1 == NULL) {
++        msyslog(LOG_ERR, "Couldn't allocate transaction memory - Time Scale");
++        return;
++    }
++
++    /* Build CS_GetTimeScale ioctl message */
++    it1->dest             = TSYNC_TMSCL_DEST_ID;
++    it1->iid              = TSYNC_TMSCL_IID;
++    it1->inPayloadOffset  = TSYNC_TMSCL_IN_PYLD_OFF;
++    it1->inLength         = TSYNC_TMSCL_IN_LEN;
++    it1->outPayloadOffset = TSYNC_TMSCL_OUT_PYLD_OFF;
++    it1->maxOutLength     = TSYNC_TMSCL_MAX_OUT_LEN;
++    it1->actualOutLength  = 0;
++    it1->status           = 0;
++    memset(it1->payloads, 0, TSYNC_TMSCL_MAX_OUT_LEN);
++
++    /* Read the Time Scale info from the TSYNC-PCI device */
++    err1 = ioctl(hBoard.file_descriptor,
++                 IOCTL_TSYNC_GET,
++                 (char *)it1);
++
++    /* Allocate memory for ioctl message */
++    itAllocationLength2 =
++        (sizeof(ioctl_trans_di) - DI_PAYLOADS_STARTER_LENGTH) +
++        TSYNC_LEAP_IN_LEN + TSYNC_LEAP_MAX_OUT_LEN;
++
++    it2 = (ioctl_trans_di*)alloca(itAllocationLength2);
++    if (it2 == NULL) {
++        msyslog(LOG_ERR, "Couldn't allocate transaction memory - Leap Second");
++        return;
++    }
++
++    /* Build CS_GetLeapSec ioctl message */
++    it2->dest             = TSYNC_LEAP_DEST_ID;
++    it2->iid              = TSYNC_LEAP_IID;
++    it2->inPayloadOffset  = TSYNC_LEAP_IN_PYLD_OFF;
++    it2->inLength         = TSYNC_LEAP_IN_LEN;
++    it2->outPayloadOffset = TSYNC_LEAP_OUT_PYLD_OFF;
++    it2->maxOutLength     = TSYNC_LEAP_MAX_OUT_LEN;
++    it2->actualOutLength  = 0;
++    it2->status           = 0;
++    memset(it2->payloads, 0, TSYNC_LEAP_MAX_OUT_LEN);
++
++    /* Read the leap seconds info from the TSYNC-PCI device */
++    err2 = ioctl(hBoard.file_descriptor,
++                 IOCTL_TSYNC_GET,
++                 (char *)it2);
++
++    pp = peer->procptr;
++    up = (TsyncUnit*)pp->unitptr;
++
++    /* Read the time from the TSYNC-PCI device */
++    err3 = ioctl(hBoard.file_descriptor,
++                 IOCTL_TPRO_GET_NTP_TIME,
++                 (char *)&TimeContext);
++
++    /* Close the TSYNC device */
++    close(hBoard.file_descriptor);
++
++    // Check for errors
++    if ((err < 0) ||(err1 < 0) || (err2 < 0) || (err3 < 0) ||
++        (it->status != 0) || (it1->status != 0) || (it2->status != 0) ||
++        (it->actualOutLength  != TSYNC_REF_OUT_LEN) ||
++        (it1->actualOutLength != TSYNC_TMSCL_OUT_LEN) ||
++        (it2->actualOutLength != TSYNC_LEAP_OUT_LEN)) {
++        refclock_report(peer, CEVNT_FAULT);
++        return;
++    }
++
++    // Extract reference identifiers from ioctl payload
++    memset(timeRef, '\0', sizeof(timeRef));
++    memset(ppsRef, '\0', sizeof(ppsRef));
++    pRefObj = (void *)it->payloads;
++    memcpy(timeRef, pRefObj->time, TSYNC_REF_LEN);
++    memcpy(ppsRef, pRefObj->pps, TSYNC_REF_LEN);
++
++    // Extract the Clock Service Time Scale and convert to correct byte order
++    memcpy(&tmscl, it1->payloads, sizeof(tmscl));
++    tmscl = ntohl(tmscl);
++
++    // Extract leap second info from ioctl payload and perform byte swapping
++    for (i = 0; i < (sizeof(leapSec) / 4); i++)
++    {
++        for (j = 0; j < 4; j++)
++        {
++            ((unsigned char*)&leapSec)[(i * 4) + j] =
++                    ((unsigned char*)(it2->payloads))[(i * 4) + (3 - j)];
++        }
++    }
++
++    // Determine time reference ID from reference name
++    for (i = 0; RefIdLookupTbl[i].pRef != NULL; i++)
++    {
++       // Search RefID table
++       if (strstr(timeRef, RefIdLookupTbl[i].pRef) != NULL)
++       {
++          // Found the matching string
++          break;
++       }
++    }
++
++    // Determine pps reference ID from reference name
++    for (j = 0; RefIdLookupTbl[j].pRef != NULL; j++)
++    {
++       // Search RefID table
++       if (strstr(ppsRef, RefIdLookupTbl[j].pRef) != NULL)
++       {
++          // Found the matching string
++          break;
++       }
++    }
++
++    // Determine synchronization state from flags
++    synch = (TimeContext.timeObj.flags == 0x4) ? 1 : 0;
++
++    // Pull seconds information from time object
++    seconds = (double) (TimeContext.timeObj.secsDouble);
++    seconds /= (double) 1000000.0;
++
++    /*
++    ** Convert the number of microseconds to double and then place in the
++    ** peer's last received long floating point format.
++    */
++    DTOLFP(((double)TimeContext.tv.tv_usec / 1000000.0), &pp->lastrec);
++
++    /*
++    ** The specTimeStamp is the number of seconds since 1/1/1970, while the
++    ** peer's lastrec time should be compatible with NTP which is seconds since
++    ** 1/1/1900.  So Add the number of seconds between 1900 and 1970 to the
++    ** specTimeStamp and place in the peer's lastrec long floating point struct.
++    */
++    pp->lastrec.Ul_i.Xl_ui += (unsigned int)TimeContext.tv.tv_sec +
++                                            SECONDS_1900_TO_1970;
++
++    pp->polls++;
++
++    /*
++    **  set the reference clock object
++    */
++    sprintf(pp->a_lastcode, "%03d %02d:%02d:%02.6f",
++            TimeContext.timeObj.days, TimeContext.timeObj.hours,
++            TimeContext.timeObj.minutes, seconds);
++
++    pp->lencode = strlen (pp->a_lastcode);
++    pp->day     = TimeContext.timeObj.days;
++    pp->hour    = TimeContext.timeObj.hours;
++    pp->minute  = TimeContext.timeObj.minutes;
++    pp->second  = (int) seconds;
++    seconds     = (seconds - (double) (pp->second / 1.0)) * 1000000000;
++    pp->nsec    = (long) seconds;
++
++    /*
++    **  calculate year start
++    */
++    jt.year       = TimeContext.timeObj.year;
++    jt.yearday    = 1;
++    jt.monthday   = 1;
++    jt.month      = 1;
++    jt.hour       = 0;
++    jt.minute     = 0;
++    jt.second     = 0;
++    pp->yearstart = caltontp(&jt);
++
++    // Calculate and report reference clock offset
++    offset.l_ui = (long)(((pp->day - 1) * 24) + pp->hour + GMT);
++    offset.l_ui = (offset.l_ui * 60) + (long)pp->minute;
++    offset.l_ui = (offset.l_ui * 60) + (long)pp->second;
++    offset.l_ui = offset.l_ui + (long)pp->yearstart;
++    offset.l_uf = 0;
++    DTOLFP(pp->nsec / 1e9, &ltemp);
++    L_ADD(&offset, &ltemp);
++    refclock_process_offset(pp, offset, pp->lastrec,
++                            pp->fudgetime1);
++
++    // KTS in sync
++    if (synch) {
++        // Subtract leap second info by one second to determine effective day
++        ApplyTimeOffset(&(leapSec.utcDate), -1);
++
++        // If there is a leap second today and the KTS is using a time scale
++        // which handles leap seconds then
++        if ((tmscl != TIME_SCALE_GPS) && (tmscl != TIME_SCALE_TAI) &&
++            (leapSec.utcDate.year == (unsigned int)TimeContext.timeObj.year) &&
++            (leapSec.utcDate.doy  == (unsigned int)TimeContext.timeObj.days))
++        {
++            // If adding a second
++            if (leapSec.offset == 1)
++            {
++                pp->leap = LEAP_ADDSECOND;
++            }
++            // Else if removing a second
++            else if (leapSec.offset == -1)
++            {
++                pp->leap = LEAP_DELSECOND;
++            }
++            // Else report no leap second pending (no handling of offsets
++            // other than +1 or -1)
++            else
++            {
++                pp->leap = LEAP_NOWARNING;
++            }
++        }
++        // Else report no leap second pending
++        else
++        {
++            pp->leap = LEAP_NOWARNING;
++        }
++
++        peer->leap = pp->leap;
++        refclock_report(peer, CEVNT_NOMINAL);
++
++        // If reference name reported, then not in holdover
++        if ((RefIdLookupTbl[i].pRef != NULL) &&
++            (RefIdLookupTbl[j].pRef != NULL))
++        {
++            // Determine if KTS being synchronized by host (identified as
++            // "LOCL")
++            if ((strcmp(RefIdLookupTbl[i].pRefId, TSYNC_REF_LOCAL) == 0) ||
++                (strcmp(RefIdLookupTbl[j].pRefId, TSYNC_REF_LOCAL) == 0))
++            {
++                // Clear prefer flag
++                peer->flags &= ~FLAG_PREFER;
++
++                // Set reference clock stratum level as unusable
++                pp->stratum   = STRATUM_UNSPEC;
++                peer->stratum = pp->stratum;
++
++                // If a valid peer is available
++                if ((sys_peer != NULL) && (sys_peer != peer))
++                {
++                    // Store reference peer stratum level and ID
++                    up->refStratum = sys_peer->stratum;
++                    up->refId      = addr2refid(&sys_peer->srcadr);
++                }
++            }
++            else
++            {
++                // Restore prefer flag
++                peer->flags |= up->refPrefer;
++
++                // Store reference stratum as local clock
++                up->refStratum = TSYNC_LCL_STRATUM;
++                strncpy((char *)&up->refId, RefIdLookupTbl[j].pRefId,
++                    TSYNC_REF_LEN);
++
++                // Set reference clock stratum level as local clock
++                pp->stratum   = TSYNC_LCL_STRATUM;
++                peer->stratum = pp->stratum;
++            }
++
++            // Update reference name
++            strncpy((char *)&pp->refid, RefIdLookupTbl[j].pRefId,
++                TSYNC_REF_LEN);
++            peer->refid = pp->refid;
++        }
++        // Else in holdover
++        else
++        {
++            // Restore prefer flag
++            peer->flags |= up->refPrefer;
++
++            // Update reference ID to saved ID
++            pp->refid   = up->refId;
++            peer->refid = pp->refid;
++
++            // Update stratum level to saved stratum level
++            pp->stratum   = up->refStratum;
++            peer->stratum = pp->stratum;
++        }
++    }
++    // Else KTS not in sync
++    else {
++        // Place local identifier in peer RefID
++        strncpy((char *)&pp->refid, TSYNC_REF_LOCAL, TSYNC_REF_LEN);
++        peer->refid = pp->refid;
++
++        // Report not in sync
++        pp->leap   = LEAP_NOTINSYNC;
++        peer->leap = pp->leap;
++    }
++
++    if (pp->coderecv == pp->codeproc) {
++        refclock_report(peer, CEVNT_TIMEOUT);
++        return;
++    }
++
++    record_clock_stats(&peer->srcadr, pp->a_lastcode);
++    refclock_receive(peer);
++
++    /* Increment the number of times the reference has been polled */
++    pp->polls++;
++
++} /* End - tsync_poll() */
++
++
++////////////////////////////////////////////////////////////////////////////////
++// Function:    ApplyTimeOffset
++// Description: The ApplyTimeOffset function adds an offset (in seconds) to a
++//              specified date and time.  The specified date and time is passed
++//              back after being modified.
++//
++// Assumptions: 1. Every fourth year is a leap year.  Therefore, this function
++//                 is only accurate through Feb 28, 2100.
++////////////////////////////////////////////////////////////////////////////////
++void ApplyTimeOffset(DoyTimeObj* pDt, int off)
++{
++    SecTimeObj st;                  // Time, in seconds
++
++
++    // Convert date and time to seconds
++    SecTimeFromDoyTime(&st, pDt);
++
++    // Apply offset
++    st.seconds = (int)((signed long long)st.seconds + (signed long long)off);
++
++    // Convert seconds to date and time
++    DoyTimeFromSecTime(pDt, &st);
++
++} // End ApplyTimeOffset
++
++
++////////////////////////////////////////////////////////////////////////////////
++// Function:    SecTimeFromDoyTime
++// Description: The SecTimeFromDoyTime function converts a specified date
++//              and time into a count of seconds since the base time.  This
++//              function operates across the range Base Time to Max Time for
++//              the system.
++//
++// Assumptions: 1. A leap year is any year evenly divisible by 4.  Therefore,
++//                 this function is only accurate through Feb 28, 2100.
++//              2. Conversion does not account for leap seconds.
++////////////////////////////////////////////////////////////////////////////////
++void SecTimeFromDoyTime(SecTimeObj* pSt, DoyTimeObj* pDt)
++{
++    unsigned int yrs;               // Years
++    unsigned int lyrs;              // Leap years
++
++
++    // Start with accumulated time of 0
++    pSt->seconds  = 0;
++
++    // Calculate the number of years and leap years
++    yrs           = pDt->year - TSYNC_TIME_BASE_YEAR;
++    lyrs          = (yrs + 1) / 4;
++
++    // Convert leap years and years
++    pSt->seconds += lyrs           * TSYNC_SECS_PER_LYR;
++    pSt->seconds += (yrs - lyrs)   * TSYNC_SECS_PER_YR;
++
++    // Convert days, hours, minutes and seconds
++    pSt->seconds += (pDt->doy - 1) * TSYNC_SECS_PER_DAY;
++    pSt->seconds += pDt->hour      * TSYNC_SECS_PER_HR;
++    pSt->seconds += pDt->minute    * TSYNC_SECS_PER_MIN;
++    pSt->seconds += pDt->second;
++
++    // Copy the subseconds count
++    pSt->ns       = pDt->ns;
++
++} // End SecTimeFromDoyTime
++
++
++////////////////////////////////////////////////////////////////////////////////
++// Function:    DoyTimeFromSecTime
++// Description: The DoyTimeFromSecTime function converts a specified count
++//              of seconds since the start of our base time into a SecTimeObj
++//              structure.
++//
++// Assumptions: 1. A leap year is any year evenly divisible by 4.  Therefore,
++//                 this function is only accurate through Feb 28, 2100.
++//              2. Conversion does not account for leap seconds.
++////////////////////////////////////////////////////////////////////////////////
++void DoyTimeFromSecTime(DoyTimeObj* pDt, SecTimeObj* pSt)
++{
++    signed long long secs;          // Seconds accumulator variable
++    unsigned int     yrs;           // Years accumulator variable
++    unsigned int     doys;          // Days accumulator variable
++    unsigned int     hrs;           // Hours accumulator variable
++    unsigned int     mins;          // Minutes accumulator variable
++
++
++    // Convert the seconds count into a signed 64-bit number for calculations
++    secs  = (signed long long)(pSt->seconds);
++
++    // Calculate the number of 4 year chunks
++    yrs   = (unsigned int)((secs /
++                           ((TSYNC_SECS_PER_YR * 3) + TSYNC_SECS_PER_LYR)) * 4);
++    secs %= ((TSYNC_SECS_PER_YR * 3) + TSYNC_SECS_PER_LYR);
++
++    // If there is at least a normal year worth of time left
++    if (secs >= TSYNC_SECS_PER_YR)
++    {
++        // Increment the number of years and subtract a normal year of time
++        yrs++;
++        secs -= TSYNC_SECS_PER_YR;
++    }
++
++    // If there is still at least a normal year worth of time left
++    if (secs >= TSYNC_SECS_PER_YR)
++    {
++        // Increment the number of years and subtract a normal year of time
++        yrs++;
++        secs -= TSYNC_SECS_PER_YR;
++    }
++
++    // If there is still at least a leap year worth of time left
++    if (secs >= TSYNC_SECS_PER_LYR)
++    {
++        // Increment the number of years and subtract a leap year of time
++        yrs++;
++        secs -= TSYNC_SECS_PER_LYR;
++    }
++
++    // Calculate the day of year as the number of days left, then add 1
++    // because months start on the 1st.
++    doys  = (unsigned int)((secs / TSYNC_SECS_PER_DAY) + 1);
++    secs %= TSYNC_SECS_PER_DAY;
++
++    // Calculate the hour
++    hrs   = (unsigned int)(secs / TSYNC_SECS_PER_HR);
++    secs %= TSYNC_SECS_PER_HR;
++
++    // Calculate the minute
++    mins  = (unsigned int)(secs / TSYNC_SECS_PER_MIN);
++    secs %= TSYNC_SECS_PER_MIN;
++
++    // Fill in the doytime structure
++    pDt->year   = yrs + TSYNC_TIME_BASE_YEAR;
++    pDt->doy    = doys;
++    pDt->hour   = hrs;
++    pDt->minute = mins;
++    pDt->second = (unsigned int)secs;
++    pDt->ns     = pSt->ns;
++
++} // End DoyTimeFromSecTime
++
++#else
++int refclock_tsyncpci_bs;
++#endif /* REFCLOCK */
diff --git a/SOURCES/ntpdate.service b/SOURCES/ntpdate.service
index 038b293..8e6e616 100644
--- a/SOURCES/ntpdate.service
+++ b/SOURCES/ntpdate.service
@@ -1,8 +1,8 @@
 [Unit]
 Description=Set time via NTP
-After=syslog.target network.target nss-lookup.target
+After=network-online.target nss-lookup.target
 Before=time-sync.target
-Wants=time-sync.target
+Wants=time-sync.target network-online.target
 
 [Service]
 Type=oneshot
diff --git a/SOURCES/ntpdate.sysconfig b/SOURCES/ntpdate.sysconfig
index 2502779..54676b4 100644
--- a/SOURCES/ntpdate.sysconfig
+++ b/SOURCES/ntpdate.sysconfig
@@ -1,8 +1,5 @@
 # Options for ntpdate
 OPTIONS="-p 2"
 
-# Number of retries before giving up
-RETRIES=2
-
 # Set to 'yes' to sync hw clock after successful ntpdate
 SYNC_HWCLOCK=no
diff --git a/SOURCES/ntpdate.wrapper b/SOURCES/ntpdate.wrapper
index 5baeab0..ed91bec 100755
--- a/SOURCES/ntpdate.wrapper
+++ b/SOURCES/ntpdate.wrapper
@@ -22,15 +22,8 @@ if ! echo "$tickers" | grep -qi '[a-z0-9]'; then
 	exit 6
 fi
 
-[ -z "$RETRIES" ] && RETRIES=2
-retry=0
-while true; do
-	/usr/sbin/ntpdate -U ntp -s -b $OPTIONS $tickers &> /dev/null
-	RETVAL=$?
-	[ $RETVAL -eq 0 ] || [ $retry -ge "$RETRIES" ] && break
-	sleep $[10 * (1 << $retry)]
-	retry=$[$retry + 1]
-done
+/usr/sbin/ntpdate -U ntp -s -b $OPTIONS $tickers &> /dev/null
+RETVAL=$?
 
 [ $RETVAL -eq 0 ] && [ "$SYNC_HWCLOCK" = "yes" ] && /sbin/hwclock --systohc
 exit $RETVAL
diff --git a/SOURCES/sntp.service b/SOURCES/sntp.service
index 70ff227..1722767 100644
--- a/SOURCES/sntp.service
+++ b/SOURCES/sntp.service
@@ -1,8 +1,8 @@
 [Unit]
 Description=Set time via SNTP
-After=syslog.target network.target NetworkManager-wait-online.service nss-lookup.target
+After=network-online.target nss-lookup.target
 Before=time-sync.target
-Wants=time-sync.target
+Wants=time-sync.target network-online.target
 
 [Service]
 Type=oneshot
diff --git a/SPECS/ntp.spec b/SPECS/ntp.spec
index b9aaabd..c706e7c 100644
--- a/SPECS/ntp.spec
+++ b/SPECS/ntp.spec
@@ -1,7 +1,7 @@
 Summary: The NTP daemon and utilities
 Name: ntp
 Version: 4.2.6p5
-Release: 25%{?dist}.2
+Release: 28%{?dist}
 # primary license (COPYRIGHT) : MIT
 # ElectricFence/ (not used) : GPLv2
 # kernel/sys/ppsclock.h (not used) : BSD with advertising
@@ -181,6 +181,18 @@ Patch66: ntp-4.2.6p5-cve-2016-7433.patch
 Patch67: ntp-4.2.6p5-cve-2016-9310.patch
 # ntpbz #3119
 Patch68: ntp-4.2.6p5-cve-2016-9311.patch
+# ntpbz #3388
+Patch69: ntp-4.2.6p5-cve-2017-6462.patch
+# ntpbz #3387
+Patch70: ntp-4.2.6p5-cve-2017-6463.patch
+# ntpbz #3389
+Patch71: ntp-4.2.6p5-cve-2017-6464.patch
+# add Spectracom TSYNC driver
+Patch72: ntp-4.2.6p5-tsyncdriver.patch
+# ntpbz #3434
+Patch73: ntp-4.2.6p5-staunsync.patch
+# use SHA1 request key by default (#1442083)
+Patch74: ntp-4.2.6p5-defreqkey.patch
 
 # handle unknown clock types
 Patch100: ntpstat-0.2-clksrc.patch
@@ -264,7 +276,7 @@ This package contains NTP documentation in HTML format.
 # pool.ntp.org vendor zone which will be used in ntp.conf
 %if 0%{!?vendorzone:1}
 %{?fedora: %global vendorzone fedora.}
-%{?rhel: %global vendorzone centos.}
+%{?rhel: %global vendorzone rhel.}
 %endif
 
 %prep
@@ -339,6 +351,12 @@ This package contains NTP documentation in HTML format.
 %patch66 -p1 -b .cve-2016-7433
 %patch67 -p1 -b .cve-2016-9310
 %patch68 -p1 -b .cve-2016-9311
+%patch69 -p1 -b .cve-2017-6462
+%patch70 -p1 -b .cve-2017-6463
+%patch71 -p1 -b .cve-2017-6464
+%patch72 -p1 -b .tsyncdriver
+%patch73 -p1 -b .staunsync
+%patch74 -p1 -b .defreqkey
 
 # ntpstat patches
 %patch100 -p1 -b .clksrc
@@ -557,13 +575,20 @@ popd
 %{ntpdocdir}/html
 
 %changelog
-* Wed Apr 12 2017 CentOS Sources <bugs@centos.org> - 4.2.6p5-25.el7.centos.2
-- rebrand vendorzone
-
-* Tue Feb 28 2017 Miroslav Lichvar <mlichvar@redhat.com> 4.2.6p5-25.el7_3.2
-- fix CVE-2016-7429 patch to work correctly on multicast client (#1427573)
-
-* Wed Jan 11 2017 Miroslav Lichvar <mlichvar@redhat.com> 4.2.6p5-25.el7_3.1
+* Mon Oct 09 2017 Miroslav Lichvar <mlichvar@redhat.com> 4.2.6p5-28
+- fix buffer overflow in datum refclock driver (CVE-2017-6462)
+- fix crash with invalid unpeer command (CVE-2017-6463)
+- fix potential crash with invalid server command (CVE-2017-6464)
+- add Spectracom TSYNC driver (#1491797)
+- fix initialization of system clock status (#1493452)
+- fix typos in ntpd man page (#1420453)
+- use SHA1 request key by default (#1442083)
+- use network-online target in ntpdate and sntp services (#1466947)
+
+* Tue Feb 28 2017 Miroslav Lichvar <mlichvar@redhat.com> 4.2.6p5-27
+- fix CVE-2016-7429 patch to work correctly on multicast client (#1422944)
+
+* Wed Jan 11 2017 Miroslav Lichvar <mlichvar@redhat.com> 4.2.6p5-26
 - don't limit rate of packets from sources (CVE-2016-7426)
 - don't change interface from received packets (CVE-2016-7429)
 - fix calculation of root distance again (CVE-2016-7433)