aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/xntpd/xntpd
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/xntpd/xntpd')
-rw-r--r--contrib/xntpd/xntpd/Makefile4
-rw-r--r--contrib/xntpd/xntpd/minpoll0
-rw-r--r--contrib/xntpd/xntpd/ntp_config.c201
-rw-r--r--contrib/xntpd/xntpd/ntp_control.c35
-rw-r--r--contrib/xntpd/xntpd/ntp_intres.c15
-rw-r--r--contrib/xntpd/xntpd/ntp_io.c95
-rw-r--r--contrib/xntpd/xntpd/ntp_loopfilter.c252
-rw-r--r--contrib/xntpd/xntpd/ntp_monitor.c51
-rw-r--r--contrib/xntpd/xntpd/ntp_peer.c26
-rw-r--r--contrib/xntpd/xntpd/ntp_proto.c225
-rw-r--r--contrib/xntpd/xntpd/ntp_refclock.c30
-rw-r--r--contrib/xntpd/xntpd/ntp_request.c175
-rw-r--r--contrib/xntpd/xntpd/ntp_restrict.c166
-rw-r--r--contrib/xntpd/xntpd/ntp_unixclock.c32
-rw-r--r--contrib/xntpd/xntpd/ntpd.c20
-rw-r--r--contrib/xntpd/xntpd/refclock_chu.c19
-rw-r--r--contrib/xntpd/xntpd/refclock_conf.c8
-rw-r--r--contrib/xntpd/xntpd/refclock_irig.c6
-rw-r--r--contrib/xntpd/xntpd/refclock_msfees.c2
-rw-r--r--contrib/xntpd/xntpd/refclock_parse.c103
-rw-r--r--contrib/xntpd/xntpd/refclock_trak.c1006
21 files changed, 1991 insertions, 480 deletions
diff --git a/contrib/xntpd/xntpd/Makefile b/contrib/xntpd/xntpd/Makefile
index 56f5dc2eb6eb..a4b083efde72 100644
--- a/contrib/xntpd/xntpd/Makefile
+++ b/contrib/xntpd/xntpd/Makefile
@@ -1,5 +1,5 @@
#
-# $Id: Makefile,v 1.4 1994/02/03 23:23:17 wollman Exp $
+# $Id: Makefile,v 1.5 1994/04/03 20:37:26 wollman Exp $
#
CFLAGS+= -I${.CURDIR}/../include
@@ -34,7 +34,7 @@ SRCS= ntp_config.c ntp_control.c ntp_io.c ntp_leap.c \
refclock_wwvb.c refclock_goes.c refclock_mx4200.c \
refclock_parse.c refclock_as2201.c refclock_omega.c \
refclock_tpro.c refclock_leitch.c refclock_irig.c \
- refclock_msfees.c refclock_gpstm.c ntp_intres.c \
+ refclock_msfees.c refclock_gpstm.c refclock_trak.c ntp_intres.c \
ntp_filegen.c version.c
beforedepend: version.c
diff --git a/contrib/xntpd/xntpd/minpoll b/contrib/xntpd/xntpd/minpoll
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/xntpd/xntpd/minpoll
diff --git a/contrib/xntpd/xntpd/ntp_config.c b/contrib/xntpd/xntpd/ntp_config.c
index 1b716f69fab5..8f356ac8c2e7 100644
--- a/contrib/xntpd/xntpd/ntp_config.c
+++ b/contrib/xntpd/xntpd/ntp_config.c
@@ -45,8 +45,9 @@
* peer 128.100.1.1 [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
* server 128.100.2.2 [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
* precision -7
- * broadcast 128.100.224.255 [ version 3 ] [ key 0 ]
- * broadcastclient yes|no
+ * broadcast 128.100.224.255 [ version 3 ] [ key 0 ] [ ttl 1 ]
+ * broadcastclient
+ * multicastclient [224.0.1.1]
* broadcastdelay 0.0102
* authenticate yes|no
* monitor yes|no
@@ -58,6 +59,16 @@
* statsdir /var/NTP/
* filegen peerstats [ file peerstats ] [ type day ] [ link ]
* resolver /path/progname
+ * clientlimit [ n ]
+ * clientperiod [ 3600 ]
+ * trustedkey [ key ]
+ * requestkey [ key]
+ * controlkey [ key ]
+ * trap [ address ]
+ * fudge [ ... ]
+ * pidfile [ ]
+ * logfile [ ]
+ * setvar [ ]
*
* And then some. See the manual page.
*/
@@ -84,22 +95,24 @@
#define CONFIG_CONTROLKEY 15
#define CONFIG_TRAP 16
#define CONFIG_FUDGE 17
-#define CONFIG_MAXSKEW 18
-#define CONFIG_RESOLVER 19
-#define CONFIG_SELECT 20
-#define CONFIG_STATSDIR 21
-#define CONFIG_FILEGEN 22
-#define CONFIG_STATISTICS 23
-#define CONFIG_PPS 24
-#define CONFIG_PIDFILE 25
-#define CONFIG_LOGFILE 26
-#define CONFIG_SETVAR 27
+#define CONFIG_RESOLVER 18
+#define CONFIG_STATSDIR 19
+#define CONFIG_FILEGEN 20
+#define CONFIG_STATISTICS 21
+#define CONFIG_PPS 22
+#define CONFIG_PIDFILE 23
+#define CONFIG_LOGFILE 24
+#define CONFIG_SETVAR 25
+#define CONFIG_CLIENTLIMIT 26
+#define CONFIG_CLIENTPERIOD 27
+#define CONFIG_MULTICASTCLIENT 28
#define CONF_MOD_VERSION 1
#define CONF_MOD_KEY 2
#define CONF_MOD_MINPOLL 3
#define CONF_MOD_MAXPOLL 4
#define CONF_MOD_PREFER 5
+#define CONF_MOD_TTL 6
#define CONF_PPS_DELAY 1
#define CONF_PPS_BAUD 2
@@ -114,6 +127,7 @@
#define CONF_RES_NOTRAP 8
#define CONF_RES_LPTRAP 9
#define CONF_RES_NTPPORT 10
+#define CONF_RES_LIMITED 11
#define CONF_TRAP_PORT 1
#define CONF_TRAP_INTERFACE 2
@@ -158,6 +172,7 @@ static struct keyword keywords[] = {
{ "driftfile", CONFIG_DRIFTFILE },
{ "broadcast", CONFIG_BROADCAST },
{ "broadcastclient", CONFIG_BROADCASTCLIENT },
+ { "multicastclient", CONFIG_MULTICASTCLIENT },
{ "authenticate", CONFIG_AUTHENTICATE },
{ "keys", CONFIG_KEYS },
{ "monitor", CONFIG_MONITOR },
@@ -170,15 +185,15 @@ static struct keyword keywords[] = {
{ "controlkey", CONFIG_CONTROLKEY },
{ "trap", CONFIG_TRAP },
{ "fudge", CONFIG_FUDGE },
- { "maxskew", CONFIG_MAXSKEW },
{ "resolver", CONFIG_RESOLVER },
- { "select", CONFIG_SELECT },
{ "statsdir", CONFIG_STATSDIR },
{ "filegen", CONFIG_FILEGEN },
{ "statistics", CONFIG_STATISTICS },
{ "pidfile", CONFIG_PIDFILE },
{ "logfile", CONFIG_LOGFILE },
{ "setvar", CONFIG_SETVAR },
+ { "clientlimit", CONFIG_CLIENTLIMIT },
+ { "clientperiod", CONFIG_CLIENTPERIOD },
{ "", CONFIG_UNKNOWN }
};
@@ -191,6 +206,7 @@ static struct keyword mod_keywords[] = {
{ "minpoll", CONF_MOD_MINPOLL },
{ "maxpoll", CONF_MOD_MAXPOLL },
{ "prefer", CONF_MOD_PREFER },
+ { "ttl", CONF_MOD_TTL },
{ "", CONFIG_UNKNOWN }
};
@@ -217,6 +233,7 @@ static struct keyword res_keywords[] = {
{ "notrap", CONF_RES_NOTRAP },
{ "lowpriotrap", CONF_RES_LPTRAP },
{ "ntpport", CONF_RES_NTPPORT },
+ { "limited", CONF_RES_LIMITED },
{ "", CONFIG_UNKNOWN }
};
@@ -318,12 +335,12 @@ extern int debug;
#endif
extern char *FindConfig();
char *progname;
-static char *xntp_options = "abc:de:f:k:l:p:r:s:t:v:V:";
+static char *xntp_options = "abc:de:f:k:l:mp:r:s:t:v:V:";
static int gettokens P((FILE *, char *, char **, int *));
static int matchkey P((char *, struct keyword *));
static int getnetnum P((char *, struct sockaddr_in *, int));
-static void save_resolve P((char *, int, int, int, int, int, U_LONG));
+static void save_resolve P((char *, int, int, int, int, int, int, U_LONG));
static void do_resolve P((char *, U_LONG, char *));
#ifdef RESOLVE_INTERNAL
static void do_resolve_internal P((void));
@@ -410,6 +427,7 @@ getconfig(argc, argv)
int peerversion;
int minpoll;
int maxpoll;
+ int ttl;
U_LONG peerkey;
int peerflags;
int hmode;
@@ -466,12 +484,15 @@ getconfig(argc, argv)
case 'a':
proto_config(PROTO_AUTHENTICATE, (LONG)1);
break;
+
case 'b':
proto_config(PROTO_BROADCLIENT, (LONG)1);
break;
+
case 'c':
config_file = ntp_optarg;
break;
+
case 'd':
#ifdef DEBUG
debug++;
@@ -516,6 +537,10 @@ getconfig(argc, argv)
}
break;
+ case 'm':
+ proto_config(PROTO_MULTICAST_ADD, INADDR_NTP);
+ break;
+
case 'p':
stats_config(STATS_PID_FILE, ntp_optarg);
break;
@@ -624,6 +649,7 @@ getconfig(argc, argv)
maxpoll = NTP_MAXPOLL;
peerkey = 0;
peerflags = 0;
+ ttl = 1;
for (i = 2; i < ntokens; i++)
switch (matchkey(tokens[i], mod_keywords)) {
case CONF_MOD_VERSION:
@@ -689,6 +715,16 @@ getconfig(argc, argv)
peerflags |= FLAG_PREFER;
break;
+ case CONF_MOD_TTL:
+ if (i >= ntokens-1) {
+ syslog(LOG_ERR,
+ "ttl: argument required");
+ errflg = 1;
+ break;
+ }
+ ttl = atoi(tokens[++i]);
+ break;
+
case CONFIG_UNKNOWN:
errflg = 1;
break;
@@ -700,14 +736,15 @@ getconfig(argc, argv)
if (errflg == 0) {
if (peer_config(&peeraddr,
(struct interface *)0, hmode, peerversion,
- minpoll, maxpoll, peerkey, peerflags) == 0) {
+ minpoll, maxpoll, peerflags, ttl, peerkey)
+ == 0) {
syslog(LOG_ERR,
"configuration of %s failed",
ntoa(&peeraddr));
}
} else if (errflg == -1) {
save_resolve(tokens[1], hmode, peerversion,
- minpoll, maxpoll, peerflags, peerkey);
+ minpoll, maxpoll, peerflags, ttl, peerkey);
}
break;
@@ -764,23 +801,20 @@ getconfig(argc, argv)
} break;
case CONFIG_BROADCASTCLIENT:
- errflg = 0;
- if (ntokens >= 2) {
- if (STREQ(tokens[1], "yes"))
- proto_config(PROTO_BROADCLIENT, (LONG)1);
- else if (STREQ(tokens[1], "no"))
- proto_config(PROTO_BROADCLIENT, (LONG)0);
- else
- errflg++;
- } else {
- errflg++;
- }
-
- if (errflg)
- syslog(LOG_ERR,
- "should be `broadcastclient yes|no'");
+ proto_config(PROTO_BROADCLIENT, (U_LONG)1);
break;
+ case CONFIG_MULTICASTCLIENT:
+ if (ntokens > 1) {
+ for (i = 1; i < ntokens; i++) {
+ if (getnetnum(tokens[i], &peeraddr, 1));
+ proto_config(PROTO_MULTICAST_ADD,
+ peeraddr.sin_addr.s_addr);
+ }
+ } else
+ proto_config(PROTO_MULTICAST_ADD, INADDR_NTP);
+ break;
+
case CONFIG_AUTHENTICATE:
errflg = 0;
if (ntokens >= 2) {
@@ -817,9 +851,9 @@ getconfig(argc, argv)
errflg = 0;
if (ntokens >= 2) {
if (STREQ(tokens[1], "yes"))
- mon_start();
+ mon_start(MON_ON);
else if (STREQ(tokens[1], "no"))
- mon_stop();
+ mon_stop(MON_ON);
else
errflg++;
} else {
@@ -965,6 +999,10 @@ getconfig(argc, argv)
peerkey |= RESM_NTPONLY;
break;
+ case CONF_RES_LIMITED:
+ peerversion |= RES_LIMITED;
+ break;
+
case CONFIG_UNKNOWN:
errflg++;
break;
@@ -1252,26 +1290,6 @@ getconfig(argc, argv)
#endif
break;
- case CONFIG_MAXSKEW:
- if (ntokens >= 2) {
- l_fp tmp;
- u_fp utmp;
-
- if (!atolfp(tokens[1], &tmp)) {
- syslog(LOG_ERR,
- "maxskew value %s undecodable",
- tokens[1]);
- } else if (tmp.l_ui != 0) {
- syslog(LOG_ERR,
- "maxskew value %s is unlikely",
- tokens[1]);
- } else {
- utmp = LFPTOFP(&tmp);
- proto_config(PROTO_MAXSKEW, (LONG)utmp);
- }
- }
- break;
-
case CONFIG_RESOLVER:
if (ntokens >= 2) {
if (strlen(tokens[1]) >= (size_t)MAXFILENAME) {
@@ -1288,18 +1306,6 @@ getconfig(argc, argv)
}
break;
- case CONFIG_SELECT:
- if (ntokens >= 2) {
- i = atoi(tokens[1]);
- if (i < SELECT_1 || i > SELECT_5)
- syslog(LOG_ERR,
- "invalid selection algorithm %s, line ignored",
- tokens[1]);
- else
- proto_config(PROTO_SELECT, (LONG)i);
- }
- break;
-
case CONFIG_STATSDIR:
if (ntokens >= 2) {
stats_config(STATS_STATSDIR,tokens[1]);
@@ -1414,6 +1420,60 @@ getconfig(argc, argv)
((((ntokens > 2) && !strcmp(tokens[2], "default"))) ? DEF : 0));
}
break;
+
+ case CONFIG_CLIENTLIMIT:
+ if (ntokens < 2)
+ {
+ syslog(LOG_ERR,
+ "no value for clientlimit command - line ignored");
+ }
+ else
+ {
+ U_LONG i;
+ if (!atouint(tokens[1], &i) || !i)
+ {
+ syslog(LOG_ERR,
+ "illegal value for clientlimit command - line ignored");
+ }
+ else
+ {
+ extern U_LONG client_limit;
+ char bp[80];
+
+ sprintf(bp, "client_limit=%d", i);
+ set_sys_var(bp, strlen(bp)+1, RO);
+
+ client_limit = i;
+ }
+ }
+ break;
+
+ case CONFIG_CLIENTPERIOD:
+ if (ntokens < 2)
+ {
+ syslog(LOG_ERR,
+ "no value for clientperiod command - line ignored");
+ }
+ else
+ {
+ U_LONG i;
+ if (!atouint(tokens[1], &i) || i < 64)
+ {
+ syslog(LOG_ERR,
+ "illegal value for clientperiod command - line ignored");
+ }
+ else
+ {
+ extern U_LONG client_limit_period;
+ char bp[80];
+
+ sprintf(bp, "client_limit_period=%d", i);
+ set_sys_var(bp, strlen(bp)+1, RO);
+
+ client_limit_period = i;
+ }
+ }
+ break;
}
}
(void) fclose(fp);
@@ -1643,13 +1703,14 @@ int sig;
* save_resolve - save configuration info into a file for later name resolution
*/
static void
-save_resolve(name, mode, version, minpoll, maxpoll, flags, keyid)
+save_resolve(name, mode, version, minpoll, maxpoll, flags, ttl, keyid)
char *name;
int mode;
int version;
int minpoll;
int maxpoll;
int flags;
+ int ttl;
U_LONG keyid;
{
if (res_fp == NULL) {
@@ -1668,8 +1729,8 @@ save_resolve(name, mode, version, minpoll, maxpoll, flags, keyid)
}
#endif
- (void) fprintf(res_fp, "%s %d %d %d %d %d %lu\n", name, mode,
- version, minpoll, maxpoll, flags, keyid);
+ (void) fprintf(res_fp, "%s %d %d %d %d %d %d %lu\n", name, mode,
+ version, minpoll, maxpoll, flags, ttl, keyid);
}
diff --git a/contrib/xntpd/xntpd/ntp_control.c b/contrib/xntpd/xntpd/ntp_control.c
index 1c7849f48820..ef9c37a6751d 100644
--- a/contrib/xntpd/xntpd/ntp_control.c
+++ b/contrib/xntpd/xntpd/ntp_control.c
@@ -264,8 +264,20 @@ static u_char def_clock_var[] = {
/*
* System and processor definitions. These will change for the gizmo board.
*/
+#ifndef HAVE_UNAME
+#ifndef STR_SYSTEM
+#define STR_SYSTEM "UNIX"
+#endif
+#ifndef STR_PROCESSOR
+#define STR_PROCESSOR "unknown"
+#endif
+
+static char str_system[] = STR_SYSTEM;
+static char str_processor[] = STR_PROCESSOR;
+#else
#include <sys/utsname.h>
static struct utsname utsname;
+#endif /* HAVE_UNAME */
/*
* Trap structures. We only allow a few of these, and send
@@ -294,7 +306,7 @@ static struct utsname utsname;
static u_char clocktypes[] = {
CTL_SST_TS_NTP, /* REFCLK_NONE */
CTL_SST_TS_UNSPEC, /* REFCLK_LOCALCLOCK */
- CTL_SST_TS_HF, /* REFCLK_WWV_HEATH */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_TRAK */
CTL_SST_TS_HF, /* REFCLK_WWV_PST */
CTL_SST_TS_LF, /* REFCLK_WWVB_SPECTRACOM */
CTL_SST_TS_UHF, /* REFCLK_GOES_TRUETIME */
@@ -379,6 +391,7 @@ extern struct peer *sys_peer;
extern l_fp last_offset;
extern s_fp drift_comp;
extern int time_constant;
+extern int pll_control;
/*
* Imported from the leap module
*/
@@ -426,7 +439,9 @@ init_control()
{
int i;
+#ifdef HAVE_UNAME
uname(&utsname);
+#endif /* HAVE_UNAME */
ctl_clr_stats();
@@ -716,10 +731,12 @@ ctlsysstatus()
if (sys_peer != 0)
if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC)
clock = sys_peer->sstclktype;
- else
+ else {
if (sys_peer->refclktype < sizeof(clocktypes))
clock = clocktypes[sys_peer->refclktype];
-
+ if (pps_control)
+ clock |= CTL_SST_TS_PPS;
+ }
return (u_short)CTL_SYS_STATUS(sys_leap, clock,
ctl_sys_num_events, ctl_sys_last_event);
}
@@ -1262,12 +1279,22 @@ ctl_putsys(varid)
ctl_putuint(sys_var[CS_LEAPWARNING].text, (U_LONG)leap_warning);
break;
case CS_PROCESSOR:
+#ifndef HAVE_UNAME
+ ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
+ sizeof(str_processor) - 1);
+#else
ctl_putstr(sys_var[CS_PROCESSOR].text, utsname.machine,
strlen(utsname.machine));
+#endif /* HAVE_UNAME */
break;
case CS_SYSTEM:
- ctl_putstr(sys_var[CS_SYSTEM].text, utsname.sysname,
+#ifndef HAVE_UNAME
+ ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
+ sizeof(str_system) - 1);
+#else
+ ctl_putstr(sys_var[CS_SYSTEM].text, utsname.sysname,
strlen(utsname.sysname));
+#endif /* HAVE_UNAME */
break;
case CS_KEYID:
ctl_putuint(sys_var[CS_KEYID].text, (U_LONG)0);
diff --git a/contrib/xntpd/xntpd/ntp_intres.c b/contrib/xntpd/xntpd/ntp_intres.c
index 20561e91b82d..5ff4af4d8242 100644
--- a/contrib/xntpd/xntpd/ntp_intres.c
+++ b/contrib/xntpd/xntpd/ntp_intres.c
@@ -48,6 +48,7 @@ struct conf_entry {
#define ce_minpoll ce_config.minpoll
#define ce_maxpoll ce_config.maxpoll
#define ce_flags ce_config.flags
+#define ce_ttl ce_config.ttl
#define ce_keyid ce_config.keyid
/*
@@ -102,8 +103,9 @@ static int resolve_value; /* next value of resolve timer */
#define TOK_MINPOLL 3
#define TOK_MAXPOLL 4
#define TOK_FLAGS 5
-#define TOK_KEYID 6
-#define NUMTOK 7
+#define TOK_TTL 6
+#define TOK_KEYID 7
+#define NUMTOK 8
#define MAXLINESIZE 512
@@ -128,7 +130,7 @@ extern int errno;
static RETSIGTYPE bong P((int));
static void checkparent P((void));
static void removeentry P((struct conf_entry *));
-static void addentry P((char *, int, int, int, int, int, U_LONG));
+static void addentry P((char *, int, int, int, int, int, int, U_LONG));
static int findhostaddr P((struct conf_entry *));
static void openntp P((void));
static int request P((struct conf_peer *));
@@ -279,13 +281,14 @@ removeentry(entry)
* addentry - add an entry to the configuration list
*/
static void
-addentry(name, mode, version, minpoll, maxpoll, flags, keyid)
+addentry(name, mode, version, minpoll, maxpoll, flags, ttl, keyid)
char *name;
int mode;
int version;
int minpoll;
int maxpoll;
int flags;
+ int ttl;
U_LONG keyid;
{
register char *cp;
@@ -304,6 +307,7 @@ addentry(name, mode, version, minpoll, maxpoll, flags, keyid)
ce->ce_minpoll = (u_char)minpoll;
ce->ce_maxpoll = (u_char)maxpoll;
ce->ce_flags = (u_char)flags;
+ ce->ce_ttl = (u_char)ttl;
ce->ce_keyid = htonl(keyid);
ce->ce_next = NULL;
@@ -751,7 +755,8 @@ readconf(fp, name)
*/
addentry(token[TOK_HOSTNAME], (int)intval[TOK_HMODE],
(int)intval[TOK_VERSION], (int)intval[TOK_MINPOLL],
- (int)intval[TOK_MAXPOLL], flags, intval[TOK_KEYID]);
+ (int)intval[TOK_MAXPOLL], flags, (int)intval[TOK_TTL],
+ intval[TOK_KEYID]);
}
}
diff --git a/contrib/xntpd/xntpd/ntp_io.c b/contrib/xntpd/xntpd/ntp_io.c
index 614d5c52bde9..551df510dc37 100644
--- a/contrib/xntpd/xntpd/ntp_io.c
+++ b/contrib/xntpd/xntpd/ntp_io.c
@@ -10,6 +10,10 @@
#include <sys/ioctl.h>
#include <sys/time.h>
+#ifdef MCAST
+#include "ntp_in.h"
+#endif /* MCAST */
+
#include "ntpd.h"
#include "ntp_select.h"
#include "ntp_io.h"
@@ -53,7 +57,6 @@
/*
* Block the interrupt, for critical sections.
*/
-
#if defined(HAVE_SIGNALED_IO)
#define BLOCKIO() ((void) block_sigio())
#define UNBLOCKIO() ((void) unblock_sigio())
@@ -228,6 +231,9 @@ create_sockets(port)
inter_list[0].sent = 0;
inter_list[0].notsent = 0;
inter_list[0].flags = INT_BROADCAST;
+#ifdef MCAST
+ inter_list[0].flags |= INT_MULTICAST;
+#endif /* MCAST */
#ifdef USE_STREAMS_DEVICE_FOR_IF_CONFIG
if ((vs = open("/dev/ip", O_RDONLY)) < 0) {
@@ -394,7 +400,7 @@ create_sockets(port)
maxactivefd = 0;
FD_ZERO(&activefds);
-
+
for (i = 0; i < ninterfaces; i++) {
inter_list[i].fd = open_socket(&inter_list[i].sin,
inter_list[i].flags & INT_BROADCAST);
@@ -458,23 +464,72 @@ io_setbclient()
}
+#ifdef MCAST
+/*
+ * io_multicast_add() - add multicast group address
+ */
+void
+io_multicast_add(addr)
+ U_LONG addr;
+{
+ int fd = inter_list[0].fd;
+ struct ip_mreq mreq;
+
+ if (!IN_CLASSD(addr))
+ return;
+ /*
+ * enable reception of multicast packets
+ */
+ mreq.imr_multiaddr.s_addr = addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *)&mreq, sizeof(mreq)) == -1)
+ syslog(LOG_ERR, "setsockopt IP_ADD_MEMBERSHIP fails: %m");
+}
+#endif /* MCAST */
+
+
/*
* io_unsetbclient - close the broadcast client sockets
*/
void
io_unsetbclient()
{
- int i;
+ int i;
for (i = 1; i < ninterfaces; i++) {
if (!(inter_list[i].flags & INT_BCASTOPEN))
continue;
close_socket(inter_list[i].bfd);
inter_list[i].flags &= ~INT_BCASTOPEN;
- }
+ }
}
+#ifdef MCAST
+/*
+ * io_multicast_del() - delete multicast group address
+ */
+void
+io_multicast_del(addr)
+ U_LONG addr;
+{
+ int fd = inter_list[0].fd;
+ struct ip_mreq mreq;
+
+ if (!IN_CLASSD(addr))
+ return;
+ /*
+ * disable reception of multicast packets
+ */
+ mreq.imr_multiaddr.s_addr = addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (char *)&mreq, sizeof(mreq)) == -1)
+ syslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails: %m");
+}
+#endif /* MCAST */
+
/*
* open_socket - open a socket, returning the file descriptor
@@ -510,7 +565,8 @@ open_socket(addr, bcast)
*/
if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
char buff[160];
- sprintf(buff, "bind() fd %d, family %d, port %d, addr %08x, bcast=%d fails: %%m",
+ sprintf(buff,
+ "bind() fd %d, family %d, port %d, addr %08x, bcast=%d fails: %%m",
fd,
addr->sin_family,
addr->sin_port,
@@ -557,6 +613,19 @@ Need non blocking I/O
syslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
}
+#ifdef MCAST
+ /* for the moment we use the bcast option to set multicast ttl */
+
+ if (bcast) {
+ unsigned char mttl = 127;
+
+ /* set the multicast ttl for outgoing packets */
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
+ &mttl, sizeof(mttl)) == -1) {
+ syslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails: %m");
+ }
+ }
+#endif /* MCAST */
#ifdef SO_BROADCAST
/* if this interface can support broadcast, set SO_BROADCAST */
@@ -566,7 +635,7 @@ Need non blocking I/O
syslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
}
}
-#endif
+#endif /* SO_BROADCAST */
#ifdef DEBUG
if (debug > 1)
@@ -608,7 +677,7 @@ struct interface *
findbcastinter(addr)
struct sockaddr_in *addr;
{
-#ifdef SIOCGIFCONF
+#ifdef SIOCGIFCONF
register int i;
register U_LONG netnum;
@@ -622,7 +691,7 @@ findbcastinter(addr)
== (netnum & NSRCADR(&inter_list[i].mask)))
return &inter_list[i];
}
-#endif
+#endif /* SIOCGIFCONF */
return any_interface;
}
@@ -744,7 +813,7 @@ sendpkt(dest, inter, pkt, len)
#ifdef DEBUG
if (debug)
- printf("sendpkt(%s, %s, %d)\n", ntoa(dest),
+ printf("sendpkt(fd=%d %s, %s, %d)\n", inter->fd, ntoa(dest),
ntoa(&inter->sin), len);
#endif
@@ -902,11 +971,16 @@ again:
}
if (FD_ISSET(fd, &fds)) {
n--;
+
/*
* Get a buffer and read the frame. If we
* haven't got a buffer, or this is received
* on the wild card socket, just dump the packet.
*/
+
+ if (!(free_recvbufs && i == 0 &&
+ inter_list[i].flags & INT_MULTICAST)) {
+
#ifdef UDP_WILDCARD_DELIVERY
/*
* these guys manage to put properly addressed packets into the wildcard queue
@@ -932,6 +1006,7 @@ again:
packets_dropped++;
continue;
}
+ }
rb = freelist;
freelist = rb->next;
@@ -958,7 +1033,7 @@ again:
if (debug)
printf("input_handler: fd=%d length %d\n", fd, rb->recv_length);
#endif
-
+
/*
* Got one. Mark how and when it got here,
* put it on the full list and do bookkeeping.
diff --git a/contrib/xntpd/xntpd/ntp_loopfilter.c b/contrib/xntpd/xntpd/ntp_loopfilter.c
index 6d79c5d52ff4..13cbd61b6741 100644
--- a/contrib/xntpd/xntpd/ntp_loopfilter.c
+++ b/contrib/xntpd/xntpd/ntp_loopfilter.c
@@ -9,9 +9,6 @@
#include "ntpd.h"
#include "ntp_io.h"
-#if defined(KERNEL_PLL)
-#include "ntp_timex.h"
-#endif /* KERNEL_PLL */
#include "ntp_unixtime.h"
#if defined(PPS) || defined(PPSCLK) || defined(PPSPPS)
@@ -46,11 +43,13 @@
#include "ntp_stdlib.h"
-#ifdef KERNEL_PLL
-#ifndef SYS_ntp_adjtime
-#define SYS_ntp_adjtime NTP_SYSCALL_ADJ
+#ifdef KERNEL_PLL
+#include <sys/timex.h>
+#ifndef NTP_SYSCALLS_LIBC
+#define ntp_gettime(t) syscall(SYS_ntp_gettime, (t))
+#define ntp_adjtime(t) syscall(SYS_ntp_adjtime, (t))
#endif
-#endif /* KERNEL_PLL */
+#endif /* KERNEL_PLL */
/*
* The loop filter is implemented in slavish adherence to the
@@ -95,17 +94,14 @@
#define RSH_DRIFT_TO_FRAC (CLOCK_DSCALE - 16)
#define RSH_DRIFT_TO_ADJ (RSH_DRIFT_TO_FRAC - CLOCK_ADJ)
#define RSH_FRAC_TO_FREQ (CLOCK_FREQ + CLOCK_ADJ - RSH_DRIFT_TO_FRAC)
+#define PPS_MAXAGE 120 /* pps signal timeout (s) */
+#define PPS_MAXUPDATE 600 /* pps update timeout (s) */
/*
- * Imported from the ntp_proto module
+ * Program variables
*/
-extern u_char sys_stratum;
-extern s_fp sys_rootdelay;
-extern u_fp sys_rootdispersion;
-extern s_char sys_precision;
-
l_fp last_offset; /* last adjustment done */
-static LONG clock_adjust; /* clock adjust register (fraction only) */
+static LONG clock_adjust; /* clock adjust (fraction only) */
s_fp drift_comp; /* drift compensation register */
static s_fp max_comp; /* drift limit imposed by max host clock slew */
@@ -114,11 +110,15 @@ static s_fp max_comp; /* drift limit imposed by max host clock slew */
static U_LONG tcadj_time; /* last time-constant adjust time */
U_LONG watchdog_timer; /* watchdog timer, in seconds */
-static int first_adjustment; /* set to 1 if waiting for first adjustment */
+static int first_adjustment; /* 1 if waiting for first adjustment */
static int tc_counter; /* time-constant hold counter */
- int pll_control; /* set nonzero if pll implemented in kernel */
- int pps_control; /* set nonzero if pps signal valid */
+static l_fp pps_offset; /* filtered pps offset */
+static u_fp pps_dispersion; /* pps dispersion */
+static U_LONG pps_time; /* last pps sample time */
+
+ int pps_control; /* true if working pps signal */
+ int pll_control; /* true if working kernel pll */
static l_fp pps_delay; /* pps tuning offset */
U_LONG pps_update; /* last pps update time */
int fdpps = -1; /* pps file descriptor */
@@ -154,29 +154,35 @@ static l_fp pps_delay; /* pps tuning offset */
( i == 300 ? B300 : 0 ))))))))
#define PPS_BAUD B38400 /* default serial port speed */
-#define PPS_MAXAGE 120 /* seconds after which we disbelieve pps */
-#define PPS_MAXUPDATE 600 /* seconds after which we disbelieve timecode */
+timecode */
#define PPS_DEV "/dev/pps" /* pps port */
#define PPS_FAC 3 /* pps shift (log2 trimmed samples) */
-#define NPPS 12 /* pps filter size (1<<PPS_FAC+2*PPS_TRIM) */
-#define PPS_TRIM 2 /* samples trimmed from median filter */
+#define PPS_TRIM 6 /* samples trimmed from median filter */
+#define NPPS ((1 << PPS_FAC) + 2 * PPS_TRIM) /* pps filter size */
#define PPS_XCPT "\377" /* intercept character */
#if defined(PPSCLK)
static struct refclockio io; /* given to the I/O handler */
static int pps_baud; /* baud rate of PPS line */
#endif /* PPSCLK */
-static l_fp pps_offset; /* filtered pps offset */
-static U_LONG pps_time; /* last pps sample time */
static U_LONG nsamples; /* number of pps samples collected */
static LONG samples[NPPS]; /* median filter for pps samples */
+
+#endif /* PPS || PPSCLK || PPSPPS */
+
+/*
+ * Imported from the ntp_proto module
+ */
+extern u_char sys_stratum;
+extern s_fp sys_rootdelay;
+extern u_fp sys_rootdispersion;
+extern s_char sys_precision;
+
/*
* Imported from ntp_io.c
*/
extern struct interface *loopback_interface;
-#endif /* PPS || PPSCLK || PPSPPS */
-
/*
* Imported from ntpd module
*/
@@ -191,10 +197,16 @@ extern U_LONG current_time; /* like it says, in seconds */
* sys_poll and sys_refskew are set here
*/
extern u_char sys_poll; /* log2 of system poll interval */
+extern u_char sys_leap; /* system leap bits */
extern l_fp sys_refskew; /* accumulated skew since last update */
extern u_fp sys_maxd; /* max dispersion of survivor list */
/*
+ * Imported from leap module
+ */
+extern u_char leapbits; /* sanitized leap bits */
+
+/*
* Function prototypes
*/
#if defined(PPS) || defined(PPSCLK) || defined(PPSPPS)
@@ -205,9 +217,15 @@ static void pps_receive P((struct recvbuf *));
#endif /* PPS || PPSCLK || PPSPPS */
#if defined(KERNEL_PLL)
+#define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | \
+ MOD_STATUS | MOD_TIMECONST)
extern int sigvec P((int, struct sigvec *, struct sigvec *));
+#ifndef NTP_SYSCALLS_LIBC
+extern int syscall P((int, void *, ...));
+#endif /* no NTP syscalls in libc */
void pll_trap P((void));
+static int pll_status; /* status bits for kernel pll */
static struct sigvec sigsys; /* current sigvec status */
static struct sigvec newsigsys; /* new sigvec status */
#endif /* KERNEL_PLL */
@@ -350,8 +368,8 @@ init_loopfilter()
}
}
#endif /* HAVE_BSD_TTYS */
- fdpps = fd232;
#endif /* HPUXGADGET */
+ fdpps = fd232;
/*
* Insert in device list.
@@ -399,7 +417,7 @@ local_clock(fp_offset, peer)
#ifdef DEBUG
if (debug > 1)
- printf("local_clock(%s, %s)\n", lfptoa(fp_offset, 9),
+ printf("local_clock(%s, %s)\n", lfptoa(fp_offset, 6),
ntoa(&peer->srcadr));
#endif
@@ -432,33 +450,26 @@ local_clock(fp_offset, peer)
last_offset = *fp_offset;
/*
- * If the magnitude of the offset is greater than CLOCK.MAX, step
- * the time and reset the registers.
+ * If the magnitude of the offset is greater than CLOCK.MAX,
+ * step the time and reset the registers.
*/
if (tmp_ui > CLOCK_MAX_I || (tmp_ui == CLOCK_MAX_I
&& (U_LONG)tmp_uf >= (U_LONG)CLOCK_MAX_F)) {
if (watchdog_timer < CLOCK_MINSTEP) {
/* Mustn't step yet, pretend we adjusted. */
-#ifdef SLEWALWAYS
syslog(LOG_INFO,
- "adjust: SLEW dropped (%s offset %s)\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
-#else
- syslog(LOG_INFO,
- "adjust: STEP dropped (%s offset %s)\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
-#endif
+ "clock correction %s too large (ignored)\n",
+ lfptoa(fp_offset, 6));
return (0);
}
+ syslog(LOG_NOTICE, "clock reset (%s) %s\n",
#ifdef SLEWALWAYS
- syslog(LOG_NOTICE, " ** adjust: SLEW %s offset %s **\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
+ "slew",
#else
- syslog(LOG_NOTICE, " ** adjust: STEP %s offset %s **\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
+ "step",
#endif
+ lfptoa(fp_offset, 6));
step_systime(fp_offset);
-
clock_adjust = 0;
watchdog_timer = 0;
first_adjustment = 1;
@@ -480,20 +491,24 @@ local_clock(fp_offset, peer)
* The time constant update goes after adjust and skew updates,
* as in appendix G.
*/
-#if defined(PPS) || defined(PPSCLK) || defined(PPSPPS)
/*
* If pps samples are valid, update offset, root delay and
- * root dispersion. This may be a dramatic surprise to high-
- * stratum clients, since all of a sudden this server looks
- * like a stratum-1 clock.
+ * root dispersion. Also, set the system stratum to 1, even if
+ * the source of approximate time runs at a higher stratum. This
+ * may be a dramatic surprise to high-stratum clients, since all
+ * of a sudden this server looks like a stratum-1 clock.
*/
if (pps_control) {
last_offset = pps_offset;
+ sys_maxd = pps_dispersion;
sys_stratum = 1;
sys_rootdelay = 0;
- sys_rootdispersion = sys_maxd;
+ offset = LFPTOFP(&pps_offset);
+ if (offset < 0)
+ offset = -offset;
+ sys_rootdispersion = offset + pps_dispersion;
}
-#endif /* PPS || PPSCLK || PPSPPS */
+ offset = last_offset.l_f;
/*
* The pll_control is active when the phase-lock code is
@@ -504,26 +519,56 @@ local_clock(fp_offset, peer)
* know the scaling of the frequency variable (s_fp) is the
* same as the kernel variable (1 << SHIFT_USEC = 16).
*
+ * For kernels with the PPS discipline, the current offset and
+ * dispersion are set from kernel variables to maintain
+ * beauteous displays, but don't do much of anything.
+ *
* In the case of stock kernels the phase-lock loop is
* implemented the hard way and the clock_adjust and drift_comp
* computed as required.
*/
- offset = last_offset.l_f;
if (pll_control) {
#if defined(KERNEL_PLL)
- ntv.mode = ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR |
- ADJ_ESTERROR;
+ memset((char *)&ntv, 0, sizeof ntv);
+ ntv.modes = MOD_BITS;
if (offset >= 0) {
TSFTOTVU(offset, ntv.offset);
} else {
TSFTOTVU(-offset, ntv.offset);
ntv.offset = -ntv.offset;
}
- ntv.maxerror = sys_rootdispersion + sys_rootdelay / 2;
- ntv.esterror = sys_rootdispersion;
- ntv.time_constant = time_constant;
+ TSFTOTVU(sys_rootdispersion + sys_rootdelay / 2, ntv.maxerror);
+ TSFTOTVU(sys_rootdispersion, ntv.esterror);
+ ntv.status = pll_status;
+ if (pps_update)
+ ntv.status |= STA_PPSTIME;
+ if (sys_leap & LEAP_ADDSECOND &&
+ sys_leap & LEAP_DELSECOND)
+ ntv.status |= STA_UNSYNC;
+ else if (sys_leap & LEAP_ADDSECOND)
+ ntv.status |= STA_INS;
+ else if (sys_leap & LEAP_DELSECOND)
+ ntv.status |= STA_DEL;
+ ntv.constant = time_constant;
(void)ntp_adjtime(&ntv);
- drift_comp = ntv.frequency;
+ drift_comp = ntv.freq;
+ if (ntv.status & STA_PPSTIME && ntv.status & STA_PPSSIGNAL
+ && ntv.shift) {
+ if (ntv.offset >= 0) {
+ TVUTOTSF(ntv.offset, offset);
+ } else {
+ TVUTOTSF(-ntv.offset, offset);
+ offset = -offset;
+ }
+ pps_offset.l_i = pps_offset.l_f = 0;
+ M_ADDF(pps_offset.l_i, pps_offset.l_f, offset);
+ TVUTOTSF(ntv.jitter, tmp);
+ pps_dispersion = (tmp >> 16) & 0xffff;
+ pps_time = current_time;
+ record_peer_stats(&loopback_interface->sin,
+ ctlsysstatus(), &pps_offset, 0, pps_dispersion);
+ } else
+ pps_time = 0;
#endif /* KERNEL_PLL */
} else {
if (offset < 0) {
@@ -533,21 +578,14 @@ local_clock(fp_offset, peer)
}
/*
- * Calculate the new frequency error. The factor given in the
- * spec gives the adjustment per 2**CLOCK_ADJ seconds, but we
- * want it as a (scaled) pure ratio, so we include that factor
- * now and remove it later.
+ * Calculate the new frequency error. The factor given
+ * in the spec gives the adjustment per 2**CLOCK_ADJ
+ * seconds, but we want it as a (scaled) pure ratio, so
+ * we include that factor now and remove it later.
*/
if (first_adjustment) {
first_adjustment = 0;
} else {
- /*
- * Clamp the integration interval to maxpoll.
- * The bitcounting in Section 5 gives (n+1)-6 for 2**n,
- * but has a factor 2**6 missing from CLOCK_FREQ.
- * We make 2**n give n instead. If watchdog_timer is
- * zero, pretend it's one.
- */
tmp = peer->maxpoll;
tmp_uf = watchdog_timer;
if (tmp_uf == 0)
@@ -558,10 +596,11 @@ local_clock(fp_offset, peer)
}
/*
- * We apply the frequency scaling at the same time as
- * the sample interval; this ensures a safe right-shift.
- * (as long as it keeps below 31 bits, which current
- * parameters should ensure.
+ * We apply the frequency scaling at the same
+ * time as the sample interval; this ensures a
+ * safe right-shift. (as long as it keeps below
+ * 31 bits, which current parameters should
+ * ensure.
*/
tmp = (RSH_FRAC_TO_FREQ - tmp) +
time_constant + time_constant;
@@ -581,7 +620,9 @@ local_clock(fp_offset, peer)
/*
* Determine when to adjust the time constant and poll interval.
*/
- if (current_time - tcadj_time >= (1 << sys_poll)) {
+ if (pps_control)
+ time_constant = 0;
+ else if (current_time - tcadj_time >= (1 << sys_poll) && !pps_control) {
tcadj_time = current_time;
tmp = offset;
if (tmp < 0)
@@ -607,8 +648,8 @@ local_clock(fp_offset, peer)
#ifdef DEBUG
if (debug > 1)
printf("adj %s, drft %s, tau %3i\n",
- mfptoa((clock_adjust<0?-1:0), clock_adjust, 9),
- fptoa(drift_comp, 9), time_constant);
+ mfptoa((clock_adjust<0?-1:0), clock_adjust, 6),
+ fptoa(drift_comp, 6), time_constant);
#endif /* DEBUG */
(void) record_loop_stats(&last_offset, &drift_comp, time_constant);
@@ -662,20 +703,20 @@ adj_host_clock()
}
}
#endif /* PPSPPS */
- if (pps_time != 0 && current_time - pps_time > PPS_MAXAGE)
- pps_time = 0;
- if (pps_update != 0 && current_time - pps_update > PPS_MAXUPDATE)
- pps_update = 0;
- if (pps_time != 0 && pps_update != 0) {
+#endif /* PPS || PPSCLK || PPSPPS */
+ if (pps_time && current_time - pps_time > PPS_MAXAGE)
+ pps_time = 0;
+ if (pps_update && current_time - pps_update > PPS_MAXUPDATE)
+ pps_update = 0;
+ if (pps_time && pps_update) {
if (!pps_control)
- syslog(LOG_INFO, "pps synch");
+ syslog(LOG_INFO, "PPS synch");
pps_control = 1;
} else {
if (pps_control)
- syslog(LOG_INFO, "pps synch lost");
+ syslog(LOG_INFO, "PPS synch lost");
pps_control = 0;
}
-#endif /* PPS || PPSCLK || PPSPPS */
/*
* Resist the following code if the phase-lock loop has been
@@ -722,22 +763,27 @@ loop_config(item, lfp_value, int_value)
tmp = LFPTOFP(lfp_value);
if (tmp >= max_comp || tmp <= -max_comp) {
syslog(LOG_ERR,
- "loop_config: skew compensation %s too large",
+ "loop_config: frequency offset %s in ntp.conf file is too large",
fptoa(tmp, 5));
} else {
drift_comp = tmp;
#if defined(KERNEL_PLL)
/*
- * If the phase-lock code is implemented in the kernel,
- * give the time_constant and saved frequency offset
- * to the kernel. If not, no harm is done.
+ * If the phase-lock code is implemented in the
+ * kernel, give the time_constant and saved
+ * frequency offset to the kernel. If not, no
+ * harm is done.
*/
pll_control = 1;
- ntv.mode = ADJ_FREQUENCY | ADJ_STATUS | ADJ_TIMECONST;
- ntv.status = TIME_BAD;
- ntv.time_constant = time_constant;
- ntv.frequency = drift_comp;
+ pll_status = STA_PLL | STA_PPSFREQ;
+ ntv.modes = MOD_BITS | MOD_FREQUENCY;
+ ntv.offset = 0;
+ ntv.freq = drift_comp;
+ ntv.maxerror = NTP_MAXDISPERSE;
+ ntv.esterror = NTP_MAXDISPERSE;
+ ntv.status = pll_status | STA_UNSYNC;
+ ntv.constant = time_constant;
newsigsys.sv_handler = pll_trap;
newsigsys.sv_mask = 0;
newsigsys.sv_flags = 0;
@@ -748,13 +794,13 @@ loop_config(item, lfp_value, int_value)
if ((sigvec(SIGSYS, &sigsys, (struct sigvec *)NULL)))
syslog(LOG_ERR,
"sigvec() fails to restore SIGSYS trap: %m\n");
- syslog(LOG_NOTICE,
- "%susing kernel phase-lock loop",
- (pll_control) ? "" : "Not ");
-#if DEBUG
- if (debug)
- printf("pll_control %d\n", pll_control);
-#endif
+ if (pll_control)
+ syslog(LOG_NOTICE,
+ "using kernel phase-lock loop %04x",
+ ntv.status);
+ else
+ syslog(LOG_NOTICE,
+ "using xntpd phase-lock loop");
#endif /* KERNEL_PLL */
}
@@ -812,7 +858,7 @@ loop_config(item, lfp_value, int_value)
* _trap - trap processor for undefined syscalls
*
* This nugget is called by the kernel when the SYS_ntp_adjtime()
- * syscall bombs because the silly thing has not been implemented int
+ * syscall bombs because the silly thing has not been implemented in
* the kernel. In this case the phase-lock loop is emulated by
* the stock adjtime() syscall and a lot of indelicate abuse.
*/
@@ -873,12 +919,14 @@ int pps_sample(tsr)
int i, j; /* temp ints */
LONG sort[NPPS]; /* temp array for sorting */
l_fp lftemp, ts; /* l_fp temps */
+ u_fp utemp; /* u_fp temp */
LONG ltemp; /* long temp */
/*
* Note the seconds offset is already in the low-order timestamp
- * doubleword, so all we have to do is sign-extend and invert it.
- * The resulting offset is believed only if within CLOCK_MAX.
+ * doubleword, so all we have to do is sign-extend and invert
+ * it. The resulting offset is believed only if within
+ * CLOCK_MAX.
*/
ts = *tsr;
lftemp.l_i = lftemp.l_f = 0;
@@ -934,14 +982,14 @@ int pps_sample(tsr)
}
lftemp.l_i = 0;
lftemp.l_f = sort[NPPS-1-PPS_TRIM] - sort[PPS_TRIM];
- sys_maxd = LFPTOFP(&lftemp);
+ pps_dispersion = LFPTOFP(&lftemp);
#ifdef DEBUG
if (debug)
printf("pps_filter: %s %s %s\n", lfptoa(&pps_delay, 6),
lfptoa(&pps_offset, 6), lfptoa(&lftemp, 5));
#endif /* DEBUG */
- record_peer_stats(&loopback_interface->sin, ctlsysstatus(), &pps_offset,
- sys_rootdelay, sys_rootdispersion);
+ record_peer_stats(&loopback_interface->sin, ctlsysstatus(),
+ &pps_offset, 0, pps_dispersion);
return (0);
}
#endif /* PPS || PPSCLK || PPSPPS */
diff --git a/contrib/xntpd/xntpd/ntp_monitor.c b/contrib/xntpd/xntpd/ntp_monitor.c
index 63af8d4d4d97..e2d2eb51adac 100644
--- a/contrib/xntpd/xntpd/ntp_monitor.c
+++ b/contrib/xntpd/xntpd/ntp_monitor.c
@@ -58,7 +58,7 @@
static struct mon_data *mon_hash; /* Pointer to array of hash buckets */
static int *mon_hash_count; /* Point to hash count stats keeper */
struct mon_data mon_mru_list;
-
+ struct mon_data mon_fifo_list;
/*
* List of free structures structures, and counters of free and total
* structures. The free structures are linked with the hash_next field.
@@ -93,7 +93,7 @@ init_mon()
* Don't do much of anything here. We don't allocate memory
* until someone explicitly starts us.
*/
- mon_enabled = 0;
+ mon_enabled = MON_OFF;
mon_have_memory = 0;
mon_free_mem = 0;
@@ -103,6 +103,7 @@ init_mon()
mon_hash = 0;
mon_hash_count = 0;
memset((char *)&mon_mru_list, 0, sizeof mon_mru_list);
+ memset((char *)&mon_fifo_list, 0, sizeof mon_fifo_list);
}
@@ -110,13 +111,18 @@ init_mon()
* mon_start - start up the monitoring software
*/
void
-mon_start()
+mon_start(mode)
+ int mode;
{
register struct mon_data *md;
register int i;
- if (mon_enabled)
+ if (mon_enabled != MON_OFF) {
+ mon_enabled |= mode;
return;
+ }
+ if (mode == MON_OFF)
+ return; /* Ooops.. */
if (!mon_have_memory) {
mon_hash = (struct mon_data *)
@@ -142,7 +148,10 @@ mon_start()
mon_mru_list.mru_next = &mon_mru_list;
mon_mru_list.mru_prev = &mon_mru_list;
- mon_enabled = 1;
+ mon_fifo_list.fifo_next = &mon_fifo_list;
+ mon_fifo_list.fifo_prev = &mon_fifo_list;
+
+ mon_enabled = mode;
}
@@ -150,12 +159,19 @@ mon_start()
* mon_stop - stop the monitoring software
*/
void
-mon_stop()
+mon_stop(mode)
+ int mode;
{
register struct mon_data *md;
register int i;
- if (!mon_enabled)
+ if (mon_enabled == MON_OFF)
+ return;
+ if ((mon_enabled & mode) == 0 || mode == MON_OFF)
+ return;
+
+ mon_enabled &= ~mode;
+ if (mon_enabled != MON_OFF)
return;
/*
@@ -176,7 +192,8 @@ mon_stop()
mon_mru_list.mru_next = &mon_mru_list;
mon_mru_list.mru_prev = &mon_mru_list;
- mon_enabled = 0;
+ mon_fifo_list.fifo_next = &mon_fifo_list;
+ mon_fifo_list.fifo_prev = &mon_fifo_list;
}
@@ -194,7 +211,7 @@ monitor(rbufp)
register int mode;
register struct mon_data *mdhash;
- if (!mon_enabled)
+ if (mon_enabled == MON_OFF)
return;
pkt = &rbufp->recv_pkt;
@@ -220,6 +237,7 @@ monitor(rbufp)
md->mru_prev = &mon_mru_list;
mon_mru_list.mru_next->mru_prev = md;
mon_mru_list.mru_next = md;
+
return;
}
md = md->hash_next;
@@ -240,6 +258,12 @@ monitor(rbufp)
md->hash_next->hash_prev = md->hash_prev;
md->hash_prev->hash_next = md->hash_next;
*(mon_hash_count + MON_HASH(md->rmtadr)) -= 1;
+ /*
+ * Get it from FIFO list
+ */
+ md->fifo_prev->fifo_next = md->fifo_next;
+ md->fifo_next->fifo_prev = md->fifo_prev;
+
} else {
if (mon_free_mem == 0)
mon_getmoremem();
@@ -252,6 +276,7 @@ monitor(rbufp)
* Got one, initialize it
*/
md->lasttime = md->firsttime = current_time;
+ md->lastdrop = 0;
md->count = 1;
md->rmtadr = netnum;
md->rmtport = NSRCPORT(&rbufp->recv_srcadr);
@@ -260,7 +285,8 @@ monitor(rbufp)
/*
* Shuffle him into the hash table, inserting him at the
- * end. Also put him on top of the MRU list.
+ * end. Also put him on top of the MRU list
+ * and at bottom of FIFO list
*/
mdhash = mon_hash + MON_HASH(netnum);
md->hash_next = mdhash;
@@ -273,6 +299,11 @@ monitor(rbufp)
md->mru_prev = &mon_mru_list;
mon_mru_list.mru_next->mru_prev = md;
mon_mru_list.mru_next = md;
+
+ md->fifo_prev = mon_fifo_list.fifo_prev;
+ md->fifo_next = &mon_fifo_list;
+ mon_fifo_list.fifo_prev->fifo_next = md;
+ mon_fifo_list.fifo_prev = md;
}
diff --git a/contrib/xntpd/xntpd/ntp_peer.c b/contrib/xntpd/xntpd/ntp_peer.c
index cadd415346a9..9d8ec35dee78 100644
--- a/contrib/xntpd/xntpd/ntp_peer.c
+++ b/contrib/xntpd/xntpd/ntp_peer.c
@@ -340,22 +340,24 @@ unpeer(peer_to_remove)
* peer_config - configure a new peer
*/
struct peer *
-peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
+peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, flags, ttl, key)
struct sockaddr_in *srcadr;
struct interface *dstadr;
int hmode;
int version;
int minpoll;
int maxpoll;
- U_LONG key;
int flags;
+ int ttl;
+ U_LONG key;
{
register struct peer *peer;
#ifdef DEBUG
if (debug)
- printf("peer_config: addr %s mode %d version %d minpoll %d maxpoll %d key %u\n",
- ntoa(srcadr), hmode, version, minpoll, maxpoll, key);
+ printf("peer_config: addr %s mode %d version %d minpoll %d maxpoll %d flags %d ttl %d key %u\n",
+ ntoa(srcadr), hmode, version, minpoll, maxpoll, flags,
+ ttl, key);
#endif
/*
* See if we have this guy in the tables already. If
@@ -387,6 +389,7 @@ peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
peer->ppoll = peer->minpoll;
peer->flags = ((u_char)(flags|FLAG_CONFIG))
|(peer->flags & (FLAG_REFCLOCK|FLAG_DEFBDELAY));
+ peer->ttl = (u_char)ttl;
peer->keyid = key;
return peer;
}
@@ -395,7 +398,8 @@ peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
* If we're here this guy is unknown to us. Make a new peer
* structure for him.
*/
- peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, key);
+ peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
+ ttl, key);
if (peer != 0)
peer->flags |= (u_char)(flags|FLAG_CONFIG);
return peer;
@@ -406,13 +410,14 @@ peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
* newpeer - initialize a new peer association
*/
struct peer *
-newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, key)
+newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, ttl, key)
struct sockaddr_in *srcadr;
struct interface *dstadr;
int hmode;
int version;
int minpoll;
int maxpoll;
+ int ttl;
U_LONG key;
{
register struct peer *peer;
@@ -454,13 +459,10 @@ newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, key)
peer->maxpoll = (u_char)maxpoll;
peer->hpoll = peer->minpoll;
peer->ppoll = peer->minpoll;
+ peer->ttl = ttl;
peer->keyid = key;
-
- if (hmode == MODE_BCLIENT) {
- peer->estbdelay = sys_bdelay;
- peer->flags |= FLAG_DEFBDELAY;
- }
-
+ peer->estbdelay = sys_bdelay;
+ peer->flags |= FLAG_DEFBDELAY;
peer->leap = LEAP_NOTINSYNC;
peer->precision = DEFPRECISION;
peer->dispersion = NTP_MAXDISPERSE;
diff --git a/contrib/xntpd/xntpd/ntp_proto.c b/contrib/xntpd/xntpd/ntp_proto.c
index 88e95bbf8d13..a3f744eae881 100644
--- a/contrib/xntpd/xntpd/ntp_proto.c
+++ b/contrib/xntpd/xntpd/ntp_proto.c
@@ -25,7 +25,7 @@ l_fp sys_reftime; /* time we were last updated */
l_fp sys_refskew; /* accumulated skew since last update */
struct peer *sys_peer; /* our current peer */
u_char sys_poll; /* log2 of desired system poll interval */
-LONG sys_clock; /* second part of current time */
+extern LONG sys_clock; /* second part of current time - now in systime.c */
LONG sys_lastselect; /* sys_clock at last synch-dist update */
/*
@@ -48,7 +48,7 @@ U_LONG sys_unknownversion; /* don't know version packets */
U_LONG sys_badlength; /* packets with bad length */
U_LONG sys_processed; /* packets processed */
U_LONG sys_badauth; /* packets dropped because of authorization */
-U_LONG sys_wanderhold; /* sys_peer held to prevent wandering */
+U_LONG sys_limitrejected; /* pkts rejected due toclient count per net */
/*
* Imported from ntp_timer.c
@@ -90,7 +90,8 @@ transmit(peer)
struct pkt xpkt; /* packet to send */
U_LONG peer_timer;
- if (peer->hmode != MODE_BCLIENT) {
+ if ((peer->hmode != MODE_BROADCAST && peer->hmode != MODE_BCLIENT) ||
+ (peer->hmode == MODE_BROADCAST && sys_leap != LEAP_NOTINSYNC)) {
U_LONG xkeyid;
/*
@@ -239,17 +240,14 @@ transmit(peer)
/*
* Finally, adjust the hpoll variable for special conditions.
*/
- if (peer->flags & FLAG_SYSPEER && peer->hpoll > sys_poll) {
- /* clamp it */
+ if (peer->hmode == MODE_BCLIENT)
+ peer->hpoll = peer->ppoll;
+ else if (peer->flags & FLAG_SYSPEER &&
+ peer->hpoll > sys_poll)
peer->hpoll = max(peer->minpoll, sys_poll);
- }
- if (peer->hmode == MODE_BROADCAST || peer->hmode == MODE_BCLIENT) {
- /* clamp it */
- peer->hpoll = peer->minpoll;
- }
/*
- * Arrange for our next time out. hpoll will be less than
+ * Arrange for our next timeout. hpoll will be less than
* maxpoll for sure.
*/
if (peer->event_timer.next != 0)
@@ -262,37 +260,6 @@ transmit(peer)
TIMER_ENQUEUE(timerqueue, &peer->event_timer);
}
-#if 0
-static void
-ct_die(after)
-{
- syslog(LOG_ERR, "timers garbled (%s)", after?"after":"before");
- abort();
-}
-
-void
-check_timers(after)
-{
- register int i;
- register struct event *p, *q;
-
- for (i = 0; i < TIMER_NSLOTS; i++) {
- p = &timerqueue[i];
- if (p->event_time != 0)
- ct_die(after);
- do {
- q = p;
- if ((p = p->next) == 0)
- ct_die(after);
- if (p->prev != q)
- ct_die(after);
- } while (p->event_time != 0);
- if (p != &timerqueue[i])
- ct_die(after);
- }
-}
-#endif
-
/*
* receive - Receive Procedure. See section 3.4.2 in the specification.
*/
@@ -373,6 +340,21 @@ receive(rbufp)
return;
/*
+ * See if we only accept limited number of clients
+ * from the net this guy is from.
+ * Note: the flag is determined dynamically within restrictions()
+ */
+ if (restrict & RES_LIMITED) {
+ extern U_LONG client_limit;
+
+ sys_limitrejected++;
+ syslog(LOG_NOTICE,
+ "rejected mode %d request from %s - per net client limit (%d) exceeded",
+ PKT_MODE(pkt->li_vn_mode),
+ ntoa(&rbufp->recv_srcadr), client_limit);
+ return;
+ }
+ /*
* Dump anything with a putrid stratum. These will most likely
* come from someone trying to poll us with ntpdc.
*/
@@ -517,6 +499,9 @@ receive(rbufp)
break;
case MODE_PASSIVE:
+#ifdef MCAST
+ /* process the packet to determine the rt-delay */
+#endif /* MCAST */
case MODE_SERVER:
/*
* These are obvious errors. Ignore.
@@ -534,8 +519,10 @@ receive(rbufp)
/*
* Sort of a repeat of the above...
*/
+/*
if ((restrict & RES_NOPEER) || !sys_bclient)
return;
+*/
mymode = MODE_BCLIENT;
break;
}
@@ -546,7 +533,7 @@ receive(rbufp)
*/
peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, mymode,
PKT_VERSION(pkt->li_vn_mode), NTP_MINDPOLL,
- NTP_MAXPOLL, hiskeyid);
+ NTP_MAXPOLL, 0, hiskeyid);
if (peer == 0) {
/*
* The only way this can happen is if the
@@ -706,12 +693,11 @@ receive(rbufp)
* out to be bad.
*/
peer2 = newpeer(&rbufp->recv_srcadr,
- rbufp->dstadr, MODE_PASSIVE,
- PKT_VERSION(pkt->li_vn_mode),
- NTP_MINDPOLL, NTP_MAXPOLL,
- hiskeyid);
+ rbufp->dstadr, MODE_PASSIVE,
+ PKT_VERSION(pkt->li_vn_mode),
+ NTP_MINDPOLL, NTP_MAXPOLL, 0, hiskeyid);
if (process_packet(peer2, pkt, &rbufp->recv_time,
- has_mac, trustable) == 0) {
+ has_mac, trustable) == 0) {
/*
* Strange situation. We've been receiving
* broadcasts from him which we liked, but
@@ -769,20 +755,21 @@ process_packet(peer, pkt, recv_ts, has_mac, trustable)
sys_processed++;
peer->processed++;
-
- peer->rec = *recv_ts;
p_dist = NTOHS_FP(pkt->rootdelay);
p_disp = NTOHS_FP(pkt->rootdispersion);
NTOHL_FP(&pkt->rec, &p_rec);
NTOHL_FP(&pkt->xmt, &p_xmt);
- NTOHL_FP(&pkt->org, &p_org);
+ if (PKT_MODE(pkt->li_vn_mode) != MODE_BROADCAST)
+ NTOHL_FP(&pkt->org, &p_org);
+ else
+ p_org = peer->rec;
+ peer->rec = *recv_ts;
peer->flash = 0;
randomize = POLL_RANDOMCHANGE;
/*
* Test for old or duplicate packets (tests 1 through 3).
*/
-
if (L_ISHIS(&peer->org, &p_xmt)) /* count old packets */
peer->oldpkt++;
if (L_ISEQU(&peer->org, &p_xmt)) /* test 1 */
@@ -796,6 +783,9 @@ process_packet(peer, pkt, recv_ts, has_mac, trustable)
if ((p_rec.l_ui == 0 && p_rec.l_uf == 0) ||
(p_org.l_ui == 0 && p_org.l_uf == 0))
peer->flash |= TEST3; /* unsynchronized */
+ } else {
+ if (p_org.l_ui == 0 && p_org.l_uf == 0)
+ peer->flash |= TEST3; /* unsynchronized */
}
peer->org = p_xmt; /* reuse byte-swapped pkt->xmt */
peer->ppoll = pkt->ppoll;
@@ -901,39 +891,23 @@ process_packet(peer, pkt, recv_ts, has_mac, trustable)
ci.l_ui = t10_ui;
ci.l_uf = t10_uf;
ei = (FP_SECOND >> (-(int)sys_precision));
- if (peer->hmode == MODE_BCLIENT) {
-#ifdef notdef
- if (PKT_MODE(pkt->li_vn_mode) == MODE_CLIENT) {
- /*
- * A client mode packet, used for delay computation.
- * Give the data to the filter.
- */
- bdelay_filter(peer, t23_ui, t23_uf, t10_ui, t10_uf);
- }
-#endif
- M_ADDUF(ci.l_ui, ci.l_uf, peer->estbdelay>>1);
+
+ /*
+ * If broadcast mode, time of last reception has been fiddled
+ * to p_org, rather than originate timestamp. We use this to
+ * augment dispersion and previously calcuated estbdelay as
+ * the delay. We know NTP_SKEWFACTOR == 16, which accounts for
+ * the simplified ei calculation.
+ */
+ if (PKT_MODE(pkt->li_vn_mode) == MODE_BROADCAST) {
+ M_ADDUF(ci.l_ui, ci.l_uf, peer->estbdelay >> 1);
di = MFPTOFP(0, peer->estbdelay);
+ ei += peer->rec.l_ui - p_org.l_ui;
} else {
M_ADD(ci.l_ui, ci.l_uf, t23_ui, t23_uf);
M_RSHIFT(ci.l_i, ci.l_uf);
-
- /*
- * Calculate di in t23 in full precision, then truncate
- * to an s_fp.
- */
M_SUB(t23_ui, t23_uf, t10_ui, t10_uf);
di = MFPTOFP(t23_ui, t23_uf);
- /*
- * Calculate (t3 - t0) in t23 in full precision, convert
- * to single, shift down by MAXSKEW and add to ei.
- * We know NTP_SKEWFACTOR == 16
- */
-#if 0
- t23_ui = peer->rec.l_ui; /* peer->rec == t0 */
- t23_uf = peer->rec.l_uf;
- M_SUB(t23_ui, t23_uf, p_org.l_ui, p_org.l_uf); /*pkt->org==t3*/
- ei += (MFPTOFP(t23_ui, t23_uf) >> NTP_SKEWFACTOR);
-#endif
ei += peer->rec.l_ui - p_org.l_ui;
}
#ifdef DEBUG
@@ -1057,9 +1031,7 @@ clock_update(peer)
if (d < 0)
d = -d;
sys_rootdelay = peer->rootdelay + d;
- sys_maxd = peer->dispersion;
- if (peer->flags & FLAG_PREFER)
- sys_maxd += peer->selectdisp;
+ sys_maxd = peer->dispersion + peer->selectdisp;
d = peer->soffset;
if (d < 0)
d = -d;
@@ -1155,7 +1127,7 @@ poll_update(peer, new_hpoll, randomize)
* Catch reference clocks here. The polling interval for a
* reference clock is fixed and needn't be maintained by us.
*/
- if (peer->flags & FLAG_REFCLOCK)
+ if (peer->flags & FLAG_REFCLOCK || peer->hmode == MODE_BROADCAST)
return;
/*
@@ -1177,7 +1149,9 @@ poll_update(peer, new_hpoll, randomize)
* less that peer.timer, update peer.timer.
*/
oldpoll = peer->hpoll;
- if ((peer->flags & FLAG_SYSPEER) && new_hpoll > sys_poll)
+ if (peer->hmode == MODE_BCLIENT)
+ peer->hpoll = peer->ppoll;
+ else if ((peer->flags & FLAG_SYSPEER) && new_hpoll > sys_poll)
peer->hpoll = max(peer->minpoll, sys_poll);
else {
if (new_hpoll > peer->maxpoll)
@@ -1192,10 +1166,10 @@ poll_update(peer, new_hpoll, randomize)
newpoll = max((u_char)min(peer->ppoll, peer->hpoll), peer->minpoll);
if (randomize == POLL_MAKERANDOM ||
(randomize == POLL_RANDOMCHANGE && newpoll != oldpoll))
- new_timer = (1<<(newpoll - 1))
+ new_timer = (1 << (newpoll - 1))
+ ranp2(newpoll - 1) + current_time;
else
- new_timer = (1<<newpoll) + current_time;
+ new_timer = (1 << newpoll) + current_time;
evp = &(peer->event_timer);
if (evp->next == 0 || evp->event_time > new_timer) {
TIMER_DEQUEUE(evp);
@@ -1342,26 +1316,10 @@ clock_filter(peer, sample_offset, sample_delay, sample_error)
/*
* Find where he goes in, then shift everyone else down
*/
- if (peer->hmode == MODE_BCLIENT) {
- register s_fp *soffsetp;
- /*
- * Sort by offset. The most positive offset
- * should correspond to the minimum delay.
- */
- soffsetp = peer->filter_soffset;
- for (i = 0; i < NTP_SHIFT-1; i++)
- if (errorp[ord[i]] >= NTP_MAXDISPERSE
- || sample_soffset >= soffsetp[ord[i]])
- break;
- } else {
- /*
- * Sort by distance.
- */
- for (i = 0; i < NTP_SHIFT-1; i++)
- if (errorp[ord[i]] >= NTP_MAXDISPERSE
- || sample_distance <= distance[ord[i]])
- break;
- }
+ for (i = 0; i < NTP_SHIFT-1; i++)
+ if (errorp[ord[i]] >= NTP_MAXDISPERSE
+ || sample_distance <= distance[ord[i]])
+ break;
for (j = NTP_SHIFT-1; j > i; j--)
ord[j] = ord[j-1];
@@ -1676,7 +1634,7 @@ clock_select()
if (d < 0)
d = -d;
sdisp += d;
- sdisp = ((sdisp>>1) + sdisp) >> 1;
+ sdisp = ((sdisp >> 1) + sdisp) >> 1;
}
peer_list[i]->selectdisp = sdisp;
if (sdisp > maxd) {
@@ -1729,9 +1687,7 @@ clock_select()
for (i = 1; i < nlist; i++)
if (peer_list[i] == sys_peer)
break;
- if (i < nlist)
- sys_wanderhold++;
- else
+ if (i >= nlist)
sys_peer = peer_list[0];
}
@@ -2064,7 +2020,6 @@ init_proto()
sys_unknownversion = 0;
sys_processed = 0;
sys_badauth = 0;
- sys_wanderhold = 0;
syslog(LOG_NOTICE, "default precision is initialized to 2**%d", sys_precision);
}
@@ -2076,7 +2031,7 @@ init_proto()
void
proto_config(item, value)
int item;
- LONG value;
+ U_LONG value;
{
/*
* Figure out what he wants to change, then do it
@@ -2087,11 +2042,33 @@ proto_config(item, value)
* Turn on/off facility to listen to broadcasts
*/
sys_bclient = (int)value;
- if (sys_bclient)
+ if (value)
io_setbclient();
else
io_unsetbclient();
break;
+
+ case PROTO_MULTICAST_ADD:
+ /*
+ * Add multicast group address
+ */
+ if (!sys_bclient) {
+ sys_bclient = 1;
+ io_setbclient();
+ }
+#ifdef MCAST
+ io_multicast_add(value);
+#endif /* MCAST */
+ break;
+
+ case PROTO_MULTICAST_DEL:
+ /*
+ * Delete multicast group address
+ */
+#ifdef MCAST
+ io_multicast_del(value);
+#endif /* MCAST */
+ break;
case PROTO_PRECISION:
/*
@@ -2104,7 +2081,7 @@ proto_config(item, value)
/*
* Set default broadcast delay
*/
- sys_bdelay = (((U_LONG)value) + 0x00000800) & 0xfffff000;
+ sys_bdelay = ((value) + 0x00000800) & 0xfffff000;
break;
case PROTO_AUTHENTICATE:
@@ -2120,23 +2097,7 @@ proto_config(item, value)
* Provide an authentication delay value. Round it to
* the microsecond. This is crude.
*/
- sys_authdelay = (((U_LONG)value) + 0x00000800) & 0xfffff000;
- break;
-
- case PROTO_MAXSKEW:
- /*
- * Set the maximum skew value
- */
- syslog(LOG_ERR,
- "proto_config: attempt to set maxskew (obsolete)");
- break;
-
- case PROTO_SELECT:
- /*
- * Set the selection algorithm.
- */
- syslog(LOG_ERR,
- "proto_config: attempt to set selection algorithm (obsolete)");
+ sys_authdelay = ((value) + 0x00000800) & 0xfffff000;
break;
default:
@@ -2163,6 +2124,6 @@ proto_clr_stats()
sys_badlength = 0;
sys_processed = 0;
sys_badauth = 0;
- sys_wanderhold = 0;
sys_stattime = current_time;
+ sys_limitrejected = 0;
}
diff --git a/contrib/xntpd/xntpd/ntp_refclock.c b/contrib/xntpd/xntpd/ntp_refclock.c
index 5199a1acbd26..2cb7cc29d9a4 100644
--- a/contrib/xntpd/xntpd/ntp_refclock.c
+++ b/contrib/xntpd/xntpd/ntp_refclock.c
@@ -93,17 +93,6 @@ refclock_newpeer(peer)
peer->stratum = STRATUM_REFCLOCK;
peer->ppoll = peer->minpoll;
peer->hpoll = peer->minpoll;
- peer->maxpoll = peer->minpoll;
-
- /*
- * Check the flags. If the peer is configured in client mode
- * but prefers the broadcast client filter algorithm, change
- * him over.
- */
- if (peer->hmode == MODE_CLIENT
- && refclock_conf[clktype]->clock_flags & REF_FLAG_BCLIENT)
- peer->hmode = MODE_BCLIENT;
-
peer->event_timer.peer = peer;
peer->event_timer.event_handler = refclock_transmit;
@@ -201,20 +190,14 @@ refclock_transmit(peer)
l_fp off;
- if (peer->valid > 0) peer->valid--;
- if (peer->hpoll > peer->minpoll) peer->hpoll--;
+ if (peer->valid > 0)
+ peer->valid--;
off.l_ui = off.l_uf = 0;
clock_filter(peer, &off, 0, NTP_MAXDISPERSE);
if (peer->flags & FLAG_SYSPEER)
- clock_select();
- } else {
- if (peer->valid < NTP_SHIFT) {
- peer->valid++;
- } else {
- if (peer->hpoll < peer->maxpoll)
- peer->hpoll++;
- }
- }
+ clock_select();
+ } else if (peer->valid < NTP_SHIFT)
+ peer->valid++;
/*
* If he wants to be polled, do it.
@@ -313,9 +296,6 @@ refclock_receive(peer, offset, delay, dispersion, reftime, rectime, leap)
case MODE_CLIENT:
peer->pmode = MODE_SERVER;
break;
- case MODE_BCLIENT:
- peer->pmode = MODE_BROADCAST;
- break;
default:
syslog(LOG_ERR, "refclock_receive: internal error, mode = %d",
peer->hmode);
diff --git a/contrib/xntpd/xntpd/ntp_request.c b/contrib/xntpd/xntpd/ntp_request.c
index c19d1925a818..355b13b42b28 100644
--- a/contrib/xntpd/xntpd/ntp_request.c
+++ b/contrib/xntpd/xntpd/ntp_request.c
@@ -16,6 +16,14 @@
#include "ntp_if.h"
#include "ntp_stdlib.h"
+#ifdef KERNEL_PLL
+#include <sys/timex.h>
+#ifndef NTP_SYSCALLS_LIBC
+#define ntp_gettime(t) syscall(SYS_ntp_gettime, (t))
+#define ntp_adjtime(t) syscall(SYS_ntp_adjtime, (t))
+#endif
+#endif /* KERNEL_PLL */
+
/*
* Structure to hold request procedure information
*/
@@ -56,7 +64,7 @@ static void do_conf P((struct sockaddr_in *, struct interface *, struct req_pkt
static void do_unconf P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void set_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void clr_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *));
-static void setclr_flags P((struct sockaddr_in *, struct interface *, struct req_pkt *, int));
+static void setclr_flags P((struct sockaddr_in *, struct interface *, struct req_pkt *, U_LONG));
static void do_monitor P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void do_nomonitor P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void list_restrict P((struct sockaddr_in *, struct interface *, struct req_pkt *));
@@ -83,13 +91,14 @@ static void set_request_keyid P((struct sockaddr_in *, struct interface *, struc
static void set_control_keyid P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void get_ctl_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void get_leap_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
+#ifdef KERNEL_PLL
+static void get_kernel_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
+#endif /* KERNEL_PLL */
#ifdef REFCLOCK
static void get_clock_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void set_clock_fudge P((struct sockaddr_in *, struct interface *, struct req_pkt *));
#endif /* REFCLOCK */
-static void set_maxskew P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void set_precision P((struct sockaddr_in *, struct interface *, struct req_pkt *));
-static void set_select_code P((struct sockaddr_in *, struct interface *, struct req_pkt *));
#ifdef REFCLOCK
static void get_clkbug_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
#endif /* REFCLOCK */
@@ -134,9 +143,10 @@ static struct req_proc xntp_codes[] = {
{ REQ_CONTROL_KEY, AUTH, sizeof(U_LONG), set_control_keyid },
{ REQ_GET_CTLSTATS, NOAUTH, 0, get_ctl_stats },
{ REQ_GET_LEAPINFO, NOAUTH, 0, get_leap_info },
- { REQ_SET_MAXSKEW, AUTH, sizeof(u_fp), set_maxskew },
{ REQ_SET_PRECISION, AUTH, sizeof(LONG), set_precision },
- { REQ_SET_SELECT_CODE, AUTH, sizeof(U_LONG), set_select_code },
+#ifdef KERNEL_PLL
+ { REQ_GET_KERNEL, NOAUTH, 0, get_kernel_info },
+#endif /* KERNEL_PLL */
#ifdef REFCLOCK
{ REQ_GET_CLOCKINFO, NOAUTH, sizeof(U_LONG), get_clock_info },
{ REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge), set_clock_fudge },
@@ -162,6 +172,10 @@ U_LONG numresppkts; /* number of resp packets sent with data */
U_LONG errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */
/* by the error code */
+#if defined(KERNEL_PLL) && !defined(NTP_SYSCALLS_LIBC)
+extern int syscall P((int, void *, ...));
+#endif /* KERNEL_PLL */
+
/*
* Imported from the I/O module
*/
@@ -178,6 +192,11 @@ extern int debug;
extern U_LONG current_time;
/*
+ * Imported from ntp_loopfilter.c
+ */
+extern int pll_control;
+
+/*
* A hack. To keep the authentication module clear of xntp-ism's, we
* include a time reset variable for its stats here.
*/
@@ -657,6 +676,7 @@ peer_list_sum(srcadr, inter, inpkt)
ips->delay = HTONS_FP(pp->delay);
HTONL_FP(&pp->offset, &ips->offset);
ips->dispersion = HTONS_FP(pp->dispersion);
+
pp = pp->next;
ips = (struct info_peer_summary *)more_pkt();
}
@@ -724,7 +744,9 @@ peer_info (srcadr, inter, inpkt)
ip->valid = pp->valid;
ip->reach = pp->reach;
ip->unreach = pp->unreach;
- ip->trust = 0;
+ ip->flash = pp->flash;
+ ip->estbdelay = htonl(pp->estbdelay);
+ ip->ttl = pp->ttl;
ip->associd = htons(pp->associd);
ip->rootdelay = HTONS_FP(pp->rootdelay);
ip->rootdispersion = HTONS_FP(pp->rootdispersion);
@@ -745,12 +767,10 @@ peer_info (srcadr, inter, inpkt)
if (ip->order[i] >= NTP_SHIFT)
ip->order[i] -= NTP_SHIFT;
}
- ip->delay = HTONS_FP(pp->delay);
HTONL_FP(&pp->offset, &ip->offset);
+ ip->delay = HTONS_FP(pp->delay);
ip->dispersion = HTONS_FP(pp->dispersion);
- for (i = 0; i < NTP_SHIFT; i++)
- ip->bdelay[i] = 0;
- ip->estbdelay = htonl(pp->estbdelay);
+ ip->selectdisp = HTONS_FP(pp->selectdisp);
ip = (struct info_peer *)more_pkt();
}
flush_pkt();
@@ -882,12 +902,8 @@ sys_info(srcadr, inter, inpkt)
is->flags |= INFO_FLAG_BCLIENT;
if (sys_authenticate)
is->flags |= INFO_FLAG_AUTHENABLE;
- is->selection = 0; /* Obsolete */
-
HTONL_UF(sys_bdelay, &is->bdelay);
HTONL_UF(sys_authdelay, &is->authdelay);
- is->maxskew = 0;
-
(void) more_pkt();
flush_pkt();
}
@@ -915,7 +931,7 @@ sys_stats(srcadr, inter, inpkt)
extern U_LONG sys_badlength;
extern U_LONG sys_processed;
extern U_LONG sys_badauth;
- extern U_LONG sys_wanderhold;
+ extern U_LONG sys_limitrejected;
ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
sizeof(struct info_sys_stats));
@@ -929,8 +945,7 @@ sys_stats(srcadr, inter, inpkt)
ss->badlength = htonl(sys_badlength);
ss->processed = htonl(sys_processed);
ss->badauth = htonl(sys_badauth);
- ss->wanderhold = htonl(sys_wanderhold);
-
+ ss->limitrejected = htonl(sys_limitrejected);
(void) more_pkt();
flush_pkt();
}
@@ -1167,7 +1182,7 @@ do_conf(srcadr, inter, inpkt)
/* XXX W2DO? minpoll/maxpoll arguments ??? */
if (peer_config(&peeraddr, (struct interface *)0,
cp->hmode, cp->version, cp->minpoll, cp->maxpoll,
- cp->keyid, fl) == 0) {
+ fl, cp->ttl, cp->keyid) == 0) {
req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
return;
}
@@ -1252,7 +1267,7 @@ set_sys_flag(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- setclr_flags(srcadr, inter, inpkt, 1);
+ setclr_flags(srcadr, inter, inpkt, (U_LONG)1);
}
@@ -1265,7 +1280,7 @@ clr_sys_flag(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- setclr_flags(srcadr, inter, inpkt, 0);
+ setclr_flags(srcadr, inter, inpkt, (U_LONG)0);
}
@@ -1277,7 +1292,7 @@ setclr_flags(srcadr, inter, inpkt, set)
struct sockaddr_in *srcadr;
struct interface *inter;
struct req_pkt *inpkt;
- int set;
+ U_LONG set;
{
register U_LONG flags;
@@ -1289,15 +1304,20 @@ setclr_flags(srcadr, inter, inpkt, set)
flags = ((struct conf_sys_flags *)inpkt->data)->flags;
if (flags
- & ~(SYS_FLAG_BCLIENT|SYS_FLAG_AUTHENTICATE)) {
+ & ~(SYS_FLAG_BCLIENT | SYS_FLAG_MCLIENT | SYS_FLAG_AUTHENTICATE)) {
req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
return;
}
if (flags & SYS_FLAG_BCLIENT)
- proto_config(PROTO_BROADCLIENT, (LONG)set);
+ proto_config(PROTO_BROADCLIENT, set);
+ if (flags & SYS_FLAG_MCLIENT)
+ if (set)
+ proto_config(PROTO_MULTICAST_ADD, INADDR_NTP);
+ else
+ proto_config(PROTO_MULTICAST_DEL, INADDR_NTP);
if (flags & SYS_FLAG_AUTHENTICATE)
- proto_config(PROTO_AUTHENTICATE, (LONG)set);
+ proto_config(PROTO_AUTHENTICATE, set);
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
@@ -1311,7 +1331,7 @@ do_monitor(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- mon_start();
+ mon_start(MON_ON);
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
@@ -1325,7 +1345,7 @@ do_nomonitor(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- mon_stop();
+ mon_stop(MON_ON);
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
@@ -1497,6 +1517,10 @@ mon_getlist(srcadr, inter, inpkt)
md = md->mru_next) {
im->lasttime = htonl(current_time - md->lasttime);
im->firsttime = htonl(current_time - md->firsttime);
+ if (md->lastdrop)
+ im->lastdrop = htonl(current_time - md->lastdrop);
+ else
+ im->lastdrop = 0;
im->count = htonl(md->count);
im->addr = md->rmtadr;
im->port = md->rmtport;
@@ -2079,6 +2103,57 @@ get_leap_info(srcadr, inter, inpkt)
}
+#ifdef KERNEL_PLL
+/*
+ * get_kernel_info - get kernel pll/pps information
+ */
+static void
+get_kernel_info(srcadr, inter, inpkt)
+ struct sockaddr_in *srcadr;
+ struct interface *inter;
+ struct req_pkt *inpkt;
+{
+ register struct info_kernel *ik;
+ struct timex ntx;
+
+ if (!pll_control)
+ return;
+ memset((char *)&ntx, 0, sizeof(ntx));
+ (void)ntp_adjtime(&ntx);
+
+ ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_kernel));
+
+ /*
+ * pll variables
+ */
+ ik->offset = htonl(ntx.offset);
+ ik->freq = htonl(ntx.freq);
+ ik->maxerror = htonl(ntx.maxerror);
+ ik->esterror = htonl(ntx.esterror);
+ ik->status = htons(ntx.status);
+ ik->constant = htonl(ntx.constant);
+ ik->precision = htonl(ntx.precision);
+ ik->tolerance = htonl(ntx.tolerance);
+
+ /*
+ * pps variables
+ */
+ ik->ppsfreq = htonl(ntx.ppsfreq);
+ ik->jitter = htonl(ntx.jitter);
+ ik->shift = htons(ntx.shift);
+ ik->stabil = htonl(ntx.stabil);
+ ik->jitcnt = htonl(ntx.jitcnt);
+ ik->calcnt = htonl(ntx.calcnt);
+ ik->errcnt = htonl(ntx.errcnt);
+ ik->stbcnt = htonl(ntx.stbcnt);
+
+ (void) more_pkt();
+ flush_pkt();
+}
+#endif /* KERNEL_PLL */
+
+
#ifdef REFCLOCK
/*
* get_clock_info - get info about a clock
@@ -2204,29 +2279,6 @@ set_clock_fudge(srcadr, inter, inpkt)
#endif
/*
- * set_maxskew - set the system maxskew parameter
- */
-static void
-set_maxskew(srcadr, inter, inpkt)
- struct sockaddr_in *srcadr;
- struct interface *inter;
- struct req_pkt *inpkt;
-{
- register u_fp maxskew;
-
- if (INFO_NITEMS(inpkt->err_nitems) > 1) {
- req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
- return;
- }
-
- maxskew = NTOHS_FP(*(u_fp *)(inpkt->data));
-
- proto_config(PROTO_MAXSKEW, (LONG)maxskew);
- req_ack(srcadr, inter, inpkt, INFO_OKAY);
-}
-
-
-/*
* set_precision - set the system precision
*/
static void
@@ -2249,31 +2301,6 @@ set_precision(srcadr, inter, inpkt)
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
-
-/*
- * set_select_code - set a select code to use
- */
-static void
-set_select_code(srcadr, inter, inpkt)
- struct sockaddr_in *srcadr;
- struct interface *inter;
- struct req_pkt *inpkt;
-{
- register U_LONG select_code;
-
- select_code = ntohl(*(U_LONG *)(inpkt->data));
-
- if (INFO_NITEMS(inpkt->err_nitems) > 1 ||
- select_code < SELECT_1 || select_code > SELECT_5) {
- req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
- return;
- }
-
- proto_config(PROTO_SELECT, (LONG)select_code);
- req_ack(srcadr, inter, inpkt, INFO_OKAY);
-}
-
-
#ifdef REFCLOCK
/*
* get_clkbug_info - get debugging info about a clock
diff --git a/contrib/xntpd/xntpd/ntp_restrict.c b/contrib/xntpd/xntpd/ntp_restrict.c
index 51d896806207..43f01f296624 100644
--- a/contrib/xntpd/xntpd/ntp_restrict.c
+++ b/contrib/xntpd/xntpd/ntp_restrict.c
@@ -1,4 +1,4 @@
-/* ntp_restrict.c,v 3.1 1993/07/06 01:11:28 jbj Exp
+/*
* ntp_restrict.c - find out what restrictions this host is running under
*/
#include <stdio.h>
@@ -60,6 +60,21 @@ U_LONG res_not_found;
U_LONG res_timereset;
/*
+ * Parameters of the RES_LIMITED restriction option.
+ * client_limit is the number of hosts allowed per source net
+ * client_limit_period is the number of seconds after which an entry
+ * is no longer considered for client limit determination
+ */
+U_LONG client_limit;
+U_LONG client_limit_period;
+/*
+ * count number of restriction entries referring to RES_LIMITED
+ * controls activation/deactivation of monitoring
+ * (with respect ro RES_LIMITED control)
+ */
+U_LONG res_limited_refcnt;
+
+/*
* Our initial allocation of list entries.
*/
static struct restrictlist resinit[INITRESLIST];
@@ -70,12 +85,18 @@ static struct restrictlist resinit[INITRESLIST];
extern U_LONG current_time;
/*
+ * debug flag
+ */
+extern int debug;
+
+/*
* init_restrict - initialize the restriction data structures
*/
void
init_restrict()
{
register int i;
+ char bp[80];
/*
* Zero the list and put all but one on the free list
@@ -108,6 +129,18 @@ init_restrict()
res_found = 0;
res_not_found = 0;
res_timereset = 0;
+
+ /*
+ * set default values for RES_LIMIT functionality
+ */
+ client_limit = 3;
+ client_limit_period = 3600;
+ res_limited_refcnt = 0;
+
+ sprintf(bp, "client_limit=%d", client_limit);
+ set_sys_var(bp, strlen(bp)+1, RO);
+ sprintf(bp, "client_limit_period=%d", client_limit_period);
+ set_sys_var(bp, strlen(bp)+1, RO);
}
@@ -150,6 +183,120 @@ restrictions(srcadr)
else
res_found++;
+ /*
+ * The following implements limiting the number of clients
+ * accepted from a given network. The notion of "same network"
+ * is determined by the mask and addr fields of the restrict
+ * list entry. The monitor mechanism has to be enabled for
+ * collecting info on current clients.
+ *
+ * The policy is as follows:
+ * - take the list of clients recorded
+ * from the given "network" seen within the last
+ * client_limit_period seconds
+ * - if there are at most client_limit entries:
+ * --> access allowed
+ * - otherwise sort by time first seen
+ * - current client among the first client_limit seen
+ * hosts?
+ * if yes: access allowed
+ * else: eccess denied
+ */
+ if (match->flags & RES_LIMITED) {
+ int lcnt;
+ struct mon_data *md, *this_client;
+ extern int mon_enabled;
+ extern struct mon_data mon_fifo_list, mon_mru_list;
+
+#ifdef DEBUG
+ if (debug > 2)
+ printf("limited clients check: %d clients, period %d seconds, net is 0x%X\n",
+ client_limit, client_limit_period,
+ netof(hostaddr));
+#endif /*DEBUG*/
+ if (mon_enabled == MON_OFF) {
+#ifdef DEBUG
+ if (debug > 4)
+ printf("no limit - monitoring is off\n");
+#endif
+ return (int)(match->flags & ~RES_LIMITED);
+ }
+
+ /*
+ * How nice, MRU list provides our current client as the
+ * first entry in the list.
+ * Monitoring was verified to be active above, thus we
+ * know an entry for our client must exist, or some
+ * brain dead set the memory limit for mon entries to ZERO!!!
+ */
+ this_client = mon_mru_list.mru_next;
+
+ for (md = mon_fifo_list.fifo_next,lcnt = 0;
+ md != &mon_fifo_list;
+ md = md->fifo_next) {
+ if ((current_time - md->lasttime)
+ > client_limit_period) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("checking: %s: ignore: too old: %d\n",
+ numtoa(md->rmtadr),
+ current_time - md->lasttime);
+#endif
+ continue;
+ }
+ if (md->mode == MODE_BROADCAST ||
+ md->mode == MODE_CONTROL ||
+ md->mode == MODE_PRIVATE) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("checking: %s: ignore mode %d\n",
+ numtoa(md->rmtadr),
+ md->mode);
+#endif
+ continue;
+ }
+ if (netof(md->rmtadr) !=
+ netof(hostaddr)) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("checking: %s: different net 0x%X\n",
+ numtoa(md->rmtadr),
+ netof(md->rmtadr));
+#endif
+ continue;
+ }
+ lcnt++;
+ if (lcnt > client_limit ||
+ md->rmtadr == hostaddr) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("considering %s: found host\n",
+ numtoa(md->rmtadr));
+#endif
+ break;
+ }
+#ifdef DEBUG
+ else {
+ if (debug > 5)
+ printf("considering %s: same net\n",
+ numtoa(md->rmtadr));
+ }
+#endif
+
+ }
+#ifdef DEBUG
+ if (debug > 4)
+ printf("this one is rank %d in list, limit is %d: %s\n",
+ lcnt, client_limit,
+ (lcnt <= client_limit) ? "ALLOW" : "REJECT");
+#endif
+ if (lcnt <= client_limit) {
+ this_client->lastdrop = 0;
+ return (int)(match->flags & ~RES_LIMITED);
+ } else {
+ this_client->lastdrop = current_time;
+ }
+ }
return (int)match->flags;
}
@@ -257,6 +404,10 @@ restrict(op, resaddr, resmask, mflags, flags)
rlprev->next = rl;
restrictcount++;
}
+ if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
+ res_limited_refcnt++;
+ mon_start(MON_RES); /* ensure data gets collected */
+ }
rl->flags |= (u_short)flags;
break;
@@ -265,8 +416,14 @@ restrict(op, resaddr, resmask, mflags, flags)
* Remove some bits from the flags. If we didn't
* find this one, just return.
*/
- if (rl != 0)
+ if (rl != 0) {
+ if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
+ res_limited_refcnt--;
+ if (res_limited_refcnt == 0)
+ mon_stop(MON_RES);
+ }
rl->flags &= (u_short)~flags;
+ }
break;
case RESTRICT_REMOVE:
@@ -280,6 +437,11 @@ restrict(op, resaddr, resmask, mflags, flags)
&& !(rl->mflags & RESM_INTERFACE)) {
rlprev->next = rl->next;
restrictcount--;
+ if (rl->flags & RES_LIMITED) {
+ res_limited_refcnt--;
+ if (res_limited_refcnt == 0)
+ mon_stop(MON_RES);
+ }
memset((char *)rl, 0, sizeof(struct restrictlist));
rl->next = resfree;
diff --git a/contrib/xntpd/xntpd/ntp_unixclock.c b/contrib/xntpd/xntpd/ntp_unixclock.c
index 6b661835dbb7..1950d8c06fb3 100644
--- a/contrib/xntpd/xntpd/ntp_unixclock.c
+++ b/contrib/xntpd/xntpd/ntp_unixclock.c
@@ -251,10 +251,23 @@ clock_parms(tickadj, tick)
* Note that this version grovels about in /dev/kmem to determine
* these values. This probably should be elsewhere.
*/
-
-/* Define the following to be what the tick and tickadj variables are
- * called in your kernel.
+#if defined(SYS_UNIXWARE1)
+/*
+ * clock_parms - return the local clock tickadj and tick parameters
+ *
+ * The values set here were determined experimentally on a 486 system
+ * I'm not confident in them. - RAS
+ *
*/
+static void
+clock_parms(tickadj, tick)
+ U_LONG *tickadj;
+ U_LONG *tick;
+{
+ *tick = 10000; /* microseconds */
+ *tickadj = 80; /* microseconds */
+}
+#else /* SYS_UNIXWARE1 */
#if defined(SYS_AUX3) || defined(SYS_AUX2) || defined(SYS_SVR4) || defined(SYS_PTX)
#define K_TICKADJ_NAME "tickadj"
@@ -373,6 +386,7 @@ clock_parms(tickadj, tick)
#undef K_TICK_NAME
#undef N_NAME
}
+#endif /* SYS_UNIXWARE1 */
#endif /* HAVE_READKMEM */
#if defined(SOLARIS)&&defined(ADJTIME_IS_ACCURATE)
@@ -421,7 +435,6 @@ clock_parms(tickadj, tick)
}
#endif /* sgi */
-
#ifdef NOKMEM
#ifndef HZ
@@ -556,13 +569,18 @@ clock_parms(tickadj, tick)
#endif /* SOLARIS */
#ifdef SYS_LINUX
-/* XXX should look this up somewhere ! */
+#include <sys/timex.h>
static void
clock_parms(tickadj, tick)
U_LONG *tickadj;
U_LONG *tick;
{
- *tickadj = (U_LONG)1;
- *tick = (U_LONG)10000;
+ struct timex txc;
+
+ txc.mode = 0;
+ __adjtimex(&txc);
+
+ *tickadj = (U_LONG)1; /* our adjtime is accurate */
+ *tick = (U_LONG)txc.tick;
}
#endif /* SYS_LINUX */
diff --git a/contrib/xntpd/xntpd/ntpd.c b/contrib/xntpd/xntpd/ntpd.c
index abe86d945151..9ed43c5c4a81 100644
--- a/contrib/xntpd/xntpd/ntpd.c
+++ b/contrib/xntpd/xntpd/ntpd.c
@@ -14,7 +14,7 @@
#include <sys/rtprio.h>
#endif
-#if defined(SYS_SVR4)
+#if defined(SYS_SVR4) || defined (SYS_UNIXWARE1)
#include <termios.h>
#endif
@@ -28,8 +28,12 @@
#include "ntp_stdlib.h"
#ifdef LOCK_PROCESS
+#ifdef SYS_SOLARIS
+#include <sys/mman.h>
+#else
#include <sys/lock.h>
#endif
+#endif
/*
* Signals we catch for debugging. If not debugging we ignore them.
@@ -139,7 +143,7 @@ main(argc, argv)
(void) dup2(0, 1);
(void) dup2(0, 2);
#ifdef NTP_POSIX_SOURCE
-#if defined(SOLARIS) || defined(SYS_PTX) || defined(SYS_AUX3) || defined(SYS_AIX)
+#if defined(SOLARIS) || defined(SYS_PTX) || defined(SYS_AUX3) || defined(SYS_AIX) || defined(SYS_ULTRIX)
(void) setsid();
#else
(void) setpgid(0, 0);
@@ -219,13 +223,23 @@ main(argc, argv)
if (rtprio(0, 120) < 0)
syslog(LOG_ERR, "rtprio() error: %m");
#else
-#if defined(PROCLOCK) && defined(LOCK_PROCESS)
+#if defined(LOCK_PROCESS)
+#if defined(MCL_CURRENT) && defined(MCL_FUTURE)
+ /*
+ * lock the process into memory
+ */
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
+ syslog(LOG_ERR, "mlockall(): %m");
+#else
+#if defined(PROCLOCK)
/*
* lock the process into memory
*/
if (plock(PROCLOCK) < 0)
syslog(LOG_ERR, "plock(): %m");
#endif
+#endif
+#endif
#if defined(NTPD_PRIO) && NTPD_PRIO != 0
/*
* Set the priority.
diff --git a/contrib/xntpd/xntpd/refclock_chu.c b/contrib/xntpd/xntpd/refclock_chu.c
index 1c7c3bfa61c1..4596db22e2f5 100644
--- a/contrib/xntpd/xntpd/refclock_chu.c
+++ b/contrib/xntpd/xntpd/refclock_chu.c
@@ -599,6 +599,25 @@ chu_receive(rbufp)
chu->lastupdate = current_time;
/*
+ * Just for fun, we can debug the whole frame if
+ * we want.
+ */
+
+#ifdef CHU_DEBUG
+ syslog(LOG_DEBUG, "CHU %s packet:", (chuc->chutype == CHU_YEAR)?
+ "year":"time");
+ for (i=0; i < NCHUCHARS; i++) {
+ char c[64];
+
+ sprintf(c,"%c%c %s",hexstring[chuc->codechars[i]&0xf],
+ hexstring[chuc->codechars[i]>>4],
+ ctime(&(chuc->codetimes[i].tv_sec)));
+ c[strlen(c)-1]=0; /* ctime() adds a damn \n */
+ syslog(LOG_DEBUG, "%s .%06d", c, chuc->codetimes[i].tv_usec);
+ }
+#endif
+
+ /*
* At this point we're assured that both halves of the
* data match because of what the kernel has done.
* But there's more than one data format. We need to
diff --git a/contrib/xntpd/xntpd/refclock_conf.c b/contrib/xntpd/xntpd/refclock_conf.c
index 430c4a60f3fa..535ca27e9ebe 100644
--- a/contrib/xntpd/xntpd/refclock_conf.c
+++ b/contrib/xntpd/xntpd/refclock_conf.c
@@ -20,6 +20,12 @@ extern struct refclock refclock_local;
#define refclock_local refclock_none
#endif
+#if defined(TRAK) || defined(TRAKCLK) || defined(TRAKPPS)
+extern struct refclock refclock_trak;
+#else
+#define refclock_trak refclock_none
+#endif
+
#if defined(PST) || defined(PSTCLK) || defined(PSTPPS)
extern struct refclock refclock_pst;
#else
@@ -107,7 +113,7 @@ extern struct refclock refclock_gpstm;
struct refclock *refclock_conf[] = {
&refclock_none, /* 0 REFCLK_NONE */
&refclock_local, /* 1 REFCLK_LOCAL */
- &refclock_none, /* 2 REFCLK_WWV_HEATH */
+ &refclock_trak, /* 2 REFCLK_GPS_TRAK */
&refclock_pst, /* 3 REFCLK_WWV_PST */
&refclock_wwvb, /* 4 REFCLK_WWVB_SPECTRACOM */
&refclock_goes, /* 5 REFCLK_GOES_TRUETIME */
diff --git a/contrib/xntpd/xntpd/refclock_irig.c b/contrib/xntpd/xntpd/refclock_irig.c
index 40345bbefde7..6167af2784ee 100644
--- a/contrib/xntpd/xntpd/refclock_irig.c
+++ b/contrib/xntpd/xntpd/refclock_irig.c
@@ -19,7 +19,7 @@
* This driver supports the IRIG audio decoder. This clever gadget uses
* a modified BSD audio driver for the Sun SPARCstation which provides
* a timestamp, raw binary timecode, status byte and decoded ASCII
- # timecode. The data are represented in the structure:
+ * timecode. The data are represented in the structure:
*
* struct irig_time {
* struct timeval stamp; timestamp
@@ -418,7 +418,9 @@ struct peer *peer;
irig->hour = MULBY10(cp[4] - '0') + cp[5] - '0';
irig->minute = MULBY10(cp[7] - '0') + cp[8] - '0';
irig->second = MULBY10(cp[10] - '0') + cp[11] - '0';
- if (cp[12] != ' ')
+ if (cp[12] = ' ')
+ irig->leap = 0;
+ else
irig->leap = LEAP_NOTINSYNC;
if (irig->day < 1 || irig->day > 366) {
irig->baddata++;
diff --git a/contrib/xntpd/xntpd/refclock_msfees.c b/contrib/xntpd/xntpd/refclock_msfees.c
index b301bc2ebb23..c2a882abb919 100644
--- a/contrib/xntpd/xntpd/refclock_msfees.c
+++ b/contrib/xntpd/xntpd/refclock_msfees.c
@@ -139,7 +139,7 @@
#define INH_DELAY_PPS BITS_TO_L_FP( 0, 9600)
#ifndef STREAM_PP1
-#define STREAM_PP1 "ppsclockd\0<-- patch space for module name1 -->"
+#define STREAM_PP1 "ppsclocd\0<-- patch space for module name1 -->"
#endif
#ifndef STREAM_PP2
#define STREAM_PP2 "ppsclock\0<-- patch space for module name2 -->"
diff --git a/contrib/xntpd/xntpd/refclock_parse.c b/contrib/xntpd/xntpd/refclock_parse.c
index 69e483764354..0d95d18908a5 100644
--- a/contrib/xntpd/xntpd/refclock_parse.c
+++ b/contrib/xntpd/xntpd/refclock_parse.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS))
/*
- * /src/NTP/REPOSITORY/v3/xntpd/refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp
+ * /src/NTP/REPOSITORY/v3/xntpd/refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp
*
- * refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp
+ * refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp
*
* generic reference clock driver for receivers
*
@@ -30,6 +30,8 @@
* PPS - supply loopfilter with PPS samples (if configured)
* PPSPPS - notify loopfilter of PPS file descriptor
*
+ * FREEBSD_CONRAD - Make very cheap "Conrad DCF77 RS-232" gadget work
+ * with FreeBSD.
* TTY defines:
* HAVE_BSD_TTYS - currently unsupported
* HAVE_SYSV_TTYS - will use termio.h
@@ -82,6 +84,9 @@
#include <time.h>
#include <sys/errno.h>
+#ifdef FREEBSD_CONRAD
+#include <sys/ioctl.h>
+#endif
extern int errno;
#if !defined(STREAM) && !defined(HAVE_SYSV_TTYS) && !defined(HAVE_BSD_TTYS) && !defined(HAVE_TERMIOS)
@@ -129,7 +134,7 @@ CURRENTLY NO BSD TTY SUPPORT
#include "parse.h"
#if !defined(NO_SCCSID) && !defined(lint) && !defined(__GNUC__)
-static char rcsid[]="refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp";
+static char rcsid[]="refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp";
#endif
/**===========================================================================
@@ -440,7 +445,12 @@ static poll_info_t wsdcf_pollinfo = { WS_POLLRATE, WS_POLLCMD, WS_CMDSIZE };
#define RAWDCF_ROOTDELAY 0x00000364 /* 13 ms */
#define RAWDCF_FORMAT "RAW DCF77 Timecode"
#define RAWDCF_MAXUNSYNC (0) /* sorry - its a true receiver - no signal - no time */
+
+#ifdef FREEBSD_CONRAD
+#define RAWDCF_CFLAG (CS8|CREAD|CLOCAL)
+#else
#define RAWDCF_CFLAG (B50|CS8|CREAD|CLOCAL)
+#endif
#define RAWDCF_IFLAG 0
#define RAWDCF_OFLAG 0
#define RAWDCF_LFLAG 0
@@ -1482,11 +1492,22 @@ local_receive(rbufp)
struct parseunit *parse = (struct parseunit *)rbufp->recv_srcclock;
register int count;
register char *s;
+#ifdef FREEBSD_CONRAD
+ struct timeval foo;
+#endif
+
/*
* eat all characters, parsing then and feeding complete samples
*/
count = rbufp->recv_length;
s = rbufp->recv_buffer;
+#ifdef FREEBSD_CONRAD
+ ioctl(parse->fd,TIOCTIMESTAMP,&foo);
+ TVTOTS(&foo, &rbufp->recv_time);
+ rbufp->recv_time.l_uf += TS_ROUNDBIT;
+ rbufp->recv_time.l_ui += JAN_1970;
+ rbufp->recv_time.l_uf &= TS_MASK;
+#endif
while (count--)
{
@@ -1653,7 +1674,8 @@ local_poll(parse)
* done if no more characters are available
*/
FD_SET(fd, &fdmask);
- if (select(fd + 1, &fdmask, 0, 0, &null_time) == 0)
+ if ((i == 0) &&
+ (select(fd + 1, &fdmask, 0, 0, &null_time) == 0))
return;
}
}
@@ -1706,7 +1728,8 @@ parsestate(state, buffer)
{ PARSEB_NOSYNC, "TIME CODE NOT CONFIRMED" },
{ PARSEB_DST, "DST" },
{ PARSEB_UTC, "UTC DISPLAY" },
- { PARSEB_LEAP, "LEAP WARNING" },
+ { PARSEB_LEAPADD, "LEAP ADD WARNING" },
+ { PARSEB_LEAPDEL, "LEAP DELETE WARNING" },
{ PARSEB_LEAPSECOND, "LEAP SECOND" },
{ PARSEB_ALTERNATE,"ALTERNATE ANTENNA" },
{ PARSEB_TIMECODE, "TIME CODE" },
@@ -2269,7 +2292,10 @@ parse_start(sysunit, peer)
tm.c_iflag = clockinfo[type].cl_iflag;
tm.c_oflag = clockinfo[type].cl_oflag;
tm.c_lflag = clockinfo[type].cl_lflag;
-
+#ifdef FREEBSD_CONRAD
+ tm.c_ispeed = 50;
+ tm.c_ospeed = 50;
+#endif
if (TTY_SETATTR(fd232, &tm) == -1)
{
syslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcsetattr(%d, &tm): %m", unit, fd232);
@@ -2312,6 +2338,21 @@ parse_start(sysunit, peer)
return 0; /* well, ok - special initialisation broke */
}
+#ifdef FREEBSD_CONRAD
+ {
+ int i,j;
+ struct timeval tv;
+ ioctl(parse->fd,TIOCTIMESTAMP,&tv);
+ j = TIOCM_RTS;
+ i = ioctl(fd232, TIOCMBIC, &j);
+ if (i < 0) {
+ syslog(LOG_ERR,
+ "PARSE receiver #%d: lowrts_poll: failed to lower RTS: %m",
+ CL_UNIT(parse->unit));
+ }
+ }
+#endif
+
strcpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format);
tmp_ctl.parseformat.parse_count = strlen(tmp_ctl.parseformat.parse_buffer);
@@ -2539,9 +2580,10 @@ static void
parse_leap()
{
/*
- * PARSE does encode a leap warning... we are aware but not afraid of that
- * as long as we get a little help for the direction from the operator until
* PARSE encodes the LEAP correction direction.
+ * For timecodes that do not pass on the leap correction direction
+ * the default PARSEB_LEAPADD must be used. It may then be modified
+ * with a fudge flag (flag2).
*/
}
@@ -2821,7 +2863,7 @@ parse_control(unit, in, out)
sprintf(tt, "refclock_iomode=\"%s\"", parse->binding->bd_description);
tt = add_var(&out->kv_list, 128, RO);
- sprintf(tt, "refclock_driver_version=\"refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp\"");
+ sprintf(tt, "refclock_driver_version=\"refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp\"");
out->lencode = strlen(outstatus);
out->lastcode = outstatus;
@@ -3100,7 +3142,11 @@ parse_process(parse, parsetime)
L_ADD(&off, &offset);
rectime = off; /* this makes org time and xmt time somewhat artificial */
- if (parse->flags & PARSE_STAT_FILTER)
+ L_SUB(&off, &parsetime->parse_stime.fp);
+
+ if ((parse->flags & PARSE_STAT_FILTER) &&
+ (off.l_i > -60) &&
+ (off.l_i < 60)) /* take usec error only if within +- 60 secs */
{
struct timeval usecerror;
/*
@@ -3112,10 +3158,6 @@ parse_process(parse, parsetime)
sTVTOTS(&usecerror, &off);
L_ADD(&off, &offset);
}
- else
- {
- L_SUB(&off, &parsetime->parse_stime.fp);
- }
}
if (PARSE_PPS(parsetime->parse_state) && CL_PPS(parse->unit))
@@ -3245,14 +3287,24 @@ parse_process(parse, parsetime)
}
else
{
- if (PARSE_LEAP(parsetime->parse_state))
+ if (PARSE_LEAPADD(parsetime->parse_state))
{
+ /*
+ * we pick this state also for time code that pass leap warnings
+ * without direction information (as earth is currently slowing
+ * down).
+ */
leap = (parse->flags & PARSE_LEAP_DELETE) ? LEAP_DELSECOND : LEAP_ADDSECOND;
}
else
- {
- leap = LEAP_NOWARNING;
- }
+ if (PARSE_LEAPDEL(parsetime->parse_state))
+ {
+ leap = LEAP_DELSECOND;
+ }
+ else
+ {
+ leap = LEAP_NOWARNING;
+ }
}
refclock_receive(parse->peer, &off, 0, LFPTOFP(&dispersion), &reftime, &rectime, leap);
@@ -3396,6 +3448,21 @@ trimble_init(parse)
* History:
*
* refclock_parse.c,v
+ * Revision 3.53 1994/03/25 13:07:39 kardel
+ * fixed offset calculation for large (>4 Min) offsets
+ *
+ * Revision 3.52 1994/03/03 09:58:00 kardel
+ * stick -kv in cvs is no fun
+ *
+ * Revision 3.49 1994/02/20 13:26:00 kardel
+ * rcs id cleanup
+ *
+ * Revision 3.48 1994/02/20 13:04:56 kardel
+ * parse add/delete second support
+ *
+ * Revision 3.47 1994/02/02 17:44:30 kardel
+ * rcs ids fixed
+ *
* Revision 3.45 1994/01/25 19:06:27 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/xntpd/refclock_trak.c b/contrib/xntpd/xntpd/refclock_trak.c
new file mode 100644
index 000000000000..f2b3eb11fc9d
--- /dev/null
+++ b/contrib/xntpd/xntpd/refclock_trak.c
@@ -0,0 +1,1006 @@
+/*
+ * refclock_trak.c - clock driver for the TRAK 8810 GPS STATION CLOCK
+ * Tsuruoka Tomoaki Oct 30, 1993
+ * tsuruoka@nc.fukuoka-u.ac.jp
+ * Faculty of Engineering,
+ * Fukuoka University, Fukuoka, JAPAN
+ */
+#if defined(REFCLOCK) && (defined(TRAK) || defined(TRAKCLK) || defined(TRAKPPS))
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/time.h>
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_refclock.h"
+#include "ntp_unixtime.h"
+
+static void gps_send();
+
+#if defined(HAVE_BSD_TTYS)
+#include <sgtty.h>
+#endif /* HAVE_BSD_TTYS */
+
+#if defined(HAVE_SYSV_TTYS)
+#include <termio.h>
+#endif /* HAVE_SYSV_TTYS */
+
+#if defined(STREAM)
+#include <termios.h>
+#include <stropts.h>
+#if defined(TRAKCLK)
+#include <sys/clkdefs.h>
+#endif /* TRAKCLK */
+#endif /* STREAM */
+
+#if defined (TRAKPPS)
+#include <sys/ppsclock.h>
+#endif /* TRAKPPS */
+
+#include "ntp_stdlib.h"
+
+/*
+ * This driver supports the TRAK 8810 GPS Receiver with
+ * Buffered RS-232-C Interface Module.
+ *
+ * Most of codes are copied from refclock_as2201.c, Thanks a lot.
+ *
+ * The program expects the radio responses once per seccond
+ * ( by "rqts,u" command or panel control )
+ * of the form "*RQTS U,ddd:hh:mm:ss.0,Q\r\n for UTC" where
+ * ddd= day of year
+ * hh= hours
+ * mm= minutes
+ * ss= seconds
+ * Q= Quality byte. Q=0 Phase error > 20 us
+ * Q=6 Pahse error < 20 us
+ * > 10 us
+ * Q=5 Pahse error < 10 us
+ * > 1 us
+ * Q=4 Pahse error < 1 us
+ * > 100 ns
+ * Q=3 Pahse error < 100 ns
+ * > 10 ns
+ * Q=2 Pahse error < 10 ns
+ * (note that my clock almost stable at 1 us per 10 hours)
+ *
+ * Request leap second status - if needed.
+ * send: rqls\n
+ * reply: RQLS yy,mm,dd
+ * where: yy is year
+ * mm is month
+ * dd is day of month.baud
+ * Note: Default data is all zeros
+ * i.e. RQLS 00,00,00
+ */
+
+/*
+ * Definitions
+ */
+#define MAXUNITS 4 /* max number of GPS units */
+#define GPS232 "/dev/gps%d" /* name of radio device */
+#define SPEED232 B9600 /* uart speed (9600 bps) */
+
+/*
+ * Radio interface parameters
+ */
+#define GPSPRECISION (-20) /* precision assumed (about 1 us) */
+#define GPSREFID "GPS" /* reference id */
+#define GPSDESCRIPTION "TRAK 8810 GPS station clock" /* who we are */
+#define GPSHSREFID 0x7f7f020a /* 127.127.2.10 refid hi strata */
+#define GMT 0 /* hour offset from Greenwich */
+#define NCODES 3 /* stages of median filter */
+#define LENTOC 25 /* *RQTS U,ddd:hh:mm:ss.0,Q datecode length */
+#define BMAX 100 /* timecode buffer length */
+#define CODEDIFF 0x20000000 /* 0.125 seconds as an l_fp fraction */
+
+/*
+ * Hack to avoid excercising the multiplier. I have no pride.
+ */
+#define MULBY10(x) (((x)<<3) + ((x)<<1))
+
+/*
+ * Imported from ntp_timer module
+ */
+extern U_LONG current_time; /* current time (s) */
+
+/*
+ * Imported from ntp_loopfilter module
+ */
+extern int fdpps; /* pps file descriptor */
+
+/*
+ * Imported from ntpd module
+ */
+extern int debug; /* global debug flag */
+
+/*
+ * GPS unit control structure.
+ */
+struct gpsunit {
+ struct peer *peer; /* associated peer structure */
+ struct refclockio io; /* given to the I/O handler */
+ l_fp lastrec; /* last data receive time */
+ l_fp lastref; /* last timecode time */
+ l_fp offset[NCODES]; /* recent sample offsets */
+ char lastcode[BMAX]; /* last timecode received */
+ u_short polled; /* when polled, means a last sample */
+ u_char lencode; /* length of last received ASCII string */
+ U_LONG lasttime; /* last time clock heard from */
+#ifdef TRAKPPS
+ U_LONG lastev; /* last ppsclock second */
+#endif /* TRAKPPS */
+ u_char unit; /* unit number for this guy */
+ u_char status; /* clock status */
+ u_char lastevent; /* last clock event */
+ u_char reason; /* reason for last abort */
+ u_char year; /* year of eternity */
+ u_short day; /* day of year */
+ u_char hour; /* hour of day */
+ u_char minute; /* minute of hour */
+ u_char second; /* seconds of minute */
+ u_short msec; /* milliseconds of second */
+ u_char leap; /* leap indicators */
+ U_LONG yearstart; /* start of current year */
+ /*
+ * Status tallies
+ */
+ U_LONG polls; /* polls sent */
+ U_LONG noreply; /* no replies to polls */
+ U_LONG coderecv; /* timecodes received */
+ U_LONG badformat; /* bad format */
+ U_LONG baddata; /* bad data */
+ U_LONG timestarted; /* time we started this */
+};
+
+
+/*
+ * Data space for the unit structures. Note that we allocate these on
+ * the fly, but never give them back.
+ */
+static struct gpsunit *gpsunits[MAXUNITS];
+static u_char unitinuse[MAXUNITS];
+
+/*
+ * Keep the fudge factors separately so they can be set even
+ * when no clock is configured.
+ */
+static l_fp fudgefactor[MAXUNITS];
+static u_char stratumtouse[MAXUNITS];
+static u_char sloppyclockflag[MAXUNITS];
+
+/*
+ * Function prototypes
+ */
+static void trak_init P(());
+static int trak_start P((u_int, struct peer *));
+static void trak_shutdown P((int));
+static void trak_report_event P((struct gpsunit *, int));
+static void trak_receive P((struct recvbuf *));
+static char trak_process P((struct gpsunit *, l_fp *, u_fp *));
+static void trak_poll P((int unit, struct peer *));
+static void trak_control P((u_int, struct refclockstat *, struct refclockstat *));
+static void trak_buginfo P((int, struct refclockbug *));
+
+/*
+ * Transfer vector
+ */
+struct refclock refclock_trak = {
+ trak_start, trak_shutdown, trak_poll,
+ trak_control, trak_init, trak_buginfo, NOFLAGS
+};
+
+/*
+ * trak_init - initialize internal gps driver data
+ */
+static void
+trak_init()
+{
+ register int i;
+ /*
+ * Just zero the data arrays
+ */
+ memset((char *)gpsunits, 0, sizeof gpsunits);
+ memset((char *)unitinuse, 0, sizeof unitinuse);
+
+ /*
+ * Initialize fudge factors to default.
+ */
+ for (i = 0; i < MAXUNITS; i++) {
+ fudgefactor[i].l_ui = 0;
+ fudgefactor[i].l_uf = 0;
+ stratumtouse[i] = 0;
+ sloppyclockflag[i] = 0;
+ }
+}
+
+
+/*
+ * trak_start - open the GPS devices and initialize data for processing
+ */
+static int
+trak_start(unit, peer)
+ u_int unit;
+ struct peer *peer;
+{
+ register struct gpsunit *gps;
+ register int i;
+ int fd232;
+ char trakdev[20];
+#ifdef TRAKPPS
+ struct ppsclockev ev;
+#endif /* TRAKPPS */
+
+ /*
+ * Check configuration info
+ */
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_start: unit %d invalid", unit);
+ return (0);
+ }
+ if (unitinuse[unit]) {
+ syslog(LOG_ERR, "trak_start: unit %d in use", unit);
+ return (0);
+ }
+
+ /*
+ * Open serial port
+ */
+ (void) sprintf(trakdev, GPS232, unit);
+ fd232 = open(trakdev, O_RDWR, 0777);
+ if (fd232 == -1) {
+ syslog(LOG_ERR, "trak_start: open of %s: %m", trakdev);
+ return (0);
+ }
+
+#if defined(HAVE_SYSV_TTYS)
+ /*
+ * System V serial line parameters (termio interface)
+ *
+ */
+ { struct termio ttyb;
+ if (ioctl(fd232, TCGETA, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TCGETA): %m", trakdev);
+ goto screwed;
+ }
+ ttyb.c_iflag = IGNBRK|IGNPAR|ICRNL;
+ ttyb.c_oflag = 0;
+ ttyb.c_cflag = SPEED232|CS8|CLOCAL|CREAD;
+ ttyb.c_lflag = ICANON;
+ ttyb.c_cc[VERASE] = ttyb.c_cc[VKILL] = '\0';
+ if (ioctl(fd232, TCSETA, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TCSETA): %m", trakdev);
+ goto screwed;
+ }
+ }
+#endif /* HAVE_SYSV_TTYS */
+#if defined(STREAM)
+ /*
+ * POSIX/STREAMS serial line parameters (termios interface)
+ *
+ * The TRAKCLK option provides timestamping at the driver level.
+ * It requires the tty_clk streams module.
+ *
+ * The TRAKPPS option provides timestamping at the driver level.
+ * It uses a 1-pps signal and level converter (gadget box) and
+ * requires the ppsclock streams module and SunOS 4.1.1 or
+ * later.
+ */
+ { struct termios ttyb, *ttyp;
+
+ ttyp = &ttyb;
+ if (tcgetattr(fd232, ttyp) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: tcgetattr(%s): %m", trakdev);
+ goto screwed;
+ }
+ ttyp->c_iflag = IGNBRK|IGNPAR;
+ ttyp->c_oflag = 0;
+ ttyp->c_cflag = SPEED232|CS8|CLOCAL|CREAD;
+ ttyp->c_lflag = ICANON;
+ ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\0';
+ if (tcsetattr(fd232, TCSANOW, ttyp) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: tcsetattr(%s): %m", trakdev);
+ goto screwed;
+ }
+ if (tcflush(fd232, TCIOFLUSH) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: tcflush(%s): %m", trakdev);
+ goto screwed;
+ }
+#if defined(TRAKCLK)
+ if (ioctl(fd232, I_PUSH, "clk") < 0)
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, I_PUSH, clk): %m", trakdev);
+ if (ioctl(fd232, CLK_SETSTR, "*") < 0)
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, CLK_SETSTR): %m", trakdev);
+#endif /* TRAKCLK */
+#if defined(TRAKPPS)
+ if (ioctl(fd232, I_PUSH, "ppsclock") < 0)
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, I_PUSH, ppsclock): %m", trakdev);
+ else
+ fdpps = fd232;
+#endif /* TRAKPPS */
+ }
+#endif /* STREAM */
+#if defined(HAVE_BSD_TTYS)
+ /*
+ * 4.3bsd serial line parameters (sgttyb interface)
+ *
+ * The TRAKCLK option provides timestamping at the driver level.
+ * It requires the tty_clk line discipline and 4.3bsd or later.
+ */
+ { struct sgttyb ttyb;
+#if defined(TRAKCLK)
+ int ldisc = CLKLDISC;
+#endif /* TRAKCLK */
+
+ if (ioctl(fd232, TIOCGETP, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TIOCGETP): %m", trakdev);
+ goto screwed;
+ }
+ ttyb.sg_ispeed = ttyb.sg_ospeed = SPEED232;
+#if defined(TRAKCLK)
+ ttyb.sg_erase = ttyb.sg_kill = '\r';
+ ttyb.sg_flags = RAW;
+#else
+ ttyb.sg_erase = ttyb.sg_kill = '\0';
+ ttyb.sg_flags = EVENP|ODDP|CRMOD;
+#endif /* TRAKCLK */
+ if (ioctl(fd232, TIOCSETP, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TIOCSETP): %m", trakdev);
+ goto screwed;
+ }
+#if defined(TRAKCLK)
+ if (ioctl(fd232, TIOCSETD, &ldisc) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TIOCSETD): %m",trakdev);
+ goto screwed;
+ }
+#endif /* TRAKCLK */
+ }
+#endif /* HAVE_BSD_TTYS */
+
+ /*
+ * Allocate unit structure
+ */
+ if (gpsunits[unit] != 0) {
+ gps = gpsunits[unit]; /* The one we want is okay */
+ } else {
+ for (i = 0; i < MAXUNITS; i++) {
+ if (!unitinuse[i] && gpsunits[i] != 0)
+ break;
+ }
+ if (i < MAXUNITS) {
+ /*
+ * Reclaim this one
+ */
+ gps = gpsunits[i];
+ gpsunits[i] = 0;
+ } else {
+ gps = (struct gpsunit *)
+ emalloc(sizeof(struct gpsunit));
+ }
+ }
+ bzero((char *)gps, sizeof(struct gpsunit));
+ gpsunits[unit] = gps;
+
+ /*
+ * Set up the structures
+ */
+ gps->peer = peer;
+ gps->unit = (u_char)unit;
+ gps->timestarted = current_time;
+
+ gps->io.clock_recv = trak_receive;
+ gps->io.srcclock = (caddr_t)gps;
+ gps->io.datalen = 0;
+ gps->io.fd = fd232;
+#ifdef TRAKPPS
+ if (ioctl(fd232, CIOGETEV, (caddr_t)&ev) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, CIOGETEV): %m", trakdev);
+ goto screwed;
+ } else
+ gps->lastev = ev.tv.tv_sec;
+#endif /* TRAKPPS */
+ if (!io_addclock(&gps->io)) {
+ goto screwed;
+ }
+
+ /*
+ * All done. Initialize a few random peer variables, then
+ * return success. Note that root delay and root dispersion are
+ * always zero for this clock.
+ */
+ peer->precision = GPSPRECISION;
+ peer->rootdelay = 0;
+ peer->rootdispersion = 0;
+ peer->stratum = stratumtouse[unit];
+ if (stratumtouse[unit] <= 1)
+ bcopy(GPSREFID, (char *)&peer->refid, 4);
+ else
+ peer->refid = htonl(GPSHSREFID);
+ unitinuse[unit] = 1;
+ /*
+ * request to give time code
+ */
+ {
+ void gps_send();
+ gps_send(gps,"\rRQTS,U\r");
+ gps_send(gps,"SEL 00\r");
+ }
+
+ return (1);
+
+ /*
+ * Something broke; abandon ship.
+ */
+screwed:
+ (void) close(fd232);
+ return (0);
+}
+
+/*
+ * trak_shutdown - shut down a GPS clock
+ */
+static void
+trak_shutdown(unit)
+ int unit;
+{
+ register struct gpsunit *gps;
+ void gps_send();
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_shutdown: unit %d invalid", unit);
+ return;
+ }
+ if (!unitinuse[unit]) {
+ syslog(LOG_ERR, "trak_shutdown: unit %d not in use", unit);
+ return;
+ }
+ gps = gpsunits[unit];
+ /*
+ * request not to give time code any more
+ */
+ gps_send(gps,"RQTX\r");
+ /*
+ * Tell the I/O module to turn us off. We're history.
+ */
+ io_closeclock(&gps->io);
+
+ unitinuse[unit] = 0;
+}
+
+
+/*
+ * trak_report_event - note the occurance of an event
+ *
+ * This routine presently just remembers the report and logs it, but
+ * does nothing heroic for the trap handler.
+ */
+static void
+trak_report_event(gps, code)
+ struct gpsunit *gps;
+ int code;
+{
+ struct peer *peer;
+
+ peer = gps->peer;
+ if (gps->status != (u_char)code) {
+ gps->status = (u_char)code;
+ if (code != CEVNT_NOMINAL)
+ gps->lastevent = (u_char)code;
+ syslog(LOG_INFO,
+ "clock %s event %x\n", ntoa(&peer->srcadr), code);
+ }
+}
+
+
+/*
+ * trak_receive - receive data from the serial interface
+ */
+static void
+trak_receive(rbufp)
+ struct recvbuf *rbufp;
+{
+ register int i,cmdtype;
+ register struct gpsunit *gps;
+
+#if defined(TRAKPPS)
+ struct ppsclockev ev;
+ l_fp trtmp;
+#endif /* TRAKPPS */
+ register u_char *dpt;
+ register u_char *cp;
+ register u_char *dpend;
+ l_fp tstmp;
+ u_fp dispersion;
+
+ /*
+ * Get the clock this applies to and pointers to the data.
+ * Edit the timecode to remove control chars and trashbits.
+ */
+ gps = (struct gpsunit *)rbufp->recv_srcclock;
+ dpt = (u_char *)&rbufp->recv_space;
+ dpend = dpt + rbufp->recv_length;
+ cp = (u_char *)gps->lastcode;
+
+ while (dpt < dpend) {
+#ifdef TRAKCLK /* prior to TRAKPPS due to timestamp */
+ if ((*cp = 0x7f & *dpt++) != '*' ) cp++;
+ else if (*cp == '*' ) { /* caught magic character */
+ if ( dpend - dpt < 8) {
+ /* short timestamp */
+ if(debug) puts("gps: short timestamp.");
+ return;
+ }
+ if (!buftvtots(dpt,&gps->lastrec)) {
+ /* screwy timestamp */
+ if(debug) puts("gps: screwy timestamp.");
+ return;
+ }
+ dpt += 8;
+ }
+#else
+#ifdef TRAKPPS
+ if ((*cp = 0x7f & *dpt++) >= ' ') cp++;
+#else
+ /* both are not specified */
+#endif /* TRAKPPS */
+#endif /* TRAKCLK */
+ }
+ *cp = '\0';
+ gps->lencode = cp - (u_char *)gps->lastcode;
+ if (gps->lencode == 0) return;
+
+#ifdef DEBUG
+ if (debug)
+ printf("gps: timecode %d %s\n",
+ gps->lencode, gps->lastcode);
+#endif
+
+ /*
+ * We check the timecode format and decode its contents. The
+ * timecode has format *........RQTS U,ddd:hh:mm:ss.0,Q\r\n).
+ * 012345678901234567890123
+ */
+#define RQTS 0
+#define RQLS 1
+ cp = (u_char *)gps->lastcode;
+ gps->leap = 0;
+ cmdtype=0;
+ if(strncmp(cp,"*RQTS",5)==0) {
+ cmdtype=RQTS;
+ cp += 8;
+ }
+ else if(strncmp(cp,"RQTS",4)==0) {
+ cmdtype=RQTS;
+ cp += 7;
+ }
+ else if(strncmp(cp,"RQLS",4)==0) {
+ cmdtype=RQLS;
+ cp += 5;
+ }
+ else
+ return;
+
+ switch( cmdtype ) {
+ case RQTS:
+ /*
+ * Check time code format of TRAK 8810
+ */
+ if( !isdigit(cp[0]) ||
+ !isdigit(cp[1]) ||
+ !isdigit(cp[2]) ||
+ cp[3] != ':' ||
+ !isdigit(cp[4]) ||
+ !isdigit(cp[5]) ||
+ cp[6] != ':' ||
+ !isdigit(cp[7]) ||
+ !isdigit(cp[8]) ||
+ cp[9] != ':' ||
+ !isdigit(cp[10])||
+ !isdigit(cp[11])) {
+ gps->badformat++;
+ trak_report_event(gps, CEVNT_BADREPLY);
+ return;
+ }
+ break;
+ case RQLS:
+ /*
+ * reply for leap second request
+ */
+ if (cp[0] !='0' || cp[1] != '0' ) gps->leap = LEAP_ADDSECOND;
+ return;
+ default:
+ return;
+
+ }
+
+ /*
+ * Convert date and check values.
+ */
+ gps->day = cp[0] - '0';
+ gps->day = MULBY10(gps->day) + cp[1] - '0';
+ gps->day = MULBY10(gps->day) + cp[2] - '0';
+ if (gps->day < 1 || gps->day > 366) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADDATE);
+ return;
+ }
+ /*
+ * Convert time and check values.
+ */
+ gps->hour = MULBY10(cp[4] - '0') + cp[5] - '0';
+ gps->minute = MULBY10(cp[7] - '0') + cp[8] - '0';
+ gps->second = MULBY10(cp[10] - '0') + cp[11] - '0';
+ gps->msec = 0;
+ if (gps->hour > 23 || gps->minute > 59 || gps->second > 59) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADTIME);
+ return;
+ }
+
+ if (!gps->polled) return;
+
+ /*
+ * Test for synchronization Check for quality byte.
+ */
+/*
+ switch( cp[15] ) {
+ case '0':
+ if(gps->peer->stratum == stratumtouse[gps->unit]) {
+ gps->peer->stratum = 10 ;
+ bzero(&gps->peer->refid,4);
+ }
+ break;
+ default:
+ if(gps->peer->stratum != stratumtouse[gps->unit]) {
+ gps->peer->stratum = stratumtouse[gps->unit] ;
+ bcopy(GPSREFID,&gps->peer->refid,4);
+ }
+ break;
+ }
+*/
+ if( cp[15] == '0') /* TRAK derailed from tracking satellites */
+ {
+ gps->leap = LEAP_NOTINSYNC;
+ gps->noreply++;
+ trak_report_event(gps, CEVNT_TIMEOUT);
+ }
+ else
+ {
+ gps->lasttime = current_time;
+ if( gps->lastevent == CEVNT_TIMEOUT ) {
+ gps->status = CEVNT_NOMINAL;
+ trak_report_event(gps, CEVNT_NOMINAL);
+ }
+ }
+
+ /*
+ * Now, compute the reference time value. Use the heavy
+ * machinery for the second, which presumably is the one which
+ * occured at the last pps pulse and which was captured by the
+ * loop_filter module. All we have to do here is present a
+ * reasonable facsimile of the time at that pulse so the clock-
+ * filter and selection machinery declares us truechimer. The
+ * precision offset within the second is really tuned by the
+ * loop_filter module. Note that this code does not yet know how
+ * to do the years and relies on the clock-calendar chip for
+ * sanity.
+ */
+
+#if defined(TRAKPPS)
+
+ /*
+ * timestamp must be greater than previous one.
+ */
+ if (ioctl(fdpps, CIOGETEV, (caddr_t)&ev) >= 0) {
+ ev.tv.tv_sec += (U_LONG)JAN_1970;
+ TVTOTS(&ev.tv,&gps->lastrec);
+ if (gps->lastev < ev.tv.tv_sec) {
+ gps->lastev = ev.tv.tv_sec;
+ } else { /* in case of 1-pps missing */
+ gps->lastev = ev.tv.tv_sec;
+ return;
+ }
+ }
+ else
+ return; /* failed to get timestamp */
+#endif /* TRAKPPS */
+
+ if (!clocktime(gps->day, gps->hour, gps->minute,
+ gps->second, GMT, gps->lastrec.l_ui,
+ &gps->yearstart, &gps->lastref.l_ui)) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADTIME);
+#ifdef DEBUG
+ if(debug) printf("gps: bad date \n");
+#endif
+ return;
+ }
+ MSUTOTSF(gps->msec, gps->lastref.l_uf);
+ tstmp = gps->lastref;
+
+ L_SUB(&tstmp, &gps->lastrec);
+ L_ADD(&tstmp, &(fudgefactor[gps->unit]));
+ i = ((int)(gps->coderecv)) % NCODES;
+ gps->offset[i] = tstmp;
+ gps->coderecv++;
+#if DEBUG
+ if (debug)
+ printf("gps: times %s %s %s\n",
+ ulfptoa(&gps->lastref, 6), ulfptoa(&gps->lastrec, 6),
+ lfptoa(&tstmp, 6));
+#endif
+/* if( tstmp.l_ui != 0 ) return; something wrong */
+
+ /*
+ * Process the samples in the median filter, add the fudge
+ * factor and pass the offset and dispersion along. We use
+ * lastref as both the reference time and receive time in order
+ * to avoid being cute, like setting the reference time later
+ * than the receive time, which may cause a paranoid protocol
+ * module to chuck out the data.
+ */
+ if (gps->coderecv < NCODES)
+ return;
+ if (!trak_process(gps, &tstmp, &dispersion)) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADTIME);
+ return;
+ }
+ refclock_receive(gps->peer, &tstmp, GMT, dispersion,
+ &gps->lastrec, &gps->lastrec, gps->leap);
+ /*
+ * after all, clear polled flag
+ */
+ gps->polled = 0;
+}
+
+/*
+ * ==================================================================
+ * gps_send(gps,cmd) Sends a command to the GPS receiver.
+ * as gps_send(gps,"rqts,u\r");
+ * ==================================================================
+ */
+static void
+gps_send(gps,cmd)
+ struct gpsunit *gps;
+ char *cmd;
+{
+ if (write(gps->io.fd, cmd, strlen(cmd)) == -1) {
+ syslog(LOG_ERR, "gps_send: unit %d: %m", gps->unit);
+ trak_report_event(gps,CEVNT_FAULT);
+ } else {
+ gps->polls++;
+ }
+}
+
+/*
+ * trak_process - process a pile of samples from the clock
+ *
+ * This routine uses a three-stage median filter to calculate offset and
+ * dispersion and reduce jitter. The dispersion is calculated as the
+ * span of the filter (max - min).
+ */
+static char
+trak_process(gps, offset, dispersion)
+ struct gpsunit *gps;
+ l_fp *offset;
+ u_fp *dispersion;
+{
+ register int i, j;
+ register U_LONG tmp_ui, tmp_uf;
+ int not_median1 = -1; /* XXX correct? */
+ int not_median2 = -1; /* XXX correct? */
+ int median;
+ u_fp disp_tmp, disp_tmp2;
+
+ /*
+ * This code implements a three-stage median filter. First, we
+ * check if the samples are within 125 ms of each other. If not,
+ * dump the sample set. We take the median of the three offsets
+ * and use that as the sample offset. There probably is not much
+ * to be gained by a longer filter, since the clock filter in
+ * ntp_proto should do its thing.
+ */
+ disp_tmp2 = 0;
+ for (i = 0; i < NCODES-1; i++) {
+ for (j = i+1; j < NCODES; j++) {
+ tmp_ui = gps->offset[i].l_ui;
+ tmp_uf = gps->offset[i].l_uf;
+ M_SUB(tmp_ui, tmp_uf, gps->offset[j].l_ui,
+ gps->offset[j].l_uf);
+ if (M_ISNEG(tmp_ui, tmp_uf)) {
+ M_NEG(tmp_ui, tmp_uf);
+ }
+ if (tmp_ui != 0 || tmp_uf > CODEDIFF) {
+ return (0);
+ }
+ disp_tmp = MFPTOFP(0, tmp_uf);
+ if (disp_tmp > disp_tmp2) {
+ disp_tmp2 = disp_tmp;
+ not_median1 = i;
+ not_median2 = j;
+ }
+ }
+ }
+ if (gps->lasttime == 0)
+ disp_tmp2 = NTP_MAXDISPERSE;
+ else
+ disp_tmp2 = current_time - gps->lasttime;
+ if (not_median1 == 0) {
+ if (not_median2 == 1)
+ median = 2;
+ else
+ median = 1;
+ } else {
+ median = 0;
+ }
+ *offset = gps->offset[median];
+ *dispersion = disp_tmp2;
+ return (1);
+}
+
+/*
+ * trak_poll - called by the transmit procedure
+ *
+ * We go to great pains to avoid changing state here, since there may be
+ * more than one eavesdropper receiving the same timecode.
+ */
+static void
+trak_poll(unit, peer)
+ int unit;
+ struct peer *peer;
+{
+ struct gpsunit *gps;
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_poll: unit %d invalid", unit);
+ return;
+ }
+ if (!unitinuse[unit]) {
+ syslog(LOG_ERR, "trak_poll: unit %d not in use", unit);
+ return;
+ }
+ gps = gpsunits[unit];
+ if ((current_time - gps->lasttime) > 150)
+ trak_report_event(gpsunits[unit], CEVNT_TIMEOUT);
+ /*
+ * usually trak_receive can get a timestamp every second
+ */
+#if !defined(TRAKPPS) && !defined(TRAKCLK)
+ gettstamp(&gps->lastrec);
+#endif
+ gps->polls++;
+ /*
+ * may be polled every 16 seconds (minpoll 4)
+ */
+ gps->polled = 1;
+}
+
+/*
+ * trak_control - set fudge factors, return statistics
+ */
+static void
+trak_control(unit, in, out)
+ u_int unit;
+ struct refclockstat *in;
+ struct refclockstat *out;
+{
+ register struct gpsunit *gps;
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_control: unit %d invalid", unit);
+ return;
+ }
+
+ if (in != 0) {
+ if (in->haveflags & CLK_HAVETIME1)
+ fudgefactor[unit] = in->fudgetime1;
+ if (in->haveflags & CLK_HAVEVAL1) {
+ stratumtouse[unit] = (u_char)(in->fudgeval1 & 0xf);
+ if (unitinuse[unit]) {
+ struct peer *peer;
+
+ /*
+ * Should actually reselect clock, but
+ * will wait for the next timecode
+ */
+ gps = gpsunits[unit];
+ peer = gps->peer;
+ peer->stratum = stratumtouse[unit];
+ if (stratumtouse[unit] <= 1)
+ bcopy(GPSREFID, (char *)&peer->refid,
+ 4);
+ else
+ peer->refid = htonl(GPSHSREFID);
+ }
+ }
+ }
+
+ if (out != 0) {
+ out->type = REFCLK_GPS_TRAK;
+ out->haveflags
+ = CLK_HAVETIME1|CLK_HAVEVAL1|CLK_HAVEVAL2;
+ out->clockdesc = GPSDESCRIPTION;
+ out->fudgetime1 = fudgefactor[unit];
+ out->fudgetime2.l_ui = 0;
+ out->fudgetime2.l_uf = 0;
+ out->fudgeval1 = (LONG)stratumtouse[unit];
+ out->fudgeval2 = 0;
+ out->flags = sloppyclockflag[unit];
+ if (unitinuse[unit]) {
+ gps = gpsunits[unit];
+ out->lencode = gps->lencode; /* LENTOC */;
+ out->lastcode = gps->lastcode;
+ out->timereset = current_time - gps->timestarted;
+ out->polls = gps->polls;
+ out->noresponse = gps->noreply;
+ out->badformat = gps->badformat;
+ out->baddata = gps->baddata;
+ out->lastevent = gps->lastevent;
+ out->currentstatus = gps->status;
+ } else {
+ out->lencode = 0;
+ out->lastcode = "";
+ out->polls = out->noresponse = 0;
+ out->badformat = out->baddata = 0;
+ out->timereset = 0;
+ out->currentstatus = out->lastevent = CEVNT_NOMINAL;
+ }
+ }
+}
+
+/*
+ * trak_buginfo - return clock dependent debugging info
+ */
+static void
+trak_buginfo(unit, bug)
+ int unit;
+ register struct refclockbug *bug;
+{
+ register struct gpsunit *gps;
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_buginfo: unit %d invalid", unit);
+ return;
+ }
+
+ if (!unitinuse[unit])
+ return;
+ gps = gpsunits[unit];
+
+ bug->nvalues = 10;
+ bug->ntimes = 5;
+ if (gps->lasttime != 0)
+ bug->values[0] = current_time - gps->lasttime;
+ else
+ bug->values[0] = 0;
+ bug->values[1] = (U_LONG)gps->reason;
+ bug->values[2] = (U_LONG)gps->year;
+ bug->values[3] = (U_LONG)gps->day;
+ bug->values[4] = (U_LONG)gps->hour;
+ bug->values[5] = (U_LONG)gps->minute;
+ bug->values[6] = (U_LONG)gps->second;
+ bug->values[7] = (U_LONG)gps->msec;
+ bug->values[8] = gps->noreply;
+ bug->values[9] = gps->yearstart;
+ bug->stimes = 0x1c;
+ bug->times[0] = gps->lastref;
+ bug->times[1] = gps->lastrec;
+ bug->times[2] = gps->offset[0];
+ bug->times[3] = gps->offset[1];
+ bug->times[4] = gps->offset[2];
+}
+#endif