diff options
410 files changed, 101569 insertions, 0 deletions
diff --git a/usr.sbin/xntpd/COPYRIGHT b/usr.sbin/xntpd/COPYRIGHT new file mode 100644 index 000000000000..be272fe18063 --- /dev/null +++ b/usr.sbin/xntpd/COPYRIGHT @@ -0,0 +1,56 @@ +/****************************************************************************** + * * + * Copyright (c) David L. Mills 1992, 1993 * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose and without fee is hereby granted, provided * + * that the above copyright notice appears in all copies and that both the * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name University of Delaware not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. The University of Delaware * + * makes no representations about the suitability this software for any * + * purpose. It is provided "as is" without express or implied warranty. * + * * + ******************************************************************************/ + +/* + * For all files included in this distribution and not specifically marked + * otherwise, the above copyright information applies. + * + * Authors + * + * Dennis Ferguson <dennis@mrbill.canet.ca> (foundation code for NTP + * Version 2 as specified in RFC-1119) + * Lars H. Mathiesen <thorinn@diku.dk> (adaptation of foundation code for + * Version 3 as specified in RFC-1305) + * Louis A. Mamakos <louie@ni.umd.edu> (support for md5-based + * authentication) + * Craig Leres <leres@ee.lbl.gov> (port to 4.4BSD operating system, + * ppsclock, Maganavox GPS clock driver) + * Nick Sayer <mrapple@quack.kfu.com> (SunOS streams modules) + * Frank Kardel <Frank.Kardel@informatik.uni-erlangen.de> + * (PARSE (GENERIC) driver, STREAMS module for PARSE, support scripts, + * reference clock configuration scripts, Makefile cleanup) + * Rainer Pruy <Rainer.Pruy@informatik.uni-erlangen.de> (monitoring/trap + * scripts, statistics file handling) + * Glenn Hollinger <glenn@herald.usask.ca> (GOES clock driver) + * Kenneth Stone <ken@sdd.hp.com> (port to HPUX operating system) + * Dave Katz <dkatz@cisco.com> (port to RS/6000 AIX operating system) + * William L. Jones <jones@hermes.chpc.utexas.edu> (RS/6000 AIX + * modifications, HPUX modifications) + * John A. Dundas III <dundas@salt.jpl.nasa.gov> (Apple A/UX port) + * David L. Mills <mills@udel.edu> (Spectractom WWVB, Austron GPS, + * and KSI/Odetics IRIG-B clock drivers; pps support) + * Jeffrey Mogul <mogul@pa.dec.com> (ntptrace utility) + * Steve Clift (clift@ml.csiro.au) OMEGA clock driver) + * Mike Iglesias (iglesias@uci.edu) (DEC Alpha changes) + * Mark Andrews <marka@syd.dms.csiro.au> (Leitch atomic clock controller) + * George Lindholm <lindholm@ucs.ubc.ca> (port to SunOS 5.1 operating system) + * Jeff Johnson <jbj@chatham.usdesign.com> (massive prototyping overhaul) + * Tom Moore <tmoore@fievel.daytonoh.ncr.com> (port to i386 svr4) + * Piete Brooks <Piete.Brooks@cl.cam.ac.uk> (MSF clock driver, Trimble PARSE + * support) + * Karl Berry <karl@owl.HQ.ileaf.com> (syslog to file option) + * Torsten Duwe <duwe@immd4.informatik.uni-erlangen.de> (Linux Port) + */ diff --git a/usr.sbin/xntpd/Config b/usr.sbin/xntpd/Config new file mode 100644 index 000000000000..c15ec053a520 --- /dev/null +++ b/usr.sbin/xntpd/Config @@ -0,0 +1,200 @@ +RANLIB= ranlib +DEFS_LOCAL=-DREFCLOCK +DEFS= -DSYS_FREEBSD -DSYS_386BSD +AUTHDEFS= -DDES -DMD5 +CLOCKDEFS= -DLOCAL_CLOCK +DAEMONLIBS= -lcrypt +RESLIB= +COPTS= -O2 +COMPILER= gcc +LIBDEFS= -DXNTP_LITTLE_ENDIAN +# This is the local configure file (distribution version). +# You must modify it to fit your particular configuration +# and name it Config.local +# The following configuratiions can be auto-generated: +# +# make Config.local.green +# make a Config.local that supports a local clock +# (i.e. allow fallback to use of the CPU's own clock) +# make Config.local.NO.clock +# make a Config.local that supports no clocks +# +# +# NOTE TO GREENHORNS +# +# For plug-'n-play and no radios or other complicated gadgetry, +# use "make Config.local.green" as above. +# +# Following defines can be set in the DEFS_OPT= define: +# +# The flag -DDEBUG includes some debugging code. To use this, include +# the define and start the daemon with one or more -d flags, depending +# on your calibration of pearannoya. The daemon will not detach your +# terminal in this case. Judicious use of grep will reduce the speaker +# volume to bearable levels. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# The -DSYSLOG_FILE defines allows logging messages that are normally +# reported via syslof() in a file. The file name can be configured using +# the configuration line "logfile <filename>" in CONFIG_FILE. +# +# There are three serial port system software interfaces, each of +# which is peculiar to one or more Unix versions. Define +# -DHAVE_SYSV_TTYS for basic System V compatibility; define -DSTREAM +# for POSIX compatibility including System V Streams, and +# HAVE_BSD_TTYS for 4.3bsd compatibility. Only one of these three +# should be defined. If none are defined, HAVE_BSD_TTYS is assumed. +# Usually these defines are already set correctly. +# +DEFS_OPT=-DDEBUG + +# +# The DEFS_LOCAL define picks up all flags from DEFS_OPT (do not delete that) +# and one of the following: +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you may also want to +# configure the particular clock drivers you want in the CLOCKDEFS= line +# below. This flag affects xntpd only. This define is included by +# default when using the "make makeconfig" script. +# +# The next two sets of defines are meaningful only when radio clock +# drivers or special 1-pps signals are to be used. For systems without +# these features, these delicious complexities can be avoided. Ordinarily, +# the "make makeconfig" script figures out which ones to use, but your +# mileage may vary. +# +# There are three ways to utilize external 1-pps signals. Define +# -DPPS to include just the pps routine, such as used by the DCF77(PARSE) +# clock driver. Define -DPPSCLK to include a serial device driver +# which avoids much of the jitter due to upper level port +# processing. This requires a dedicated serial port and either the +# tty_clock line discipline or tty_clk_streams module, both of +# which are in the ./kernel directory. Define -DPPSCD to include a +# special driver which intercepts carrier-detect transitions +# generated by the pps signal. This requires a nondedicated serial +# port and the ppsclock streams module in the ./kernel directory. +# Only one of these three flags should be defined. +# +# The flag KERNEL_PLL causes code to be compiled for a special feature of +# the kernel that (a) implements the phase-lock loop and (b) provides +# a user interface to learn time, maximum error and estimated error. +# See the file README.kern in the doc directory for further info. +# This code is activated only if the relevant kernel features have +# been configured; it does not affect operation of unmodified kernels. +# To compile it, however, requires a few header files from the +# special distribution. +# +# Note: following line must always start with DEFS_LOCAL= $(DEFS_OPT) +DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DPPSPPS -DKERNEL_PLL + +# +# Radio clock support definitions (these only make sense if -DREFCLOCK +# used), which is normally the case. Note that a configuration can include +# no clocks, more than one type of clock and even multiple clocks of the +# same type. +# +# For most radio clocks operating with serial ports, accuracy can +# be considerably improved through use of the tty_clk line +# discipline or tty_clk_STREAMS streams module found in the +# ./kernel directory. These gizmos capture a timestamp upon +# occurrence of an intercept character and stuff it in the data +# stream for the clock driver to munch. To select this mode, +# postfix the driver name with the string CLK; that is, WWVB +# becomes WWVBCLK. If more than one clock is in use, the CLK +# postfix can be used with any or all of them. +# +# Alternatively, for the best accuracy, use the ppsclock streams +# module in the ./ppsclock directory to steal the carrier-detect +# transition and capture a precision timestamp. At present this +# works only with SunOS 4.1.1 or later. To select this mode, +# postfix the driver name with the string PPS; that is, AS2201 +# becomes AS2201PPS. If more than one clock is in use, the PPS +# postfix should be used with only one of them. If any PPS +# postfix is defined, the -DPPSPPS define should be used on the +# DEFS above. +# +# Define -DLOCAL_CLOCK for a local pseudo-clock to masquerade as a +# reference clock for those subnets without access to the real thing. +# Works in all systems and requires no hardware support. This is defined +# by default when using the "make makeconfig" script and greenhorn +# configuraiton. +# +# Define -DPST for a PST/Traconex 1020 WWV/H receiver. The driver +# supports both the CLK and PPS modes. It should work in all systems +# with a serial port. +# +# Define -DWWVB for a Spectracom 8170 or Netclock/2 WWVB receiver. It +# should work in all systems with a serial port. The driver supports +# both the CLK and PPS modes if the requisite kernel support is installed. +# +# Define -DCHU for a special CHU receiver using an ordinary shortwave +# radio. This requires the chu_clk line discipline or chu_clk_STREAMS +# module in the ./kernel directory. At present, this driver works only +# on SunOS4.1.x; operation in other systems has not been confirmed. +# Construction details for a suitable modem can be found in the ./gadget +# directory. The driver supports # neither the CLK nor PPS modes. +# +# Define -DPARSE for a DCF77/GPS(GENERIC) receiver. For best performance +# this requires a special parsestreams STREAMS (SunOS 4.x) module in the +# ./parse directory. Define -DPARSEPPS for PPS support via the +# DCF77/GPS (GENERIC) receiver; also, define -DPPS in the DEFS above. +# Define: -DCLOCK_MEINBERG for Meinberg clocks +# -DCLOCK_SCHMID for Schmid receivers +# -DCLOCK_DCF7000 for ELV DCF7000 +# -DCLOCK_RAWDCF for simple receivers (100/200ms pulses on Rx) +# -DCLOCK_TRIMSV6 for Trimble SV6 GPS receiver +# +# Define -DMX4200PPS for a Magnavox 4200 GPS receiver. At present, this +# driver works only on SunOS4.1.x with CPU serial ports only. The PPS +# mode is required. +# +# Define -DAS2201 for an Austron 2200A or 2201A GPS receiver. It should +# work in all systems with a serial port. The driver does not support the +# CLK mode, but does support the PPS mode. If the radio is connected to +# more than one machine, the PPS mode is required. +# +# Define -DGOES for a Kinemetrics/TrueTime 468-DC GOES receiver. This +# driver is known to work with some other TrueTime products as well, +# including the GPS-DC GPS receiver. It should work in all systems with +# a serial port. The driver does not support the CLK mode, but does +# support the PPS mode. +# +# Define -DOMEGA for a Kinemetrics/TrueTime OM-DC OMEGA receiver. It +# should work in all systems with a serial port. The driver does not +# support the CLK mode, but does support the PPS mode. +# +# Define -DTPRO for a KSI/Odetics TPRO-S IRIG-B timecode reader. This +# requires the SunOS interface driver available from KSI. The driver +# supports neither the CLK nor PPS modes. +# +# Define -DLEITCH for a Leitch CSD 5300 Master Clock System Driver for +# the HP 5061B Cesium Clock. It should work in all systems with a serial +# port. The driver does not support the CLK mode, but does support the +# PPS mode. +# +# Define -DMSFEESPPS for an EES M201 MSF receiver. It currently only works +# under SunOS 4.x with the PPSCD (ppsclock) STREAMS module, but the RCS +# files on cl.cam.ac.uk still has support for CLK and CBREAK modes. +# +# Define -DIRIG for a IRIG-B timecode timecode using the audio codec of +# the Sun SPARCstations. This requires a modified BSD audio driver and +# exclusive access to the audio port. A memo describing how it works and +# how to install the driver is in the README.irig file in the ./doc +# directory. +# +# Note: The following defines result in compilation of all the above radio +# clocks. This works on a Sun 4.1.x system which has tty_clk, chu_clk and +# ppsclock STREAMS modules installed. If the trailing CLK and PPS suffixes +# are removed and the IRIG, PARSE* and CLOCK* deleted, all of the rest compile +# under Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC +# OSF/1 Alpha. +# +CLOCKDEFS= -DLOCAL_CLOCK -DAS2201PPS -DCHU -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPSTCLK -DTPRO -DWWVBCLK -DMSFEESPPS -DLEITCH + +# +# Directory into which binaries should be installed (default /usr/local) +# +BINDIR= /usr/local/bin diff --git a/usr.sbin/xntpd/Config.local b/usr.sbin/xntpd/Config.local new file mode 100644 index 000000000000..4c5095c164da --- /dev/null +++ b/usr.sbin/xntpd/Config.local @@ -0,0 +1,190 @@ +# This is the local configure file (distribution version). +# You must modify it to fit your particular configuration +# and name it Config.local +# The following configuratiions can be auto-generated: +# +# make Config.local.green +# make a Config.local that supports a local clock +# (i.e. allow fallback to use of the CPU's own clock) +# make Config.local.NO.clock +# make a Config.local that supports no clocks +# +# +# NOTE TO GREENHORNS +# +# For plug-'n-play and no radios or other complicated gadgetry, +# use "make Config.local.green" as above. +# +# Following defines can be set in the DEFS_OPT= define: +# +# The flag -DDEBUG includes some debugging code. To use this, include +# the define and start the daemon with one or more -d flags, depending +# on your calibration of pearannoya. The daemon will not detach your +# terminal in this case. Judicious use of grep will reduce the speaker +# volume to bearable levels. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# The -DSYSLOG_FILE defines allows logging messages that are normally +# reported via syslof() in a file. The file name can be configured using +# the configuration line "logfile <filename>" in CONFIG_FILE. +# +# There are three serial port system software interfaces, each of +# which is peculiar to one or more Unix versions. Define +# -DHAVE_SYSV_TTYS for basic System V compatibility; define -DSTREAM +# for POSIX compatibility including System V Streams, and +# HAVE_BSD_TTYS for 4.3bsd compatibility. Only one of these three +# should be defined. If none are defined, HAVE_BSD_TTYS is assumed. +# Usually these defines are already set correctly. +# +DEFS_OPT=-DDEBUG + +# +# The DEFS_LOCAL define picks up all flags from DEFS_OPT (do not delete that) +# and one of the following: +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you may also want to +# configure the particular clock drivers you want in the CLOCKDEFS= line +# below. This flag affects xntpd only. This define is included by +# default when using the "make makeconfig" script. +# +# The next two sets of defines are meaningful only when radio clock +# drivers or special 1-pps signals are to be used. For systems without +# these features, these delicious complexities can be avoided. Ordinarily, +# the "make makeconfig" script figures out which ones to use, but your +# mileage may vary. +# +# There are three ways to utilize external 1-pps signals. Define +# -DPPS to include just the pps routine, such as used by the DCF77(PARSE) +# clock driver. Define -DPPSCLK to include a serial device driver +# which avoids much of the jitter due to upper level port +# processing. This requires a dedicated serial port and either the +# tty_clock line discipline or tty_clk_streams module, both of +# which are in the ./kernel directory. Define -DPPSCD to include a +# special driver which intercepts carrier-detect transitions +# generated by the pps signal. This requires a nondedicated serial +# port and the ppsclock streams module in the ./kernel directory. +# Only one of these three flags should be defined. +# +# The flag KERNEL_PLL causes code to be compiled for a special feature of +# the kernel that (a) implements the phase-lock loop and (b) provides +# a user interface to learn time, maximum error and estimated error. +# See the file README.kern in the doc directory for further info. +# This code is activated only if the relevant kernel features have +# been configured; it does not affect operation of unmodified kernels. +# To compile it, however, requires a few header files from the +# special distribution. +# +# Note: following line must always start with DEFS_LOCAL= $(DEFS_OPT) +DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DPPSPPS -DKERNEL_PLL + +# +# Radio clock support definitions (these only make sense if -DREFCLOCK +# used), which is normally the case. Note that a configuration can include +# no clocks, more than one type of clock and even multiple clocks of the +# same type. +# +# For most radio clocks operating with serial ports, accuracy can +# be considerably improved through use of the tty_clk line +# discipline or tty_clk_STREAMS streams module found in the +# ./kernel directory. These gizmos capture a timestamp upon +# occurrence of an intercept character and stuff it in the data +# stream for the clock driver to munch. To select this mode, +# postfix the driver name with the string CLK; that is, WWVB +# becomes WWVBCLK. If more than one clock is in use, the CLK +# postfix can be used with any or all of them. +# +# Alternatively, for the best accuracy, use the ppsclock streams +# module in the ./ppsclock directory to steal the carrier-detect +# transition and capture a precision timestamp. At present this +# works only with SunOS 4.1.1 or later. To select this mode, +# postfix the driver name with the string PPS; that is, AS2201 +# becomes AS2201PPS. If more than one clock is in use, the PPS +# postfix should be used with only one of them. If any PPS +# postfix is defined, the -DPPSPPS define should be used on the +# DEFS above. +# +# Define -DLOCAL_CLOCK for a local pseudo-clock to masquerade as a +# reference clock for those subnets without access to the real thing. +# Works in all systems and requires no hardware support. This is defined +# by default when using the "make makeconfig" script and greenhorn +# configuraiton. +# +# Define -DPST for a PST/Traconex 1020 WWV/H receiver. The driver +# supports both the CLK and PPS modes. It should work in all systems +# with a serial port. +# +# Define -DWWVB for a Spectracom 8170 or Netclock/2 WWVB receiver. It +# should work in all systems with a serial port. The driver supports +# both the CLK and PPS modes if the requisite kernel support is installed. +# +# Define -DCHU for a special CHU receiver using an ordinary shortwave +# radio. This requires the chu_clk line discipline or chu_clk_STREAMS +# module in the ./kernel directory. At present, this driver works only +# on SunOS4.1.x; operation in other systems has not been confirmed. +# Construction details for a suitable modem can be found in the ./gadget +# directory. The driver supports # neither the CLK nor PPS modes. +# +# Define -DPARSE for a DCF77/GPS(GENERIC) receiver. For best performance +# this requires a special parsestreams STREAMS (SunOS 4.x) module in the +# ./parse directory. Define -DPARSEPPS for PPS support via the +# DCF77/GPS (GENERIC) receiver; also, define -DPPS in the DEFS above. +# Define: -DCLOCK_MEINBERG for Meinberg clocks +# -DCLOCK_SCHMID for Schmid receivers +# -DCLOCK_DCF7000 for ELV DCF7000 +# -DCLOCK_RAWDCF for simple receivers (100/200ms pulses on Rx) +# -DCLOCK_TRIMSV6 for Trimble SV6 GPS receiver +# +# Define -DMX4200PPS for a Magnavox 4200 GPS receiver. At present, this +# driver works only on SunOS4.1.x with CPU serial ports only. The PPS +# mode is required. +# +# Define -DAS2201 for an Austron 2200A or 2201A GPS receiver. It should +# work in all systems with a serial port. The driver does not support the +# CLK mode, but does support the PPS mode. If the radio is connected to +# more than one machine, the PPS mode is required. +# +# Define -DGOES for a Kinemetrics/TrueTime 468-DC GOES receiver. This +# driver is known to work with some other TrueTime products as well, +# including the GPS-DC GPS receiver. It should work in all systems with +# a serial port. The driver does not support the CLK mode, but does +# support the PPS mode. +# +# Define -DOMEGA for a Kinemetrics/TrueTime OM-DC OMEGA receiver. It +# should work in all systems with a serial port. The driver does not +# support the CLK mode, but does support the PPS mode. +# +# Define -DTPRO for a KSI/Odetics TPRO-S IRIG-B timecode reader. This +# requires the SunOS interface driver available from KSI. The driver +# supports neither the CLK nor PPS modes. +# +# Define -DLEITCH for a Leitch CSD 5300 Master Clock System Driver for +# the HP 5061B Cesium Clock. It should work in all systems with a serial +# port. The driver does not support the CLK mode, but does support the +# PPS mode. +# +# Define -DMSFEESPPS for an EES M201 MSF receiver. It currently only works +# under SunOS 4.x with the PPSCD (ppsclock) STREAMS module, but the RCS +# files on cl.cam.ac.uk still has support for CLK and CBREAK modes. +# +# Define -DIRIG for a IRIG-B timecode timecode using the audio codec of +# the Sun SPARCstations. This requires a modified BSD audio driver and +# exclusive access to the audio port. A memo describing how it works and +# how to install the driver is in the README.irig file in the ./doc +# directory. +# +# Note: The following defines result in compilation of all the above radio +# clocks. This works on a Sun 4.1.x system which has tty_clk, chu_clk and +# ppsclock STREAMS modules installed. If the trailing CLK and PPS suffixes +# are removed and the IRIG, PARSE* and CLOCK* deleted, all of the rest compile +# under Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC +# OSF/1 Alpha. +# +CLOCKDEFS= -DLOCAL_CLOCK -DAS2201PPS -DCHU -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPSTCLK -DTPRO -DWWVBCLK -DMSFEESPPS -DLEITCH + +# +# Directory into which binaries should be installed (default /usr/local) +# +BINDIR= /usr/local/bin diff --git a/usr.sbin/xntpd/Config.local.dist b/usr.sbin/xntpd/Config.local.dist new file mode 100644 index 000000000000..4c5c24672700 --- /dev/null +++ b/usr.sbin/xntpd/Config.local.dist @@ -0,0 +1,190 @@ +# This is the local configure file (distribution version). +# You must modify it to fit your particular configuration +# and name it Config.local +# The following configuratiions can be auto-generated: +# +# make Config.local.green +# make a Config.local that supports a local clock +# (i.e. allow fallback to use of the CPU's own clock) +# make Config.local.NO.clock +# make a Config.local that supports no clocks +# +# +# NOTE TO GREENHORNS +# +# For plug-'n-play and no radios or other complicated gadgetry, +# use "make Config.local.green" as above. +# +# Following defines can be set in the DEFS_OPT= define: +# +# The flag -DDEBUG includes some debugging code. To use this, include +# the define and start the daemon with one or more -d flags, depending +# on your calibration of pearannoya. The daemon will not detach your +# terminal in this case. Judicious use of grep will reduce the speaker +# volume to bearable levels. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# The -DSYSLOG_FILE defines allows logging messages that are normally +# reported via syslof() in a file. The file name can be configured using +# the configuration line "logfile <filename>" in CONFIG_FILE. +# +# There are three serial port system software interfaces, each of +# which is peculiar to one or more Unix versions. Define +# -DHAVE_SYSV_TTYS for basic System V compatibility; define -DSTREAM +# for POSIX compatibility including System V Streams, and +# HAVE_BSD_TTYS for 4.3bsd compatibility. Only one of these three +# should be defined. If none are defined, HAVE_BSD_TTYS is assumed. +# Usually these defines are already set correctly. +# +DEFS_OPT=-DDEBUG + +# +# The DEFS_LOCAL define picks up all flags from DEFS_OPT (do not delete that) +# and one of the following: +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you may also want to +# configure the particular clock drivers you want in the CLOCKDEFS= line +# below. This flag affects xntpd only. This define is included by +# default when using the "make makeconfig" script. +# +# The next two sets of defines are meaningful only when radio clock +# drivers or special 1-pps signals are to be used. For systems without +# these features, these delicious complexities can be avoided. Ordinarily, +# the "make makeconfig" script figures out which ones to use, but your +# mileage may vary. +# +# There are three ways to utilize external 1-pps signals. Define +# -DPPS to include just the pps routine, such as used by the DCF77(PARSE) +# clock driver. Define -DPPSCLK to include a serial device driver +# which avoids much of the jitter due to upper level port +# processing. This requires a dedicated serial port and either the +# tty_clock line discipline or tty_clk_streams module, both of +# which are in the ./kernel directory. Define -DPPSCD to include a +# special driver which intercepts carrier-detect transitions +# generated by the pps signal. This requires a nondedicated serial +# port and the ppsclock streams module in the ./kernel directory. +# Only one of these three flags should be defined. +# +# The flag KERNEL_PLL causes code to be compiled for a special feature of +# the kernel that (a) implements the phase-lock loop and (b) provides +# a user interface to learn time, maximum error and estimated error. +# See the file README.kern in the doc directory for further info. +# This code is activated only if the relevant kernel features have +# been configured; it does not affect operation of unmodified kernels. +# To compile it, however, requires a few header files from the +# special distribution. +# +# Note: following line must always start with DEFS_LOCAL= $(DEFS_OPT) +DEFS_LOCAL= $(DEFS_OPT) #GREEN -DREFCLOCK #TEST -DPPSPPS -DKERNEL_PLL + +# +# Radio clock support definitions (these only make sense if -DREFCLOCK +# used), which is normally the case. Note that a configuration can include +# no clocks, more than one type of clock and even multiple clocks of the +# same type. +# +# For most radio clocks operating with serial ports, accuracy can +# be considerably improved through use of the tty_clk line +# discipline or tty_clk_STREAMS streams module found in the +# ./kernel directory. These gizmos capture a timestamp upon +# occurrence of an intercept character and stuff it in the data +# stream for the clock driver to munch. To select this mode, +# postfix the driver name with the string CLK; that is, WWVB +# becomes WWVBCLK. If more than one clock is in use, the CLK +# postfix can be used with any or all of them. +# +# Alternatively, for the best accuracy, use the ppsclock streams +# module in the ./ppsclock directory to steal the carrier-detect +# transition and capture a precision timestamp. At present this +# works only with SunOS 4.1.1 or later. To select this mode, +# postfix the driver name with the string PPS; that is, AS2201 +# becomes AS2201PPS. If more than one clock is in use, the PPS +# postfix should be used with only one of them. If any PPS +# postfix is defined, the -DPPSPPS define should be used on the +# DEFS above. +# +# Define -DLOCAL_CLOCK for a local pseudo-clock to masquerade as a +# reference clock for those subnets without access to the real thing. +# Works in all systems and requires no hardware support. This is defined +# by default when using the "make makeconfig" script and greenhorn +# configuraiton. +# +# Define -DPST for a PST/Traconex 1020 WWV/H receiver. The driver +# supports both the CLK and PPS modes. It should work in all systems +# with a serial port. +# +# Define -DWWVB for a Spectracom 8170 or Netclock/2 WWVB receiver. It +# should work in all systems with a serial port. The driver supports +# both the CLK and PPS modes if the requisite kernel support is installed. +# +# Define -DCHU for a special CHU receiver using an ordinary shortwave +# radio. This requires the chu_clk line discipline or chu_clk_STREAMS +# module in the ./kernel directory. At present, this driver works only +# on SunOS4.1.x; operation in other systems has not been confirmed. +# Construction details for a suitable modem can be found in the ./gadget +# directory. The driver supports # neither the CLK nor PPS modes. +# +# Define -DPARSE for a DCF77/GPS(GENERIC) receiver. For best performance +# this requires a special parsestreams STREAMS (SunOS 4.x) module in the +# ./parse directory. Define -DPARSEPPS for PPS support via the +# DCF77/GPS (GENERIC) receiver; also, define -DPPS in the DEFS above. +# Define: -DCLOCK_MEINBERG for Meinberg clocks +# -DCLOCK_SCHMID for Schmid receivers +# -DCLOCK_DCF7000 for ELV DCF7000 +# -DCLOCK_RAWDCF for simple receivers (100/200ms pulses on Rx) +# -DCLOCK_TRIMSV6 for Trimble SV6 GPS receiver +# +# Define -DMX4200PPS for a Magnavox 4200 GPS receiver. At present, this +# driver works only on SunOS4.1.x with CPU serial ports only. The PPS +# mode is required. +# +# Define -DAS2201 for an Austron 2200A or 2201A GPS receiver. It should +# work in all systems with a serial port. The driver does not support the +# CLK mode, but does support the PPS mode. If the radio is connected to +# more than one machine, the PPS mode is required. +# +# Define -DGOES for a Kinemetrics/TrueTime 468-DC GOES receiver. This +# driver is known to work with some other TrueTime products as well, +# including the GPS-DC GPS receiver. It should work in all systems with +# a serial port. The driver does not support the CLK mode, but does +# support the PPS mode. +# +# Define -DOMEGA for a Kinemetrics/TrueTime OM-DC OMEGA receiver. It +# should work in all systems with a serial port. The driver does not +# support the CLK mode, but does support the PPS mode. +# +# Define -DTPRO for a KSI/Odetics TPRO-S IRIG-B timecode reader. This +# requires the SunOS interface driver available from KSI. The driver +# supports neither the CLK nor PPS modes. +# +# Define -DLEITCH for a Leitch CSD 5300 Master Clock System Driver for +# the HP 5061B Cesium Clock. It should work in all systems with a serial +# port. The driver does not support the CLK mode, but does support the +# PPS mode. +# +# Define -DMSFEESPPS for an EES M201 MSF receiver. It currently only works +# under SunOS 4.x with the PPSCD (ppsclock) STREAMS module, but the RCS +# files on cl.cam.ac.uk still has support for CLK and CBREAK modes. +# +# Define -DIRIG for a IRIG-B timecode timecode using the audio codec of +# the Sun SPARCstations. This requires a modified BSD audio driver and +# exclusive access to the audio port. A memo describing how it works and +# how to install the driver is in the README.irig file in the ./doc +# directory. +# +# Note: The following defines result in compilation of all the above radio +# clocks. This works on a Sun 4.1.x system which has tty_clk, chu_clk and +# ppsclock STREAMS modules installed. If the trailing CLK and PPS suffixes +# are removed and the IRIG, PARSE* and CLOCK* deleted, all of the rest compile +# under Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC +# OSF/1 Alpha. +# +CLOCKDEFS= #GREEN -DLOCAL_CLOCK #TEST -DAS2201PPS -DCHU -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPST -DPSTCLK -DTPRO -DWWVBCLK -DMSFEESPPS -DLEITCH -DPARSE -DPARSEPPS -DCLOCK_MEINBERG -DCLOCK_RAWDCF -DCLOCK_SCHMID -DCLOCK_DCF7000 -DCLOCK_TRIMSV6 + +# +# Directory into which binaries should be installed (default /usr/local) +# +BINDIR= /usr/local/bin diff --git a/usr.sbin/xntpd/Config.sed b/usr.sbin/xntpd/Config.sed new file mode 100644 index 000000000000..fe5a9b7927bd --- /dev/null +++ b/usr.sbin/xntpd/Config.sed @@ -0,0 +1,14 @@ +s~^RANLIB=.*~RANLIB= ranlib~ +s~^DEFS_LOCAL=.*~DEFS_LOCAL=-DREFCLOCK~ +s~^DEFS=.*~DEFS= -DSYS_FREEBSD -DSYS_386BSD~ +s~^AUTHDEFS=.*~AUTHDEFS= -DDES -DMD5~ +s~^CLOCKDEFS=.*~CLOCKDEFS= -DLOCAL_CLOCK~ +s~^DAEMONLIBS=.*~DAEMONLIBS= -lcrypt~ +s~^RESLIB=.*~RESLIB=~ +s~^COPTS=.*~COPTS= -O2~ +s~^COMPILER=.*~COMPILER= gcc~ +s~^LIBDEFS=.*~LIBDEFS= -DXNTP_LITTLE_ENDIAN~ +s~^DEFS_OPT=.*~DEFS_OPT=-DDEBUG~ +s~^DEFS_LOCAL=.*~DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DPPSPPS -DKERNEL_PLL~ +s~^CLOCKDEFS=.*~CLOCKDEFS= -DLOCAL_CLOCK -DAS2201PPS -DCHU -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPSTCLK -DTPRO -DWWVBCLK -DMSFEESPPS -DLEITCH~ +s~^BINDIR=.*~BINDIR= /usr/local/bin~ diff --git a/usr.sbin/xntpd/Makefile b/usr.sbin/xntpd/Makefile new file mode 100644 index 000000000000..30e59bbb5ce0 --- /dev/null +++ b/usr.sbin/xntpd/Makefile @@ -0,0 +1,359 @@ +# WARNING: +# CONTENTS UNDER PRESSURE. +# HIGHLY FLAMMABLE. +# RISK OF SHOCK. +# DO NOT ATTEMPT TO OPEN COVER. +# NO USER SERVICEABLE PARTS INSIDE. +# REFER SERVICING TO QUALIFIED PERSONNEL. +# +# The vendor hits you... +# You try to hit the vendor... +# You die. +# +# Unfortunately the above is no fun... +# +# During testing/porting we have found a long list +# of "make" and "sh" and "awk" features in different implementations. +# Some goodies (make good horror stories for your kids 8-(): +# gmake 3.62 +# non standard target construction +# +# pmake (e. g. NetBSD on MAC, possible other BNR2+pmake systems) +# skips '' (empty string positional) args to sh +# (this leads to following stupid constructions +# sh -c "./scripts/makeconfig.sh '$(OS)' '$(COMP)'") +# +# Following Makefile construction fails for no +# apparent reason (at least to me) +# doit: +# $(MAKE) MAKE=\"$(MAKE)\" all +# +# all: +# @echo all done. +# +# for the "make MAKE=make" call not for "make" or +# "make -e MAKE=make". Use the last form if you suffer +# from that kind of make problems. (Easily detected +# by failure to build with the message: +# "don't know how to make make". +# +# sh (Ultrix 4.2 MIPS) +# shell broken (reversed pipe construction "false | true" +# returns false - major bummer) +# +# awk (EP/IX 2.?) +# unable to do regexp matches +# (aka awk '/..*/ { print; }' fails on match) +# +# Usually the vendor should fix these bugs in vital utilities. +# We try to circumvent these bugs in a hopefully portable way. +# If you can reproduce these bugs on your system please bug your +# vendor to fix them. We are not trying anything fancy in here and +# we are shocked that even the most common tools fail so miserably. +# By the time you get this code the above utilities may already +# have been fixed. Hopefully one day we do not have to cope with +# this kind of broken utilities. +# +# Sorry about the situation, +# Frank Kardel +# +SHELL=/bin/sh +CONF = Config +CONFL = $(CONF).local +CONFLD= $(CONFL).dist +TARGETS = xntpd/xntpd xntpdc/xntpdc ntpq/ntpq ntpdate/ntpdate \ + ntptrace/ntptrace xntpres/xntpres authstuff/authspeed util/tickadj +OPTTARG = adjtime/adjtimed util/ntptime util/precision +REFCONF= +COMPRESSOR=compress +# Base distribution name (will be extended by <VERSION>.tar.<comperssorsuffix>) +DISTNAME=xntp- +MAKE= make + +all: version $(TARGETS) kernel_modules + +$(TARGETS): VERSION $(CONF) + +version: + @echo '### Building XNTP:' "`egrep '^.*=.*$$' VERSION | tr '\012' ';'`" + +makeconfig: + sh -c "./scripts/makeconfig.sh '$(OS)' '$(COMP)'" + +$(CONFL).NO.clock: + @echo '###' creating $(CONFL) for absolutely '*NO*' clocks '*AT ALL*' + rm -f $(CONFL)-t $(CONFL) + cat < $(CONFLD) > $(CONFL)-t && mv $(CONFL)-t $(CONFL) + +$(CONFL).green: + @echo '###' creating $(CONFL) for greenhorns '(local refclock only)' + rm -f $(CONFL)-t $(CONFL) + sed 's/#GREEN//' < $(CONFLD) > $(CONFL)-t && mv $(CONFL)-t $(CONFL) + +$(CONFL): + @echo '' + @echo '### creating a $(CONFL) file as none existed.' + @echo '### Use "make refconf" if you have a radio clock' + @echo '' + @$(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" $(CONFL).green + +$(CONF): $(CONFL) + @echo + @echo '###' creating new configuration + @sh -c "./scripts/makeconfig.sh '$(OS)' '$(COMP)'" + +refconf: $(CONF) + -@sh refclocks/rconfig '$(REFCONF)' + @sh -c "./scripts/makeconfig.sh '$(OS)' '$(COMP)'" + +kernel_modules: kernel/Makefile + @cd kernel && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +xntpd/xntpd: lib/libntp.a parse/libparse.a xntpd/Makefile FRC + @echo + @echo '###' creating NTP daemon + @cd xntpd && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +xntpdc/xntpdc: lib/libntp.a xntpdc/Makefile FRC + @echo + @echo '###' creating XNTPDC utility + @cd xntpdc && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +ntpq/ntpq: lib/libntp.a ntpq/Makefile FRC + @echo + @echo '###' creating NTPQ utility + @cd ntpq && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +ntptrace/ntptrace: lib/libntp.a ntptrace/Makefile FRC + @echo + @echo '###' creating NTPTRACE utility + @cd ntptrace && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +ntpdate/ntpdate: lib/libntp.a ntpdate/Makefile FRC + @echo + @echo '###' creating NTPDATE utility + @cd ntpdate && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +authstuff/authspeed: lib/libntp.a authstuff/Makefile FRC + @echo + @echo '###' creating AUTH utilities + @cd authstuff && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +xntpres/xntpres: lib/libntp.a xntpres/Makefile FRC + @echo + @echo '###' creating XNTPRES utility + @cd xntpres && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +util/tickadj: util/Makefile FRC + @echo + @echo '###' creating TICKADJ utility + @cd util && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +lib/libntp.a: lib/*.c lib/Makefile adjtime/Makefile + @echo + @echo '###' creating NTP library + @cd lib && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +parse/libparse.a: parse/*.c parse/Makefile parse/util/Makefile lib/libntp.a + @echo + @echo '### creating PARSE subsystem (if configured)' + @cd parse && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +FRC: + +savebin: + @test -d bin || mkdir bin + @echo + @echo '### saving $(TARGETS) $(OPTTARG) in bin' + -@for f in $(TARGETS) $(OPTTARG); \ + do test -f $$f && mv $$f bin/. && echo "### saved $$f in bin/"; \ + done; \ + true + +neatneat: + @echo '###' cleaning derived config files + -@rm -f $(CONF).sed $(CONF) + +neat: + @echo '###' cleaning top level left overs + -@rm -f eddep makedep Makefile.bak make.log make.out + +distclean: neatneat clean + @echo '###' cleaning configuration dependent Makefiles + -@find . -name Makefile -print | \ + while read X; do \ + if [ -f "$$X.tmpl" ]; then \ + rm -f "$$X"; \ + else \ + :; \ + fi \ + done + @echo '###' cleaning old scratch files + -@find . \( -name '*.rej' -o -name '*.orig' -o -name '*~' -o \ + -name '.version' -o -name '#*' -o -name '.#*' -o \ + -name core -o -name version.c \) -print | xargs rm -f + @echo '###' cleaning saved binaries + -@rm -fr bin + +clean: neat + @echo '###' cleaning adjtime + @cd adjtime && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" -f Makefile.tmpl $@ + @echo '###' cleaning authstuff + @cd authstuff && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning clockstuff + @cd clockstuff && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning lib + @cd lib && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning ntpdate + @cd ntpdate && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning ntpq + @cd ntpq && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning ntptrace + @cd ntptrace && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning util + @cd util && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning xntpd + @cd xntpd && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning xntpdc + @cd xntpdc && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning xntpres + @cd xntpres && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + @echo '###' cleaning parse + @cd parse && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" $@ + +install: all + @echo installing from xntpd + @cd xntpd && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + @echo installing from xntpdc + @cd xntpdc && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + @echo installing from ntpq + @cd ntpq && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + @echo installing from ntptrace + @cd ntptrace && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + @echo installing from ntpdate + @cd ntpdate && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + @echo installing from xntpres + @cd xntpres && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + @echo installing from util + @cd util && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + @echo installing from parse + @cd parse && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" install + +dist: + @echo '### building distribution ...' + @$(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" distclean + @DISTVERSION="`sed -e 's/^[ ]*[Vv][Ee][Rr][Ss][Ii][Oo][Nn][ ]*=\(.*\)$$/\1/' VERSION | \ + sed -e 's/[^0-9a-zA-Z\.]/_/g; s/__*/_/g; s/_*$$//'`" && \ + echo "### creating distribution file $(DISTNAME)$${DISTVERSION}.tar" && \ + rm -f $(DISTNAME)$${DISTVERSION}.tar $(DISTNAME)$${DISTVERSION}.tar.* && \ + tar cfv $(DISTNAME)$${DISTVERSION}.tar `ls | egrep -v "^$(CONFL)$$|^$(DISTNAME)$${DISTVERSION}.tar$$"` && \ + $(COMPRESSOR) -v $(DISTNAME)$${DISTVERSION}.tar + +$(CONF).sed: $(CONF) Makefile + @sed -n -e 's:^\([^ ]*\)=[ ]*\(.*\):s~^\1=.*~&~:p' < $(CONF) > $@ + +depend: + find . -name Makefile.tmpl -print > eddep + echo >> makedep + sed -e 's:^\./::' -e '/^Makefile/d' \ + -e h \ + -e 's/^\(.*\)\.tmpl$$/\1: \1.tmpl $${CONF}.sed/' -e p -e g \ + -e 's/.*/ @echo/' -e p -e g \ + -e 's:^\(.*\)/Makefile\.tmpl$$: @echo '"'###'"' updating Makefile in \1:' -e p -e g \ + -e 's/.*/ @sed -f $${CONF}.sed < $$@.tmpl > $$@/' -e p -e g \ + -e 's:^\(.*\)/Makefile\.tmpl$$: @echo '"'###'"' cleaning in \1:' -e p -e g \ + -e 's:^\(.*\)/Makefile\.tmpl$$: @cd \1 \&\& $$(MAKE) $$(MFLAGS) MFLAGS="$$(MFLAGS)" -f Makefile.tmpl MAKE="$$(MAKE)" clean:p' \ + < eddep >> makedep + echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep + echo '$$r makedep' >>eddep + echo 'w' >>eddep + cp Makefile Makefile.bak + /bin/ed - Makefile < eddep + rm eddep makedep + +# DO NOT DELETE THIS LINE -- It is used by 'make depend' to update this file + +adjtime/Makefile: adjtime/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in adjtime + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in adjtime + @cd adjtime && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +authstuff/Makefile: authstuff/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in authstuff + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in authstuff + @cd authstuff && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +clockstuff/Makefile: clockstuff/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in clockstuff + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in clockstuff + @cd clockstuff && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +kernel/Makefile: kernel/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in kernel + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in kernel + @cd kernel && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +lib/Makefile: lib/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in lib + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in lib + @cd lib && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +ntpdate/Makefile: ntpdate/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in ntpdate + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in ntpdate + @cd ntpdate && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +ntpq/Makefile: ntpq/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in ntpq + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in ntpq + @cd ntpq && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +ntptrace/Makefile: ntptrace/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in ntptrace + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in ntptrace + @cd ntptrace && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +util/Makefile: util/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in util + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in util + @cd util && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +xntpd/Makefile: xntpd/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in xntpd + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in xntpd + @cd xntpd && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +xntpdc/Makefile: xntpdc/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in xntpdc + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in xntpdc + @cd xntpdc && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +xntpres/Makefile: xntpres/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in xntpres + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in xntpres + @cd xntpres && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +parse/util/Makefile: parse/util/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in parse/util + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in parse/util + @cd parse/util && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean +parse/Makefile: parse/Makefile.tmpl ${CONF}.sed + @echo + @echo '###' updating Makefile in parse + @sed -f ${CONF}.sed < $@.tmpl > $@ + @echo '###' cleaning in parse + @cd parse && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" -f Makefile.tmpl MAKE="$(MAKE)" clean diff --git a/usr.sbin/xntpd/PORTING b/usr.sbin/xntpd/PORTING new file mode 100644 index 000000000000..7f236424ec4f --- /dev/null +++ b/usr.sbin/xntpd/PORTING @@ -0,0 +1,37 @@ +These are the rules so that older bsd systems and the POSIX standard +system can coexist togather. + + 1) If you use select then include "ntp_select.h" + select is not standard, since it is very system depenedent as to where + select is defined. The logic to include the right system dependent + include file is in "ntp_select.h". + 2) Always use POSIX defintion of strings. Inlcude "ntp_string.h" instaed + of <string.h>. + 3) Always include "ntp_malloc.h" if you use malloc. + 4) Always include "ntp_io.h" instead of <sys/file.h> or <fnctl.h> to + get O_* flags. + 5) Always include "ntp_if.h" instead of <net/if.h>. + 6) Always include "ntp_stdlib.h" instead of <stdlib.h>. + 7) Always define a system identifier for any new system added to the + machines directory. The identifier should always start with SYS_! + 8) Define any special defines needed for a system in + ./include/ntp_machine.h based on system identifier. This file is + included by the "ntp_types.h" file and should always be placed + first after the <> defines. + 9) Define any special library prototypes left over from the system + library and include files in the "l_stdlib.h" file. This file is + included by the "ntp_stdlib.h" file and should ordinarily be + placed last in the includes list. + 10) Don't define a include file by the same name as a system include file. + + +"l_stdlib.h" can contain any extra definitions that are needed so that +gcc will shut up. They should be controlled by a system identifier and +there should be a seperate section for each system. Really this will +make it easier to maintain. + +See include/ntp_machines.h for the verious compile time options. + +Good luck. + +Bill Jones, with amendments by Dave Mills diff --git a/usr.sbin/xntpd/README b/usr.sbin/xntpd/README new file mode 100644 index 000000000000..76414a2a52d5 --- /dev/null +++ b/usr.sbin/xntpd/README @@ -0,0 +1,163 @@ +The xntp3 Distribution + +This directory and its subdirectories contain the Network Time Protocol +Version 3 (NTP) distribution for Unix systems. It contains source code +for the daemon, together with related auxiliary programs, documentation +and strange stuff. You are welcome to the lot, with due consideration of +the COPYRIGHT files stashed in the distributions. You are also invited +to contribute bugfixes and drivers for new and exotic radios, telephones +and sundials. This distribution is normally available by anonymous ftp +as the compressed tar archive xntp-<version>.tar.Z in the pub/ntp directory +on louie.udel.edu. + +The base directory contains the distributions and related stuff. The files +marked with a "*" are not distributed, but generated. Most of +the subdirectories contain README files describing their contents. The +base directory ./ includes: + +COPYRIGHT file specifying copyright conditions, together with a + list of major authors and electric addresses + +Config * configuration file built by the configuration script + "make makeconfig" and used to buile the makefiles in the + various subdirectories. Do not edit. + +Config.local * Unless you have a reference clock (besides the local + computer clock) or want to change the default installlation + directory (/usr/local/bin) not action is needed. For + configuring a reference clock a "make refconf" should + suffice. Diehards can still use an editor on this file. + +Config.local.dist file used to generate a plausible Config.local by commands + such as "make Config.local.green" + +Config.sed * sed script used to build makefiles from the + configuration file. Do not edit. + +Makefile this is the root of the makefile tree. Do not edit. + (Contents under pressure - qualified personel only 8-) + +PORTING contains useful information for porting to unexplored + new systems + +RELNOTES instructions for compiling and installing the daemon and + supporting programs + +README this file + +TODO our current problems where we could need help. + +adjtime directory containing the sources for the adjtime daemon + for HP/UX systems + +authstuff directory containing sources for miscellaneous programs + to test, calibrate and certify the cryptographic + mechanisms for DES and MD5 based authentication. These + programs do not include the cryptographic routines + themselves, so are free of U.S. export restrictions. + +clockstuff directory containing sources for miscellaneous programs + to test certain auxilliary programs used with some + kernel configurations, together with a program to + calculate propagation delays for use with radio clocks + and national time dissemination services such as + WWV/WWVH, WWVB and CHU + +compilers directory containing configuration scripts for various + compilers and operating systems + +conf directory containing a motley collection of + configuration files for various systems. For example + only. + +doc directory containing miscellaneous man pages and memos + useful for installation and subnet management + +gadget directory containing instructions and construction data + for a mysterious little box used as a CHU radio + demodulator and/or a level converter-pulse generator for + a precision 1-pps signal + +include directory containing include header files used by most + programs in the distribution + +hints directory containing files with hints on particular + topics like installation on specific OS variants or + general information + +historical.tar.Z + tar file with stuff believed to be old. If you find things + in there that are helpful for the current release, please + send email to mills@udel.edu. + +kernel directory containing sources for kernel programs such as + line disciplines and STREAMS modules used with the CHU + decoder and precision 1-pps signals + +lib directory containing sources for the library programs + used by most programs in the distribution + +machines directory containing configuration scripts for various + operating systems + +ntpdate directory containing sources for a program to set the + local machine time from one or more remote machines + running NTP. Operates like rdate, but much more + accurate. + +ntpq directory containing sources for a utility program to + query local and remote NTP peers for state variables and + related timekeeping information. This program conforms + to Appendix A of the NTP Version 3 Specification RFC + 1305. + +ntptrace directory containing sources for a utility program that + can be used to reveal the chain of NTP peers from a + designated peer to the primary server at the root of the + timekeeping subnet + +parse directory containing file belonging to the generic parse + reference clock driver. for reasonable simple clocks it + is possible to get away with about 3-4Kb of code. + additionally the SunOS 4.x streams module for parse is + residing here. + +parse/util some goodies for testing parse processing of DCF77 information. + (primarily for use on Suns / although others may work + also - possibly with a little porting) + one little gem is dcfd.c - DCF77 decoder with ntp loopfilter + code for standalone DCF77 synchronisation without the full + works of NTP. + +ppsclock directory containing sources for modifications to the + kernel asynchronous serial driver plus a STREAMS module + to capture a precision 1-pps signal. Useful on SunOS + 4.1.X systems only. + +refclocks directory containing reference clock configuration support + the file in here are still experimental. Do not expect them + to work flawlessly on all architectures. the coded dependencies + might not even be correct. + +scripts directory containing scripts to build the configuration + file "config" in this directory and then the makefiles + used in various dependent directories. + the subdirectories monitoring and support hold various + perl and shell scripts for visualising synchronisation + and daemon startup. + +util directory containing sources for various utility and + testing programs + +xntpd directory containing sources for the NTP Version 3 + daemon + +xntpdc directory containing sources for a utility program to + query local and remote NTP peers for state variables and + related timekeeping information. This program is + specific to this implmentation of NTP Version 3 and does + not conform to Appendix A of the NTP Version 3 + Specification RFC 1305. + +xntpres directory containing sources for a name-resolution + program used in some configurations of NTP Version 3 diff --git a/usr.sbin/xntpd/RELNOTES b/usr.sbin/xntpd/RELNOTES new file mode 100644 index 000000000000..277b8921de82 --- /dev/null +++ b/usr.sbin/xntpd/RELNOTES @@ -0,0 +1,195 @@ +For special hints on setup/compilation/installation and other general +topics you may persue the files in the hints directory. + +This file contains the usual instructions to compile and install the programs in +this distribution. To make these programs: + +(0) Make sure that you have all necessary tools for building executables. + These tools include cc/gcc, make, awk, sed, tr, sh, grep, egrep and + a few others. Not all of these tools exist in the standard distribution + of todays Unix versions (Compilers are likely to be an extra product). + For a successful build all of these tools should be accessible via the + current path. + +(1) By default, if there is no Config.local, the system will generate one + to support a local ref clock (i.e. run off the system clock). + Greenhorns can skip on to (2). + + HACKers can create a Config.local and choose the compilation options, + install destination directory and clock drivers. + A template for Config.local can be found in Config.local.dist. + There are two Configurations that can be auto-generated: + make Config.local.local # network configuration plus local + # reference clock (the default) + make Config.local.NO.clock # network only configuration + + To set up for a radio clock, type "make refconf" and answer the questions + about PLL, PPS and radio clock type. + If this is the first use of the ref clock, don't forget to make suitable + files in /dev/ + + For custom tailored configuration copying Config.local.dist to Config.local + and editing Config.local to suit the local needs is neccessary (at most + 3 lines to change), or use one of the make's above and then tweak it. + +(2) Type "make" to compile everything of general interest. Expect few or + no warnings using cc and a moderate level of warnings using gcc. + Note: On some Unix platforms the use of gcc can result in quite a few + complaints about system header files and type problems within xntp + code. This is usually the case when the OS header files are not up + up to ANSI standards or GCCISMs. (There may, however, be still some + inconsistencies in the code) + + Other known problems stem from bugs/features/... in utility programs + of some vendors. + + See section "build problems" for known problems and possible work- + arounds. + + Each time you change the configuration a script that pokes your hard- and + software will be run to build the actual configuration files. + If the script fails, it will give you a list of machines it knows about. + You can override the automatic choice by cd to the ../machines directory + and typing "make makeconfig OS=<machine>", where <machine> is one of the + file names in the ../machine directory. + + The shell script will attempt to find the gcc compiler and, if + found, will use it instead of the cc compiler. You can override + this automatic choice by cd to the ../machines directory and typing + "make makeconfig COMP=<compiler>", where <compiler> is one of the file + names in the ../compilers directory. This can be combined with + the OS argument above. + + The configuration step can be separatly invoked by "make makeconfig". + + Note that any reconfiguration will result in cleaning the old + program and object files. + +(3) Assuming you have write permission on the install destination directory, + type "make install" to install the binaries in the destination directory. + At the time of writing this includes + the programs xntpd (the daemon), xntpdc (an xntpd-dependent query + program), ntpq (a standard query program), ntpdate (an rdate + replacement for boot time date setting and sloppy time keeping) + and xntpres (a program which provides name resolver support for + some xntpd configurations). + +(4) You are now ready to configure the daemon and start it. At this + point it might be useful to format and print the file doc/notes.me + and read a little bit. The sections on configuration and on the + tickadj program will be immediately useful. + +Additional "make" target you might find useful are: + +clean cleans out object files, programs and temporary files + +dist makes a new distribution file (also cleans current binaries) + All usual scratch and backup files (*.rej, *.orig, *.o, *~ + core, lint*.errs, executables, tags, Makefile.bak, make.log) + will be removed. The distribution is created in a tar file + (file name: <prefix><version>.tar.<compression suffix> - with + the prefix usually being ../xntp- and a compression suffix + of .Z (compress)) + Note: the file Config.local will never be included in the + distribution tar file. For configuration hints to propagate + in in distribution changes must be made to Config.local.dist. + +depend possible maker of hazardous waste + +refconf a target to interactively configure reference clock support. + This should work for you, but has not yet been tested on + the more exotic Unix ports (mostly the supercomputer ones). + +Bug reports of a general nature can be sent to David Mills (mills@udel.edu). +Reports concerning specific hardware or software systems mentioned in the +COPYRIGHT file should be sent to the author, with copy to David Mills for +archive. + +The distribution has been compiled and run on at least the following +machines, operating systems and compilers. In all known cases, if +the gcc compiler eats it with some success, the cc compiler also enjoys +the meal. The converse is not always true. + + VAX-11/785 4.3 tahoe cc no REFCLOCK (dm 93/11/20) + Sun3 SunOS 4.1.1 gcc no REFCLOCK (pb 93/10/25) + Sun4 SunOS 4.1.1 gcc all REFCLOCK drivers (dm 93/10/25) + Sun4 SunOS 4.1.3 gcc all REFLCOCK drivers + Sun4 SunOS 5.1 gcc no REFCLOCK (pb 93/10/25) + Sun4 SunOS 5.2 gcc no REFCLOCK (dm 93/11/20) + Sun4 SunOS 5.2 gcc PARSE REFCLOCK (kd 93/11/10) + Sun4 SunOS 5.3 gcc local (pb 93/11/10) + HP700 HPUX 9.0 cc no REFCLOCK + hp7xx HPUX 9.01 cc local + PARSE (kd 93/10/26) + HP3xx HPUX 9.01 cc no REFCLOCK (pb 93/10/25) + HP3xx HPUX 8.0 cc no REFCLOCK (pb 93/10/25) + MIPS Ultrix 4.3a gcc WWVB clock (dm 93/11/20) + MIPS Ultrix 3a gcc green (pb 93/10/26) + ALPHA OSF 1.2a gcc no REFCLOCK (dm 93/11/20) + ALPHA OSF 1.3 gcc no REFCLOCK (pb 93/10/25) + ALPHA OSF1 1.3 gcc green (pb 93/10/26) + Convex Convex OS 10.1 ? ? + SGI IRIX 4.0.5F gcc no REFCLOCK (pb 93/11/10) + AIX 3.2 ? ? + A/UX 2.0.1, 3.0.x ? ? + RS6000 AIX 3.2 gcc no REFCLOCK + MX500 Sinix-m V5.40 cc PARSE REFCLOCK + S2000 Sequent PTX 1.4 cc LOCAL_CLOCK (kd 93/11/10) + S2000 Sequent PTX 1.4 gcc LOCAL_CLOCK (kd 93/11/10) + PC FreeBSD gcc LOCAL_CLOCK see "build problems" + PC NetBSD? gcc LOCAL_CLOCK possibly see "build problems" + PC BSDI? gcc LOCAL_CLOCK possibly see "build problems" + PC Linux (pl14) gcc LOCAL_CLOCK (dw 93/10/30) + + pb: Piete Brooks + kd: Frank Kardel + dw: Torsten Duwe (duwe@informatik.uni-erlangen.de) + dm: David Mills (mills@udel.edu) + +Build Problems (and workaround): + +During testing/porting we have found some +of "make" and "sh" and "awk" features in different implementations. +If you have problems other tha the one listed below please check for +usualy things like the latest sh compatible pd shell in your own +environment. Things like this are known to hinder compilation if +they ate not fully compatible with sh or are buggy. + +Current build problem on (Mac) NetBSD, possibly BSDI and 386BSD: + pmake (e. g. NetBSD on MAC, possible other BNR2+pmake systems) + Following Makefile construction fails for no + apparent reason (at least to me) + doit: + $(MAKE) MAKE=\"$(MAKE)\" all + + all: + @echo all done. + + for the "make MAKE=make" call but not for "make" or + "make -e MAKE=make". Use the last form if you suffer + from that kind of make problems. (Easily detected + by failure to build with the message: + "don't know how to make make". + +The known sh and some make pecularities have already been taken care of. +The pmake (in the BNR2 branches) problem seems to be real at the time of this +writing. If you know a portable(!) fix we'd like to hear from you. + +Usually the vendor should fix these bugs in vital utilities. +We try to circumvent these bugs in a hopefully portable way. +If you can reproduce these bugs on your system please bug your +vendor/developer group to fix them. We are not trying anything fancy +in here (except for starting sub-makes) and we are shocked that even +the most common tools fail so miserably. By the time you get this +code the above utilities may already have been fixed. Hopefully one +day we do not have to cope with this kind of broken utilities. + Frank Kardel + +William L. Jones <jones@chpc.utexas.edu> +Dennis Ferguson (Advanced Network Systems) <dennis@ans.net> +Lars Mathiesen (University of Copenhagen) <thorinn@diku.dk> +David Mills <mills@udel.edu> +Frank Kardel <Frank.Kardel@informatik.uni-erlangen.de> +Piete Brooks <Piete.Brooks@cl.cam.ac.uk> + +-- and a cast of thousands -- see the COPYRIGHT file +16 November 1993 diff --git a/usr.sbin/xntpd/TODO b/usr.sbin/xntpd/TODO new file mode 100644 index 000000000000..9b803722efc9 --- /dev/null +++ b/usr.sbin/xntpd/TODO @@ -0,0 +1,37 @@ +# +# TODO,v 3.3 1993/11/09 23:20:16 kardel Exp +# +This file contains problems known to the authors that still need to be done. +We would appreciate if you could spare some of your time to look through +these topics and help us with some open questions. Most of the topics +pertain to specific architectures where we have no direct access or not +the time or expertise to currently track down the problem further. +If you don't know what we are talking about in the topics don't bother +with finding out - somebody else will probably solve that problem. + +Before you try to send a solution to mills@udel.edu please check whether +this problem still exists in the distribution on louie.udel.edu. + +Thank you for your help ! + Dave Mills + Frank Kardel + Piete Brooks + +Open issues: + +HPUX: + - Time warp + During the last few month disturbing reports about xntp setting + preposterous times during periods of high load have been reported + on HPUX 8 and 9. The theory is that the adjtimed message queue + gets deleted. Symptoms are that xntp() complains about interrupted + system calls in adjtime()-emulation and the time is set to some + invalid date. Also the adjtimed seems to have problems. We could + need some help here by an experienced HPUX guru. + Files affected: adjtime/* + +Apollo: + - terminal affiliation + Check whether thing are still correct in respect to breaking + terminal affiliation - horrible stories are told in the code. + File affected: xntpd/ntpd.c diff --git a/usr.sbin/xntpd/VERSION b/usr.sbin/xntpd/VERSION new file mode 100644 index 000000000000..80868e3ba5fb --- /dev/null +++ b/usr.sbin/xntpd/VERSION @@ -0,0 +1 @@ +version=3.3b (beta) diff --git a/usr.sbin/xntpd/adjtime/Makefile.tmpl b/usr.sbin/xntpd/adjtime/Makefile.tmpl new file mode 100644 index 000000000000..c2e8381165b8 --- /dev/null +++ b/usr.sbin/xntpd/adjtime/Makefile.tmpl @@ -0,0 +1,53 @@ +######################################################################### +## (c) Copyright 1988, Hewlett-Packard Co. All Rights Reserved. ## +## ## +## Author: Tai Jin, Hewlett-Packard Laboratories. ## +######################################################################### + +## Makefile.tmpl,v 3.1 1993/07/06 01:04:40 jbj Exp + +# +PROGRAM = adjtimed +COMPILER= cc +CC= $(COMPILER) +BINDIR= /usr/local/etc +COPTS= -O +DEFS= +DEFS_OPT= +DEFS_LOCAL= +INCL= -I../include +LLIBS= +INSTALL= install + + +CFLAGS= $(COPTS) $(DEFS) $(DEFS_LOCAL) $(INCL) +CC= $(COMPILER) +LDFLAGS= +LIBS= $(LLIBS) -lc +OBJ= adjtime.o adjtimed.o +ALL= libadjtime.a adjtimed + +all: $(ALL) + +libadjtime.a: adjtime.o + ar vr libadjtime.a $? + +adjtimed: adjtimed.o ../lib/libntp.a + $(CC) $(LDFLAGS) -o adjtimed adjtimed.o ../lib/libntp.a $(LIBS) + +../lib/libntp.a: + cd ../lib && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" MAKE="$(MAKE)" + +install: $(BINDIR)/$(PROGRAM) + +$(BINDIR)/$(PROGRAM): $(PROGRAM) + $(INSTALL) -c -m 0755 $(PROGRAM) $(BINDIR) + +clean: + -@rm -f *.a *.o adjtimed + +distclean: clean + -@rm -f *.orig *.rej .version Makefile + +install: $(PROGRAM) + cp $(PROGRAM) $(BINDIR) diff --git a/usr.sbin/xntpd/adjtime/README b/usr.sbin/xntpd/adjtime/README new file mode 100644 index 000000000000..fe8b7e51e78a --- /dev/null +++ b/usr.sbin/xntpd/adjtime/README @@ -0,0 +1,23 @@ +------------------------------------------------------------------------------ +The adjtimed daemon emulates the BSD adjtime(2) system call. The +adjtime() routine communicates with this daemon via SYSV messages. + +The emulation uses an undocumented kernel variable (as of 6.0/2.0 +and later releases) and as such it cannot be guaranteed to work in +future HP-UX releases. Perhaps HP-UX will have a real adjtime(2) +system call in the future. + +Author: Tai Jin (tai@sde.hp.com) +------------------------------------------------------------------------------ + +IMPORTANT NOTE: This stuff must be compiled with no optimization !! + +NOTE: This code is known to work as of 8.0 on s300's, s700's and s800's. + PLEASE do not modify it unless you have access to kernel sources + and fully understand the implications of any changes you are making. + One person already has trashed adjtimed by making it do "the right + thing". This is not an exact replacement for BSD adjtime(2), don't + try to make it into one. + + -- Ken + diff --git a/usr.sbin/xntpd/adjtime/adjtime.c b/usr.sbin/xntpd/adjtime/adjtime.c new file mode 100644 index 000000000000..5b0475e1d31b --- /dev/null +++ b/usr.sbin/xntpd/adjtime/adjtime.c @@ -0,0 +1,101 @@ +/*************************************************************************/ +/* (c) Copyright Tai Jin, 1988. All Rights Reserved. */ +/* Hewlett-Packard Laboratories. */ +/* */ +/* Permission is hereby granted for unlimited modification, use, and */ +/* distribution. This software is made available with no warranty of */ +/* any kind, express or implied. This copyright notice must remain */ +/* intact in all versions of this software. */ +/* */ +/* The author would appreciate it if any bug fixes and enhancements were */ +/* to be sent back to him for incorporation into future versions of this */ +/* software. Please send changes to tai@iag.hp.com or ken@sdd.hp.com. */ +/*************************************************************************/ + +#ifndef lint +static char RCSid[] = "adjtime.c,v 3.1 1993/07/06 01:04:42 jbj Exp"; +#endif + +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <time.h> +#include <signal.h> +#include "adjtime.h" + +#define abs(x) ((x) < 0 ? -(x) : (x)) +static LONG adjthresh = 400L; +static LONG saveup; + + +_clear_adjtime() +{ + saveup = 0L; +} + + +adjtime(delta, olddelta) + register struct timeval *delta; + register struct timeval *olddelta; +{ + struct timeval newdelta; + + /* If they are giving us seconds, ignore up to current threshold saved */ + if (delta->tv_sec) { + saveup = 0L; + return(_adjtime(delta, olddelta)); + } + + /* add in, needs check for overflow ? */ + saveup += delta->tv_usec; + + /* Broke the threshold, call adjtime() */ + if (abs(saveup) > adjthresh) { + newdelta.tv_sec = 0L; + newdelta.tv_usec = saveup; + saveup = 0L; + return(_adjtime(&newdelta, olddelta)); + } + + if (olddelta) + olddelta->tv_sec = olddelta->tv_usec = 0L; + return(0); +} + + +_adjtime(delta, olddelta) + register struct timeval *delta; + register struct timeval *olddelta; +{ + register int mqid; + MsgBuf msg; + register MsgBuf *msgp = &msg; + + /* + * get the key to the adjtime message queue + * (note that we must get it every time because the queue might have been + * removed and recreated) + */ + if ((mqid = msgget(KEY, 0)) == -1) + return (-1); + + msgp->msgb.mtype = CLIENT; + msgp->msgb.tv = *delta; + + if (olddelta) + msgp->msgb.code = DELTA2; + else + msgp->msgb.code = DELTA1; + + if (msgsnd(mqid, &msgp->msgp, MSGSIZE, 0) == -1) + return (-1); + + if (olddelta) { + if (msgrcv(mqid, &msgp->msgp, MSGSIZE, SERVER, 0) == -1) + return (-1); + + *olddelta = msgp->msgb.tv; + } + + return (0); +} diff --git a/usr.sbin/xntpd/adjtime/adjtime.h b/usr.sbin/xntpd/adjtime/adjtime.h new file mode 100644 index 000000000000..f063a4777bf1 --- /dev/null +++ b/usr.sbin/xntpd/adjtime/adjtime.h @@ -0,0 +1,63 @@ +/*************************************************************************/ +/* (c) Copyright Tai Jin, 1988. All Rights Reserved. */ +/* Hewlett-Packard Laboratories. */ +/* */ +/* Permission is hereby granted for unlimited modification, use, and */ +/* distribution. This software is made available with no warranty of */ +/* any kind, express or implied. This copyright notice must remain */ +/* intact in all versions of this software. */ +/* */ +/* The author would appreciate it if any bug fixes and enhancements were */ +/* to be sent back to him for incorporation into future versions of this */ +/* software. Please send changes to tai@iag.hp.com or ken@sdd.hp.com. */ +/*************************************************************************/ + +/* "adjtime.h,v 3.1 1993/07/06 01:04:43 jbj Exp" */ +/* adjtime.h,v + * Revision 3.1 1993/07/06 01:04:43 jbj + * XNTP release 3.1 + * + * + * Revision 1.5 90/02/07 15:34:18 15:34:18 src (Source Hacker) + * CHANGED KEY !!! + * + * Revision 1.4 89/02/09 12:26:35 12:26:35 tai (Tai Jin (Guest)) + * *** empty log message *** + * + * Revision 1.4 89/02/09 12:26:35 12:26:35 tai (Tai Jin) + * added comment + * + * Revision 1.3 88/08/30 01:08:29 01:08:29 tai (Tai Jin) + * fix copyright notice again + * + * Revision 1.2 88/08/30 00:51:55 00:51:55 tai (Tai Jin) + * fix copyright notice + * + * Revision 1.1 88/04/02 14:56:54 14:56:54 tai (Tai Jin) + * Initial revision + * */ + +#include "ntp_types.h" + +#define KEY 659847L + +typedef union { + struct msgbuf msgp; + struct { + LONG mtype; + int code; + struct timeval tv; + } msgb; +} MsgBuf; + +#define MSGSIZE (sizeof(int) + sizeof(struct timeval)) +/* + * mtype values + */ +#define CLIENT 1L +#define SERVER 2L +/* + * code values + */ +#define DELTA1 0 +#define DELTA2 1 diff --git a/usr.sbin/xntpd/adjtime/adjtimed.c b/usr.sbin/xntpd/adjtime/adjtimed.c new file mode 100644 index 000000000000..f2de6921cf34 --- /dev/null +++ b/usr.sbin/xntpd/adjtime/adjtimed.c @@ -0,0 +1,485 @@ +/*************************************************************************/ +/* (c) Copyright Tai Jin, 1988. All Rights Reserved. */ +/* Hewlett-Packard Laboratories. */ +/* */ +/* Permission is hereby granted for unlimited modification, use, and */ +/* distribution. This software is made available with no warranty of */ +/* any kind, express or implied. This copyright notice must remain */ +/* intact in all versions of this software. */ +/* */ +/* The author would appreciate it if any bug fixes and enhancements were */ +/* to be sent back to him for incorporation into future versions of this */ +/* software. Please send changes to tai@iag.hp.com or ken@sdd.hp.com. */ +/*************************************************************************/ + +#ifndef lint +static char RCSid[] = "adjtimed.c,v 3.1 1993/07/06 01:04:45 jbj Exp"; +#endif + +/* + * Adjust time daemon. + * This deamon adjusts the rate of the system clock a la BSD's adjtime(). + * The adjtime() routine uses SYSV messages to communicate with this daemon. + * + * Caveat: This emulation uses an undocumented kernel variable. As such, it + * cannot be guaranteed to work in future HP-UX releases. Perhaps a real + * adjtime(2) will be supported in the future. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <time.h> +#include <signal.h> +#include <nlist.h> +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> +#include "ntp_syslog.h" +#include "adjtime.h" + +double atof(); +extern int optind; +extern char *optarg; + +int InitClockRate(); +int AdjustClockRate(); +#ifdef notdef +LONG GetClockRate(); +#endif +int SetClockRate(); +void ResetClockRate(); +void Cleanup(); +void Exit(); + +#define MILLION 1000000L + +#define tvtod(tv) ((double)(LONG)tv.tv_sec + \ + ((double)tv.tv_usec / (double)MILLION)) + +char *progname = NULL; +int verbose = 0; +int sysdebug = 0; +static int mqid; +static double oldrate = 0.0; +static double RATE = 0.25; +static double PERIOD = 6.666667; + + +main(argc, argv) + int argc; + char **argv; +{ + struct timeval remains; + struct sigvec vec; + MsgBuf msg; + char ch; + int nofork = 0; + int fd; + + progname = argv[0]; + + openlog("adjtimed", LOG_PID, LOG_LOCAL6); + + while ((ch = getopt(argc, argv, "hkrvdfp:")) != EOF) { + switch (ch) { + case 'k': + case 'r': + if ((mqid = msgget(KEY, 0)) != -1) { + if (msgctl(mqid, IPC_RMID, (struct msqid_ds *)0) == -1) { + syslog(LOG_ERR, "remove old message queue: %m"); + perror("adjtimed: remove old message queue"); + exit(1); + } + } + + if (ch == 'k') + exit(0); + + break; + + case 'v': + ++verbose, nofork = 1; + break; + + case 'd': + ++sysdebug; + break; + + case 'f': + nofork = 1; + break; + + case 'p': + if ((RATE = atof(optarg)) <= 0.0 || RATE >= 100.0) { + fputs("adjtimed: percentage must be between 0.0 and 100.0\n", stderr); + exit(1); + } + + RATE /= 100.0; + PERIOD = 1.0 / RATE; + break; + + default: + puts("usage: adjtimed -hkrvdf -p rate"); + puts("-h\thelp"); + puts("-k\tkill existing adjtimed, if any"); + puts("-r\trestart (kills existing adjtimed, if any)"); + puts("-v\tdebug output (repeat for more output)"); + puts("-d\tsyslog output (repeat for more output)"); + puts("-f\tno fork"); + puts("-p rate\tpercent rate of change"); + syslog(LOG_ERR, "usage error"); + exit(1); + } /* switch */ + } /* while */ + + if (!nofork) { + switch (fork()) { + case 0: + close(fileno(stdin)); + close(fileno(stdout)); + close(fileno(stderr)); + +#ifdef TIOCNOTTY + if ((fd = open("/dev/tty")) != -1) { + ioctl(fd, TIOCNOTTY, 0); + close(fd); + } +#else + setpgrp(); +#endif + break; + + case -1: + syslog(LOG_ERR, "fork: %m"); + perror("adjtimed: fork"); + exit(1); + + default: + exit(0); + } /* switch */ + } /* if */ + + if (nofork) { + setvbuf(stdout, NULL, _IONBF, BUFSIZ); + setvbuf(stderr, NULL, _IONBF, BUFSIZ); + } + + syslog(LOG_INFO, "started (rate %.2f%%)", RATE * 100.0); + if (verbose) printf("adjtimed: started (rate %.2f%%)\n", RATE * 100.0); + + if (InitClockRate() == -1) + Exit(2); + + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGQUIT, SIG_IGN); + (void)signal(SIGTERM, Cleanup); + + vec.sv_handler = ResetClockRate; + vec.sv_flags = 0; + vec.sv_mask = ~0; + sigvector(SIGALRM, &vec, (struct sigvec *)0); + + if (msgget(KEY, IPC_CREAT|IPC_EXCL) == -1) { + if (errno == EEXIST) { + syslog(LOG_ERR, "message queue already exists, use -r to remove it"); + fputs("adjtimed: message queue already exists, use -r to remove it\n", + stderr); + Exit(1); + } + + syslog(LOG_ERR, "create message queue: %m"); + perror("adjtimed: create message queue"); + Exit(1); + } + + if ((mqid = msgget(KEY, 0)) == -1) { + syslog(LOG_ERR, "get message queue id: %m"); + perror("adjtimed: get message queue id"); + Exit(1); + } + + for (;;) { + if (msgrcv(mqid, &msg.msgp, MSGSIZE, CLIENT, 0) == -1) { + if (errno == EINTR) continue; + syslog(LOG_ERR, "read message: %m"); + perror("adjtimed: read message"); + Cleanup(); + } + + switch (msg.msgb.code) { + case DELTA1: + case DELTA2: + AdjustClockRate(&msg.msgb.tv, &remains); + + if (msg.msgb.code == DELTA2) { + msg.msgb.tv = remains; + msg.msgb.mtype = SERVER; + + while (msgsnd(mqid, &msg.msgp, MSGSIZE, 0) == -1) { + if (errno == EINTR) continue; + syslog(LOG_ERR, "send message: %m"); + perror("adjtimed: send message"); + Cleanup(); + } + } + + if (remains.tv_sec + remains.tv_usec != 0L) { + if (verbose) { + printf("adjtimed: previous correction remaining %.6fs\n", + tvtod(remains)); + } + if (sysdebug) { + syslog(LOG_INFO, "previous correction remaining %.6fs", + tvtod(remains)); + } + } + break; + + default: + fprintf(stderr, "adjtimed: unknown message code %d\n", msg.msgb.code); + syslog(LOG_ERR, "unknown message code %d", msg.msgb.code); + } /* switch */ + } /* loop */ +} /* main */ + +/* + * Default clock rate (old_tick). + */ +#define DEFAULT_RATE (MILLION / HZ) +#define UNKNOWN_RATE 0L +#define SLEW_RATE (MILLION / DEFAULT_RATE) +#define MIN_DELTA SLEW_RATE +/* +#define RATE 0.005 +#define PERIOD (1.0 / RATE) +*/ +static LONG default_rate = DEFAULT_RATE; +static LONG slew_rate = SLEW_RATE; + +AdjustClockRate(delta, olddelta) + register struct timeval *delta, *olddelta; +{ + register LONG rate, dt; + struct itimerval period, remains; + static LONG leftover = 0; +/* + * rate of change + */ + dt = (delta->tv_sec * MILLION) + delta->tv_usec + leftover; + + if (dt < MIN_DELTA && dt > -MIN_DELTA) { + leftover += delta->tv_usec; + + if (olddelta) { + getitimer(ITIMER_REAL, &remains); + dt = ((remains.it_value.tv_sec * MILLION) + remains.it_value.tv_usec) * + oldrate; + olddelta->tv_sec = dt / MILLION; + olddelta->tv_usec = dt - (olddelta->tv_sec * MILLION); + } + + if (verbose > 2) printf("adjtimed: delta is too small: %dus\n", dt); + if (sysdebug > 2) syslog(LOG_INFO, "delta is too small: %dus", dt); + return (1); + } + + leftover = dt % MIN_DELTA; + dt -= leftover; + + if (verbose) + printf("adjtimed: new correction %.6fs\n", (double)dt / (double)MILLION); + if (sysdebug) + syslog(LOG_INFO, "new correction %.6fs", (double)dt / (double)MILLION); + if (verbose > 2) printf("adjtimed: leftover %dus\n", leftover); + if (sysdebug > 2) syslog(LOG_INFO, "leftover %dus", leftover); + rate = dt * RATE; + + if (rate < slew_rate && rate > -slew_rate) { + rate = (rate < 0L ? -slew_rate : slew_rate); + dt = abs(dt * (MILLION / slew_rate)); + period.it_value.tv_sec = dt / MILLION; + } else { + period.it_value.tv_sec = (LONG)PERIOD; + } +/* + * The adjustment will always be a multiple of the minimum adjustment. + * So the period will always be a whole second value. + */ + period.it_value.tv_usec = 0; + + if (verbose > 1) + printf("adjtimed: will be complete in %ds\n", period.it_value.tv_sec); + if (sysdebug > 1) + syslog(LOG_INFO, "will be complete in %ds", period.it_value.tv_sec); +/* + * adjust the clock rate + */ + if (SetClockRate((rate / slew_rate) + default_rate) == -1) { + syslog(LOG_ERR, "set clock rate: %m"); + perror("adjtimed: set clock rate"); + } +/* + * start the timer + * (do this after changing the rate because the period has been rounded down) + */ + period.it_interval.tv_sec = period.it_interval.tv_usec = 0L; + setitimer(ITIMER_REAL, &period, &remains); +/* + * return old delta + */ + if (olddelta) { + dt = ((remains.it_value.tv_sec * MILLION) + remains.it_value.tv_usec) * + oldrate; + olddelta->tv_sec = dt / MILLION; + olddelta->tv_usec = dt - (olddelta->tv_sec * MILLION); + } + + oldrate = (double)rate / (double)MILLION; +} /* AdjustClockRate */ + +static struct nlist nl[] = { +#ifdef hp9000s800 +#ifdef PRE7_0 + { "tick" }, +#else + { "old_tick" }, +#endif +#else + { "_old_tick" }, +#endif + { "" } +}; + +static int kmem; + +/* + * The return value is the clock rate in old_tick units or -1 if error. + */ +LONG +GetClockRate() +{ + LONG rate, mask; + + if (lseek(kmem, (LONG)nl[0].n_value, 0) == -1L) + return (-1L); + + mask = sigblock(sigmask(SIGALRM)); + + if (read(kmem, (caddr_t)&rate, sizeof(rate)) != sizeof(rate)) + rate = UNKNOWN_RATE; + + sigsetmask(mask); + return (rate); +} /* GetClockRate */ + +/* + * The argument is the new rate in old_tick units. + */ +SetClockRate(rate) + LONG rate; +{ + LONG mask; + + if (lseek(kmem, (LONG)nl[0].n_value, 0) == -1L) + return (-1); + + mask = sigblock(sigmask(SIGALRM)); + + if (write(kmem, (caddr_t)&rate, sizeof(rate)) != sizeof(rate)) { + sigsetmask(mask); + return (-1); + } + + sigsetmask(mask); + + if (rate != default_rate) { + if (verbose > 3) { + printf("adjtimed: clock rate (%lu) %ldus/s\n", rate, + (rate - default_rate) * slew_rate); + } + if (sysdebug > 3) { + syslog(LOG_INFO, "clock rate (%lu) %ldus/s", rate, + (rate - default_rate) * slew_rate); + } + } + + return (0); +} /* SetClockRate */ + +InitClockRate() +{ + if ((kmem = open("/dev/kmem", O_RDWR)) == -1) { + syslog(LOG_ERR, "open(/dev/kmem): %m"); + perror("adjtimed: open(/dev/kmem)"); + return (-1); + } + + nlist("/hp-ux", nl); + + if (nl[0].n_type == 0) { + fputs("adjtimed: /hp-ux has no symbol table\n", stderr); + syslog(LOG_ERR, "/hp-ux has no symbol table"); + return (-1); + } +/* + * Set the default to the system's original value + */ + default_rate = GetClockRate(); + if (default_rate == UNKNOWN_RATE) default_rate = DEFAULT_RATE; + slew_rate = (MILLION / default_rate); + + return (0); +} /* InitClockRate */ + +/* + * Reset the clock rate to the default value. + */ +void +ResetClockRate() +{ + struct itimerval it; + + it.it_value.tv_sec = it.it_value.tv_usec = 0L; + setitimer(ITIMER_REAL, &it, (struct itimerval *)0); + + if (verbose > 2) puts("adjtimed: resetting the clock"); + if (sysdebug > 2) syslog(LOG_INFO, "resetting the clock"); + + if (GetClockRate() != default_rate) { + if (SetClockRate(default_rate) == -1) { + syslog(LOG_ERR, "set clock rate: %m"); + perror("adjtimed: set clock rate"); + } + } + + oldrate = 0.0; +} /* ResetClockRate */ + +void +Cleanup() +{ + ResetClockRate(); + + if (msgctl(mqid, IPC_RMID, (struct msqid_ds *)0) == -1) { + if (errno != EINVAL) { + syslog(LOG_ERR, "remove message queue: %m"); + perror("adjtimed: remove message queue"); + } + } + + Exit(2); +} /* Cleanup */ + +void +Exit(status) + int status; +{ + syslog(LOG_ERR, "terminated"); + closelog(); + if (kmem != -1) close(kmem); + exit(status); +} /* Exit */ diff --git a/usr.sbin/xntpd/authstuff/Makefile.tmpl b/usr.sbin/xntpd/authstuff/Makefile.tmpl new file mode 100644 index 000000000000..e5f0310eb330 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/Makefile.tmpl @@ -0,0 +1,92 @@ +# +# Makefile.tmpl,v 3.1 1993/07/06 01:04:48 jbj Exp +# +PROGRAM= authcert authspeed md5 +# +# authcert, authspeed - authentication utilities +# +COMPILER= cc +COPTS= -O +BINDIR= /usr/local +DEFS= +DEFS_OPT= +DEFS_LOCAL= +COMPAT= +RESLIB= +# +INCL= -I../include +CFLAGS= $(COPTS) $(DEFS) $(DEFS_LOCAL) $(INCL) +CC= $(COMPILER) +LIB= ../lib/libntp.a +MAKE= make +# +CRTOBJS= authcert.o +SPDOBJS= authspeed.o +PAROBJS= keyparity.o +IFPOBJS= makeIPFP.o +PC1OBJS= makePC1.o +PC2OBJS= makePC2.o +SPOBJS= makeSP.o +RNDOBJS= mkrandkeys.o +OIFOBJS= omakeIPFP.o +UNXOBJS= unixcert.o +MD5OBJS= md5driver.o + +SOURCE= authcert.c authspeed.c keyparity.c makeIPFP.c makePC1.c \ + makePC2.c makeSP.c mkrandkeys.c omakeIPFP.c unixcert.c md5driver.c + +all: $(PROGRAM) + +authcert: $(CRTOBJS) $(LIB) + $(CC) $(COPTS) -o $@ $(CRTOBJS) $(LIB) + +authspeed: $(SPDOBJS) $(LIB) + $(CC) $(COPTS) -o $@ $(SPDOBJS) $(LIB) $(COMPAT) $(RESLIB) + +keyparity: $(PAROBJS) $(LIB) + $(CC) $(COPTS) -o $@ $(PAROBJS) $(LIB) + +makeIPFP: $(IFPOBJS) + $(CC) $(COPTS) -o $@ $(IFPOBJS) + +makePC1: $(PC1OBJS) + $(CC) $(COPTS) -o $@ $(PC1OBJS) + +makePC2: $(PC2OBJS) + $(CC) $(COPTS) -o $@ $(PC2OBJS) + +makeSP: $(SPOBJS) + $(CC) $(COPTS) -o $@ $(SPOBJS) + +mkrandkeys: $(RNDOBJS) $(LIB) + $(CC) $(COPTS) -o $@ $(RNDOBJS) $(LIB) + +omakeIPFP: $(OIFBJS) + $(CC) $(COPTS) -o $@ $(OIFBJS) + +unixcert: $(UNXBJS) + $(CC) $(COPTS) -o $@ $(UNXBJS) + +md5: $(MD5OBJS) + $(CC) $(COPTS) -o $@ $(MD5OBJS) $(LIB) + +tags: + ctags *.c *.h + +install: + # Don't install any of this shit + +depend: + mkdep $(CFLAGS) $(SOURCE) + +clean: + -@rm -f $(PROGRAM) *.o *.out tags make.log Makefile.bak keyparity \ + makeIPFP makePC1 makePC2 makeSP mkrandkeys omakeIPFP unixcert \ + lint.errs md5cert + +distclean: clean + -@rm -f *.orig *.rej .version Makefile + +../lib/libntp.a: + cd ../lib && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" + diff --git a/usr.sbin/xntpd/authstuff/README b/usr.sbin/xntpd/authstuff/README new file mode 100644 index 000000000000..2985751cc0c0 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/README @@ -0,0 +1,13 @@ +README file for directory ./authstuff of the NTP Version 3 distribution + +This directory contains the sources for miscellaneous programs to test, +validate and calibreate cryptographic routines used by NTP. These include + +authcert.c used to certify the DES and MD5 message digest algorithms + work properly. See the source for directions for use. + +authspeed.c used to determing the running time for DES and MD5 + messge digest algorithms. See the source for directions + for use. + +For other programs, see the source files. diff --git a/usr.sbin/xntpd/authstuff/auth.samplekeys b/usr.sbin/xntpd/authstuff/auth.samplekeys new file mode 100644 index 000000000000..c46d283405f2 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/auth.samplekeys @@ -0,0 +1,45 @@ +# auth.samplekeys,v 3.1 1993/07/06 01:04:49 jbj Exp +# +# Sample key file, also used for testing. +# +# Note that there are three formats for keys. Standard format is a +# hex format with the low order bit of each byte being a parity +# bit, a la the NBS standard. NTP format is also hex, but uses the +# high order bit of each byte for parity. Ascii format simply encodes +# a 1-8 character ascii string as a key. Note that because of the +# simple tokenizing routine, the characters ' ', '#', '\t', '\n' and +# '\0' can't be used in an ascii key. Everything else is fair game, though. +# + +1 S 0101010101010101 # odd parity 0 key +2 N 8080808080808080 # and again +3 A ugosnod +4 A BigbOObs +5 S f1f1f1f1f1f1f1f1 +6 N f8f8f8f8f8f8f8f8 # same as key 5 +7 S f8f8f8f8f8f8f8f8 # not same as key 6 +8 A a # short ascii keys are zero padded +9 A &^%$@!*( +10 S 01020407080bf1f1 +11 N 4040404040404040 +12 A more +13 A random +14 A keys +15 A password # 15 used as password by runtime configuration +# +16 M password # MD5 key +17 M secret +18 M key1 +19 M key2 +20 M foobar +21 M tick +22 M tock +23 M key23 +24 M key24 +25 M key25 +26 M a +27 M few +28 M more +29 M random +30 M md5 +31 M keys! diff --git a/usr.sbin/xntpd/authstuff/auth.speed b/usr.sbin/xntpd/authstuff/auth.speed new file mode 100644 index 000000000000..b55f20cbd821 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/auth.speed @@ -0,0 +1,20 @@ +Authentication delays (us) DES MD5 +DEC 3000/400 OSF/1 bunnylou 14 35 +HP9000/735 hpux9.0 na 30 +HP9000/730 hpux8.07(+OV) 16 55 +SGI Indigo R4000 19 48 +HP9000/720 hpux8.07 21 66 +SGI 4/35 38 110 +DECstation 5000/240 cowbird 39 81 +Sun4c/75 SS2 43 96 +Sun4c/50 IPX malarky 47 94 +DECstation 5000/33 sundeck 49 106 +SGI Indigo 54 115 +DECstation 5000/125 herald 63 136 +Sun4c/65 SS1+ pogo 72 159 +Sun4c/40 IPC grundoon 73 163 +Sun4c/60 SS1 albert 95 199 +Sun4c/20 SLC 95 203 +DECstation 3100 sheol 98 214 +DECstation 2100 circus 126 278 +VAX 780 985 ? diff --git a/usr.sbin/xntpd/authstuff/authcert.c b/usr.sbin/xntpd/authstuff/authcert.c new file mode 100644 index 000000000000..6f6e42c220c8 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/authcert.c @@ -0,0 +1,96 @@ +/* authcert.c,v 3.1 1993/07/06 01:04:52 jbj Exp + * This file, and the certdata file, shamelessly stolen + * from Phil Karn's DES implementation. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#define DES +#include "ntp_stdlib.h" + +u_char ekeys[128]; +u_char dkeys[128]; + +static void get8 P((U_LONG *)); +static void put8 P((U_LONG *)); + +void +main() +{ + U_LONG key[2], plain[2], cipher[2], answer[2]; + int i; + int test; + int fail; + + for(test=0;!feof(stdin);test++){ + get8(key); + DESauth_subkeys(key, ekeys, dkeys); + printf(" K: "); put8(key); + + get8(plain); + printf(" P: "); put8(plain); + + get8(answer); + printf(" C: "); put8(answer); + + + for(i=0;i<2;i++) + cipher[i] = htonl(plain[i]); + DESauth_des(cipher, ekeys); + + for(i=0;i<2;i++) + if(ntohl(cipher[i]) != answer[i]) + break; + fail = 0; + if(i != 2){ + printf(" Encrypt FAIL"); + fail++; + } + DESauth_des(cipher, dkeys); + for(i=0;i<2;i++) + if(ntohl(cipher[i]) != plain[i]) + break; + if(i != 2){ + printf(" Decrypt FAIL"); + fail++; + } + if(fail == 0) + printf(" OK"); + printf("\n"); + } +} + +static void +get8(lp) +U_LONG *lp; +{ + int t; + U_LONG l[2]; + int i; + + l[0] = l[1] = 0L; + for(i=0;i<8;i++){ + scanf("%2x",&t); + if(feof(stdin)) + exit(0); + l[i/4] <<= 8; + l[i/4] |= (U_LONG)(t & 0xff); + } + *lp = l[0]; + *(lp+1) = l[1]; +} + +static void +put8(lp) +U_LONG *lp; +{ + int i; + + + for(i=0;i<2;i++){ + printf("%08x",*lp++); + } +} diff --git a/usr.sbin/xntpd/authstuff/authspeed.c b/usr.sbin/xntpd/authstuff/authspeed.c new file mode 100644 index 000000000000..05af1326d8ed --- /dev/null +++ b/usr.sbin/xntpd/authstuff/authspeed.c @@ -0,0 +1,315 @@ +/* authspeed.c,v 3.1 1993/07/06 01:04:54 jbj Exp + * authspeed - figure out how LONG it takes to do an NTP encryption + */ + +#if defined(SYS_HPUX) || defined(SYS_AUX3) || defined(SYS_AUX2) || defined(SOLARIS) || defined(SYS_SVR4) || defined(SYS_PTX) +#define FAKE_RUSAGE +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#ifdef FAKE_RUSAGE +#include <sys/param.h> +#include <sys/times.h> +#endif + +#include "ntp_fp.h" +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +#define DEFLOOPS -1 + +#define DEFDELAYLOOPS 20000 +#define DEFCOSTLOOPS 2000 + +char *progname; +int debug; + +struct timeval tstart, tend; +#ifdef FAKE_RUSAGE +struct tms rstart, rend; +#define getrusage(foo, t) times(t) +#define RUSAGE_SELF 0 +#else +struct rusage rstart, rend; +#endif + +l_fp dummy1, dummy2; +U_LONG dummy3; + +U_LONG pkt[15]; + +int totalcost = 0; +double rtime; +double vtime; + +int domd5 = 0; + +static void dodelay P((int)); +static void docheap P((int)); +static void docost P((int)); +static void subtime P((struct timeval *, struct timeval *, double *)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int loops; + int i; + int errflg = 0; + extern int optind; + extern char *optarg; + + progname = argv[0]; + loops = DEFLOOPS; + while ((c = getopt_l(argc, argv, "cdmn:")) != EOF) + switch (c) { + case 'c': + totalcost++; + break; + case 'd': + ++debug; + break; + case 'm': + domd5 = 16; /* offset into list of keys */ + break; + case 'n': + loops = atoi(optarg); + if (loops <= 0) { + (void) fprintf(stderr, + "%s: %s is unlikely to be a useful number of loops\n", + progname, optarg); + errflg++; + } + break; + default: + errflg++; + break; + } + if (errflg || optind == argc) { + (void) fprintf(stderr, + "usage: %s [-d] [-n loops] [ -c ] auth.samplekeys\n", + progname); + exit(2); + } + printf("Compute timing for "); + if (domd5) + printf("MD5"); + else + printf("DES"); + printf(" based authentication.\n"); + + init_auth(); + authreadkeys(argv[optind]); + for (i = 0; i < 16; i++) { + if (!auth_havekey(i + domd5)) { + errflg++; + (void) fprintf(stderr, "%s: key %d missing\n", + progname, i + domd5); + } + } + + if (errflg) { + (void) fprintf(stderr, + "%s: check syslog for errors, or use file with complete set of keys\n", + progname); + exit(1); + } + + if (loops == DEFLOOPS) { + if (totalcost) + loops = DEFCOSTLOOPS; + else + loops = DEFDELAYLOOPS; + } + + dummy1.l_ui = 0x80808080; + dummy1.l_uf = 0xffffff00; + dummy3 = 0x0aaaaaaa; + + for (i = 0; i < 12; i++) + pkt[i] = i * 0x22222; + + if (totalcost) { + if (totalcost > 1) + docheap(loops); + else + docost(loops); + } else { + dodelay(loops); + } + + printf("total real time: %.3f\n", rtime); + printf("total CPU time: %.3f\n", vtime); + if (totalcost) { + printf("real cost (in seconds): %.6f\n", + rtime/(double)loops); + printf("CPU cost (in seconds): %.6f\n", + vtime/(double)loops); + printf("\nThis includes the cost of a decryption plus the\n"); + printf("the cost of an encryption, i.e. the cost to process\n"); + printf("a single authenticated packet.\n"); + } else { + printf("authdelay in the configuration file\n"); + printf("real authentication delay: %.6f\n", + rtime/(double)loops); + printf("authentication delay in CPU time: %.6f\n", + vtime/(double)loops); + printf("\nThe CPU delay is probably the best bet for\n"); + printf("authdelay in the configuration file\n"); + } + exit(0); +} + + +/* + * dodelay - do the delay measurement + */ +static void +dodelay(loops) + int loops; +{ + double vtime1, rtime1, vtime2, rtime2; + register int loopcount; + /* + * If we're attempting to compute the cost of an auth2crypt() + * for first compute the total cost, then compute the + * cost of only doing the first step, auth1crypt(). What + * remains is the cost of auth2crypt. + */ + loopcount = loops; + (void) gettimeofday(&tstart, (struct timezone *)0); + (void) getrusage(RUSAGE_SELF, &rstart); + + while (loopcount-- > 0) { + auth1crypt((loops & 0xf) + domd5, pkt, 48); + L_ADDUF(&dummy1, dummy3); + auth2crypt((loops & 0xf) + domd5, pkt, 48); + } + + (void) getrusage(RUSAGE_SELF, &rend); + (void) gettimeofday(&tend, (struct timezone *)0); + + subtime(&tstart, &tend, &rtime1); +#ifdef FAKE_RUSAGE + vtime1 = (rend.tms_utime - rstart.tms_utime) * 1.0 / HZ; +#else + subtime(&rstart.ru_utime, &rend.ru_utime, &vtime1); +#endif +printf("Time for full encryptions is %f rusage %f real\n", vtime1, rtime1); + loopcount = loops; + (void) gettimeofday(&tstart, (struct timezone *)0); + (void) getrusage(RUSAGE_SELF, &rstart); + + while (loopcount-- > 0) { + auth1crypt((loops & 0xf) + domd5, pkt, 48); + } + + (void) getrusage(RUSAGE_SELF, &rend); + (void) gettimeofday(&tend, (struct timezone *)0); + + subtime(&tstart, &tend, &rtime2); +#ifdef FAKE_RUSAGE + vtime2 = (rend.tms_utime - rstart.tms_utime) * 1.0 / HZ; +#else + subtime(&rstart.ru_utime, &rend.ru_utime, &vtime2); +#endif + +printf("Time for auth1crypt is %f rusage %f real\n", vtime2, rtime2); + vtime = vtime1 - vtime2; + rtime = rtime1 - rtime2; +} + + +/* + * docheap - do the cost measurement the cheap way + */ +static void +docheap(loops) + register int loops; +{ + + (void) authhavekey(3 + domd5); + + (void) gettimeofday(&tstart, (struct timezone *)0); + (void) getrusage(RUSAGE_SELF, &rstart); + + while (loops-- > 0) { + auth1crypt(3 + domd5, pkt, 48); + L_ADDUF(&dummy1, dummy3); + auth2crypt(3 + domd5, pkt, 48); + (void) authdecrypt(3 + domd5, pkt, 48); + } + + (void) getrusage(RUSAGE_SELF, &rend); + (void) gettimeofday(&tend, (struct timezone *)0); + + subtime(&tstart, &tend, &rtime); +#ifdef FAKE_RUSAGE + vtime = (rend.tms_utime - rstart.tms_utime) * 1.0 / HZ; +#else + subtime(&rstart.ru_utime, &rend.ru_utime, &vtime); +#endif +} + + +/* + * docost - do the cost measurement + */ +static void +docost(loops) + register int loops; +{ + + (void) gettimeofday(&tstart, (struct timezone *)0); + (void) getrusage(RUSAGE_SELF, &rstart); + + while (loops-- > 0) { + auth1crypt((loops & 0xf) + domd5, pkt, 48); + L_ADDUF(&dummy1, dummy3); + auth2crypt((loops & 0xf) + domd5, pkt, 48); + (void) authdecrypt(((loops+1) & 0xf) + domd5, pkt, 48); + } + + (void) getrusage(RUSAGE_SELF, &rend); + (void) gettimeofday(&tend, (struct timezone *)0); + + subtime(&tstart, &tend, &rtime); +#ifdef FAKE_RUSAGE + vtime = (rend.tms_utime - rstart.tms_utime) * 1.0 / HZ; +#else + subtime(&rstart.ru_utime, &rend.ru_utime, &vtime); +#endif +} + + +/* + * subtime - subtract two struct timevals, return double result + */ +static void +subtime(tvs, tve, res) + struct timeval *tvs, *tve; + double *res; +{ + LONG sec; + LONG usec; + + sec = tve->tv_sec - tvs->tv_sec; + usec = tve->tv_usec - tvs->tv_usec; + + if (usec < 0) { + usec += 1000000; + sec--; + } + + *res = (double)sec + (double)usec/1000000.; + return; +} diff --git a/usr.sbin/xntpd/authstuff/certdata b/usr.sbin/xntpd/authstuff/certdata new file mode 100644 index 000000000000..f9a818efecb8 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/certdata @@ -0,0 +1,34 @@ +0000000000000000 0000000000000000 8CA64DE9C1B123A7 +FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58 +3000000000000000 1000000000000001 958E6E627A05557B +1111111111111111 1111111111111111 F40379AB9E0EC533 +0123456789ABCDEF 1111111111111111 17668DFC7292532D +1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD +0000000000000000 0000000000000000 8CA64DE9C1B123A7 +FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4 +7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B +0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 +07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A +3849674C2602319E 51454B582DDF440A 7178876E01F19B2A +04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 +0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B +0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 +43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A +07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F +04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 +37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 +1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A +584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 +025816164629B007 480D39006EE762F2 A1F9915541020B56 +49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 +4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC +49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A +018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 +1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 +0101010101010101 0123456789ABCDEF 617B3A0CE8F07100 +1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606 +E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7 +0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451 +FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE +0123456789ABCDEF 0000000000000000 D5D44FF720683D0D +FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2 diff --git a/usr.sbin/xntpd/authstuff/keyparity.c b/usr.sbin/xntpd/authstuff/keyparity.c new file mode 100644 index 000000000000..45a706173b43 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/keyparity.c @@ -0,0 +1,279 @@ +/* keyparity.c,v 3.1 1993/07/06 01:04:57 jbj Exp + * keyparity - add parity bits to key and/or change an ascii key to binary + */ + +#include <stdio.h> +#include <sys/types.h> +#include <ctype.h> + +#include "ntp_string.h" +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +/* + * Types of ascii representations for keys. "Standard" means a 64 bit + * hex number in NBS format, i.e. with the low order bit of each byte + * a parity bit. "NTP" means a 64 bit key in NTP format, with the + * high order bit of each byte a parity bit. "Ascii" means a 1-to-8 + * character string whose ascii representation is used as the key. + */ +#define KEY_TYPE_STD 1 +#define KEY_TYPE_NTP 2 +#define KEY_TYPE_ASCII 3 + +#define STD_PARITY_BITS 0x01010101 + +char *progname; +int debug; + +int ntpflag = 0; +int stdflag = 0; +int asciiflag = 0; +int ntpoutflag = 0; +int gotoopt = 0; + +static int parity P((U_LONG *)); +static int decodekey P((int, char *, U_LONG *)); +static void output P((U_LONG *, int)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + int keytype; + U_LONG key[2]; + extern int optind; + extern char *optarg; + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "adno:s")) != EOF) + switch (c) { + case 'a': + asciiflag = 1; + break; + case 'd': + ++debug; + break; + case 'n': + ntpflag = 1; + break; + case 's': + stdflag = 1; + break; + case 'o': + if (*optarg == 'n') { + ntpoutflag = 1; + gotoopt = 1; + } else if (*optarg == 's') { + ntpoutflag = 0; + gotoopt = 1; + } else { + (void) fprintf(stderr, + "%s: output format must be `n' or `s'\n", + progname); + errflg++; + } + break; + default: + errflg++; + break; + } + if (errflg || optind == argc) { + (void) fprintf(stderr, + "usage: %s -n|-s [-a] [-o n|s] key [...]\n", + progname); + exit(2); + } + + if (!ntpflag && !stdflag) { + (void) fprintf(stderr, + "%s: one of either the -n or -s flags must be specified\n", + progname); + exit(2); + } + + if (ntpflag && stdflag) { + (void) fprintf(stderr, + "%s: only one of the -n and -s flags may be specified\n", + progname); + exit(2); + } + + if (!gotoopt) { + if (ntpflag) + ntpoutflag = 1; + } + + if (asciiflag) + keytype = KEY_TYPE_ASCII; + else if (ntpflag) + keytype = KEY_TYPE_NTP; + else + keytype = KEY_TYPE_STD; + + for (; optind < argc; optind++) { + if (!decodekey(keytype, argv[optind], key)) { + (void) fprintf(stderr, + "%s: format of key %s invalid\n", + progname, argv[optind]); + exit(1); + } + (void) parity(key); + output(key, ntpoutflag); + } + exit(0); +} + + + +/* + * parity - set parity on a key/check for odd parity + */ +static int +parity(key) + U_LONG *key; +{ + U_LONG mask; + int parity_err; + int bitcount; + int half; + int byte; + int i; + + /* + * Go through counting bits in each byte. Check to see if + * each parity bit was set correctly. If not, note the error + * and set it right. + */ + parity_err = 0; + for (half = 0; half < 2; half++) { /* two halves of key */ + mask = 0x80000000; + for (byte = 0; byte < 4; byte++) { /* 4 bytes per half */ + bitcount = 0; + for (i = 0; i < 7; i++) { /* 7 data bits / byte */ + if (key[half] & mask) + bitcount++; + mask >>= 1; + } + + /* + * If bitcount is even, parity must be set. If + * bitcount is odd, parity must be clear. + */ + if ((bitcount & 0x1) == 0) { + if (!(key[half] & mask)) { + parity_err++; + key[half] |= mask; + } + } else { + if (key[half] & mask) { + parity_err++; + key[half] &= ~mask; + } + } + mask >>= 1; + } + } + + /* + * Return the result of the parity check. + */ + return (parity_err == 0); +} + + +static int +decodekey(keytype, str, key) + int keytype; + char *str; + U_LONG *key; +{ + u_char keybytes[8]; + char *cp; + char *xdigit; + int len; + int i; + static char *hex = "0123456789abcdef"; + + cp = str; + len = strlen(cp); + if (len == 0) + return 0; + + switch(keytype) { + case KEY_TYPE_STD: + case KEY_TYPE_NTP: + if (len != 16) /* Lazy. Should define constant */ + return 0; + /* + * Decode hex key. + */ + key[0] = 0; + key[1] = 0; + for (i = 0; i < 16; i++) { + if (!isascii(*cp)) + return 0; + xdigit = strchr(hex, isupper(*cp) ? tolower(*cp) : *cp); + cp++; + if (xdigit == 0) + return 0; + key[i>>3] <<= 4; + key[i>>3] |= (U_LONG)(xdigit - hex) & 0xf; + } + + /* + * If this is an NTP format key, put it into NBS format + */ + if (keytype == KEY_TYPE_NTP) { + for (i = 0; i < 2; i++) + key[i] = ((key[i] << 1) & ~STD_PARITY_BITS) + | ((key[i] >> 7) & STD_PARITY_BITS); + } + break; + + case KEY_TYPE_ASCII: + /* + * Make up key from ascii representation + */ + bzero(keybytes, sizeof(keybytes)); + for (i = 0; i < 8 && i < len; i++) + keybytes[i] = *cp++ << 1; + key[0] = keybytes[0] << 24 | keybytes[1] << 16 + | keybytes[2] << 8 | keybytes[3]; + key[1] = keybytes[4] << 24 | keybytes[5] << 16 + | keybytes[6] << 8 | keybytes[7]; + break; + + default: + /* Oh, well */ + return 0; + } + + return 1; +} + + +/* + * output - print a hex key on the standard output + */ +static void +output(key, ntpformat) + U_LONG *key; + int ntpformat; +{ + int i; + + if (ntpformat) { + for (i = 0; i < 2; i++) + key[i] = ((key[i] & ~STD_PARITY_BITS) >> 1) + | ((key[i] & STD_PARITY_BITS) << 7); + } + (void) printf("%08x%08x\n", key[0], key[1]); +} diff --git a/usr.sbin/xntpd/authstuff/makeIPFP.c b/usr.sbin/xntpd/authstuff/makeIPFP.c new file mode 100644 index 000000000000..51f8a55e7240 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/makeIPFP.c @@ -0,0 +1,345 @@ +/* makeIPFP.c,v 3.1 1993/07/06 01:04:58 jbj Exp + * makeIPFP - make fast DES IP and FP tables + */ + +#include <stdio.h> +#include <sys/types.h> + +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +U_LONG IPL[256]; +U_LONG FPL[256]; + +char *progname; +int debug; + +static void perm P((u_char *, u_char *, U_LONG *, U_LONG *)); +static void doit P((void)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + extern int optind; + extern char *optarg; + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "d")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + default: + errflg++; + break; + } + if (errflg) { + (void) fprintf(stderr, "usage: %s [-d]\n", progname); + exit(2); + } + doit(); + exit(0); +} + + +/* + * Initial permutation table + */ +u_char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +/* + * Inverse initial permutation table + */ +u_char FP[64] = { + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; + + +/* + * Bit order after the operation + * + * ((left & 0x55555555) << 1) | (right & 0x55555555) + */ +u_char IPLbits[32] = { + 2, 34, 4, 36, 6, 38, 8, 40, + 10, 42, 12, 44, 14, 46, 16, 48, + 18, 50, 20, 52, 22, 54, 24, 56, + 26, 58, 28, 60, 30, 62, 32, 64 +}; + + +/* + * Bit order after the operation + * + * (left & 0xaaaaaaaa) | ((right & 0xaaaaaaaa) >> 1) + */ +u_char IPRbits[32] = { + 1, 33, 3, 35, 5, 37, 7, 39, + 9, 41, 11, 43, 13, 45, 15, 47, + 17, 49, 19, 51, 21, 53, 23, 55, + 25, 57, 27, 59, 29, 61, 31, 63 +}; + + +/* + * Bit order after the operation + * + * ((left & 0x0f0f0f0f) << 4) | (right & 0x0f0f0f0f) + */ +u_char FPLbits[32] = { + 5, 6, 7, 8, 37, 38, 39, 40, + 13, 14, 15, 16, 45, 46, 47, 48, + 21, 22, 23, 24, 53, 54, 55, 56, + 29, 30, 31, 32, 61, 62, 63, 64 +}; + + +/* + * Bit order after the operation + * + * (left & 0xf0f0f0f0) | ((right & 0xf0f0f0f0) >> 4) + */ +u_char FPRbits[32] = { + 1, 2, 3, 4, 33, 34, 35, 36, + 9, 10, 11, 12, 41, 42, 43, 44, + 17, 18, 19, 20, 49, 50, 51, 52, + 25, 26, 27, 28, 57, 58, 59, 60 +}; + + +/* + * perm - do a permutation with the given table + */ +static void +perm(databits, permtab, leftp, rightp) + u_char *databits; + u_char *permtab; + U_LONG *leftp; + U_LONG *rightp; +{ + register U_LONG left; + register U_LONG right; + register u_char *PT; + register u_char *bits; + register int i; + + left = right = 0; + PT = permtab; + bits = databits; + + for (i = 0; i < 32; i++) { + left <<= 1; + if (bits[PT[i]-1]) + left |= 1; + } + + for (i = 32; i < 64; i++) { + right <<= 1; + if (bits[PT[i]-1]) + right |= 1; + } + + *leftp = left; + *rightp = right; +} + + +/* + * doit - make up the tables + */ +static void +doit() +{ + u_char bits[64]; + U_LONG left; + U_LONG right; + int tabno; + int i; + int ind0, ind1, ind2, ind3; + int ind4, ind5, ind6, ind7; + int octbits; + + bzero((char *)bits, sizeof bits); + + /* + * Do the rounds for the IP table. We save the results of + * this as well as printing them. Note that this is the + * left-half table, the right half table will be identical. + */ + printf("static U_LONG IP[256] = {"); + for (tabno = 0; tabno < 4; tabno++) { + i = tabno * 8; + ind7 = IPLbits[i] - 1; + ind6 = IPLbits[i+1] - 1; + ind5 = IPLbits[i+2] - 1; + ind4 = IPLbits[i+3] - 1; + ind3 = IPLbits[i+4] - 1; + ind2 = IPLbits[i+5] - 1; + ind1 = IPLbits[i+6] - 1; + ind0 = IPLbits[i+7] - 1; + for (octbits = 0; octbits < 256; octbits++) { + if (octbits & (1 << 7)) + bits[ind7] = 1; + if (octbits & (1 << 6)) + bits[ind6] = 1; + if (octbits & (1 << 5)) + bits[ind5] = 1; + if (octbits & (1 << 4)) + bits[ind4] = 1; + if (octbits & (1 << 3)) + bits[ind3] = 1; + if (octbits & (1 << 2)) + bits[ind2] = 1; + if (octbits & (1 << 1)) + bits[ind1] = 1; + if (octbits & 1) + bits[ind0] = 1; + perm(bits, IP, &left, &right); + bits[ind7] = 0; + bits[ind6] = 0; + bits[ind5] = 0; + bits[ind4] = 0; + bits[ind3] = 0; + bits[ind2] = 0; + bits[ind1] = 0; + bits[ind0] = 0; + if (right != 0) { + fprintf(stderr, + "IP tabno %d oct %d right not zero\n", + tabno, octbits); + exit(1); + } + if (tabno > 0) { + if ((IPL[octbits] << tabno) != left) { + fprintf(stderr, + "IP tabno %d oct %d IP %d left %d, IP != left\n", + tabno, octbits, IPL[octbits], left); + exit (1); + } + } else { + IPL[octbits] = left; + if (octbits == 255) { + printf(" 0x%08x", left); + } else if (octbits & 0x3) { + printf(" 0x%08x,", left); + } else { + printf("\n\t0x%08x,", left); + } + } + } + if (tabno == 0) + printf("\n};\n\n"); + } + + /* + * Next is the FP table, in big endian order + */ + printf("#if BYTE_ORDER == LITTLE_ENDIAN\nstatic U_LONG FP[256] = {"); + for (tabno = 3; tabno >= 0; tabno--) { + i = tabno * 8; + ind7 = FPLbits[i] - 1; + ind6 = FPLbits[i+1] - 1; + ind5 = FPLbits[i+2] - 1; + ind4 = FPLbits[i+3] - 1; + ind3 = FPLbits[i+4] - 1; + ind2 = FPLbits[i+5] - 1; + ind1 = FPLbits[i+6] - 1; + ind0 = FPLbits[i+7] - 1; + for (octbits = 0; octbits < 256; octbits++) { + if (octbits & (1 << 7)) + bits[ind7] = 1; + if (octbits & (1 << 6)) + bits[ind6] = 1; + if (octbits & (1 << 5)) + bits[ind5] = 1; + if (octbits & (1 << 4)) + bits[ind4] = 1; + if (octbits & (1 << 3)) + bits[ind3] = 1; + if (octbits & (1 << 2)) + bits[ind2] = 1; + if (octbits & (1 << 1)) + bits[ind1] = 1; + if (octbits & 1) + bits[ind0] = 1; + perm(bits, FP, &left, &right); + bits[ind7] = 0; + bits[ind6] = 0; + bits[ind5] = 0; + bits[ind4] = 0; + bits[ind3] = 0; + bits[ind2] = 0; + bits[ind1] = 0; + bits[ind0] = 0; + if (right != 0) { + fprintf(stderr, + "FP tabno %d oct %d right not zero\n", + tabno, octbits); + exit(1); + } + if (tabno != 3) { + if ((FPL[octbits] << ((3-tabno)<<1)) != left) { + fprintf(stderr, + "FP tabno %d oct %d FP %x left %x, FP != left\n", + tabno, octbits, FPL[octbits], left); + exit (1); + } + } else { + FPL[octbits] = left; + if (octbits == 255) { + printf(" 0x%08x", left); + } else if (octbits & 0x3) { + printf(" 0x%08x,", left); + } else { + printf("\n\t0x%08x,", left); + } + } + } + if (tabno == 3) + printf("\n};\n"); + } + + /* + * Now reouput the FP table in order appropriate for little + * endian machines + */ + printf("#else\nstatic U_LONG FP[256] = {"); + for (octbits = 0; octbits < 256; octbits++) { + left = ((FPL[octbits] >> 24) & 0x000000ff) + | ((FPL[octbits] >> 8) & 0x0000ff00) + | ((FPL[octbits] << 8) & 0x00ff0000) + | ((FPL[octbits] << 24) & 0xff000000); + if (octbits == 255) { + printf(" 0x%08x", left); + } else if (octbits & 0x3) { + printf(" 0x%08x,", left); + } else { + printf("\n\t0x%08x,", left); + } + } + printf("\n};\n#endif\n"); +} diff --git a/usr.sbin/xntpd/authstuff/makePC1.c b/usr.sbin/xntpd/authstuff/makePC1.c new file mode 100644 index 000000000000..c0109892fa10 --- /dev/null +++ b/usr.sbin/xntpd/authstuff/makePC1.c @@ -0,0 +1,286 @@ +/* makePC1.c,v 3.1 1993/07/06 01:04:59 jbj Exp + * makePC1 - build custom permutted choice 1 tables + */ + +#include <stdio.h> +#include <sys/types.h> + +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +char *progname; +int debug; + +static void permute P((u_char *, U_LONG *, U_LONG *)); +static void doit P((void)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + extern int optind; + extern char *optarg; + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "d")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + default: + errflg++; + break; + } + if (errflg) { + (void) fprintf(stderr, "usage: %s [-d]\n", progname); + exit(2); + } + doit(); + exit(0); +} + +/* + * Permuted choice 1 table, to produce the initial C. This table + * has had 1 subtracted from it to give it a zero base. + */ +static u_char PC1_C[28] = { + 56, 48, 40, 32, 24, 16, 8, + 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, + 18, 10, 2, 59, 51, 43, 35 +}; + +/* + * Permuted choice 1 table, to produce the initial D. Again, 1 has + * been subtracted to match C language zero base arrays. + */ +static u_char PC1_D[28] = { + 62, 54, 46, 38, 30, 22, 14, + 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, + 20, 12, 4, 27, 19, 11, 3 +}; + +/* + * permute - produce c and d for the given bits + */ +static void +permute(bits, cp, dp) + u_char *bits; + U_LONG *cp; + U_LONG *dp; +{ + register int i; + register U_LONG mask; + u_char c[28]; + u_char d[28]; + + bzero((char *)c, sizeof c); + bzero((char *)d, sizeof d); + + for (i = 0; i < 28; i++) { + c[i] = bits[PC1_C[i]]; + d[i] = bits[PC1_D[i]]; + } + + mask = 0x10000000; + *cp = *dp = 0; + for (i = 0; i < 28; i++) { + mask >>= 1; + if (c[i]) + *cp |= mask; + if (d[i]) + *dp |= mask; + } +} + + +/* + * bits from the left part of the key used to form the C subkey + */ +static int lc3[4] = { 0, 8, 16, 24 }; + +/* + * bits from the left part of the key used to form the D subkey + */ +static int ld4[4] = { 3, 11, 19, 27 }; + +/* + * bits from the right part of the key used to form the C subkey + */ +static int rc4[4] = { 32, 40, 48, 56 }; + +/* + * bits from the right part of the key used to form the D subkey + */ +static int rd3[4] = { 36, 44, 52, 60 }; + +static U_LONG PC_CL[8]; +static U_LONG PC_DL[16]; +static U_LONG PC_CR[16]; +static U_LONG PC_DR[8]; + + +/* + * doit - compute and print the four PC1 tables + */ +static void +doit() +{ + int i; + int comb; + U_LONG c; + U_LONG d; + u_char bits[64]; + + bzero((char *)bits, sizeof bits); + + printf("static U_LONG PC1_CL[8] = {"); + for (i = 0; i < 4; i++) { + for (comb = 0; comb < 8; comb++) { + if (comb & 0x4) + bits[lc3[i]] = 1; + if (comb & 0x2) + bits[lc3[i]+1] = 1; + if (comb & 0x1) + bits[lc3[i]+2] = 1; + permute(bits, &c, &d); + bits[lc3[i]] = 0; + bits[lc3[i]+1] = 0; + bits[lc3[i]+2] = 0; + if (d != 0) { + (void) fprintf(stderr, + "Error PC_CL i %d comb %d\n", i, comb); + } + if (i == 0) { + PC_CL[comb] = c; + if ((comb & 0x3) == 0) + printf("\n\t0x%08x,", c); + else if (comb == 7) + printf(" 0x%08x\n};\n\n", c); + else + printf(" 0x%08x,", c); + } else { + if (c != PC_CL[comb] << i) + (void) fprintf(stderr, + "Error PC_CL 0x%08x c 0x%08x\n", + PC_CL[comb], c); + } + } + } + + printf("static U_LONG PC1_DL[16] = {"); + for (i = 0; i < 4; i++) { + for (comb = 0; comb < 16; comb++) { + if (comb & 0x8) + bits[ld4[i]] = 1; + if (comb & 0x4) + bits[ld4[i]+1] = 1; + if (comb & 0x2) + bits[ld4[i]+2] = 1; + if (comb & 0x1) + bits[ld4[i]+3] = 1; + permute(bits, &c, &d); + bits[ld4[i]] = 0; + bits[ld4[i]+1] = 0; + bits[ld4[i]+2] = 0; + bits[ld4[i]+3] = 0; + if (c != 0) { + (void) fprintf(stderr, + "Error PC_DL i %d comb %d\n", i, comb); + } + if (i == 0) { + PC_DL[comb] = d; + if ((comb & 0x3) == 0) + printf("\n\t0x%08x,", d); + else if (comb == 15) + printf(" 0x%08x\n};\n\n", d); + else + printf(" 0x%08x,", d); + } else { + if (d != PC_DL[comb] << i) + (void) fprintf(stderr, + "Error PC_DL 0x%08x c 0x%08x\n", + PC_DL[comb], d); + } + } + } + + printf("static U_LONG PC1_CR[16] = {"); + for (i = 0; i < 4; i++) { + for (comb = 0; comb < 16; comb++) { + if (comb & 0x8) + bits[rc4[i]] = 1; + if (comb & 0x4) + bits[rc4[i]+1] = 1; + if (comb & 0x2) + bits[rc4[i]+2] = 1; + if (comb & 0x1) + bits[rc4[i]+3] = 1; + permute(bits, &c, &d); + bits[rc4[i]] = 0; + bits[rc4[i]+1] = 0; + bits[rc4[i]+2] = 0; + bits[rc4[i]+3] = 0; + if (d != 0) { + (void) fprintf(stderr, + "Error PC_CR i %d comb %d\n", i, comb); + } + if (i == 0) { + PC_CR[comb] = c; + if ((comb & 0x3) == 0) + printf("\n\t0x%08x,", c); + else if (comb == 15) + printf(" 0x%08x\n};\n\n", c); + else + printf(" 0x%08x,", c); + } else { + if (c != PC_CR[comb] << i) + (void) fprintf(stderr, + "Error PC_CR 0x%08x c 0x%08x\n", + PC_CR[comb], c); + } + } + } + + printf("static U_LONG PC1_DR[8] = {"); + for (i = 0; i < 4; i++) { + for (comb = 0; comb < 8; comb++) { + if (comb & 0x4) + bits[rd3[i]] = 1; + if (comb & 0x2) + bits[rd3[i]+1] = 1; + if (comb & 0x1) + bits[rd3[i]+2] = 1; + permute(bits, &c, &d); + bits[rd3[i]] = 0; + bits[rd3[i]+1] = 0; + bits[rd3[i]+2] = 0; + if (c != 0) { + (void) fprintf(stderr, + "Error PC_DR i %d comb %d\n", i, comb); + } + if (i == 0) { + PC_DR[comb] = d; + if ((comb & 0x3) == 0) + printf("\n\t0x%08x,", d); + else if (comb == 7) + printf(" 0x%08x\n};\n\n", d); + else + printf(" 0x%08x,", d); + } else { + if (d != PC_DR[comb] << i) + (void) fprintf(stderr, + "Error PC_DR 0x%08x c 0x%08x\n", + PC_DR[comb], d); + } + } + } +} diff --git a/usr.sbin/xntpd/authstuff/makePC2.c b/usr.sbin/xntpd/authstuff/makePC2.c new file mode 100644 index 000000000000..d92d2b2a9eaf --- /dev/null +++ b/usr.sbin/xntpd/authstuff/makePC2.c @@ -0,0 +1,238 @@ +/* makePC2.c,v 3.1 1993/07/06 01:05:01 jbj Exp + * makePC2 - build custom permutted choice 2 tables + */ + +#include <stdio.h> +#include <sys/types.h> + +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +char *progname; +int debug; + +static void permc P((u_char *, U_LONG *)); +static void permd P((u_char *, U_LONG *)); +static void doit P((void)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + extern int optind; + extern char *optarg; + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "d")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + default: + errflg++; + break; + } + if (errflg) { + (void) fprintf(stderr, "usage: %s [-d]\n", progname); + exit(2); + } + doit(); + exit(0); +} + +/* + * Permuted choice 2 table. This actually produces the low order 24 + * bits of the subkey Ki from the 28 bit value of Ci. This has had + * 1 subtracted from it to give a zero base. + */ +static u_char PC2_C[24] = { + 13, 16, 10, 23, 0, 4, + 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, + 15, 6, 26, 19, 12, 1 +}; + +/* + * Permuted choice 2 table, operating on the 28 Di bits to produce the + * high order 24 bits of subkey Ki. This has had 29 subtracted from + * it to give it a zero base into our D bit array. + */ +static u_char PC2_D[24] = { + 12, 23, 2, 8, 18, 26, + 1, 11, 22, 16, 4, 19, + 15, 20, 10, 27, 5, 24, + 17, 13, 21, 7, 0, 3 +}; + +U_LONG masks[4] = { 0x40000000, 0x400000, 0x4000, 0x40 }; + + +/* + * permc - permute C, producing a four byte result + */ +static void +permc(bits, resp) + u_char *bits; + U_LONG *resp; +{ + register int part; + register int i; + register U_LONG mask; + u_char res[24]; + + bzero((char *)res, sizeof res); + + for (i = 0; i < 24; i++) { + res[i] = bits[PC2_C[i]]; + } + + *resp = 0; + for (part = 0; part < 4; part++) { + mask = masks[part]; + for (i = part*6; i < (part+1)*6; i++) { + mask >>= 1; + if (res[i]) + *resp |= mask; + } + } +} + +/* + * permd - permute D, producing a four byte result + */ +static void +permd(bits, resp) + u_char *bits; + U_LONG *resp; +{ + register int part; + register int i; + register U_LONG mask; + u_char res[24]; + + bzero((char *)res, sizeof res); + + for (i = 0; i < 24; i++) { + res[i] = bits[PC2_D[i]]; + } + + *resp = 0; + for (part = 0; part < 4; part++) { + mask = masks[part]; + for (i = part*6; i < (part+1)*6; i++) { + mask >>= 1; + if (res[i]) + *resp |= mask; + } + } +} + + +/* + * bits used for each round in C + */ +static int cbits[4][6] = { + 0, 1, 2, 3, 4, 5, + 6, 7, 9, 10, 11, 12, + 13, 14, 15, 16, 22, 23, + 18, 19, 20, 25, 26, 27 +}; + + +/* + * bits used for each round in D + */ +static int dbits[4][6] = { + 0, 1, 2, 3, 4, 5, + 7, 8, 10, 11, 12, 13, + 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 26, 27 +}; + + +/* + * doit - compute and print the four PC1 tables + */ +static void +doit() +{ + int i; + int comb; + U_LONG res; + u_char bits[28]; + + bzero((char *)bits, sizeof bits); + + printf("static U_LONG PC2_C[4][64] = {"); + for (i = 0; i < 4; i++) { + for (comb = 0; comb < 64; comb++) { + if (comb & 0x20) + bits[cbits[i][0]] = 1; + if (comb & 0x10) + bits[cbits[i][1]] = 1; + if (comb & 0x8) + bits[cbits[i][2]] = 1; + if (comb & 0x4) + bits[cbits[i][3]] = 1; + if (comb & 0x2) + bits[cbits[i][4]] = 1; + if (comb & 0x1) + bits[cbits[i][5]] = 1; + permc(bits, &res); + bits[cbits[i][0]] = 0; + bits[cbits[i][1]] = 0; + bits[cbits[i][2]] = 0; + bits[cbits[i][3]] = 0; + bits[cbits[i][4]] = 0; + bits[cbits[i][5]] = 0; + if ((comb & 0x3) == 0) + printf("\n\t0x%08x,", res); + else if (comb == 63 && i == 3) + printf(" 0x%08x\n};\n\n", res); + else if (comb == 63) + printf(" 0x%08x,\n", res); + else + printf(" 0x%08x,", res); + } + } + + printf("static U_LONG PC2_D[4][64] = {"); + for (i = 0; i < 4; i++) { + for (comb = 0; comb < 64; comb++) { + if (comb & 0x20) + bits[dbits[i][0]] = 1; + if (comb & 0x10) + bits[dbits[i][1]] = 1; + if (comb & 0x8) + bits[dbits[i][2]] = 1; + if (comb & 0x4) + bits[dbits[i][3]] = 1; + if (comb & 0x2) + bits[dbits[i][4]] = 1; + if (comb & 0x1) + bits[dbits[i][5]] = 1; + permd(bits, &res); + bits[dbits[i][0]] = 0; + bits[dbits[i][1]] = 0; + bits[dbits[i][2]] = 0; + bits[dbits[i][3]] = 0; + bits[dbits[i][4]] = 0; + bits[dbits[i][5]] = 0; + if ((comb & 0x3) == 0) + printf("\n\t0x%08x,", res); + else if (comb == 63 && i == 3) + printf(" 0x%08x\n};\n\n", res); + else if (comb == 63) + printf(" 0x%08x,\n", res); + else + printf(" 0x%08x,", res); + } + } +} diff --git a/usr.sbin/xntpd/authstuff/makeSP.c b/usr.sbin/xntpd/authstuff/makeSP.c new file mode 100644 index 000000000000..bfeb82c1304e --- /dev/null +++ b/usr.sbin/xntpd/authstuff/makeSP.c @@ -0,0 +1,183 @@ +/* makeSP.c,v 3.1 1993/07/06 01:05:02 jbj Exp + * makeSP - build combination S and P tables for quick DES computation + */ + +#include <stdio.h> +#include <sys/types.h> + +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +char *progname; +int debug; + +static void selperm P((int, int, U_LONG *)); +static void doit P((void)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + extern int optind; + extern char *optarg; + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "d")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + default: + errflg++; + break; + } + if (errflg) { + (void) fprintf(stderr, "usage: %s [-d]\n", progname); + exit(2); + } + doit(); + exit(0); +} + + +/* + * The cipher selection function tables. These turn 6 bit data back + * into 4 bit data. + */ +u_char S[8][64] = { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, + + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, + + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, + + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, + + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, + + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, + + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, + + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 +}; + +/* + * Cipher function permutation table + */ +u_char PT[32] = { + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 +}; + + +/* + * Bits array. We keep this zeroed. + */ +u_char bits[32]; + + +/* + * selperm - run six bit data through the given selection table, then + * through the PT table to produce a LONG output. + */ +static void +selperm(selnumber, sixbits, resp) + int selnumber; + int sixbits; + U_LONG *resp; +{ + register U_LONG res; + register int selno; + register int i; + register int ind; + + selno = selnumber; + i = sixbits; + ind = (i & 0x20) | ((i >> 1) & 0xf) | ((i & 0x1) << 4); + i = S[selno][ind]; + + for (ind = 0; ind < 4; ind++) { + if (i & 0x8) + bits[4*selno + ind] = 1; + i <<= 1; + } + + res = 0; + for (i = 0; i < 32; i++) { + res <<= 1; + if (bits[PT[i]-1]) + res |= 1; + } + + *resp = res; + bits[4*selno] = 0; + bits[4*selno + 1] = 0; + bits[4*selno + 2] = 0; + bits[4*selno + 3] = 0; +} + + +/* + * doit - compute and print the 8 SP tables + */ +static void +doit() +{ + int selno; + U_LONG result; + int sixbits; + + bzero((char *)bits, sizeof bits); + printf("static U_LONG SP[8][64] = {"); + for (selno = 0; selno < 8; selno++) { + for (sixbits = 0; sixbits < 64; sixbits++) { + selperm(selno, sixbits, &result); + if ((sixbits & 0x3) == 0) + printf("\n\t0x%08x,", result); + else if (sixbits == 63 && selno == 7) + printf(" 0x%08x\n};\n", result); + else if (sixbits == 63) + printf(" 0x%08x,\n", result); + else + printf(" 0x%08x,", result); + } + } +} diff --git a/usr.sbin/xntpd/authstuff/md5_sample_output b/usr.sbin/xntpd/authstuff/md5_sample_output new file mode 100644 index 000000000000..a7d4282d2edb --- /dev/null +++ b/usr.sbin/xntpd/authstuff/md5_sample_output @@ -0,0 +1,8 @@ +MD5 test suite results: +d41d8cd98f00b204e9800998ecf8427e "" +0cc175b9c0f1b6a831c399e269772661 "a" +900150983cd24fb0d6963f7d28e17f72 "abc" +f96b697d7cb7938d525a2f31aaf161d0 "message digest" +c3fcd3d76192e4007dfb496cca67e13b "abcdefghijklmnopqrstuvwxyz" +d174ab98d277d9f5a5611c2c9f419d9f "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" +57edf4a22be3c955ac49da2e2107b67a "12345678901234567890123456789012345678901234567890123456789012345678901234567890" diff --git a/usr.sbin/xntpd/authstuff/md5driver.c b/usr.sbin/xntpd/authstuff/md5driver.c new file mode 100644 index 000000000000..73db940598fd --- /dev/null +++ b/usr.sbin/xntpd/authstuff/md5driver.c @@ -0,0 +1,209 @@ +/* md5driver.c,v 3.1 1993/07/06 01:05:07 jbj Exp + *********************************************************************** + ** md5driver.c -- sample test routines ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/16/90 RLR ** + ** Updated: 1/91 SRD ** + ** Updated: 7/91 SRD Removed file "foo" from test suite ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#include <stdio.h> +#include <sys/types.h> +#include <time.h> +#ifdef __bsdi__ +#include <sys/time.h> +#endif /* __bsdi__ */ +#include "md5.h" + +#define MD5 +#include "ntp_string.h" +#include "ntp_stdlib.h" + +/* Prints message digest buffer in mdContext as 32 hexadecimal digits. + Order is from low-order byte to high-order byte of digest. + Each byte is printed with high-order hexadecimal digit first. + */ +static void +MDPrint (mdContext) +MD5_CTX *mdContext; +{ + int i; + + for (i = 0; i < 16; i++) + printf ("%02x", mdContext->digest[i]); +} + +/* size of test block */ +#define TEST_BLOCK_SIZE 1000 + +/* number of blocks to process */ +#define TEST_BLOCKS 10000 + +/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */ +static LONG TEST_BYTES = (LONG)TEST_BLOCK_SIZE * (LONG)TEST_BLOCKS; + +/* A time trial routine, to measure the speed of MD5. + Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE + characters. + */ +static void +MDTimeTrial () +{ + MD5_CTX mdContext; + time_t endTime, startTime; + unsigned char data[TEST_BLOCK_SIZE]; + unsigned int i; + + /* initialize test data */ + for (i = 0; i < TEST_BLOCK_SIZE; i++) + data[i] = (unsigned char)(i & 0xFF); + + /* start timer */ + printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES); + time (&startTime); + + /* digest data in TEST_BLOCK_SIZE byte blocks */ + MD5Init (&mdContext); + for (i = TEST_BLOCKS; i > 0; i--) + MD5Update (&mdContext, data, TEST_BLOCK_SIZE); + MD5Final (&mdContext); + + /* stop timer, get time difference */ + time (&endTime); + MDPrint (&mdContext); + printf (" is digest of test input.\n"); + printf + ("Seconds to process test input: %ld\n", (LONG)(endTime-startTime)); + printf + ("Characters processed per second: %ld\n", + TEST_BYTES/(endTime-startTime)); +} + +/* Computes the message digest for string inString. + Prints out message digest, a space, the string (in quotes) and a + carriage return. + */ +static void +MDString (inString) +char *inString; +{ + MD5_CTX mdContext; + unsigned int len = strlen (inString); + + MD5Init (&mdContext); + MD5Update (&mdContext, inString, len); + MD5Final (&mdContext); + MDPrint (&mdContext); + printf (" \"%s\"\n", inString); +} + +/* Computes the message digest for a specified file. + Prints out message digest, a space, the file name, and a carriage + return. + */ +static void +MDFile (filename) +char *filename; +{ + FILE *inFile = fopen (filename, "rb"); + MD5_CTX mdContext; + int bytes; + unsigned char data[1024]; + + if (inFile == NULL) { + printf ("%s can't be opened.\n", filename); + return; + } + + MD5Init (&mdContext); + while ((bytes = fread (data, 1, 1024, inFile)) != 0) + MD5Update (&mdContext, data, bytes); + MD5Final (&mdContext); + MDPrint (&mdContext); + printf (" %s\n", filename); + fclose (inFile); +} + +/* Writes the message digest of the data from stdin onto stdout, + followed by a carriage return. + */ +static void +MDFilter () +{ + MD5_CTX mdContext; + int bytes; + unsigned char data[16]; + + MD5Init (&mdContext); + while ((bytes = fread (data, 1, 16, stdin)) != 0) + MD5Update (&mdContext, data, bytes); + MD5Final (&mdContext); + MDPrint (&mdContext); + printf ("\n"); +} + +/* Runs a standard suite of test data. + */ +static void +MDTestSuite () +{ + printf ("MD5 test suite results:\n"); + MDString (""); + MDString ("a"); + MDString ("abc"); + MDString ("message digest"); + MDString ("abcdefghijklmnopqrstuvwxyz"); + MDString + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); + MDString + ("12345678901234567890123456789012345678901234567890123456789012345678901234567890"); +} + +void +main (argc, argv) +int argc; +char *argv[]; +{ + int i; + + /* For each command line argument in turn: + ** filename -- prints message digest and name of file + ** -sstring -- prints message digest and contents of string + ** -t -- prints time trial statistics for 10M + characters + ** -x -- execute a standard suite of test data + ** (no args) -- writes messages digest of stdin onto stdout + */ + if (argc == 1) + MDFilter (); + else + for (i = 1; i < argc; i++) + if (argv[i][0] == '-' && argv[i][1] == 's') + MDString (argv[i] + 2); + else if (strcmp (argv[i], "-t") == 0) + MDTimeTrial (); + else if (strcmp (argv[i], "-x") == 0) + MDTestSuite (); + else MDFile (argv[i]); +} + +/* + *********************************************************************** + ** End of md5driver.c ** + ******************************** (cut) ******************************** + */ diff --git a/usr.sbin/xntpd/authstuff/mkrandkeys.c b/usr.sbin/xntpd/authstuff/mkrandkeys.c new file mode 100644 index 000000000000..3bb987af8f2d --- /dev/null +++ b/usr.sbin/xntpd/authstuff/mkrandkeys.c @@ -0,0 +1,167 @@ +/* mkrandkeys.c,v 3.1 1993/07/06 01:05:08 jbj Exp + * mkrandkeys - make a key file for xntpd with some quite random keys + */ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +char *progname; +int debug; + +U_LONG keydata[2]; + +int std = 1; /* DES standard key format */ +u_char dokey[16] = { 0 }; + +static void rand_data P((U_LONG *)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int i; + int j; + int errflg = 0; + int numkeys; + U_LONG tmp; + char *passwd; + extern int optind; + extern char *optarg; + extern char *getpass(); + + numkeys = 0; + progname = argv[0]; + passwd = NULL; + while ((c = getopt_l(argc, argv, "dnp:s")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + case 'n': + std = 0; + break; + case 'p': + passwd = optarg; + break; + case 's': + std = 1; + break; + default: + errflg++; + break; + } + + numkeys = 0; + for (; !errflg && optind < argc; optind++) { + c = atoi(argv[optind]); + if (c <= 0 || c > 15) { + (void) fprintf("%s: invalid key number `%s'\n", + progname, argv[optind]); + exit(2); + } + dokey[c] = 1; + numkeys++; + } + + if (errflg || numkeys == 0) { + (void) fprintf(stderr, + "usage: %s [-ns] [-p seed] key# [key# ...]\n", + progname); + exit(2); + } + + while (passwd == 0 || *passwd == '\0') { + passwd = getpass("Seed: "); + if (*passwd == '\0') { + (void) fprintf(stderr, + "better use a better seed than that\n"); + } + } + + keydata[0] = keydata[1] = 0; + for (i = 0; i < 8 && *passwd != '\0'; i++) { + keydata[i/4] |= ((((U_LONG)(*passwd))&0xff)<<(1+((3-(i%4))*8))); + passwd++; + } + + for (i = 1; i <= 15; i++) { + if (dokey[i]) { + for (c = 0, tmp = 0; c < 32; c += 4) + tmp |= (i << c); + keydata[0] ^= tmp; + keydata[1] ^= tmp; + rand_data(keydata); + DESauth_parity(keydata); + + if (std) { + (void)printf("%-2d S\t%08x%08x\n", + i, keydata[0], keydata[1]); + } else { + for (j = 0; j < 2; j++) { + keydata[j] + = ((keydata[j] & 0xfefefefe) >> 1) + | ((keydata[j] & 0x01010101) << 7); + } + (void)printf("%-2d N\t%08x%08x\n", + i, keydata[0], keydata[1]); + } + } + } + exit(0); +} + +char *volatile_file[] = { + "/bin/echo", + "/bin/sh", + "/bin/cat", + "/bin/ls", + "/bin/stty", + "/bin/date", + "/bin/cat", + "/bin/cc", + "/etc/motd", + "/etc/utmp", + "/dev/kmem", + "/dev/null", + "", +}; + +#define NEXT(X) (0x1e1f2f2d*(X) + 0x361962e9) + +static void +rand_data(data) + U_LONG *data; +{ + register i; + struct stat buf; + extern LONG time(); + char ekeys[128], dkeys[128]; + + *data ^= 0x9662f394; + *(data+1) ^= 0x9f17c55f; + DESauth_subkeys(data, ekeys, dkeys); + *data ^= NEXT(getpid() + (getuid() << 16)); + *(data+1) ^= NEXT(time((LONG *)0)); + DESauth_des(data, ekeys); + for (i = 0; strlen(volatile_file[i]); i++) { + if (stat(volatile_file[i], &buf) == -1) + continue; + if (i & 1) { + *data ^= NEXT(buf.st_atime); + *(data+1) ^= NEXT(buf.st_mtime); + } else { + *data ^= NEXT(buf.st_mtime); + *(data+1) ^= NEXT(buf.st_atime); + } + DESauth_des(data, ekeys); + } +} diff --git a/usr.sbin/xntpd/authstuff/omakeIPFP.c b/usr.sbin/xntpd/authstuff/omakeIPFP.c new file mode 100644 index 000000000000..887cc58c287b --- /dev/null +++ b/usr.sbin/xntpd/authstuff/omakeIPFP.c @@ -0,0 +1,361 @@ +/* omakeIPFP.c,v 3.1 1993/07/06 01:05:10 jbj Exp + * makeIPFP - make fast DES IP and FP tables + * + * This is an older version which generated tables half the size of + * the current version, but which took about double the CPU time to + * compute permutations from these tables. Since the CPU spent on the + * permutations is small compared to the CPU spent in the cipher code, + * I may go back to the smaller tables to save the space some day. + */ + +#include <stdio.h> +#include <sys/types.h> + +#include "ntp_stdlib.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +U_LONG IPL[8][16]; +U_LONG FPL[8][16]; + +char *progname; +int debug; + +static void perm P((u_char *, u_char *, U_LONG *, U_LONG *)); +static void doit P((void)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + extern int optind; + extern char *optarg; + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "d")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + default: + errflg++; + break; + } + if (errflg) { + (void) fprintf(stderr, "usage: %s [-d]\n", progname); + exit(2); + } + doit(); + exit(0); +} + + +/* + * Initial permutation table + */ +u_char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +/* + * Inverse initial permutation table + */ +u_char FP[64] = { + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; + + +/* + * Bit order after the operation + * + * ((left & 0x55555555) << 1) | (right & 0x55555555) + */ +u_char IPLbits[32] = { + 2, 34, 4, 36, 6, 38, 8, 40, + 10, 42, 12, 44, 14, 46, 16, 48, + 18, 50, 20, 52, 22, 54, 24, 56, + 26, 58, 28, 60, 30, 62, 32, 64 +}; + + +/* + * Bit order after the operation + * + * (left & 0xaaaaaaaa) | ((right & 0xaaaaaaaa) >> 1) + */ +u_char IPRbits[32] = { + 1, 33, 3, 35, 5, 37, 7, 39, + 9, 41, 11, 43, 13, 45, 15, 47, + 17, 49, 19, 51, 21, 53, 23, 55, + 25, 57, 27, 59, 29, 61, 31, 63 +}; + + +/* + * Bit order after the operation + * + * ((left & 0x0f0f0f0f) << 4) | (right & 0x0f0f0f0f) + */ +u_char FPLbits[32] = { + 5, 6, 7, 8, 37, 38, 39, 40, + 13, 14, 15, 16, 45, 46, 47, 48, + 21, 22, 23, 24, 53, 54, 55, 56, + 29, 30, 31, 32, 61, 62, 63, 64 +}; + + +/* + * Bit order after the operation + * + * (left & 0xf0f0f0f0) | ((right & 0xf0f0f0f0) >> 4) + */ +u_char FPRbits[32] = { + 1, 2, 3, 4, 33, 34, 35, 36, + 9, 10, 11, 12, 41, 42, 43, 44, + 17, 18, 19, 20, 49, 50, 51, 52, + 25, 26, 27, 28, 57, 58, 59, 60 +}; + + +/* + * perm - do a permutation with the given table + */ +static void +perm(databits, permtab, leftp, rightp) + u_char *databits; + u_char *permtab; + U_LONG *leftp; + U_LONG *rightp; +{ + register U_LONG left; + register U_LONG right; + register u_char *PT; + register u_char *bits; + register int i; + + left = right = 0; + PT = permtab; + bits = databits; + + for (i = 0; i < 32; i++) { + left <<= 1; + if (bits[PT[i]-1]) + left |= 1; + } + + for (i = 32; i < 64; i++) { + right <<= 1; + if (bits[PT[i]-1]) + right |= 1; + } + + *leftp = left; + *rightp = right; +} + + +/* + * doit - make up the tables + */ +static void +doit() +{ + u_char bits[64]; + U_LONG left; + U_LONG right; + int tabno; + int i; + int ind0, ind1, ind2, ind3; + int quadbits; + + bzero((char *)bits, sizeof bits); + + /* + * Do the rounds for the IPL table. We save the results of + * this as well as printing them. Note that this is the + * left-half table. + */ + printf("static U_LONG IP[8][16] = {"); + for (tabno = 0; tabno < 8; tabno++) { + i = tabno * 4; + ind3 = IPLbits[i] - 1; + ind2 = IPLbits[i+1] - 1; + ind1 = IPLbits[i+2] - 1; + ind0 = IPLbits[i+3] - 1; + for (quadbits = 0; quadbits < 16; quadbits++) { + if (quadbits & (1 << 3)) + bits[ind3] = 1; + if (quadbits & (1 << 2)) + bits[ind2] = 1; + if (quadbits & (1 << 1)) + bits[ind1] = 1; + if (quadbits & 1) + bits[ind0] = 1; + perm(bits, IP, &left, &right); + bits[ind3] = 0; + bits[ind2] = 0; + bits[ind1] = 0; + bits[ind0] = 0; + if (right != 0) { + fprintf(stderr, + "IPL tabno %d quad %d right not zero\n", + tabno, quadbits); + exit(1); + } + IPL[tabno][quadbits] = left; + if (quadbits == 15 && tabno == 7) { + printf(" 0x%08x", left); + } else if (quadbits & 0x3) { + printf(" 0x%08x,", left); + } else { + printf("\n\t0x%08x,", left); + } + } + if (tabno == 7) + printf("\n};\n"); + printf("\n"); + } + + /* + * Compute the right half of the same table. I noticed this table + * was the same as the previous one, just by luck, so we don't + * actually have to do this. Do it anyway just for a check. + */ + for (tabno = 0; tabno < 8; tabno++) { + i = tabno * 4; + ind3 = IPRbits[i] - 1; + ind2 = IPRbits[i+1] - 1; + ind1 = IPRbits[i+2] - 1; + ind0 = IPRbits[i+3] - 1; + for (quadbits = 0; quadbits < 16; quadbits++) { + if (quadbits & (1 << 3)) + bits[ind3] = 1; + if (quadbits & (1 << 2)) + bits[ind2] = 1; + if (quadbits & (1 << 1)) + bits[ind1] = 1; + if (quadbits & 1) + bits[ind0] = 1; + perm(bits, IP, &left, &right); + bits[ind3] = 0; + bits[ind2] = 0; + bits[ind1] = 0; + bits[ind0] = 0; + if (left != 0) { + fprintf(stderr, + "IPR tabno %d quad %d left not zero\n", + tabno, quadbits); + exit(1); + } + if (right != IPL[tabno][quadbits]) { + fprintf(stderr, + "IPR tabno %d quad %d: 0x%08x not same as 0x%08x\n", + tabno, quadbits, right,IPL[tabno][quadbits]); + exit(1); + } + } + } + + /* + * Next are the FP tables + */ + printf("static U_LONG FP[8][16] = {"); + for (tabno = 0; tabno < 8; tabno++) { + i = tabno * 4; + ind3 = FPLbits[i] - 1; + ind2 = FPLbits[i+1] - 1; + ind1 = FPLbits[i+2] - 1; + ind0 = FPLbits[i+3] - 1; + for (quadbits = 0; quadbits < 16; quadbits++) { + if (quadbits & (1 << 3)) + bits[ind3] = 1; + if (quadbits & (1 << 2)) + bits[ind2] = 1; + if (quadbits & (1 << 1)) + bits[ind1] = 1; + if (quadbits & 1) + bits[ind0] = 1; + perm(bits, FP, &left, &right); + bits[ind3] = 0; + bits[ind2] = 0; + bits[ind1] = 0; + bits[ind0] = 0; + if (right != 0) { + fprintf(stderr, + "FPL tabno %d quad %d right not zero\n", + tabno, quadbits); + exit(1); + } + FPL[tabno][quadbits] = left; + if (quadbits == 15 && tabno == 7) { + printf(" 0x%08x", left); + } else if (quadbits & 0x3) { + printf(" 0x%08x,", left); + } else { + printf("\n\t0x%08x,", left); + } + } + if (tabno == 7) + printf("\n};"); + printf("\n"); + } + + /* + * Right half of same set of tables. This was symmetric too. + * Amazing! + */ + for (tabno = 0; tabno < 8; tabno++) { + i = tabno * 4; + ind3 = FPRbits[i] - 1; + ind2 = FPRbits[i+1] - 1; + ind1 = FPRbits[i+2] - 1; + ind0 = FPRbits[i+3] - 1; + for (quadbits = 0; quadbits < 16; quadbits++) { + if (quadbits & (1 << 3)) + bits[ind3] = 1; + if (quadbits & (1 << 2)) + bits[ind2] = 1; + if (quadbits & (1 << 1)) + bits[ind1] = 1; + if (quadbits & 1) + bits[ind0] = 1; + perm(bits, FP, &left, &right); + bits[ind3] = 0; + bits[ind2] = 0; + bits[ind1] = 0; + bits[ind0] = 0; + if (left != 0) { + fprintf(stderr, + "FPR tabno %d quad %d left not zero\n", + tabno, quadbits); + exit(1); + } + if (right != FPL[tabno][quadbits]) { + fprintf(stderr, + "FPR tabno %d quad %d: 0x%08x not same as 0x%08x\n", + tabno, quadbits, right,FPL[tabno][quadbits]); + exit(1); + } + } + } +} diff --git a/usr.sbin/xntpd/authstuff/results b/usr.sbin/xntpd/authstuff/results new file mode 100644 index 000000000000..305a179d0a2c --- /dev/null +++ b/usr.sbin/xntpd/authstuff/results @@ -0,0 +1,2 @@ +odin/1000000: 0.000145 +idavolde/1000000: 0.000451 diff --git a/usr.sbin/xntpd/authstuff/unixcert.c b/usr.sbin/xntpd/authstuff/unixcert.c new file mode 100644 index 000000000000..36234b13f55f --- /dev/null +++ b/usr.sbin/xntpd/authstuff/unixcert.c @@ -0,0 +1,156 @@ +/* unixcert.c,v 3.1 1993/07/06 01:05:14 jbj Exp + * This file, and the certdata file, shamelessly stolen + * from Phil Karn's DES implementation. + * + * This version uses the standard Unix setkey() and encrypt() + * routines to do the encryption. + */ + +#include <stdio.h> +#include <sys/types.h> + +#include "ntp_stdlib.h" + +static void get8 P((U_LONG *)); +static void put8 P((U_LONG *)); +static void do_setkey P((U_LONG *)); +static void do_crypt P((U_LONG *, int)); + +void +main() +{ + U_LONG key[2], plain[2], cipher[2], answer[2]; + int i; + int test; + int fail; + + for(test=0;!feof(stdin);test++){ + get8(key); + do_setkey(key); + printf(" K: "); put8(key); + + get8(plain); + printf(" P: "); put8(plain); + + get8(answer); + printf(" C: "); put8(answer); + + + for(i=0;i<2;i++) + cipher[i] = plain[i]; + do_crypt(cipher, 0); + + for(i=0;i<2;i++) + if(cipher[i] != answer[i]) + break; + fail = 0; + if(i != 2){ + printf(" Encrypt FAIL"); + fail++; + } + do_crypt(cipher, 1); + for(i=0;i<2;i++) + if(cipher[i] != plain[i]) + break; + if(i != 2){ + printf(" Decrypt FAIL"); + fail++; + } + if(fail == 0) + printf(" OK"); + printf("\n"); + } +} + +static void +get8(lp) +U_LONG *lp; +{ + int t; + U_LONG l[2]; + int i; + + l[0] = l[1] = 0L; + for(i=0;i<8;i++){ + scanf("%2x",&t); + if(feof(stdin)) + exit(0); + l[i/4] <<= 8; + l[i/4] |= (U_LONG)(t & 0xff); + } + *lp = l[0]; + *(lp+1) = l[1]; +} + +static void +put8(lp) +U_LONG *lp; +{ + int i; + + + for(i=0;i<2;i++){ + printf("%08x",*lp++); + } +} + +static void +do_setkey(key) + U_LONG *key; +{ + int j; + register int i; + register char *kb; + register U_LONG *kp; + char keybits[64]; + + kb = keybits; + kp = key; + for (j = 0; j < 2; j++) { + for (i = 0; i < 32; i++) { + if (*kp & (1<<(31-i))) + *kb++ = 1; + else + *kb++ = 0; + } + kp++; + } + setkey(keybits); +} + +static void +do_crypt(data, edflag) + U_LONG *data; + int edflag; +{ + int j; + register int i; + register char *bp; + register U_LONG *dp; + char block[64]; + + bp = block; + dp = data; + for (j = 0; j < 2; j++) { + for (i = 0; i < 32; i++) { + if (*dp & (1<<(31-i))) + *bp++ = 1; + else + *bp++ = 0; + } + dp++; + } + + encrypt(block, edflag); + + bp = block; + dp = data; + for (j = 0; j < 2; j++) { + *dp = 0; + for (i = 0; i < 32; i++) { + if (*bp++) + *dp |= 1<<(31-i); + } + dp++; + } +} diff --git a/usr.sbin/xntpd/clockstuff/Makefile.tmpl b/usr.sbin/xntpd/clockstuff/Makefile.tmpl new file mode 100644 index 000000000000..9a0f9c184b43 --- /dev/null +++ b/usr.sbin/xntpd/clockstuff/Makefile.tmpl @@ -0,0 +1,60 @@ +# +# Makefile.tmpl,v 3.1 1993/07/06 01:05:19 jbj Exp +# +PROGRAM= propdelay +# +# Makefile for clock miscellany +# +COMPILER= cc +COPTS= -O +BINDIR= /usr/local +DEFS= +DEFS_OPT= +DEFS_LOCAL= +COMPAT= +# +INCL= -I../include +CFLAGS= $(COPTS) $(DEFS) $(DEFS_LOCAL) $(INCL) +CC= $(COMPILER) +LIB= ../lib/libntp.a +LINTLIB= ../lib/llib-llibntp.ln +MAKE= make +INSTALL= install +# +SOURCE= chutest.c propdelay.c +OBJS= propdelay.o +CHUOBJS= chutest.o +CLKOBJS= clktest.o + +all: $(PROGRAM) + +$(PROGRAM): $(OBJS) + $(CC) $(COPTS) -o $@ $(OBJS) -lm $(COMPAT) + +chutest: $(CHUOBJS) $(LIB) + $(CC) $(COPTS) -o $@ $(CHUOBJS) $(LIB) + +clktest: $(CLKOBJS) $(LIB) + $(CC) $(COPTS) -o $@ $(CLKOBJS) $(LIB) + +install: $(BINDIR)/$(PROGRAM) + +$(BINDIR)/$(PROGRAM): $(PROGRAM) +# $(INSTALL) -c -m 0755 $(PROGRAM) $(BINDIR) + +tags: + ctags *.c *.h + +depend: + mkdep $(CFLAGS) $(SOURCE) + +clean: + -@rm -f $(PROGRAM) *.o *.out tags make.log Makefile.bak chutest clktest \ + lint.errs + +distclean: clean + -@rm -f *.orig *.rej .version Makefile + +../lib/libntp.a: + cd ../lib && $(MAKE) $(MFLAGS) MFLAGS="$(MFLAGS)" + diff --git a/usr.sbin/xntpd/clockstuff/README b/usr.sbin/xntpd/clockstuff/README new file mode 100644 index 000000000000..3714ab3b4767 --- /dev/null +++ b/usr.sbin/xntpd/clockstuff/README @@ -0,0 +1,31 @@ +README file for directory ./clockstuff of the NTP Version 3 distribution + +This directory contains the sources for utility programs designed to +support radio clocks. The chutest.c and clktest.c are desgined to +test the chu_clk and tty_clk line disciplines and STREAMS modules in +the ../kernel directory. + +These files have been modified to work with either the line disciplines +or the STREAMS modules. Be sure to define -DSTREAM if appropriate. + +These are random bits of things written to help with clocks. You can +make things in here by typing one or more of: + + make propdelay (or `make') + make chutest + make clktest + +Propdelay computes high frequency propagation delays, given the +longitude and latitude of the transmitter and receiver. Use +this for WWV/H and CHU. Don't use it for WWVB (the computation +is easier for that). + +Chutest can be used to input and process data from a CHU modem +attached to a serial port. It will use the CHU line discipline +(if installed), or raw mode otherwise. This was used to test +out the initial reduction algorithms, and may not be up to date. + +Clktest can be used to test the clock line discipline (CLKLDISC, +it must be available), and to take a look at radio clocks attached to a +serial port. + diff --git a/usr.sbin/xntpd/clockstuff/chutest.c b/usr.sbin/xntpd/clockstuff/chutest.c new file mode 100644 index 000000000000..f65686c3b3ca --- /dev/null +++ b/usr.sbin/xntpd/clockstuff/chutest.c @@ -0,0 +1,798 @@ +/* chutest.c,v 3.1 1993/07/06 01:05:21 jbj Exp + * chutest - test the CHU clock + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> +#include <sgtty.h> + +#include "../include/ntp_fp.h" +#include "../include/ntp.h" +#include "../include/ntp_unixtime.h" + +#ifdef STREAM +#include <sys/chudefs.h> +#include <stropts.h> +#endif + +#ifdef CHULDISC +#include <sys/chudefs.h> +#endif + +#ifndef CHULDISC +#ifndef STREAM +#define NCHUCHARS (10) + +struct chucode { + u_char codechars[NCHUCHARS]; /* code characters */ + u_char ncodechars; /* number of code characters */ + u_char chustatus; /* not used currently */ + struct timeval codetimes[NCHUCHARS]; /* arrival times */ +}; +#endif +#endif + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +char *progname; +int debug; + +int dofilter = 0; /* set to 1 when we should run filter algorithm */ +int showtimes = 0; /* set to 1 when we should show char arrival times */ +int doprocess = 0; /* set to 1 when we do processing analogous to driver */ +#ifdef CHULDISC +int usechuldisc = 0; /* set to 1 when CHU line discipline should be used */ +#endif +#ifdef STREAM +int usechuldisc = 0; /* set to 1 when CHU line discipline should be used */ +#endif + +struct timeval lasttv; +struct chucode chudata; + +extern u_long ustotslo[]; +extern u_long ustotsmid[]; +extern u_long ustotshi[]; + +/* + * main - parse arguments and handle options + */ +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + extern int optind; + extern char *optarg; + void init_chu(); + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "cdfpt")) != EOF) + switch (c) { + case 'c': +#ifdef STREAM + usechuldisc = 1; + break; +#endif +#ifdef CHULDISC + usechuldisc = 1; + break; +#endif +#ifndef STREAM +#ifndef CHULDISC + (void) fprintf(stderr, + "%s: CHU line discipline not available on this machine\n", + progname); + exit(2); +#endif +#endif + case 'd': + ++debug; + break; + case 'f': + dofilter = 1; + break; + case 'p': + doprocess = 1; + case 't': + showtimes = 1; + break; + default: + errflg++; + break; + } + if (errflg || optind+1 != argc) { +#ifdef STREAM + (void) fprintf(stderr, "usage: %s [-dft] tty_device\n", + progname); +#endif +#ifdef CHULDISC + (void) fprintf(stderr, "usage: %s [-dft] tty_device\n", + progname); +#endif +#ifndef STREAM +#ifndef CHULDISC + (void) fprintf(stderr, "usage: %s [-cdft] tty_device\n", + progname); +#endif +#endif + exit(2); + } + + (void) gettimeofday(&lasttv, (struct timezone *)0); + c = openterm(argv[optind]); + init_chu(); +#ifdef STREAM + if (usechuldisc) + process_ldisc(c); + else +#endif +#ifdef CHULDISC + if (usechuldisc) + process_ldisc(c); + else +#endif + process_raw(c); + /*NOTREACHED*/ +} + + +/* + * openterm - open a port to the CHU clock + */ +int +openterm(dev) + char *dev; +{ + int s; + struct sgttyb ttyb; + + if (debug) + (void) fprintf(stderr, "Doing open..."); + if ((s = open(dev, O_RDONLY, 0777)) < 0) + error("open(%s)", dev, ""); + if (debug) + (void) fprintf(stderr, "open okay\n"); + + if (debug) + (void) fprintf(stderr, "Setting exclusive use..."); + if (ioctl(s, TIOCEXCL, (char *)0) < 0) + error("ioctl(TIOCEXCL)", "", ""); + if (debug) + (void) fprintf(stderr, "done\n"); + + ttyb.sg_ispeed = ttyb.sg_ospeed = B300; + ttyb.sg_erase = ttyb.sg_kill = 0; + ttyb.sg_flags = EVENP|ODDP|RAW; + if (debug) + (void) fprintf(stderr, "Setting baud rate et al..."); + if (ioctl(s, TIOCSETP, (char *)&ttyb) < 0) + error("ioctl(TIOCSETP, raw)", "", ""); + if (debug) + (void) fprintf(stderr, "done\n"); + +#ifdef CHULDISC + if (usechuldisc) { + int ldisc; + + if (debug) + (void) fprintf(stderr, "Switching to CHU ldisc..."); + ldisc = CHULDISC; + if (ioctl(s, TIOCSETD, (char *)&ldisc) < 0) + error("ioctl(TIOCSETD, CHULDISC)", "", ""); + if (debug) + (void) fprintf(stderr, "okay\n"); + } +#endif +#ifdef STREAM + if (usechuldisc) { + + if (debug) + (void) fprintf(stderr, "Poping off streams..."); + while (ioctl(s, I_POP, 0) >=0) ; + if (debug) + (void) fprintf(stderr, "okay\n"); + if (debug) + (void) fprintf(stderr, "Pushing CHU stream..."); + if (ioctl(s, I_PUSH, "chu") < 0) + error("ioctl(I_PUSH, \"chu\")", "", ""); + if (debug) + (void) fprintf(stderr, "okay\n"); + } +#endif + return s; +} + + +/* + * process_raw - process characters in raw mode + */ +process_raw(s) + int s; +{ + u_char c; + int n; + struct timeval tv; + struct timeval difftv; + + while ((n = read(s, &c, sizeof(char))) > 0) { + (void) gettimeofday(&tv, (struct timezone *)0); + if (dofilter) + raw_filter((unsigned int)c, &tv); + else { + difftv.tv_sec = tv.tv_sec - lasttv.tv_sec; + difftv.tv_usec = tv.tv_usec - lasttv.tv_usec; + if (difftv.tv_usec < 0) { + difftv.tv_sec--; + difftv.tv_usec += 1000000; + } + (void) printf("%02x\t%lu.%06lu\t%lu.%06lu\n", + c, tv.tv_sec, tv.tv_usec, difftv.tv_sec, + difftv.tv_usec); + lasttv = tv; + } + } + + if (n == 0) { + (void) fprintf(stderr, "%s: zero returned on read\n", progname); + exit(1); + } else + error("read()", "", ""); +} + + +/* + * raw_filter - run the line discipline filter over raw data + */ +raw_filter(c, tv) + unsigned int c; + struct timeval *tv; +{ + static struct timeval diffs[10] = { 0 }; + struct timeval diff; + l_fp ts; + void chufilter(); + + if ((c & 0xf) > 9 || ((c>>4)&0xf) > 9) { + if (debug) + (void) fprintf(stderr, + "character %02x failed BCD test\n"); + chudata.ncodechars = 0; + return; + } + + if (chudata.ncodechars > 0) { + diff.tv_sec = tv->tv_sec + - chudata.codetimes[chudata.ncodechars].tv_sec; + diff.tv_usec = tv->tv_usec + - chudata.codetimes[chudata.ncodechars].tv_usec; + if (diff.tv_usec < 0) { + diff.tv_sec--; + diff.tv_usec += 1000000; + } /* + if (diff.tv_sec != 0 || diff.tv_usec > 900000) { + if (debug) + (void) fprintf(stderr, + "character %02x failed time test\n"); + chudata.ncodechars = 0; + return; + } */ + } + + chudata.codechars[chudata.ncodechars] = c; + chudata.codetimes[chudata.ncodechars] = *tv; + if (chudata.ncodechars > 0) + diffs[chudata.ncodechars] = diff; + if (++chudata.ncodechars == 10) { + if (doprocess) { + TVTOTS(&chudata.codetimes[NCHUCHARS-1], &ts); + ts.l_ui += JAN_1970; + chufilter(&chudata, &chudata.codetimes[NCHUCHARS-1]); + } else { + register int i; + + for (i = 0; i < chudata.ncodechars; i++) { + (void) printf("%x%x\t%lu.%06lu\t%lu.%06lu\n", + chudata.codechars[i] & 0xf, + (chudata.codechars[i] >>4 ) & 0xf, + chudata.codetimes[i].tv_sec, + chudata.codetimes[i].tv_usec, + diffs[i].tv_sec, diffs[i].tv_usec); + } + } + chudata.ncodechars = 0; + } +} + + +/* #ifdef CHULDISC*/ +/* + * process_ldisc - process line discipline + */ +process_ldisc(s) + int s; +{ + struct chucode chu; + int n; + register int i; + struct timeval diff; + l_fp ts; + void chufilter(); + + while ((n = read(s, (char *)&chu, sizeof chu)) > 0) { + if (n != sizeof chu) { + (void) fprintf(stderr, "Expected %d, got %d\n", + sizeof chu, n); + continue; + } + + if (doprocess) { + TVTOTS(&chu.codetimes[NCHUCHARS-1], &ts); + ts.l_ui += JAN_1970; + chufilter(&chu, &ts); + } else { + for (i = 0; i < NCHUCHARS; i++) { + if (i == 0) + diff.tv_sec = diff.tv_usec = 0; + else { + diff.tv_sec = chu.codetimes[i].tv_sec + - chu.codetimes[i-1].tv_sec; + diff.tv_usec = chu.codetimes[i].tv_usec + - chu.codetimes[i-1].tv_usec; + if (diff.tv_usec < 0) { + diff.tv_sec--; + diff.tv_usec += 1000000; + } + } + (void) printf("%x%x\t%lu.%06lu\t%lu.%06lu\n", + chu.codechars[i] & 0xf, (chu.codechars[i]>>4)&0xf, + chu.codetimes[i].tv_sec, chu.codetimes[i].tv_usec, + diff.tv_sec, diff.tv_usec); + } + } + } + if (n == 0) { + (void) fprintf(stderr, "%s: zero returned on read\n", progname); + exit(1); + } else + error("read()", "", ""); +} +/*#endif*/ + + +/* + * error - print an error message + */ +error(fmt, s1, s2) + char *fmt; + char *s1; + char *s2; +{ + (void) fprintf(stderr, "%s: ", progname); + (void) fprintf(stderr, fmt, s1, s2); + (void) fprintf(stderr, ": "); + perror(""); + exit(1); +} + +/* + * Definitions + */ +#define MAXUNITS 4 /* maximum number of CHU units permitted */ +#define CHUDEV "/dev/chu%d" /* device we open. %d is unit number */ +#define NCHUCODES 9 /* expect 9 CHU codes per minute */ + +/* + * When CHU is operating optimally we want the primary clock distance + * to come out at 300 ms. Thus, peer.distance in the CHU peer structure + * is set to 290 ms and we compute delays which are at least 10 ms long. + * The following are 290 ms and 10 ms expressed in u_fp format + */ +#define CHUDISTANCE 0x00004a3d +#define CHUBASEDELAY 0x0000028f + +/* + * To compute a quality for the estimate (a pseudo delay) we add a + * fixed 10 ms for each missing code in the minute and add to this + * the sum of the differences between the remaining offsets and the + * estimated sample offset. + */ +#define CHUDELAYPENALTY 0x0000028f + +/* + * Other constant stuff + */ +#define CHUPRECISION (-9) /* what the heck */ +#define CHUREFID "CHU\0" + +/* + * Default fudge factors + */ +#define DEFPROPDELAY 0x00624dd3 /* 0.0015 seconds, 1.5 ms */ +#define DEFFILTFUDGE 0x000d1b71 /* 0.0002 seconds, 200 us */ + +/* + * Hacks to avoid excercising the multiplier. I have no pride. + */ +#define MULBY10(x) (((x)<<3) + ((x)<<1)) +#define MULBY60(x) (((x)<<6) - ((x)<<2)) /* watch overflow */ +#define MULBY24(x) (((x)<<4) + ((x)<<3)) + +/* + * Constants for use when multiplying by 0.1. ZEROPTONE is 0.1 + * as an l_fp fraction, NZPOBITS is the number of significant bits + * in ZEROPTONE. + */ +#define ZEROPTONE 0x1999999a +#define NZPOBITS 29 + +/* + * The CHU table. This gives the expected time of arrival of each + * character after the on-time second and is computed as follows: + * The CHU time code is sent at 300 bps. Your average UART will + * synchronize at the edge of the start bit and will consider the + * character complete at the center of the first stop bit, i.e. + * 0.031667 ms later. Thus the expected time of each interrupt + * is the start bit time plus 0.031667 seconds. These times are + * in chutable[]. To this we add such things as propagation delay + * and delay fudge factor. + */ +#define CHARDELAY 0x081b4e80 + +static u_long chutable[NCHUCHARS] = { + 0x2147ae14 + CHARDELAY, /* 0.130 (exactly) */ + 0x2ac08312 + CHARDELAY, /* 0.167 (exactly) */ + 0x34395810 + CHARDELAY, /* 0.204 (exactly) */ + 0x3db22d0e + CHARDELAY, /* 0.241 (exactly) */ + 0x472b020c + CHARDELAY, /* 0.278 (exactly) */ + 0x50a3d70a + CHARDELAY, /* 0.315 (exactly) */ + 0x5a1cac08 + CHARDELAY, /* 0.352 (exactly) */ + 0x63958106 + CHARDELAY, /* 0.389 (exactly) */ + 0x6d0e5604 + CHARDELAY, /* 0.426 (exactly) */ + 0x76872b02 + CHARDELAY, /* 0.463 (exactly) */ +}; + +/* + * Keep the fudge factors separately so they can be set even + * when no clock is configured. + */ +static l_fp propagation_delay; +static l_fp fudgefactor; +static l_fp offset_fudge; + +/* + * We keep track of the start of the year, watching for changes. + * We also keep track of whether the year is a leap year or not. + * All because stupid CHU doesn't include the year in the time code. + */ +static u_long yearstart; + +/* + * Imported from the timer module + */ +extern u_long current_time; +extern struct event timerqueue[]; + +/* + * Time conversion tables imported from the library + */ +extern u_long ustotslo[]; +extern u_long ustotsmid[]; +extern u_long ustotshi[]; + + +/* + * init_chu - initialize internal chu driver data + */ +void +init_chu() +{ + + /* + * Initialize fudge factors to default. + */ + propagation_delay.l_ui = 0; + propagation_delay.l_uf = DEFPROPDELAY; + fudgefactor.l_ui = 0; + fudgefactor.l_uf = DEFFILTFUDGE; + offset_fudge = propagation_delay; + L_ADD(&offset_fudge, &fudgefactor); + + yearstart = 0; +} + + +void +chufilter(chuc, rtime) + struct chucode *chuc; + l_fp *rtime; +{ + register int i; + register u_long date_ui; + register u_long tmp; + register u_char *code; + int isneg; + int imin; + int imax; + u_long reftime; + l_fp off[NCHUCHARS]; + l_fp ts; + int day, hour, minute, second; + static u_char lastcode[NCHUCHARS]; + extern u_long calyearstart(); + extern char *mfptoa(); + void chu_process(); + extern char *prettydate(); + + /* + * We'll skip the checks made in the kernel, but assume they've + * been done. This means that all characters are BCD and + * the intercharacter spacing isn't unreasonable. + */ + + /* + * print the code + */ + for (i = 0; i < NCHUCHARS; i++) + printf("%c%c", (chuc->codechars[i] & 0xf) + '0', + ((chuc->codechars[i]>>4) & 0xf) + '0'); + printf("\n"); + + /* + * Format check. Make sure the two halves match. + */ + for (i = 0; i < NCHUCHARS/2; i++) + if (chuc->codechars[i] != chuc->codechars[i+(NCHUCHARS/2)]) { + (void) printf("Bad format, halves don't match\n"); + return; + } + + /* + * Break out the code into the BCD nibbles. Only need to fiddle + * with the first half since both are identical. Note the first + * BCD character is the low order nibble, the second the high order. + */ + code = lastcode; + for (i = 0; i < NCHUCHARS/2; i++) { + *code++ = chuc->codechars[i] & 0xf; + *code++ = (chuc->codechars[i] >> 4) & 0xf; + } + + /* + * If the first nibble isn't a 6, we're up the creek + */ + code = lastcode; + if (*code++ != 6) { + (void) printf("Bad format, no 6 at start\n"); + return; + } + + /* + * Collect the day, the hour, the minute and the second. + */ + day = *code++; + day = MULBY10(day) + *code++; + day = MULBY10(day) + *code++; + hour = *code++; + hour = MULBY10(hour) + *code++; + minute = *code++; + minute = MULBY10(minute) + *code++; + second = *code++; + second = MULBY10(second) + *code++; + + /* + * Sanity check the day and time. Note that this + * only occurs on the 31st through the 39th second + * of the minute. + */ + if (day < 1 || day > 366 + || hour > 23 || minute > 59 + || second < 31 || second > 39) { + (void) printf("Failed date sanity check: %d %d %d %d\n", + day, hour, minute, second); + return; + } + + /* + * Compute seconds into the year. + */ + tmp = (u_long)(MULBY24((day-1)) + hour); /* hours */ + tmp = MULBY60(tmp) + (u_long)minute; /* minutes */ + tmp = MULBY60(tmp) + (u_long)second; /* seconds */ + + /* + * Now the fun begins. We demand that the received time code + * be within CLOCK_WAYTOOBIG of the receive timestamp, but + * there is uncertainty about the year the timestamp is in. + * Use the current year start for the first check, this should + * work most of the time. + */ + date_ui = tmp + yearstart; + if (date_ui < (rtime->l_ui + CLOCK_WAYTOOBIG) + && date_ui > (rtime->l_ui - CLOCK_WAYTOOBIG)) + goto codeokay; /* looks good */ + + /* + * Trouble. Next check is to see if the year rolled over and, if + * so, try again with the new year's start. + */ + date_ui = calyearstart(rtime->l_ui); + if (date_ui != yearstart) { + yearstart = date_ui; + date_ui += tmp; + (void) printf("time %u, code %u, difference %d\n", + date_ui, rtime->l_ui, (long)date_ui-(long)rtime->l_ui); + if (date_ui < (rtime->l_ui + CLOCK_WAYTOOBIG) + && date_ui > (rtime->l_ui - CLOCK_WAYTOOBIG)) + goto codeokay; /* okay this time */ + } + + ts.l_uf = 0; + ts.l_ui = yearstart; + printf("yearstart %s\n", prettydate(&ts)); + printf("received %s\n", prettydate(rtime)); + ts.l_ui = date_ui; + printf("date_ui %s\n", prettydate(&ts)); + + /* + * Here we know the year start matches the current system + * time. One remaining possibility is that the time code + * is in the year previous to that of the system time. This + * is only worth checking if the receive timestamp is less + * than CLOCK_WAYTOOBIG seconds into the new year. + */ + if ((rtime->l_ui - yearstart) < CLOCK_WAYTOOBIG) { + date_ui = tmp + calyearstart(yearstart - CLOCK_WAYTOOBIG); + if ((rtime->l_ui - date_ui) < CLOCK_WAYTOOBIG) + goto codeokay; + } + + /* + * One last possibility is that the time stamp is in the year + * following the year the system is in. Try this one before + * giving up. + */ + date_ui = tmp + calyearstart(yearstart + (400*24*60*60)); /* 400 days */ + if ((date_ui - rtime->l_ui) >= CLOCK_WAYTOOBIG) { + printf("Date hopelessly off\n"); + return; /* hopeless, let it sync to other peers */ + } + +codeokay: + reftime = date_ui; + /* + * We've now got the integral seconds part of the time code (we hope). + * The fractional part comes from the table. We next compute + * the offsets for each character. + */ + for (i = 0; i < NCHUCHARS; i++) { + register u_long tmp2; + + off[i].l_ui = date_ui; + off[i].l_uf = chutable[i]; + tmp = chuc->codetimes[i].tv_sec + JAN_1970; + TVUTOTSF(chuc->codetimes[i].tv_usec, tmp2); + M_SUB(off[i].l_ui, off[i].l_uf, tmp, tmp2); + } + + /* + * Here is a *big* problem. What one would normally + * do here on a machine with lots of clock bits (say + * a Vax or the gizmo board) is pick the most positive + * offset and the estimate, since this is the one that + * is most likely suffered the smallest interrupt delay. + * The trouble is that the low order clock bit on an IBM + * RT, which is the machine I had in mind when doing this, + * ticks at just under the millisecond mark. This isn't + * precise enough. What we can do to improve this is to + * average all 10 samples and rely on the second level + * filtering to pick the least delayed estimate. Trouble + * is, this means we have to divide a 64 bit fixed point + * number by 10, a procedure which really sucks. Oh, well. + * First compute the sum. + */ + date_ui = 0; + tmp = 0; + for (i = 0; i < NCHUCHARS; i++) + M_ADD(date_ui, tmp, off[i].l_ui, off[i].l_uf); + if (M_ISNEG(date_ui, tmp)) + isneg = 1; + else + isneg = 0; + + /* + * Here is a multiply-by-0.1 optimization that should apply + * just about everywhere. If the magnitude of the sum + * is less than 9 we don't have to worry about overflow + * out of a 64 bit product, even after rounding. + */ + if (date_ui < 9 || date_ui > 0xfffffff7) { + register u_long prod_ui; + register u_long prod_uf; + + prod_ui = prod_uf = 0; + /* + * This code knows the low order bit in 0.1 is zero + */ + for (i = 1; i < NZPOBITS; i++) { + M_LSHIFT(date_ui, tmp); + if (ZEROPTONE & (1<<i)) + M_ADD(prod_ui, prod_uf, date_ui, tmp); + } + + /* + * Done, round it correctly. Prod_ui contains the + * fraction. + */ + if (prod_uf & 0x80000000) + prod_ui++; + if (isneg) + date_ui = 0xffffffff; + else + date_ui = 0; + tmp = prod_ui; + /* + * date_ui is integral part, tmp is fraction. + */ + } else { + register u_long prod_ovr; + register u_long prod_ui; + register u_long prod_uf; + register u_long highbits; + + prod_ovr = prod_ui = prod_uf = 0; + if (isneg) + highbits = 0xffffffff; /* sign extend */ + else + highbits = 0; + /* + * This code knows the low order bit in 0.1 is zero + */ + for (i = 1; i < NZPOBITS; i++) { + M_LSHIFT3(highbits, date_ui, tmp); + if (ZEROPTONE & (1<<i)) + M_ADD3(prod_ovr, prod_uf, prod_ui, + highbits, date_ui, tmp); + } + + if (prod_uf & 0x80000000) + M_ADDUF(prod_ovr, prod_ui, (u_long)1); + date_ui = prod_ovr; + tmp = prod_ui; + } + + /* + * At this point we have the mean offset, with the integral + * part in date_ui and the fractional part in tmp. Store + * it in the structure. + */ + /* + * Add in fudge factor. + */ + M_ADD(date_ui, tmp, offset_fudge.l_ui, offset_fudge.l_uf); + + /* + * Find the minimun and maximum offset + */ + imin = imax = 0; + for (i = 1; i < NCHUCHARS; i++) { + if (L_ISGEQ(&off[i], &off[imax])) { + imax = i; + } else if (L_ISGEQ(&off[imin], &off[i])) { + imin = i; + } + } + + L_ADD(&off[imin], &offset_fudge); + if (imin != imax) + L_ADD(&off[imax], &offset_fudge); + (void) printf("mean %s, min %s, max %s\n", + mfptoa(date_ui, tmp, 8), lfptoa(&off[imin], 8), + lfptoa(&off[imax], 8)); +} diff --git a/usr.sbin/xntpd/clockstuff/clktest.c b/usr.sbin/xntpd/clockstuff/clktest.c new file mode 100644 index 000000000000..7ed13b3aa33c --- /dev/null +++ b/usr.sbin/xntpd/clockstuff/clktest.c @@ -0,0 +1,511 @@ +/* clktest.c,v 3.1 1993/07/06 01:05:23 jbj Exp + * clktest - test the clock line discipline + * + * usage: clktest -b bps -f -t timeo -s cmd -c char1 -a char2 /dev/whatever + */ + +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <signal.h> +#include <netinet/in.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/file.h> +#include <sgtty.h> + +#include "../include/ntp_fp.h" +#include "../include/ntp.h" +#include "../include/ntp_unixtime.h" + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +#if defined(ULT_2_0_SUCKS) +#ifndef sigmask +#define sigmask(m) (1<<(m)) +#endif +#endif + +#ifndef STREAM +#ifndef CLKLDISC + CLOCK_LINE_DISCIPLINE_NEEDED_BY_THIS_PROGRAM; +#endif +#endif + +/* + * Mask for blocking SIGIO and SIGALRM + */ +#define BLOCKSIGMASK (sigmask(SIGIO)|sigmask(SIGALRM)) + +/* + * speed table + */ +struct speeds { + int bps; + int rate; +} speedtab[] = { + { 300, B300 }, + { 1200, B1200 }, + { 2400, B2400 }, + { 4800, B4800 }, + { 9600, B9600 }, + { 19200, EXTA }, + { 38400, EXTB }, + { 0, 0 } +}; + +char *progname; +int debug; + +#ifdef CLKLDISC +#define DEFMAGIC '\r' +#endif + +#ifdef STREAM +#include <stropts.h> +#include <sys/clkdefs.h> +#define DEFMAGIC "\r" +#endif + +struct timeval timeout = { 0 }; +char *cmd = NULL; +int cmdlen; +int docmd = 0; +#ifdef CLKLDISC +u_long magic1 = DEFMAGIC; +u_long magic2 = DEFMAGIC; +#endif +#ifdef STREAM +char magic[32]; +#endif +int speed = B9600; +int ttflags = RAW|EVENP|ODDP; + +int wasalarmed; +int iosig; + +struct timeval lasttv; + +extern u_long ustotslo[]; +extern u_long ustotsmid[]; +extern u_long ustotshi[]; + +/* + * main - parse arguments and handle options + */ +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + struct speeds *spd; + u_long tmp; + int fd; + struct sgttyb ttyb; + struct itimerval itimer; + extern int optind; + extern char *optarg; + int alarming(); + int ioready(); + + progname = argv[0]; +#ifdef STREAM + magic[0] = 0; +#endif + while ((c = getopt_l(argc, argv, "a:b:c:dfs:t:")) != EOF) + switch (c) { +#ifdef CLKLDISC + case 'a': +#endif + case 'c': + if (!atouint(optarg, &tmp)) { + (void) fprintf(stderr, + "%s: argument for -%c must be integer\n", + progname, c); + errflg++; + break; + } +#ifdef CLKLDISC + if (c == 'c') + magic1 = tmp; + else + magic2 = tmp; +#endif +#ifdef STREAM + magic[strlen(magic)+1] = '\0'; + magic[strlen(magic)] = tmp; +#endif + break; + case 'b': + if (!atouint(optarg, &tmp)) { + errflg++; + break; + } + spd = speedtab; + while (spd->bps != 0) + if ((int)tmp == spd->bps) + break; + if (spd->bps == 0) { + (void) fprintf(stderr, + "%s: speed %lu is unsupported\n", + progname, tmp); + errflg++; + } else { + speed = spd->rate; + } + break; + case 'd': + ++debug; + break; + case 'f': + ttflags |= CRMOD; + break; + case 's': + cmdlen = strlen(optarg); + if (cmdlen == 0) + errflg++; + else + cmd = optarg; + break; + case 't': + if (!atouint(optarg, &tmp)) + errflg++; + else { + timeout.tv_sec = (long)tmp; + docmd = 1; + } + break; + default: + errflg++; + break; + } + if (errflg || optind+1 != argc) { + (void) fprintf(stderr, +#ifdef CLKLDISC +"usage: %s [-b bps] [-c magic1] [-a magic2] [-f] [-s cmd] [-t timeo] tty_device\n", +#endif +#ifdef STREAM +"usage: %s [-b bps] [-c magic1] [-c magic2]... [-f] [-s cmd] [-t timeo] tty_device\n", +#endif + progname); + exit(2); + } + +#ifdef STREAM + if (!strlen(magic)) + strcpy(magic,DEFMAGIC); +#endif + + if (docmd) + fd = open(argv[optind], O_RDWR, 0777); + else + fd = open(argv[optind], O_RDONLY, 0777); + if (fd == -1) { + (void) fprintf(stderr, "%s: open(%s): ", progname, + argv[optind]); + perror(""); + exit(1); + } + + if (ioctl(fd, TIOCEXCL, (char *)0) < 0) { + (void) fprintf(stderr, "%s: ioctl(TIOCEXCL): ", progname); + perror(""); + exit(1); + } + + /* + * If we have the clock discipline, set the port to raw. Otherwise + * we run cooked. + */ + ttyb.sg_ispeed = ttyb.sg_ospeed = speed; +#ifdef CLKLDISC + ttyb.sg_erase = (char)magic1; + ttyb.sg_kill = (char)magic2; +#endif + ttyb.sg_flags = (short)ttflags; + if (ioctl(fd, TIOCSETP, (char *)&ttyb) < 0) { + (void) fprintf(stderr, "%s: ioctl(TIOCSETP): ", progname); + perror(""); + exit(1); + } + + if (fcntl(fd, F_SETOWN, getpid()) == -1) { + (void) fprintf(stderr, "%s: fcntl(F_SETOWN): ", progname); + perror(""); + exit(1); + } + +#ifdef CLKLDISC + { + int ldisc; + ldisc = CLKLDISC; + if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0) { + (void) fprintf(stderr, "%s: ioctl(TIOCSETD): ", progname); + perror(""); + exit(1); + } + } +#endif +#ifdef STREAM + if (ioctl(fd, I_POP, 0) >=0 ) ; + if (ioctl(fd, I_PUSH, "clk") < 0) { + (void) fprintf(stderr, "%s: ioctl(I_PUSH): ", progname); + perror(""); + exit(1); + } + if (ioctl(fd, CLK_SETSTR, magic) < 0) { + (void) fprintf(stderr, "%s: ioctl(CLK_SETSTR): ", progname); + perror(""); + exit(1); + } +#endif + + + (void) gettimeofday(&lasttv, (struct timezone *)0); + if (docmd) { + /* + * set non-blocking, async I/O on the descriptor + */ + iosig = 0; + (void) signal(SIGIO, ioready); + if (fcntl(fd, F_SETFL, FNDELAY|FASYNC) < 0) { + (void) fprintf(stderr, "%s: fcntl(F_SETFL): ", + progname); + perror(""); + exit(1); + } + + /* + * Set up the alarm interrupt. + */ + wasalarmed = 0; + (void) signal(SIGALRM, alarming); + itimer.it_interval = itimer.it_value = timeout; + setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); + doboth(fd); + } + doioonly(fd); +} + + +/* + * doboth - handle both I/O and alarms via SIGIO + */ +doboth(fd) + int fd; +{ + int n; + int sawalarm; + int sawiosig; + int omask; + fd_set fds; + struct timeval tvzero; + + sawalarm = 0; + sawiosig = 0; + FD_ZERO(&fds); + for (;;) { + omask = sigblock(BLOCKSIGMASK); + if (wasalarmed) { /* alarmed? */ + sawalarm = 1; + wasalarmed = 0; + } + if (iosig) { + sawiosig = 1; + iosig = 0; + } + + if (!sawalarm && !sawiosig) { + /* + * Nothing to do. Wait for something. + */ + sigpause(omask); + if (wasalarmed) { /* alarmed? */ + sawalarm = 1; + wasalarmed = 0; + } + if (iosig) { + sawiosig = 1; + iosig = 0; + } + } + (void)sigsetmask(omask); + + if (sawiosig) { + + do { + tvzero.tv_sec = tvzero.tv_usec = 0; + FD_SET(fd, &fds); + n = select(fd+1, &fds, (fd_set *)0, + (fd_set *)0, &tvzero); + if (n > 0) + doio(fd); + } while (n > 0); + + if (n == -1) { + (void) fprintf(stderr, "%s: select: ", + progname); + perror(""); + exit(1); + } + sawiosig = 0; + } + if (sawalarm) { + doalarm(fd); + sawalarm = 0; + } + } +} + + +/* + * doioonly - do I/O. This avoids the use of signals + */ +doioonly(fd) + int fd; +{ + int n; + fd_set fds; + + FD_ZERO(&fds); + for (;;) { + FD_SET(fd, &fds); + n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0, + (struct timeval *)0); + if (n > 0) + doio(fd); + } +} + + +/* + * doio - read a buffer full of stuff and print it out + */ +doio(fd) + int fd; +{ + register char *rp, *rpend; + register char *cp; + register int i; + char raw[512]; + struct timeval tv, tvd; + int rlen; + int ind; + char cooked[2049]; + static char *digits = "0123456789abcdef"; + + rlen = read(fd, raw, sizeof(raw)); + if (rlen < 0) { + (void) fprintf(stderr, "%s: read(): ", progname); + perror(""); + return; + } + if (rlen == 0) { + (void) printf("Zero length read\n"); + return; + } + + cp = cooked; + rp = raw; + rpend = &raw[rlen]; + ind = 0; + + while (rp < rpend) { + ind = 1; + if (isprint(*rp)) + *cp++ = *rp; + else { + *cp++ = '<'; + *cp++ = digits[((*rp)>>4) & 0xf]; + *cp++ = digits[*rp & 0xf]; + *cp++ = '>'; + } +#ifdef CLKLDISC + if (*rp == (char)magic1 || *rp == (char)magic2) { +#else + if ( strchr( magic, *rp) != NULL ) { +#endif + rp++; + ind = 0; + *cp = '\0'; + if ((rpend - rp) < sizeof(struct timeval)) { + (void)printf( + "Too little data (%d): %s\n", + rpend-rp, cooked); + return; + } + + tv.tv_sec = 0; + for (i = 0; i < 4; i++) { + tv.tv_sec <<= 8; + tv.tv_sec |= ((long)*rp++) & 0xff; + } + tv.tv_usec = 0; + for (i = 0; i < 4; i++) { + tv.tv_usec <<= 8; + tv.tv_usec |= ((long)*rp++) & 0xff; + } + + tvd.tv_sec = tv.tv_sec - lasttv.tv_sec; + tvd.tv_usec = tv.tv_usec - lasttv.tv_usec; + if (tvd.tv_usec < 0) { + tvd.tv_usec += 1000000; + tvd.tv_sec--; + } + + (void)printf("%lu.%06lu %lu.%06lu %s\n", + tv.tv_sec, tv.tv_usec, tvd.tv_sec, tvd.tv_usec, + cooked); + lasttv = tv; + } else { + rp++; + } + } + + if (ind) { + *cp = '\0'; + (void)printf("Incomplete data: %s\n", cooked); + } +} + + +/* + * doalarm - send a string out the port, if we have one. + */ +doalarm(fd) + int fd; +{ + int n; + + if (cmd == NULL || cmdlen <= 0) + return; + + n = write(fd, cmd, cmdlen); + + if (n < 0) { + (void) fprintf(stderr, "%s: write(): ", progname); + perror(""); + } else if (n < cmdlen) { + (void) printf("Short write (%d bytes, should be %d)\n", + n, cmdlen); + } +} + + +/* + * alarming - receive alarm interupt + */ +alarming() +{ + wasalarmed = 1; +} + +/* + * ioready - handle SIGIO interrupt + */ +ioready() +{ + iosig = 1; +} diff --git a/usr.sbin/xntpd/clockstuff/propdelay.c b/usr.sbin/xntpd/clockstuff/propdelay.c new file mode 100644 index 000000000000..5ba1789eee67 --- /dev/null +++ b/usr.sbin/xntpd/clockstuff/propdelay.c @@ -0,0 +1,536 @@ +/* propdelay.c,v 3.1 1993/07/06 01:05:24 jbj Exp + * propdelay - compute propagation delays + * + * cc -o propdelay propdelay.c -lm + * + * "Time and Frequency Users' Manual", NBS Technical Note 695 (1977). + */ + +/* + * This can be used to get a rough idea of the HF propagation delay + * between two points (usually between you and the radio station). + * The usage is + * + * propdelay latitudeA longitudeA latitudeB longitudeB + * + * where points A and B are the locations in question. You obviously + * need to know the latitude and longitude of each of the places. + * The program expects the latitude to be preceded by an 'n' or 's' + * and the longitude to be preceded by an 'e' or 'w'. It understands + * either decimal degrees or degrees:minutes:seconds. Thus to compute + * the delay between the WWVH (21:59:26N, 159:46:00W) and WWV (40:40:49N, + * 105:02:27W) you could use: + * + * propdelay n21:59:26 w159:46 n40:40:49 w105:02:27 + * + * By default it prints out a summer (F2 average virtual height 350 km) and + * winter (F2 average virtual height 250 km) number. The results will be + * quite approximate but are about as good as you can do with HF time anyway. + * You might pick a number between the values to use, or use the summer + * value in the summer and switch to the winter value when the static + * above 10 MHz starts to drop off in the fall. You can also use the + * -h switch if you want to specify your own virtual height. + * + * You can also do a + * + * propdelay -W n45:17:47 w75:45:22 + * + * to find the propagation delays to WWV and WWVH (from CHU in this + * case), a + * + * propdelay -C n40:40:49 w105:02:27 + * + * to find the delays to CHU, and a + * + * propdelay -G n52:03:17 w98:34:18 + * + * to find delays to GOES via each of the three satellites. + */ + +#include <stdio.h> +#include <string.h> + +#include "ntp_stdlib.h" + +extern double sin P((double)); +extern double cos P((double)); +extern double acos P((double)); +extern double tan P((double)); +extern double atan P((double)); +extern double sqrt P((double)); + +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +/* + * Program constants + */ +#define EARTHRADIUS (6370.0) /* raduis of earth (km) */ +#define LIGHTSPEED (299800.0) /* speed of light, km/s */ +#define PI (3.1415926536) +#define RADPERDEG (PI/180.0) /* radians per degree */ +#define MILE (1.609344) /* km in a mile */ + +#define SUMMERHEIGHT (350.0) /* summer height in km */ +#define WINTERHEIGHT (250.0) /* winter height in km */ + +#define SATHEIGHT (6.6110 * 6378.0) /* geosync satellite height in km + from centre of earth */ + +#define WWVLAT "n40:40:49" +#define WWVLONG "w105:02:27" + +#define WWVHLAT "n21:59:26" +#define WWVHLONG "w159:46:00" + +#define CHULAT "n45:17:47" +#define CHULONG "w75:45:22" + +#define GOES_UP_LAT "n37:52:00" +#define GOES_UP_LONG "w75:27:00" +#define GOES_EAST_LONG "w75:00:00" +#define GOES_STBY_LONG "w105:00:00" +#define GOES_WEST_LONG "w135:00:00" +#define GOES_SAT_LAT "n00:00:00" + +char *wwvlat = WWVLAT; +char *wwvlong = WWVLONG; + +char *wwvhlat = WWVHLAT; +char *wwvhlong = WWVHLONG; + +char *chulat = CHULAT; +char *chulong = CHULONG; + +char *goes_up_lat = GOES_UP_LAT; +char *goes_up_long = GOES_UP_LONG; +char *goes_east_long = GOES_EAST_LONG; +char *goes_stby_long = GOES_STBY_LONG; +char *goes_west_long = GOES_WEST_LONG; +char *goes_sat_lat = GOES_SAT_LAT; + +int hflag = 0; +int Wflag = 0; +int Cflag = 0; +int Gflag = 0; +int height; + +char *progname; +int debug; + +static void doit P((double, double, double, double, double, char *)); +static double latlong P((char *, int)); +static double greatcircle P((double, double, double, double)); +static double waveangle P((double, double, int)); +static double propdelay P((double, double, int)); +static int finddelay P((double, double, double, double, double, double *)); +static void satdoit P((double, double, double, double, double, double, char *)); +static void satfinddelay P((double, double, double, double, double *)); +static double satpropdelay P((double)); + +/* + * main - parse arguments and handle options + */ +void +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + int errflg = 0; + double lat1, long1; + double lat2, long2; + double lat3, long3; + extern int optind; + extern char *optarg; + + progname = argv[0]; + while ((c = getopt_l(argc, argv, "dh:CWG")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + case 'h': + hflag++; + height = atof(optarg); + if (height <= 0.0) { + (void) fprintf(stderr, "height %s unlikely\n", + optarg); + errflg++; + } + break; + case 'C': + Cflag++; + break; + case 'W': + Wflag++; + break; + case 'G': + Gflag++; + break; + default: + errflg++; + break; + } + if (errflg || (!(Cflag || Wflag || Gflag) && optind+4 != argc) || + ((Cflag || Wflag || Gflag) && optind+2 != argc)) { + (void) fprintf(stderr, + "usage: %s [-d] [-h height] lat1 long1 lat2 long2\n", + progname); + (void) fprintf(stderr," - or -\n"); + (void) fprintf(stderr, + "usage: %s -CWG [-d] lat long\n", + progname); + exit(2); + } + + + if (!(Cflag || Wflag || Gflag)) { + lat1 = latlong(argv[optind], 1); + long1 = latlong(argv[optind + 1], 0); + lat2 = latlong(argv[optind + 2], 1); + long2 = latlong(argv[optind + 3], 0); + if (hflag) { + doit(lat1, long1, lat2, long2, height, ""); + } else { + doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, + "summer propagation, "); + doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, + "winter propagation, "); + } + } else if (Wflag) { + /* + * Compute delay from WWV + */ + lat1 = latlong(argv[optind], 1); + long1 = latlong(argv[optind + 1], 0); + lat2 = latlong(wwvlat, 1); + long2 = latlong(wwvlong, 0); + if (hflag) { + doit(lat1, long1, lat2, long2, height, "WWV "); + } else { + doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, + "WWV summer propagation, "); + doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, + "WWV winter propagation, "); + } + + /* + * Compute delay from WWVH + */ + lat2 = latlong(wwvhlat, 1); + long2 = latlong(wwvhlong, 0); + if (hflag) { + doit(lat1, long1, lat2, long2, height, "WWVH "); + } else { + doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, + "WWVH summer propagation, "); + doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, + "WWVH winter propagation, "); + } + } else if (Cflag) { + lat1 = latlong(argv[optind], 1); + long1 = latlong(argv[optind + 1], 0); + lat2 = latlong(chulat, 1); + long2 = latlong(chulong, 0); + if (hflag) { + doit(lat1, long1, lat2, long2, height, "CHU "); + } else { + doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, + "CHU summer propagation, "); + doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, + "CHU winter propagation, "); + } + } else if (Gflag) { + lat1 = latlong(goes_up_lat, 1); + long1 = latlong(goes_up_long, 0); + lat3 = latlong(argv[optind], 1); + long3 = latlong(argv[optind + 1], 0); + + lat2 = latlong(goes_sat_lat, 1); + + long2 = latlong(goes_west_long, 0); + satdoit(lat1, long1, lat2, long2, lat3, long3, + "GOES Delay via WEST"); + + long2 = latlong(goes_stby_long, 0); + satdoit(lat1, long1, lat2, long2, lat3, long3, + "GOES Delay via STBY"); + + long2 = latlong(goes_east_long, 0); + satdoit(lat1, long1, lat2, long2, lat3, long3, + "GOES Delay via EAST"); + + } + exit(0); +} + + +/* + * doit - compute a delay and print it + */ +static void +doit(lat1, long1, lat2, long2, h, str) + double lat1; + double long1; + double lat2; + double long2; + double h; + char *str; +{ + int hops; + double delay; + + hops = finddelay(lat1, long1, lat2, long2, h, &delay); + printf("%sheight %g km, hops %d, delay %g seconds\n", + str, h, hops, delay); +} + + +/* + * latlong - decode a latitude/longitude value + */ +static double +latlong(str, islat) + char *str; + int islat; +{ + register char *cp; + register char *bp; + double arg; + double div; + int isneg; + char buf[32]; + char *colon; + + if (islat) { + /* + * Must be north or south + */ + if (*str == 'N' || *str == 'n') + isneg = 0; + else if (*str == 'S' || *str == 's') + isneg = 1; + else + isneg = -1; + } else { + /* + * East is positive, west is negative + */ + if (*str == 'E' || *str == 'e') + isneg = 0; + else if (*str == 'W' || *str == 'w') + isneg = 1; + else + isneg = -1; + } + + if (isneg >= 0) + str++; + + colon = strchr(str, ':'); + if (colon != NULL) { + /* + * in hhh:mm:ss form + */ + cp = str; + bp = buf; + while (cp < colon) + *bp++ = *cp++; + *bp = '\0'; + cp++; + arg = atof(buf); + div = 60.0; + colon = strchr(cp, ':'); + if (colon != NULL) { + bp = buf; + while (cp < colon) + *bp++ = *cp++; + *bp = '\0'; + cp++; + arg += atof(buf) / div; + div = 3600.0; + } + if (*cp != '\0') + arg += atof(cp) / div; + } else { + arg = atof(str); + } + + if (isneg == 1) + arg = -arg; + + if (debug > 2) + (void) printf("latitude/longitude %s = %g\n", str, arg); + + return arg; +} + + +/* + * greatcircle - compute the great circle distance in kilometers + */ +static double +greatcircle(lat1, long1, lat2, long2) + double lat1; + double long1; + double lat2; + double long2; +{ + double dg; + double l1r, l2r; + + l1r = lat1 * RADPERDEG; + l2r = lat2 * RADPERDEG; + dg = EARTHRADIUS * acos( + (cos(l1r) * cos(l2r) * cos((long2-long1)*RADPERDEG)) + + (sin(l1r) * sin(l2r))); + if (debug >= 2) + printf( + "greatcircle lat1 %g long1 %g lat2 %g long2 %g dist %g\n", + lat1, long1, lat2, long2, dg); + return dg; +} + + +/* + * waveangle - compute the wave angle for the given distance, virtual + * height and number of hops. + */ +static double +waveangle(dg, h, n) + double dg; + double h; + int n; +{ + double theta; + double delta; + + theta = dg / (EARTHRADIUS * (double)(2 * n)); + delta = atan((h / (EARTHRADIUS * sin(theta))) + tan(theta/2)) - theta; + if (debug >= 2) + printf("waveangle dist %g height %g hops %d angle %g\n", + dg, h, n, delta / RADPERDEG); + return delta; +} + + +/* + * propdelay - compute the propagation delay + */ +static double +propdelay(dg, h, n) + double dg; + double h; + int n; +{ + double phi; + double theta; + double td; + + theta = dg / (EARTHRADIUS * (double)(2 * n)); + phi = (PI/2.0) - atan((h / (EARTHRADIUS * sin(theta))) + tan(theta/2)); + td = dg / (LIGHTSPEED * sin(phi)); + if (debug >= 2) + printf("propdelay dist %g height %g hops %d time %g\n", + dg, h, n, td); + return td; +} + + +/* + * finddelay - find the propagation delay + */ +static int +finddelay(lat1, long1, lat2, long2, h, delay) + double lat1; + double long1; + double lat2; + double long2; + double h; + double *delay; +{ + double dg; /* great circle distance */ + double delta; /* wave angle */ + int n; /* number of hops */ + + dg = greatcircle(lat1, long1, lat2, long2); + if (debug) + printf("great circle distance %g km %g miles\n", dg, dg/MILE); + + n = 1; + while ((delta = waveangle(dg, h, n)) < 0.0) { + if (debug) + printf("tried %d hop%s, no good\n", n, n>1?"s":""); + n++; + } + if (debug) + printf("%d hop%s okay, wave angle is %g\n", n, n>1?"s":"", + delta / RADPERDEG); + + *delay = propdelay(dg, h, n); + return n; +} + +/* + * satdoit - compute a delay and print it + */ +static void +satdoit(lat1, long1, lat2, long2, lat3, long3, str) + double lat1; + double long1; + double lat2; + double long2; + double lat3; + double long3; + char *str; +{ + double up_delay,down_delay; + + satfinddelay(lat1, long1, lat2, long2, &up_delay); + satfinddelay(lat3, long3, lat2, long2, &down_delay); + + printf("%s, delay %g seconds\n", str, up_delay + down_delay); +} + +/* + * satfinddelay - calculate the one-way delay time between a ground station + * and a satellite + */ +static void +satfinddelay(lat1, long1, lat2, long2, delay) + double lat1; + double long1; + double lat2; + double long2; + double *delay; +{ + double dg; /* great circle distance */ + + dg = greatcircle(lat1, long1, lat2, long2); + + *delay = satpropdelay(dg); +} + +/* + * satpropdelay - calculate the one-way delay time between a ground station + * and a satellite + */ +static double +satpropdelay(dg) + double dg; +{ + double k1, k2, dist; + double theta; + double td; + + theta = dg / (EARTHRADIUS); + k1 = EARTHRADIUS * sin(theta); + k2 = SATHEIGHT - (EARTHRADIUS * cos(theta)); + if (debug >= 2) + printf("Theta %g k1 %g k2 %g\n", theta, k1, k2); + dist = sqrt(k1*k1 + k2*k2); + td = dist / LIGHTSPEED; + if (debug >= 2) + printf("propdelay dist %g height %g time %g\n", dg, dist, td); + return td; +} diff --git a/usr.sbin/xntpd/compilers/README b/usr.sbin/xntpd/compilers/README new file mode 100644 index 000000000000..46794dc5399c --- /dev/null +++ b/usr.sbin/xntpd/compilers/README @@ -0,0 +1,5 @@ +README file for directory ./compilers of the NTP Version 3 distribution + +This directory contains configuration files for the various machines +and compilers supported by the distribution. README and RELNOTES files in the +parent directory for directions on how to use these files. diff --git a/usr.sbin/xntpd/compilers/aux2.gcc b/usr.sbin/xntpd/compilers/aux2.gcc new file mode 100644 index 000000000000..53672c45366e --- /dev/null +++ b/usr.sbin/xntpd/compilers/aux2.gcc @@ -0,0 +1 @@ +COMPILER=gcc -O -pipe -finline-functions -fomit-frame-pointer -D_POSIX_SOURCE diff --git a/usr.sbin/xntpd/compilers/aux3.gcc b/usr.sbin/xntpd/compilers/aux3.gcc new file mode 100644 index 000000000000..53672c45366e --- /dev/null +++ b/usr.sbin/xntpd/compilers/aux3.gcc @@ -0,0 +1 @@ +COMPILER=gcc -O -pipe -finline-functions -fomit-frame-pointer -D_POSIX_SOURCE diff --git a/usr.sbin/xntpd/compilers/decosf1.gcc b/usr.sbin/xntpd/compilers/decosf1.gcc new file mode 100644 index 000000000000..d071385d7a79 --- /dev/null +++ b/usr.sbin/xntpd/compilers/decosf1.gcc @@ -0,0 +1 @@ +COMPILER= gcc -Wall -O2 -finline-functions diff --git a/usr.sbin/xntpd/compilers/hpux.cc b/usr.sbin/xntpd/compilers/hpux.cc new file mode 100644 index 000000000000..e3c27af87bd8 --- /dev/null +++ b/usr.sbin/xntpd/compilers/hpux.cc @@ -0,0 +1,2 @@ +COMPILER=cc +COPTS=+O1 diff --git a/usr.sbin/xntpd/compilers/hpux.gcc b/usr.sbin/xntpd/compilers/hpux.gcc new file mode 100644 index 000000000000..ecd037212eda --- /dev/null +++ b/usr.sbin/xntpd/compilers/hpux.gcc @@ -0,0 +1,2 @@ +COMPILER=gcc +COPTS=-O2 diff --git a/usr.sbin/xntpd/compilers/hpux10+.cc b/usr.sbin/xntpd/compilers/hpux10+.cc new file mode 100644 index 000000000000..cf058ef46b5c --- /dev/null +++ b/usr.sbin/xntpd/compilers/hpux10+.cc @@ -0,0 +1 @@ +COMPILER=cc +O1 diff --git a/usr.sbin/xntpd/compilers/linux.gcc b/usr.sbin/xntpd/compilers/linux.gcc new file mode 100644 index 000000000000..501568c714e3 --- /dev/null +++ b/usr.sbin/xntpd/compilers/linux.gcc @@ -0,0 +1,2 @@ +COMPILER= gcc -DUSE_PROTOTYPES -Wall +COPTS= -O6 -finline-functions -fomit-frame-pointer diff --git a/usr.sbin/xntpd/compilers/mips.cc b/usr.sbin/xntpd/compilers/mips.cc new file mode 100644 index 000000000000..dcd8697077ab --- /dev/null +++ b/usr.sbin/xntpd/compilers/mips.cc @@ -0,0 +1 @@ +COMPILER= cc -systype bsd43 diff --git a/usr.sbin/xntpd/compilers/sinix-m.cc b/usr.sbin/xntpd/compilers/sinix-m.cc new file mode 100644 index 000000000000..e4712dc89ed6 --- /dev/null +++ b/usr.sbin/xntpd/compilers/sinix-m.cc @@ -0,0 +1 @@ +COMPILER= /usr/ucb/cc diff --git a/usr.sbin/xntpd/compilers/sinix-m.gcc b/usr.sbin/xntpd/compilers/sinix-m.gcc new file mode 100644 index 000000000000..fe6af589c439 --- /dev/null +++ b/usr.sbin/xntpd/compilers/sinix-m.gcc @@ -0,0 +1,2 @@ +COMPILER= gcc -traditional + diff --git a/usr.sbin/xntpd/compilers/sunos4.bsd.cc b/usr.sbin/xntpd/compilers/sunos4.bsd.cc new file mode 100644 index 000000000000..eb4dd629860a --- /dev/null +++ b/usr.sbin/xntpd/compilers/sunos4.bsd.cc @@ -0,0 +1 @@ +COMPILER= cc diff --git a/usr.sbin/xntpd/compilers/sunos4.bsd.gcc b/usr.sbin/xntpd/compilers/sunos4.bsd.gcc new file mode 100644 index 000000000000..09e841a2b4de --- /dev/null +++ b/usr.sbin/xntpd/compilers/sunos4.bsd.gcc @@ -0,0 +1 @@ +COMPILER= gcc -DUSE_PROTOTYPES -Wall -O2 -finline-functions -fdelayed-branch -fomit-frame-pointer diff --git a/usr.sbin/xntpd/compilers/sunos4.posix.gcc b/usr.sbin/xntpd/compilers/sunos4.posix.gcc new file mode 100644 index 000000000000..09e841a2b4de --- /dev/null +++ b/usr.sbin/xntpd/compilers/sunos4.posix.gcc @@ -0,0 +1 @@ +COMPILER= gcc -DUSE_PROTOTYPES -Wall -O2 -finline-functions -fdelayed-branch -fomit-frame-pointer diff --git a/usr.sbin/xntpd/compilers/sunos5.1.gcc b/usr.sbin/xntpd/compilers/sunos5.1.gcc new file mode 100644 index 000000000000..fe6af589c439 --- /dev/null +++ b/usr.sbin/xntpd/compilers/sunos5.1.gcc @@ -0,0 +1,2 @@ +COMPILER= gcc -traditional + diff --git a/usr.sbin/xntpd/compilers/sunos5.2.gcc b/usr.sbin/xntpd/compilers/sunos5.2.gcc new file mode 100644 index 000000000000..fe6af589c439 --- /dev/null +++ b/usr.sbin/xntpd/compilers/sunos5.2.gcc @@ -0,0 +1,2 @@ +COMPILER= gcc -traditional + diff --git a/usr.sbin/xntpd/compilers/ultrix.bsd.cc b/usr.sbin/xntpd/compilers/ultrix.bsd.cc new file mode 100644 index 000000000000..06f68830e503 --- /dev/null +++ b/usr.sbin/xntpd/compilers/ultrix.bsd.cc @@ -0,0 +1,2 @@ +COMPILER= cc -Olimit 800 + diff --git a/usr.sbin/xntpd/compilers/ultrix.bsd.gcc b/usr.sbin/xntpd/compilers/ultrix.bsd.gcc new file mode 100644 index 000000000000..5ed9d554abc8 --- /dev/null +++ b/usr.sbin/xntpd/compilers/ultrix.bsd.gcc @@ -0,0 +1 @@ +COMPILER= gcc -Wall -O2 -finline-functions -fdelayed-branch diff --git a/usr.sbin/xntpd/compilers/ultrix.posix.cc b/usr.sbin/xntpd/compilers/ultrix.posix.cc new file mode 100644 index 000000000000..06f68830e503 --- /dev/null +++ b/usr.sbin/xntpd/compilers/ultrix.posix.cc @@ -0,0 +1,2 @@ +COMPILER= cc -Olimit 800 + diff --git a/usr.sbin/xntpd/compilers/ultrix.posix.gcc b/usr.sbin/xntpd/compilers/ultrix.posix.gcc new file mode 100644 index 000000000000..5ed9d554abc8 --- /dev/null +++ b/usr.sbin/xntpd/compilers/ultrix.posix.gcc @@ -0,0 +1 @@ +COMPILER= gcc -Wall -O2 -finline-functions -fdelayed-branch diff --git a/usr.sbin/xntpd/conf/Config.CHATHAM b/usr.sbin/xntpd/conf/Config.CHATHAM new file mode 100644 index 000000000000..41e6fc2aa340 --- /dev/null +++ b/usr.sbin/xntpd/conf/Config.CHATHAM @@ -0,0 +1,214 @@ +# Edit this file to reflect information specific to your installation. +# Then run 'make makeconfig' to propagate the information to all the makefiles, +# Config.CHATHAM,v 3.1 1993/07/06 01:03:42 jbj Exp + +# +# Definitions for the library: +# +# You must define one of -DXNTP_BIG_ENDIAN, -DXNTP_LITTLE_ENDIAN +# or -DXNTP_AUTO_ENDIAN depending on which way your machine's +# bytes go for the benefit of the DES routine. Most things +# sold by DEC, the NS32x32 and the 80386 deserve a +# -DXNTP_LITTLE_ENDIAN. Most of the rest of the world does +# it the other way. If in doubt, pick one, compile +# everything and run authstuff/authcert < authstuff/certdata. +# If everything fails, do it the other way. +# +# Under BSD, you may define -DXNTP_NETINET_ENDIAN to use +# netinet/in.h to determine which of -DXNTP_BIG_ENDIAN and +# XNTP_LITTLE_ENDIAN should be used. +# +LIBDEFS= -DWORDS_BIGENDIAN + +# +# Library loading: +# +# If you don't want your library ranlib'ed, chose the second line +# +RANLIB= ranlib +#RANLIB= : # ar does the work of ranlib under System V + +# +# Definitions for programs: +# +# If your compiler doesn't understand the declaration `signed char', +# add -DNO_SIGNED_CHAR_DECL. Your `char' data type had better be +# signed. If you don't know what the compiler knows, try it +# without the flag. If you get a syntax error on line 13 of +# ntp.h, add it. Note that `signed char' is an ANSIism. Most +# older, pcc-derived compilers will need this flag. +# +# If your library already has 's_char' defined, add -DS_CHAR_DEFINED. +# +# For SunOS 3.x, add -DSUN_3_3_STINKS (otherwise it will complain +# about broadaddr and will hang if you run without a -d flag +# on the command line. I actually can't believe the latter +# bug. If it hangs on your system with the flag defined, peruse +# xntpd/ntp_io.c for some rude comments about SunOS 3.5 and try it +# the other way). This flag affects xntpd only. +# +# For Ultrix 2.0, add -DULT_2_0_SUCKS. This OS has the same hanging +# bug as SunOS 3.5 (is this an original 4.2 bug?) and in addition +# has some strangeness concerning signal masks. Ultrix 2.3 doesn't +# have these problems. If you're running something in between +# you're on your own. This flag affects xntpd only. +# +# For SunOS 4.x, add -DDOSYNCTODR_SUCKS to include the code in ntp_util.c +# that sets the battery clock at the same time that it updates +# the driftfile. It does this by revving up the niceness, then +# sets the time of day to the current time of day. Ordinarily, +# you would need this only on non-networked machines. +# +# For some machines, settimeofday does not set the sub-second component +# of the time correctly. For these machines add -DSETTIMEOFDAY_BROKEN. +# If xntpd keeps STEPPING the clock by small amounts, then it is +# possible that you are suffering from this problem. +# +# There are three ways to pry loose the kernel variables tick and tickadj +# needed by ntp_unixclock.c. One reads kmem and and is enabled +# with -DREADKMEM. One uses Sun's libkvm and is enabled with +# -DUSELIBKVM. The last one uses builtin defaults and is enabled +# with -DNOKMEM. Therefore, one of -DUSELIBKVM, -DREADKMEM or +# -DNOKMEM must be defined. Suns and recent BSD should use +# -DUSELIBKVM; others should use -DREADKMEM. If -DUSELIBKVM, use +# the DAEMONLIBS below to get the kernel routines. +# +# If your gethostbyname() routine isn't based on the DNS resolver (and, +# in particular, h_errno doesn't exist) add a -DNODNS. There +# doesn't seem to be a good way to detect this automatically which +# works in all cases. This flag affects xntpres only. +# +# Adding -DLOCK_PROCESS to the compilation flags will prevent +# xntpd from being swapped out on systems where the plock(3) call +# is available. +# +# The flag -DDEBUG includes some debugging code. +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you will also want +# to configure the particular clock drivers you want in the +# CLOCKDEFS= line below. This flag affects xntpd only. +# +# There is an occurance of a call to rindex() in the daemon. You may +# have to include a -Drindex=strrchr to get this to load right. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# Under HP-UX, you must use either -Dhpux70 or -Dhpux80 as, +# well as -DNOKMEM +# +# If your library doesn't include the vsprintf() routine, define +# NEED_VSPRINTF. +# +# There are three ways to utilize external 1-pps signals. Define -DPPS to +# include just the pps routine, such as used by the DCF77 reference clock +# driver. Define -DPPSDEV ito include a serial device driver. This +# requires a serial port and either a line discipline or STREAMS module. +# Define -DPPSCD to include the driver and a special kernal hack +# (for SunOS 4.1.1) that intercepts carrier-detect transitions +# generated by the pps signal. Only one of these flags should be defined. +# +DEFS= -DUSELIBKVM -DDEBUG -DSTREAM -DREFCLOCK -DNO_SIGNED_CHAR_DECL -DPPS -DPPSDEV -DXNTP_RETROFIT_STDLIB -DHAVE_UNISTD_H + +# +# Authentication types supported. Choose from DES and MD5. If you +# have a 680x0 type CPU and GNU-C, also choose -DFASTMD5 +# +AUTHDEFS=-DDES -DMD5 + +# +# Clock support definitions (these only make sense if -DREFCLOCK used): +# +# Define -DLOCAL_CLOCK to include local pseudo-clock support +# +# Define -DPST to include support for the PST 1020 WWV/H receiver. +# +# Define -DWWVB to include support for the Spectracom 8170 WWVB receiver. +# Define -DWWVBPPS for PPS support via the WWVB receiver; also, +# define -DPPSCD in the DEFS above. This requires the ppsclock +# streams module under SunOS 4.2. +# +# Define -DCHU to include support for a driver to receive the CHU +# timecode. Note that to compile in CHU support you must +# previously have installed the CHU serial line discipline in +# the kernel of the machine you are doing the compile on. +# +# Define -DDCF to include support for the DCF77 receiver. This code +# requires a special STREAMS module found in the kernel directory. +# Define -DDCFPPS for PPS support via the DCF77 receiver; also, +# devine -DPPS in the DEFS above. +# +# Define -DMX4200 to support a Magnavox 4200 GPS receiver. Define -DPPSCD +# in the DEFS above for PPS support via this receiver. This requires +# the ppsclock streams module under SunOS 4.2. +# +# Define -DAS2201 to include support for the Austron 2201 GPS Timing +# Receiver. Define -DPPSCD in the DEFS above for PPS support via this +# receiver. This requires the ppsclock streams module under SunOS 4.2. +# +# Define -DGOES to support a Kinemetrics TrueTime 468-DC GOES receiver. This +# driver may work with other True-Time products as well. +# +# Define -DOMEGA to support a Kinemetrics TrueTime OM-DC OMEGA receiver. +# +# Define -DTPRO to support a KSI/Odetics TPRO-S IRIG-B timecode reader. This +# requires the Sun interface driver available from KSI. +# +# Define -DLEITCH to support a Leitch CSD 5300 Master Clock System Driver +# for the HP 5061B Cesium Clock. +# +CLOCKDEFS= -DLOCAL_CLOCK -DPST -DWWVB -DWWVBPPS -DCHU -DDCF -DMX4200 -DAS2201 -DGOES -DOMEGA -DTPRO -DLEITCH -DIRIG + +# +# For MIPS 4.3BSD or RISCos 4.0, include a -lmld to get the nlist() routine. +# If USELIBKVM is defined above, include a -lkvm to get the kernel +# routines. +# +#DAEMONLIBS= -lmld +DAEMONLIBS= -lkvm +#DAEMONLIBS= + +# +# Name resolver library. Included when loading xntpres, which calls +# gethostbyname(). Define this if you would rather use a different +# version of the routine than the one in libc.a +# +#RESLIB= -lresolv +RESLIB= + +# +# Option flags for the C compiler. A -g if you are uncomfortable +# +COPTS= -O + +# +# C compiler to use. gcc will work, but avoid the -fstrength-reduce option +# if the version is 1.35 or earlier (using this option caused incorrect +# code to be generated in the DES key permutation code, and perhaps +# elsewhere). +# +COMPILER= gcc -pipe -Wall -g -O2 -finline-functions -fdelayed-branch -fomit-frame-pointer +#COMPILER= cc -pipe + +# +# Directory into which binaries should be installed +# +BINDIR= /usr/local/bin + +# +# Special library for adjtime emulation. Used under HP-UX +# (remember to run make in the adjtime directory) +# +#ADJLIB= ../adjtime/libadjtime.a +ADJLIB= + +# +# BSD emulation library. In theory, this fixes signal semantics under +# HP-UX, but it doesn't work with 8.0 on a 9000s340, so there is now +# a work-around in the code (compiled when hpux80 is defined). In other +# words, use this for HP-UX prior to 8.0. +# +#COMPAT= -lBSD +COMPAT= + diff --git a/usr.sbin/xntpd/conf/Config.MONOMOY b/usr.sbin/xntpd/conf/Config.MONOMOY new file mode 100644 index 000000000000..b9e075fbfce6 --- /dev/null +++ b/usr.sbin/xntpd/conf/Config.MONOMOY @@ -0,0 +1,189 @@ +# Edit this file to reflect information specific to your installation. +# Then run 'make makeconfig' to propagate the information to all the makefiles, +# Config.MONOMOY,v 3.1 1993/07/06 01:03:43 jbj Exp + +# Config.bsdi by Bdale Garbee, N3EUA, bdale@gag.com +# +# Tested with the BSDI BSD/386 0.9.3 "gamma 4" revision. It should +# work fine with this or later revs of BSD/386. +# +# Definitions for the library: +# +# You must define one of -DXNTP_BIG_ENDIAN, -DXNTP_LITTLE_ENDIAN +# or -DXNTP_AUTO_ENDIAN depending on which way your machine's +# bytes go for the benefit of the DES routine. Most things +# sold by DEC, the NS32x32 and the 80386 deserve a +# -DXNTP_LITTLE_ENDIAN. Most of the rest of the world does +# it the other way. If in doubt, pick one, compile +# everything and run authstuff/authcert < authstuff/certdata. +# If everything fails, do it the other way. +# +# Under BSD, you may define -DXNTP_NETINET_ENDIAN to use +# netinet/in.h to determine which of -DXNTP_BIG_ENDIAN and +# XNTP_LITTLE_ENDIAN should be used. +# +LIBDEFS= -DXNTP_LITTLE_ENDIAN + +# +# Library loading: +# +# If you don't want your library ranlib'ed, chose the second line +# +RANLIB= ranlib +#RANLIB= : # ar does the work of ranlib under System V + +# +# Definitions for programs: +# +# If your compiler doesn't understand the declaration `signed char', +# add -DNO_SIGNED_CHAR_DECL. Your `char' data type had better be +# signed. If you don't know what the compiler knows, try it +# without the flag. If you get a syntax error on line 13 of +# ntp.h, add it. Note that `signed char' is an ANSIism. Most +# older, pcc-derived compilers will need this flag. +# +# If your library already has 's_char' defined, add -DS_CHAR_DEFINED. +# +# For SunOS 3.x, add -DSUN_3_3_STINKS (otherwise it will complain +# about broadaddr and will hang if you run without a -d flag +# on the command line. I actually can't believe the latter +# bug. If it hangs on your system with the flag defined, peruse +# xntpd/ntp_io.c for some rude comments about SunOS 3.5 and try it +# the other way). This flag affects xntpd only. +# +# For Ultrix 2.0, add -DULT_2_0_SUCKS. This OS has the same hanging +# bug as SunOS 3.5 (is this an original 4.2 bug?) and in addition +# has some strangeness concerning signal masks. Ultrix 2.3 doesn't +# have these problems. If you're running something in between +# you're on your own. This flag affects xntpd only. +# +# For SunOS 4.x, add -DDOSYNCTODR_SUCKS to include the code in ntp_util.c +# that sets the battery clock at the same time that it updates +# the driftfile. It does this by revving up the niceness, then +# sets the time of day to the current time of day. Ordinarily, +# you would need this only on non-networked machines. +# +# There are three ways to pry loose the kernel variables tick and tickadj +# needed by ntp_unixclock.c. One reads kmem and and is enabled +# with -DREADKMEM. One uses Sun's libkvm and is enabled with +# -DUSELIBKVM. The last one uses builtin defaults and is enabled +# with -DNOKMEM. Therefore, one of -DUSELIBKVM, -DREADKMEM or +# -DNOKMEM must be defined. Suns and recent BSD should use +# -DUSELIBKVM; others should use -DREADKMEM. If -DUSELIBKVM, use +# the DAEMONLIBS below to get the kernel routines. +# +# If your gethostbyname() routine isn't based on the DNS resolver (and, +# in particular, h_errno doesn't exist) add a -DNODNS. There +# doesn't seem to be a good way to detect this automatically which +# works in all cases. This flag affects xntpres only. +# +# The flag -DDEBUG includes some debugging code. +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you will also want +# to configure the particular clock drivers you want in the +# CLOCKDEFS= line below. This flag affects xntpd only. +# +# There is an occurance of a call to rindex() in the daemon. You may +# have to include a -Drindex=strrchr to get this to load right. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# Under HP-UX, you must use either -Dhpux70 or -Dhpux80 as, +# well as -DNOKMEM +# +# If your library doesn't include the vsprintf() routine, define +# NEED_VSPRINTF. +# +# Define -DPPS to include support for a 1-pps signal. Define -DPPSDEV +# to include a device driver for it. The latter requires a +# serial port and either a line discipline or STREAMS module. +# The PPS signal may also be generated via a reference clock +# module like DCF77. In that case a special define is required for +# the reference clock module (only one source of PPS signal should +# be used) +# +DEFS= -DBSDI -DUSELIBKVM -DDEBUG -DREFCLOCK -DPPS -DCONFIG_FILE=\\"/usr/local/etc/xntp.conf\\" -DHAVE_UNISTD_H + +# +# Authentication types supported. Choose from DES and MD5. If you +# have a 680x0 type CPU and GNU-C, also choose -DFASTMD5 +# +AUTHDEFS=-DDES -DMD5 + +# +# Clock support definitions (these only make sense if -DREFCLOCK used): +# +# Define -DLOCAL_CLOCK to include local pseudo-clock support +# +# Define -DPST to include support for the PST 1020 WWV/H receiver. +# +# Define -DWWVB to include support for the Spectracom 8170 WWVB receiver. +# +# Define -DCHU to include support for a driver to receive the CHU +# timecode. Note that to compile in CHU support you must +# previously have installed the CHU serial line discipline in +# the kernel of the machine you are doing the compile on. +# +# Define -DDCF to include support for the DCF77 receiver. This code +# requires a special STREAMS module found in the kernel directory. +# Define -DDCFPPS for PPS support via the DCF77 receiver +# (see also: -DPPS) +# +# Define -DGOES to support a Kinemetrics TrueTime 468-DC GOES receiver. +# +CLOCKDEFS= -DLOCAL_CLOCK -DPST -DWWVB -DCHU -DGOES # -DMX4200 -DAS2201 + +# +# For MIPS 4.3BSD or RISCos 4.0, include a -lmld to get the nlist() routine. +# If USELIBKVM is defined above, include a -lkvm to get the kernel +# routines. +# +#DAEMONLIBS= -lmld +DAEMONLIBS= -lkvm +#DAEMONLIBS= + +# +# Name resolver library. Included when loading xntpres, which calls +# gethostbyname(). Define this if you would rather use a different +# version of the routine than the one in libc.a +# +#RESLIB= -lresolv +RESLIB= + +# +# Option flags for the C compiler. A -g if you are uncomfortable +# +COPTS= -O + +# +# C compiler to use. gcc will work, but avoid the -fstrength-reduce option +# if the version is 1.35 or earlier (using this option caused incorrect +# code to be generated in the DES key permutation code, and perhaps +# elsewhere). +# +COMPILER= gcc -pipe -Wall -g -O -finline-functions -fdelayed-branch -fomit-frame-pointer +#COMPILER= cc -pipe -g + +# +# Directory into which binaries should be installed +# +BINDIR= /usr/local/bin + +# +# Special library for adjtime emulation. Used under HP-UX +# (remember to run make in the adjtime directory) +# +#ADJLIB= ../adjtime/libadjtime.a +ADJLIB= + +# +# BSD emulation library. In theory, this fixes signal semantics under +# HP-UX, but it doesn't work with 8.0 on a 9000s340, so there is now +# a work-around in the code (compiled when hpux80 is defined). In other +# words, use this for HP-UX prior to 8.0. +# +#COMPAT= -lBSD +COMPAT= + diff --git a/usr.sbin/xntpd/conf/Config.TIGER b/usr.sbin/xntpd/conf/Config.TIGER new file mode 100644 index 000000000000..c757ad90e186 --- /dev/null +++ b/usr.sbin/xntpd/conf/Config.TIGER @@ -0,0 +1,185 @@ +# Edit this file to reflect information specific to your installation. +# Then run 'make makeconfig' to propagate the information to all the makefiles, +# Config.TIGER,v 3.1 1993/07/06 01:03:45 jbj Exp + +# +# Definitions for the library: +# +# You must define one of -DXNTP_BIG_ENDIAN, -DXNTP_LITTLE_ENDIAN +# or -DXNTP_AUTO_ENDIAN depending on which way your machine's +# bytes go for the benefit of the DES routine. Most things +# sold by DEC, the NS32x32 and the 80386 deserve a +# -DXNTP_LITTLE_ENDIAN. Most of the rest of the world does +# it the other way. If in doubt, pick one, compile +# everything and run authstuff/authcert < authstuff/certdata. +# If everything fails, do it the other way. +# +# Under BSD, you may define -DXNTP_NETINET_ENDIAN to use +# netinet/in.h to determine which of -DXNTP_BIG_ENDIAN and +# XNTP_LITTLE_ENDIAN should be used. +# +LIBDEFS= -DXNTP_LITTLE_ENDIAN + +# +# Library loading: +# +# If you don't want your library ranlib'ed, chose the second line +# +RANLIB= ranlib +#RANLIB= : # ar does the work of ranlib under System V + +# +# Definitions for programs: +# +# If your compiler doesn't understand the declaration `signed char', +# add -DNO_SIGNED_CHAR_DECL. Your `char' data type had better be +# signed. If you don't know what the compiler knows, try it +# without the flag. If you get a syntax error on line 13 of +# ntp.h, add it. Note that `signed char' is an ANSIism. Most +# older, pcc-derived compilers will need this flag. +# +# If your library already has 's_char' defined, add -DS_CHAR_DEFINED. +# +# For SunOS 3.x, add -DSUN_3_3_STINKS (otherwise it will complain +# about broadaddr and will hang if you run without a -d flag +# on the command line. I actually can't believe the latter +# bug. If it hangs on your system with the flag defined, peruse +# xntpd/ntp_io.c for some rude comments about SunOS 3.5 and try it +# the other way). This flag affects xntpd only. +# +# For Ultrix 2.0, add -DULT_2_0_SUCKS. This OS has the same hanging +# bug as SunOS 3.5 (is this an original 4.2 bug?) and in addition +# has some strangeness concerning signal masks. Ultrix 2.3 doesn't +# have these problems. If you're running something in between +# you're on your own. This flag affects xntpd only. +# +# For SunOS 4.x, add -DDOSYNCTODR_SUCKS to include the code in ntp_util.c +# that sets the battery clock at the same time that it updates +# the driftfile. It does this by revving up the niceness, then +# sets the time of day to the current time of day. Ordinarily, +# you would need this only on non-networked machines. +# +# There are three ways to pry loose the kernel variables tick and tickadj +# needed by ntp_unixclock.c. One reads kmem and and is enabled +# with -DREADKMEM. One uses Sun's libkvm and is enabled with +# -DUSELIBKVM. The last one uses builtin defaults and is enabled +# with -DNOKMEM. Therefore, one of -DUSELIBKVM, -DREADKMEM or +# -DNOKMEM must be defined. Suns and recent BSD should use +# -DUSELIBKVM; others should use -DREADKMEM. If -DUSELIBKVM, use +# the DAEMONLIBS below to get the kernel routines. +# +# If your gethostbyname() routine isn't based on the DNS resolver (and, +# in particular, h_errno doesn't exist) add a -DNODNS. There +# doesn't seem to be a good way to detect this automatically which +# works in all cases. This flag affects xntpres only. +# +# The flag -DDEBUG includes some debugging code. +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you will also want +# to configure the particular clock drivers you want in the +# CLOCKDEFS= line below. This flag affects xntpd only. +# +# There is an occurance of a call to rindex() in the daemon. You may +# have to include a -Drindex=strrchr to get this to load right. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# Under HP-UX, you must use either -Dhpux70 or -Dhpux80 as, +# well as -DNOKMEM +# +# If your library doesn't include the vsprintf() routine, define +# NEED_VSPRINTF. +# +# Define -DPPS to include support for a 1-pps signal. Define -DPPSDEV +# to include a device driver for it. The latter requires a +# serial port and either a line discipline or STREAMS module. +# The PPS signal may also be generated via a reference clock +# module like DCF77. In that case a special define is required for +# the reference clock module (only one source of PPS signal should +# be used) +# +DEFS= -DREFCLOCK -DS_CHAR_DEFINED -DREADKMEM -DDEBUG -DPLL -DXNTP_RETROFIT_STDLIB -DHAVE_UNISTD_H + +# +# Authentication types supported. Choose from DES and MD5. If you +# have a 680x0 type CPU and GNU-C, also choose -DFASTMD5 +# +AUTHDEFS=-DDES -DMD5 + +# +# Clock support definitions (these only make sense if -DREFCLOCK used): +# +# Define -DLOCAL_CLOCK to include local pseudo-clock support +# +# Define -DPST to include support for the PST 1020 WWV/H receiver. +# +# Define -DWWVB to include support for the Spectracom 8170 WWVB receiver. +# +# Define -DCHU to include support for a driver to receive the CHU +# timecode. Note that to compile in CHU support you must +# previously have installed the CHU serial line discipline in +# the kernel of the machine you are doing the compile on. +# +# Define -DDCF to include support for the DCF77 receiver. This code +# requires a special STREAMS module found in the kernel directory. +# Define -DDCFPPS for PPS support via the DCF77 receiver +# (see also: -DPPS) +# +# Define -DGOES to support a Kinemetrics TrueTime 468-DC GOES receiver. +# +CLOCKDEFS= -DLOCAL_CLOCK -DPST -DWWVB -DGOES -DCHU + +# +# For MIPS 4.3BSD or RISCos 4.0, include a -lmld to get the nlist() routine. +# If USELIBKVM is defined above, include a -lkvm to get the kernel +# routines. +# +#DAEMONLIBS= -lmld +#DAEMONLIBS= -lkvm +DAEMONLIBS= + +# +# Name resolver library. Included when loading xntpres, which calls +# gethostbyname(). Define this if you would rather use a different +# version of the routine than the one in libc.a +# +#RESLIB= -lresolv +RESLIB= + +# +# Option flags for the C compiler. A -g if you are uncomfortable +# +COPTS= -O + +# +# C compiler to use. gcc will work, but avoid the -fstrength-reduce option +# if the version is 1.35 or earlier (using this option caused incorrect +# code to be generated in the DES key permutation code, and perhaps +# elsewhere). +# +COMPILER= gcc -Wall -g -O2 -finline-functions -fdelayed-branch -fomit-frame-pointer +#COMPILER= cc + +# +# Directory into which binaries should be installed +# +BINDIR= /usr/local/bin + +# +# Special library for adjtime emulation. Used under HP-UX +# (remember to run make in the adjtime directory) +# +#ADJLIB= ../adjtime/libadjtime.a +ADJLIB= + +# +# BSD emulation library. In theory, this fixes signal semantics under +# HP-UX, but it doesn't work with 8.0 on a 9000s340, so there is now +# a work-around in the code (compiled when hpux80 is defined). In other +# words, use this for HP-UX prior to 8.0. +# +#COMPAT= -lBSD +COMPAT= + diff --git a/usr.sbin/xntpd/conf/Config.TRURO b/usr.sbin/xntpd/conf/Config.TRURO new file mode 100644 index 000000000000..6caa2b82d62e --- /dev/null +++ b/usr.sbin/xntpd/conf/Config.TRURO @@ -0,0 +1,205 @@ +# Edit this file to reflect information specific to your installation. +# Then run 'make makeconfig' to propagate the information to all the makefiles, +# Config.TRURO,v 3.1 1993/07/06 01:03:46 jbj Exp + +# +# Definitions for the library: +# +# You must define one of -DXNTP_BIG_ENDIAN, -DXNTP_LITTLE_ENDIAN +# or -DXNTP_AUTO_ENDIAN depending on which way your machine's +# bytes go for the benefit of the DES routine. Most things +# sold by DEC, the NS32x32 and the 80386 deserve a +# -DXNTP_LITTLE_ENDIAN. Most of the rest of the world does +# it the other way. If in doubt, pick one, compile +# everything and run authstuff/authcert < authstuff/certdata. +# If everything fails, do it the other way. +# +# Under BSD, you may define -DXNTP_NETINET_ENDIAN to use +# netinet/in.h to determine which of -DXNTP_BIG_ENDIAN and +# XNTP_LITTLE_ENDIAN should be used. +# +LIBDEFS= -DWORDS_BIGENDIAN + +# +# Library loading: +# +# If you don't want your library ranlib'ed, chose the second line +# +RANLIB= : # ar does the work of ranlib under System V + +# +# Definitions for programs: +# +# If your compiler doesn't understand the declaration `signed char', +# add -DNO_SIGNED_CHAR_DECL. Your `char' data type had better be +# signed. If you don't know what the compiler knows, try it +# without the flag. If you get a syntax error on line 13 of +# ntp.h, add it. Note that `signed char' is an ANSIism. Most +# older, pcc-derived compilers will need this flag. +# +# If your library already has 's_char' defined, add -DS_CHAR_DEFINED. +# +# For SunOS 3.x, add -DSUN_3_3_STINKS (otherwise it will complain +# about broadaddr and will hang if you run without a -d flag +# on the command line. I actually can't believe the latter +# bug. If it hangs on your system with the flag defined, peruse +# xntpd/ntp_io.c for some rude comments about SunOS 3.5 and try it +# the other way). This flag affects xntpd only. +# +# For Ultrix 2.0, add -DULT_2_0_SUCKS. This OS has the same hanging +# bug as SunOS 3.5 (is this an original 4.2 bug?) and in addition +# has some strangeness concerning signal masks. Ultrix 2.3 doesn't +# have these problems. If you're running something in between +# you're on your own. This flag affects xntpd only. +# +# For SunOS 4.x, add -DDOSYNCTODR_SUCKS to include the code in ntp_util.c +# that sets the battery clock at the same time that it updates +# the driftfile. It does this by revving up the niceness, then +# sets the time of day to the current time of day. Ordinarily, +# you would need this only on non-networked machines. +# +# For some machines, settimeofday does not set the sub-second component +# of the time correctly. For these machines add -DSETTIMEOFDAY_BROKEN. +# If xntpd keeps STEPPING the clock by small amounts, then it is +# possible that you are suffering from this problem. +# +# There are four ways to pry loose the kernel variables tick and tickadj +# needed by ntp_unixclock.c. One reads kmem and and is enabled +# with -DREADKMEM. One uses Sun's libkvm and is enabled with +# -DUSELIBKVM. The last one uses builtin defaults and is enabled +# with -DNOKMEM. Therefore, one of -DUSELIBKVM, -DREADKMEM or +# -DNOKMEM must be defined. Suns, if they are not running Solaris, +# and recent BSD should use -DUSELIBKVM; others should use +# -DREADKMEM. Soalris 2.1 should use -DSOLARIS. +# If -DUSELIBKVM, use the DAEMONLIBS below to get the +# kernel routines. +# +# If your gethostbyname() routine isn't based on the DNS resolver (and, +# in particular, h_errno doesn't exist) add a -DNODNS. There +# doesn't seem to be a good way to detect this automatically which +# works in all cases. This flag affects xntpres only. +# +# The flag -DDEBUG includes some debugging code. +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you will also want +# to configure the particular clock drivers you want in the +# CLOCKDEFS= line below. This flag affects xntpd only. +# +# There is an occurance of a call to rindex() in the daemon. You may +# have to include a -Drindex=strrchr to get this to load right. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# Under HP-UX, you must use either -Dhpux70 or -Dhpux80 as, +# well as -DNOKMEM +# +# Under Solaris 2.1, you must use -DSOLARIS and -DSLEWALWAYS. +# Don't define USELIBKVM, NOKMEM or READKMEM. +# +# If your library doesn't include the vsprintf() routine, define +# NEED_VSPRINTF. +# +# There are three ways to utilize external 1-pps signals. Define -DPPS to +# include just the pps routine, such as used by the DCF77 reference clock +# driver. Define -DPPSDEV ito include a serial device driver. This +# requires a serial port and either a line discipline or STREAMS module. +# Define -DPPSCD to include the driver and a special kernal hack +# (for SunOS 4.1.1) that intercepts carrier-detect transitions +# generated by the pps signal. Only one of these flags should be defined. +# +DEFS= -DDEBUG -DSTREAM -DREFCLOCK -DNO_SIGNED_CHAR_DECL -DSLEWALWAYS -DSOLARIS -DPPS -DSTUPID_SIGNAL -DXNTP_RETROFIT_STDLIB -DHAVE_UNISTD_H + +# +# Authentication types supported. Choose from DES and MD5. If you +# have a 680x0 type CPU and GNU-C, also choose -DFASTMD5 +# +AUTHDEFS=-DDES -DMD5 + +# +# Clock support definitions (these only make sense if -DREFCLOCK used): +# +# Define -DLOCAL_CLOCK to include local pseudo-clock support +# +# Define -DPST to include support for the PST 1020 WWV/H receiver. +# +# Define -DWWVB to include support for the Spectracom 8170 WWVB receiver. +# Define -DWWVBPPS for PPS support via the WWVB receiver; also, +# define -DPPSCD in the DEFS above. This requires the ppsclock +# streams module under SunOS 4.2. +# +# Define -DCHU to include support for a driver to receive the CHU +# timecode. Note that to compile in CHU support you must +# previously have installed the CHU serial line discipline in +# the kernel of the machine you are doing the compile on. +# +# Define -DDCF to include support for the DCF77 receiver. This code +# requires a special STREAMS module found in the kernel directory. +# Define -DDCFPPS for PPS support via the DCF77 receiver; also, +# devine -DPPS in the DEFS above. +# +# Define -DMX4200 to support a Magnavox 4200 GPS receiver. Define -DPPSCD +# in the DEFS above for PPS support via this receiver. This requires +# the ppsclock streams module under SunOS 4.2. +# +# Define -DAS2201 to include support for the Austron 2201 GPS Timing +# Receiver. Define -DPPSCD in the DEFS above for PPS support via this +# receiver. This requires the ppsclock streams module under SunOS 4.2. +# +# Define -DGOES to support a Kinemetrics TrueTime 468-DC GOES receiver. This +# driver may work with other True-Time products as well. +# +CLOCKDEFS= -DLOCAL_CLOCK -DPST -DWWVB -DWWVBPPS -DGOES -DCHU -DMX4200 -DAS2201 -DOMEGA -DTPRO -DLEITCH -DIRIG + +# +# For MIPS 4.3BSD or RISCos 4.0, include a -lmld to get the nlist() routine. +# If USELIBKVM is defined above, include a -lkvm to get the kernel +# routines. +# +#DAEMONLIBS= -lmld +DAEMONLIBS= + +# +# Name resolver library. Included when loading xntpres, which calls +# gethostbyname(). Define this if you would rather use a different +# version of the routine than the one in libc.a +# +#RESLIB= -lresolv +RESLIB= -lsocket -lnsl -lelf + +# +# Option flags for the C compiler. A -g if you are uncomfortable +# +COPTS= -O + +# +# C compiler to use. gcc will work, but avoid the -fstrength-reduce option +# if the version is 1.35 or earlier (using this option caused incorrect +# code to be generated in the DES key permutation code, and perhaps +# elsewhere). +# +#COMPILER= gcc -traditional +COMPILER= gcc -pipe -Wall -g -O2 -finline-functions -fdelayed-branch -fomit-frame-pointer + +# +# Directory into which binaries should be installed +# +BINDIR= /usr/local/bin + +# +# Special library for adjtime emulation. Used under HP-UX +# (remember to run make in the adjtime directory) +# +#ADJLIB= ../adjtime/libadjtime.a +ADJLIB= + +# +# BSD emulation library. In theory, this fixes signal semantics under +# HP-UX, but it doesn't work with 8.0 on a 9000s340, so there is now +# a work-around in the code (compiled when hpux80 is defined). In other +# words, use this for HP-UX prior to 8.0. +# +#COMPAT= -lBSD +COMPAT= + diff --git a/usr.sbin/xntpd/conf/Config.dartnet b/usr.sbin/xntpd/conf/Config.dartnet new file mode 100644 index 000000000000..b591db341655 --- /dev/null +++ b/usr.sbin/xntpd/conf/Config.dartnet @@ -0,0 +1,187 @@ +# This is the local configure file (distribution version). +# You must modify it to fit your particular configuration +# and name it Config.local +# The following configuratiions can be auto-generated: +# +# make Config.local.green +# make a Config.local that supports a local clock +# (i.e. allow fallback to use of the CPU's own clock) +# make Config.local.NO.clock +# make a Config.local that supports no clocks +# +# +# NOTE TO GREENHORNS +# +# For plug-'n-play and no radios or other complicated gadgetry, +# use "make Config.local.green" or "make Config.local.local" as above. +# +# Following defines can be set in the DEFS_OPT= define: +# +# The flag -DDEBUG includes some debugging code. To use this, include +# the define and start the daemon with one or more -d flags, depending +# on your calibration of pearannoya. The daemon will not detach your +# terminal in this case. Judicious use of grep will reduce the speaker +# volume to bearable levels. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# The -DSYSLOG_FILE defines allows logging messages that are normally +# reported via syslof() in a file. The file name can be configured using +# the configuration line "logfile <filename>" in CONFIG_FILE. +# +# There are three serial port system software interfaces, each of +# which is peculiar to one or more Unix versions. Define +# -DHAVE_SYSV_TTYS for basic System V compatibility; define -DSTREAM +# for POSIX compatibility including System V Streams, and +# HAVE_BSD_TTYS for 4.3bsd compatibility. Only one of these three +# should be defined. If none are defined, HAVE_BSD_TTYS is assumed. +# Usually these defines are already set correctly. +# +DEFS_OPT=-DDEBUG +# +# The DEFS_LOCAL define picks up all flags from DEFS_OPT (do not delete that) +# and one of the following: +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you may also want to +# configure the particular clock drivers you want in the CLOCKDEFS= line +# below. This flag affects xntpd only. This define is included by +# default when using the "make makeconfig" script. +# +# The next two sets of defines are meaningful only when radio clock +# drivers or special 1-pps signals are to be used. For systems without +# these features, these delicious complexities can be avoided. Ordinarily, +# the "make makeconfig" script figures out which ones to use, but your +# mileage may vary. +# +# There are three ways to utilize external 1-pps signals. Define +# -DPPS to include just the pps routine, such as used by the DCF77(PARSE) +# clock driver. Define -DPPSCLK to include a serial device driver +# which avoids much of the jitter due to upper level port +# processing. This requires a dedicated serial port and either the +# tty_clock line discipline or tty_clk_streams module, both of +# which are in the ./kernel directory. Define -DPPSCD to include a +# special driver which intercepts carrier-detect transitions +# generated by the pps signal. This requires a nondedicated serial +# port and the ppsclock streams module in the ./kernel directory. +# Only one of these three flags should be defined. +# +# The flag KERNEL_PLL causes code to be compiled for a special feature of +# the kernel that (a) implements the phase-lock loop and (b) provides +# a user interface to learn time, maximum error and estimated error. +# See the file README.kern in the doc directory for further info. +# This code is activated only if the relevant kernel features have +# been configured; it does not affect operation of unmodified kernels. +# To compile it, however, requires a few header files from the +# special distribution. +# +# Note: following line must always start with DEFS_LOCAL= $(DEFS_OPT) +DEFS_LOCAL= $(DEFS_OPT) -DPPSPPS -DREFCLOCK -DKERNEL_PLL +# +# Radio clock support definitions (these only make sense if -DREFCLOCK +# used), which is normally the case. Note that a configuration can include +# no clocks, more than one type of clock and even multiple clocks of the +# same type. +# +# For most radio clocks operating with serial ports, accuracy can +# be considerably improved through use of the tty_clk line +# discipline or tty_clk_STREAMS streams module found in the +# ./kernel directory. These gizmos capture a timestamp upon +# occurrence of an intercept character and stuff it in the data +# stream for the clock driver to munch. To select this mode, +# postfix the driver name with the string CLK; that is, WWVB +# becomes WWVBCLK. If more than one clock is in use, the CLK +# postfix can be used with any or all of them. +# +# Alternatively, for the best accuracy, use the ppsclock streams +# module in the ./ppsclock directory to steal the carrier-detect +# transition and capture a precision timestamp. At present this +# works only with SunOS 4.1.1 or later. To select this mode, +# postfix the driver name with the string PPS; that is, AS2201 +# becomes AS2201PPS. If more than one clock is in use, the PPS +# postfix should be used with only one of them. If any PPS +# postfix is defined, the -DPPSPPS define should be used on the +# DEFS above. +# +# Define -DLOCAL_CLOCK for a local pseudo-clock to masquerade as a +# reference clock for those subnets without access to the real thing. +# Works in all systems and requires no hardware support. This is defined +# by default when using the "make makeconfig" script and greenhorn +# configuraiton. +# +# Define -DPST for a PST/Traconex 1020 WWV/H receiver. The driver +# supports both the CLK and PPS modes. It should work in all systems +# with a serial port. +# +# Define -DWWVB for a Spectracom 8170 or Netclock/2 WWVB receiver. It +# should work in all systems with a serial port. The driver supports +# both the CLK and PPS modes if the requisite kernel support is installed. +# +# Define -DCHU for a special CHU receiver using an ordinary shortwave +# radio. This requires the chu_clk line discipline or chu_clk_STREAMS +# module in the ./kernel directory. At present, this driver works only +# on SunOS4.1.x; operation in other systems has not been confirmed. +# Construction details for a suitable modem can be found in the ./gadget +# directory. The driver supports # neither the CLK nor PPS modes. +# +# Define -DPARSE for a DCF77/GPS(GENERIC) receiver. For best performance +# this requires a special parsestreams STREAMS (SunOS 4.x) module in the +# ./parse directory. Define -DPARSEPPS for PPS support via the +# DCF77/GPS (GENERIC) receiver; also, define -DPPS in the DEFS above. +# Define: -DCLOCK_MEINBERG for Meinberg clocks +# -DCLOCK_SCHMID for Schmid receivers +# -DCLOCK_DCF7000 for ELV DCF7000 +# -DCLOCK_RAWDCF for simple receivers (100/200ms pulses on Rx) +# -DCLOCK_TRIMSV6 for Trimble SV6 GPS receiver +# +# Define -DMX4200PPS for a Magnavox 4200 GPS receiver. At present, this +# driver works only on SunOS4.1.x with CPU serial ports only. The PPS +# mode is required. +# +# Define -DAS2201 for an Austron 2200A or 2201A GPS receiver. It should +# work in all systems with a serial port. The driver does not support the +# CLK mode, but does support the PPS mode. If the radio is connected to +# more than one machine, the PPS mode is required. +# +# Define -DGOES for a Kinemetrics/TrueTime 468-DC GOES receiver. This +# driver is known to work with some other TrueTime products as well, +# including the GPS-DC GPS receiver. It should work in all systems with +# a serial port. The driver does not support the CLK mode, but does +# support the PPS mode. +# +# Define -DOMEGA for a Kinemetrics/TrueTime OM-DC OMEGA receiver. It +# should work in all systems with a serial port. The driver does not +# support the CLK mode, but does support the PPS mode. +# +# Define -DTPRO for a KSI/Odetics TPRO-S IRIG-B timecode reader. This +# requires the SunOS interface driver available from KSI. The driver +# supports neither the CLK nor PPS modes. +# +# Define -DLEITCH for a Leitch CSD 5300 Master Clock System Driver for +# the HP 5061B Cesium Clock. It should work in all systems with a serial +# port. The driver does not support the CLK mode, but does support the +# PPS mode. +# +# Define -DMSFEESPPS for an EES M201 MSF receiver. It currently only works +# under SunOS 4.x with the PPSCD (ppsclock) STREAMS module, but the RCS +# files on cl.cam.ac.uk still has support for CLK and CBREAK modes. +# +# Define -DIRIG for a IRIG-B timecode timecode using the audio codec of +# the Sun SPARCstations. This requires a modified BSD audio driver and +# exclusive access to the audio port. A memo describing how it works and +# how to install the driver is in the README.irig file in the ./doc +# directory. +# +# Note: The following defines result in compilation of all the above radio +# clocks. This works on a Sun 4.1.x system which has tty_clk, chu_clk and +# ppsclock STREAMS modules installed. If the trailing CLK and PPS suffixes +# are removed and the IRIG, PARSE* and CLOCK* deleted, all of the rest compile +# under Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC +# OSF/1 Alpha. +# +CLOCKDEFS=-DAS2201PPS -DCHU -DGOES -DIRIG -DLEITCH -DLOCAL_CLOCK -DMX4200PPS -DOMEGA -DPSTCLK -DTPRO -DWWVBCLK +# +# Directory into which binaries should be installed (default /usr/local) +# +BINDIR= /usr/local/bin diff --git a/usr.sbin/xntpd/conf/Config.local b/usr.sbin/xntpd/conf/Config.local new file mode 100644 index 000000000000..4c5095c164da --- /dev/null +++ b/usr.sbin/xntpd/conf/Config.local @@ -0,0 +1,190 @@ +# This is the local configure file (distribution version). +# You must modify it to fit your particular configuration +# and name it Config.local +# The following configuratiions can be auto-generated: +# +# make Config.local.green +# make a Config.local that supports a local clock +# (i.e. allow fallback to use of the CPU's own clock) +# make Config.local.NO.clock +# make a Config.local that supports no clocks +# +# +# NOTE TO GREENHORNS +# +# For plug-'n-play and no radios or other complicated gadgetry, +# use "make Config.local.green" as above. +# +# Following defines can be set in the DEFS_OPT= define: +# +# The flag -DDEBUG includes some debugging code. To use this, include +# the define and start the daemon with one or more -d flags, depending +# on your calibration of pearannoya. The daemon will not detach your +# terminal in this case. Judicious use of grep will reduce the speaker +# volume to bearable levels. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# The -DSYSLOG_FILE defines allows logging messages that are normally +# reported via syslof() in a file. The file name can be configured using +# the configuration line "logfile <filename>" in CONFIG_FILE. +# +# There are three serial port system software interfaces, each of +# which is peculiar to one or more Unix versions. Define +# -DHAVE_SYSV_TTYS for basic System V compatibility; define -DSTREAM +# for POSIX compatibility including System V Streams, and +# HAVE_BSD_TTYS for 4.3bsd compatibility. Only one of these three +# should be defined. If none are defined, HAVE_BSD_TTYS is assumed. +# Usually these defines are already set correctly. +# +DEFS_OPT=-DDEBUG + +# +# The DEFS_LOCAL define picks up all flags from DEFS_OPT (do not delete that) +# and one of the following: +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you may also want to +# configure the particular clock drivers you want in the CLOCKDEFS= line +# below. This flag affects xntpd only. This define is included by +# default when using the "make makeconfig" script. +# +# The next two sets of defines are meaningful only when radio clock +# drivers or special 1-pps signals are to be used. For systems without +# these features, these delicious complexities can be avoided. Ordinarily, +# the "make makeconfig" script figures out which ones to use, but your +# mileage may vary. +# +# There are three ways to utilize external 1-pps signals. Define +# -DPPS to include just the pps routine, such as used by the DCF77(PARSE) +# clock driver. Define -DPPSCLK to include a serial device driver +# which avoids much of the jitter due to upper level port +# processing. This requires a dedicated serial port and either the +# tty_clock line discipline or tty_clk_streams module, both of +# which are in the ./kernel directory. Define -DPPSCD to include a +# special driver which intercepts carrier-detect transitions +# generated by the pps signal. This requires a nondedicated serial +# port and the ppsclock streams module in the ./kernel directory. +# Only one of these three flags should be defined. +# +# The flag KERNEL_PLL causes code to be compiled for a special feature of +# the kernel that (a) implements the phase-lock loop and (b) provides +# a user interface to learn time, maximum error and estimated error. +# See the file README.kern in the doc directory for further info. +# This code is activated only if the relevant kernel features have +# been configured; it does not affect operation of unmodified kernels. +# To compile it, however, requires a few header files from the +# special distribution. +# +# Note: following line must always start with DEFS_LOCAL= $(DEFS_OPT) +DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DPPSPPS -DKERNEL_PLL + +# +# Radio clock support definitions (these only make sense if -DREFCLOCK +# used), which is normally the case. Note that a configuration can include +# no clocks, more than one type of clock and even multiple clocks of the +# same type. +# +# For most radio clocks operating with serial ports, accuracy can +# be considerably improved through use of the tty_clk line +# discipline or tty_clk_STREAMS streams module found in the +# ./kernel directory. These gizmos capture a timestamp upon +# occurrence of an intercept character and stuff it in the data +# stream for the clock driver to munch. To select this mode, +# postfix the driver name with the string CLK; that is, WWVB +# becomes WWVBCLK. If more than one clock is in use, the CLK +# postfix can be used with any or all of them. +# +# Alternatively, for the best accuracy, use the ppsclock streams +# module in the ./ppsclock directory to steal the carrier-detect +# transition and capture a precision timestamp. At present this +# works only with SunOS 4.1.1 or later. To select this mode, +# postfix the driver name with the string PPS; that is, AS2201 +# becomes AS2201PPS. If more than one clock is in use, the PPS +# postfix should be used with only one of them. If any PPS +# postfix is defined, the -DPPSPPS define should be used on the +# DEFS above. +# +# Define -DLOCAL_CLOCK for a local pseudo-clock to masquerade as a +# reference clock for those subnets without access to the real thing. +# Works in all systems and requires no hardware support. This is defined +# by default when using the "make makeconfig" script and greenhorn +# configuraiton. +# +# Define -DPST for a PST/Traconex 1020 WWV/H receiver. The driver +# supports both the CLK and PPS modes. It should work in all systems +# with a serial port. +# +# Define -DWWVB for a Spectracom 8170 or Netclock/2 WWVB receiver. It +# should work in all systems with a serial port. The driver supports +# both the CLK and PPS modes if the requisite kernel support is installed. +# +# Define -DCHU for a special CHU receiver using an ordinary shortwave +# radio. This requires the chu_clk line discipline or chu_clk_STREAMS +# module in the ./kernel directory. At present, this driver works only +# on SunOS4.1.x; operation in other systems has not been confirmed. +# Construction details for a suitable modem can be found in the ./gadget +# directory. The driver supports # neither the CLK nor PPS modes. +# +# Define -DPARSE for a DCF77/GPS(GENERIC) receiver. For best performance +# this requires a special parsestreams STREAMS (SunOS 4.x) module in the +# ./parse directory. Define -DPARSEPPS for PPS support via the +# DCF77/GPS (GENERIC) receiver; also, define -DPPS in the DEFS above. +# Define: -DCLOCK_MEINBERG for Meinberg clocks +# -DCLOCK_SCHMID for Schmid receivers +# -DCLOCK_DCF7000 for ELV DCF7000 +# -DCLOCK_RAWDCF for simple receivers (100/200ms pulses on Rx) +# -DCLOCK_TRIMSV6 for Trimble SV6 GPS receiver +# +# Define -DMX4200PPS for a Magnavox 4200 GPS receiver. At present, this +# driver works only on SunOS4.1.x with CPU serial ports only. The PPS +# mode is required. +# +# Define -DAS2201 for an Austron 2200A or 2201A GPS receiver. It should +# work in all systems with a serial port. The driver does not support the +# CLK mode, but does support the PPS mode. If the radio is connected to +# more than one machine, the PPS mode is required. +# +# Define -DGOES for a Kinemetrics/TrueTime 468-DC GOES receiver. This +# driver is known to work with some other TrueTime products as well, +# including the GPS-DC GPS receiver. It should work in all systems with +# a serial port. The driver does not support the CLK mode, but does +# support the PPS mode. +# +# Define -DOMEGA for a Kinemetrics/TrueTime OM-DC OMEGA receiver. It +# should work in all systems with a serial port. The driver does not +# support the CLK mode, but does support the PPS mode. +# +# Define -DTPRO for a KSI/Odetics TPRO-S IRIG-B timecode reader. This +# requires the SunOS interface driver available from KSI. The driver +# supports neither the CLK nor PPS modes. +# +# Define -DLEITCH for a Leitch CSD 5300 Master Clock System Driver for +# the HP 5061B Cesium Clock. It should work in all systems with a serial +# port. The driver does not support the CLK mode, but does support the +# PPS mode. +# +# Define -DMSFEESPPS for an EES M201 MSF receiver. It currently only works +# under SunOS 4.x with the PPSCD (ppsclock) STREAMS module, but the RCS +# files on cl.cam.ac.uk still has support for CLK and CBREAK modes. +# +# Define -DIRIG for a IRIG-B timecode timecode using the audio codec of +# the Sun SPARCstations. This requires a modified BSD audio driver and +# exclusive access to the audio port. A memo describing how it works and +# how to install the driver is in the README.irig file in the ./doc +# directory. +# +# Note: The following defines result in compilation of all the above radio +# clocks. This works on a Sun 4.1.x system which has tty_clk, chu_clk and +# ppsclock STREAMS modules installed. If the trailing CLK and PPS suffixes +# are removed and the IRIG, PARSE* and CLOCK* deleted, all of the rest compile +# under Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC +# OSF/1 Alpha. +# +CLOCKDEFS= -DLOCAL_CLOCK -DAS2201PPS -DCHU -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPSTCLK -DTPRO -DWWVBCLK -DMSFEESPPS -DLEITCH + +# +# Directory into which binaries should be installed (default /usr/local) +# +BINDIR= /usr/local/bin diff --git a/usr.sbin/xntpd/conf/Config.svr4 b/usr.sbin/xntpd/conf/Config.svr4 new file mode 100644 index 000000000000..d6d0661539f1 --- /dev/null +++ b/usr.sbin/xntpd/conf/Config.svr4 @@ -0,0 +1,167 @@ +# +# This is the local configure file. Modify it to fit your particular +# configuration. +# +# NOTE TO GREENHORNS +# +# For plug-'n-play and no radios or other complicated gadgetry, set the +# alternate defines as shown. +# +# The flag -DDEBUG includes some debugging code. To use this, include +# the define and start the daemon with one or more -d flags, depending +# on your calibration of pearannoya. The daemon will not detach your +# terminal in this case. Judicious use of grep will reduce the speaker +# volume to bearable levels. +# +# To change the location of the configuration file, use a +# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar. +# +# The flag -DREFCLOCK causes the basic reference clock support to be +# compiled into the daemon. If you set this you may also want to +# configure the particular clock drivers you want in the CLOCKDEFS= line +# below. This flag affects xntpd only. This define is included by +# default when using the "make makeconfig" script. +# +# The next two sets of defines are meaningful only when radio clock +# drivers or special 1-pps signals are to be used. For systems without +# these features, these delicious complexities can be avoided. Ordinarily, +# the "make makeconfig" script figures out which ones to use, but your +# mileage may vary. +# +# There are three ways to utilize external 1-pps signals. Define +# -DPPS to include just the pps routine, such as used by the DCF77 +# clock driver. Define -DPPSCLK to include a serial device driver +# which avoids much of the jitter due to upper level port +# processing. This requires a dedicated serial port and either the +# tty_clock line discipline or tty_clk_streams module, both of +# which are in the ./kernel directory. Define -DPPSCD to include a +# special driver which intercepts carrier-detect transitions +# generated by the pps signal. This requires a nondedicated serial +# port and the ppsclock streams module in the ./kernel directory. +# Only one of these three flags should be defined. +# +# There are three serial port system software interfaces, each of +# which is peculiar to one or more Unix versions. Define +# -DHAVE_SYSV_TTYS for basic System V compatibility; define -DSTREAM +# for POSIX compatibility including System V Streams, and +# HAVE_BSD_TTYS for 4.3bsd compatibility. Only one of these three +# should be defined. If none are defined, HAVE_BSD_TTYS is assumed. +# Ordinarily, the correct define is sniffed by the "make makeconfig" +# script and automatically included. +# +# The flag KERNEL_PLL is a temporary hack to use when the phase-lock loop +# is implmented in the kernel. Do not use unless you have modified +# kernel routines (see doc/README.kern). +# +#DEFS_LOCAL= -DDEBUG -DPPSPPS -DKERNEL_PLL +DEFS_LOCAL= -DDEBUG +#DEFS_LOCAL= # for greenhorns +# +# Radio clock support definitions (these only make sense if -DREFCLOCK +# used), which is normally the case. Note that a configuration can include +# no clocks, more than one type of clock and even multiple clocks of the +# same type. +# +# For most radio clocks operating with serial ports, accuracy can +# be considerably improved through use of the tty_clk line +# discipline or tty_clk_STREAMS streams module found in the +# ./kernel directory. These gizmos capture a timestamp upon +# occurrence of an intercept character and stuff it in the data +# stream for the clock driver to munch. To select this mode, +# postfix the driver name with the string CLK; that is, WWVB +# becomes WWVBCLK. If more than one clock is in use, the CLK +# postfix can be used with any or all of them. +# +# Alternatively, for the best accuracy, use the ppsclock streams +# module in the ./ppsclock directory to steal the carrier-detect +# transition and capture a precision timestamp. At present this +# works only with SunOS 4.1.1 or later. To select this mode, +# postfix the driver name with the string PPS; that is, AS2201 +# becomes AS2201PPS. If more than one clock is in use, the PPS +# postfix should be used with only one of them. If any PPS +# postfix is defined, the -DPPSPPS define should be used on the +# DEFS above. +# +# Define -DLOCAL_CLOCK for a local pseudo-clock to masquerade as a +# reference clock for those subnets without access to the real thing. +# Works in all systems and requires no hardware support. This is defined +# by default when using the "make makeconfig" script. +# +# Define -DPST for a PST/Traconex 1020 WWV/H receiver. The driver +# supports both the CLK and PPS modes. It should work in all systems +# with a serial port. +# +# Define -DWWVB for a Spectracom 8170 or Netclock/2 WWVB receiver. It +# should work in all systems with a serial port. The driver supports +# both the CLK and PPS modes if the requisite kernel support is installed. +# +# Define -DCHU for a special CHU receiver using an ordinary shortwave +# radio. This requires the chu_clk line discipline or chu_clk_STREAMS +# module in the ./kernel directory. At present, this driver works only +# on SunOS4.1.x; operation in other systems has not been confirmed. +# Construction details for a suitable modem can be found in the ./gadget +# directory. The driver supports # neither the CLK nor PPS modes. +# +# Define -DPARSE for a DCF77/GPS(GENERIC) receiver. For best performance +# this requires a special parsestreams STREAMS (SunOS 4.x) module in the +# ./kernel directory. Define -DPARSEPPS for PPS support via the +# DCF77/GPS (GENERIC) receiver; also, define -DPPS in the DEFS above. +# Define PARSESTREAM for utilising the STREAMS module for improved +# precision (currently only SunOS4.x) +# +# Define: -DCLOCK_MEINBERG for Meinberg clocks +# -DCLOCK_SCHMID for Schmid receivers +# -DCLOCK_DCF7000 for ELV DCF7000 +# -DCLOCK_RAWDCF for simple receivers (100/200ms pulses on Rx) +# +# Define -DMX4200PPS for a Magnavox 4200 GPS receiver. At present, this +# driver works only on SunOS4.1.x with CPU serial ports only. The PPS +# mode is required. +# +# Define -DAS2201 for an Austron 2200A or 2201A GPS receiver. It should +# work in all systems with a serial port. The driver does not support the +# CLK mode, but does support the PPS mode. If the radio is connected to +# more than one machine, the PPS mode is required. +# +# Define -DGOES for a Kinemetrics/TrueTime 468-DC GOES receiver. This +# driver is known to work with some other TrueTime products as well, +# including the GPS-DC GPS receiver. It should work in all systems with +# a serial port. The driver does not support the CLK mode, but does +# support the PPS mode. +# +# Define -DOMEGA for a Kinemetrics/TrueTime OM-DC OMEGA receiver. It +# should work in all systems with a serial port. The driver does not +# support the CLK mode, but does support the PPS mode. +# +# Define -DTPRO for a KSI/Odetics TPRO-S IRIG-B timecode reader. This +# requires the SunOS interface driver available from KSI. The driver +# supports neither the CLK nor PPS modes. +# +# Define -DLEITCH for a Leitch CSD 5300 Master Clock System Driver for +# the HP 5061B Cesium Clock. It should work in all systems with a serial +# port. The driver does not support the CLK mode, but does support the +# PPS mode. +# +# Define -DMSF for a EES M201 MSF receiver. It should work in all systems +# with a serial port. The driver does not support the CLK mode, but does +# support the # PPS mode. +# +# Define -DIRIG for a IRIG-B timecode timecode using the audio codec of +# the Sun SPARCstations. This requires a modified BSD audio driver and +# exclusive access to the audio port. A memo describing how it works and +# how to install the driver is in the README.irig file in the ./doc +# directory. +# +# Note: The following defines result in compilation of all the above radio +# clocks. This works on a Sun 4.1.x system which has tty_clk, chu_clk and +# ppsclock STREAMS modules installed. If the trailing CLK and PPS suffixes +# are removed and the IRIG deleted, all of the rest compile under +# Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC +# OSF/1 Alpha. +# +#CLOCKDEFS= -DAS2201PPS -DCHU -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPST -DPSTCLK -DTPRO -DWWVBCLK +CLOCKDEFS= # for greenhorns +# +# Directory into which binaries should be installed +# +BINDIR= /usr/etc diff --git a/usr.sbin/xntpd/conf/README b/usr.sbin/xntpd/conf/README new file mode 100644 index 000000000000..19dcb795f80c --- /dev/null +++ b/usr.sbin/xntpd/conf/README @@ -0,0 +1,8 @@ +README file for directory ./conf of the NTP Version 3 distribution + +This directory contains example run-time configuration files for the +NTP Version 3 daemon xntpd. These files illustrate some of the more +obtuse configurations you may run into. They are not likely to do +anything good if run on machines other than their native spot, so don't +just blindly copy something and put it up. Additional information can +be found in the ./doc directory of the base directory. diff --git a/usr.sbin/xntpd/conf/dewey.conf b/usr.sbin/xntpd/conf/dewey.conf new file mode 100644 index 000000000000..523008fcdc82 --- /dev/null +++ b/usr.sbin/xntpd/conf/dewey.conf @@ -0,0 +1,38 @@ +# +# NTP configuration file (ntp.conf) +# dewey.udel.edu (128.175.1.2) +# +# Stratum-1 peers +# +#peer 128.4.1.5 # dcn5.udel.edu +#peer 128.8.10.1 # umd1.umd.edu +#peer 18.72.0.3 version 2 # bitsy.mit.edu +peer 192.43.244.9 # ncar-fuzz.nsf.net +peer 132.249.16.1 # sdsc-fuzz.nsf.net +peer 128.118.46.3 version 2 # otc1.psu.edu +#peer 130.126.174.40 # truechimer.cso.uiuc.edu +#peer 128.9.2.129 # wwvb.isi.edu +#peer 130.43.2.2 version 2 # apple.com +# +# Stratum-2 peers +# +peer 128.175.1.1 # huey.udel.edu +#peer 128.175.1.2 # dewey.udel.edu +peer 128.175.1.3 # louie.udel.edu +#peer 128.175.2.33 # louie.udel.edu +#peer 128.175.7.39 # louie.udel.edu +# +# Miscellaneous stuff +# +monitor yes # enable monitoring +precision -7 # clock reading precision (10 msec) +driftfile /etc/ntp.drift # path for drift file +# +# Authentication stuff +# +authenticate yes # enable authentication +keys /etc/ntp.keys # path for key file +trustedkey 1 2 15 # define trusted keys +requestkey 15 # key (7) for accessing server variables +controlkey 15 # key (6) for accessing server variables +authdelay 0.001501 # authentication delay (VAX 11/780) diff --git a/usr.sbin/xntpd/conf/grundoon.conf b/usr.sbin/xntpd/conf/grundoon.conf new file mode 100644 index 000000000000..c5aef6eb88e3 --- /dev/null +++ b/usr.sbin/xntpd/conf/grundoon.conf @@ -0,0 +1,58 @@ +# +# NTP configuration file (ntp.conf) +# grundoon.udel.edu (128.4.2.7) +# +server 127.127.6.0 prefer # irig audio decoder +fudge 127.127.6.0 time1 0.0005 +#pps delay -0.0004 # pps correction for CLK streams module +server 127.127.4.1 # spectracom 8170/netclock-2 wwvb receiver +# propagation delay: wwvb 0.0088; receiver delay 0.0173 os delay .0035 +fudge 127.127.4.1 time1 0.0035 flag4 1 +server 127.127.3.1 # pst/traconex 1020 wwv/h receiver +# propagation delay: wwv 0.0088 wwvh 0.0281; receiver+os delay 0.0035 +fudge 127.127.3.1 time1 0.0123 time2 0.0316 +server 127.127.7.1 # scratchbuilt chu receiver/demodulator +# propagtion delay: chu 0.0030; receiver+os delay 0.0060 +fudge 127.127.7.1 time1 0.0030 time2 0.0060 +#server 127.127.10.1 # austron 2201 gps receiver + +server 127.127.1.2 # local clock +#server 127.127.12.2 # ksi/odetics tpr0-s irig-b reader + +#broadcast 128.4.2.255 + +peer 128.4.1.1 key 3 # rackety.udel.edu (Sun4c/40 IPC) +peer 128.4.1.4 # barnstable.udel.edu (Sun4c/65 SS1+) +#peer 128.4.1.5 # churchy.udel.edu (Bancomm bc700LAN) +#peer 128.4.2.7 key 3 # grundoon.udel.edu (Sun4c/40 IPC) +peer 128.4.1.8 # bridgeport.udel.edu (Sun4c/40 IPC) +peer 128.4.1.20 key 3 # pogo.udel.edu (Sun4c/65 SS1+) +peer 128.4.1.22 # malarky.udel.edu (Sun4c/50 IPX) +peer 128.4.1.23 # beauregard.udel.edu (Sun4/40 IPC) +peer 128.4.1.24 # baldwin.udel.edu (Sun4/40 IPC) +peer 128.4.1.25 # albert.udel.edu (Sun4c/60 SS1) +peer 128.4.1.27 # bunnylou.udel.edu (Sun4c/40 IPC) +peer 128.4.1.28 # cowbird.udel.edu (DEC 5000/240) +peer 128.4.1.29 # porkypine.udel.edu (DEC 5000/240) +# +# Miscellaneous stuff +# +monitor yes # enable monitoring +precision -18 # clock reading precision (usec) +driftfile /etc/ntp.drift # path for drift file +statsdir /grundoon/ntpstats/ # directory for statistics files +filegen peerstats file peerstats type day enable +filegen loopstats file loopstats type day enable +filegen clockstats file clockstats type day enable + +# +# Authentication stuff +# +authenticate yes # enable authentication +keys /usr/local/ntp.keys # path for keys file +trustedkey 1 2 3 4 14 15 # define trusted keys +requestkey 15 # key (7) for accessing server variables +controlkey 15 # key (6) for accessing server variables +#authdelay 0.000073 # authentication delay (SPARC4c/40 IPC DES) +authdelay 0.000163 # authentication delay (SPARC4c/40 IPC MD5) + diff --git a/usr.sbin/xntpd/conf/malarky.conf b/usr.sbin/xntpd/conf/malarky.conf new file mode 100644 index 000000000000..f887f839d1bb --- /dev/null +++ b/usr.sbin/xntpd/conf/malarky.conf @@ -0,0 +1,40 @@ +# +# NTP configuration file (ntp.conf) +# malarky.udel.edu (128.4.1.22) +# +peer 128.4.1.1 # rackety.udel.edu +peer 128.4.1.4 # barnstable.udel.edu +#peer 128.4.1.5 #churchy.udel.edu +peer 128.4.2.7 # grundoon.udel.edu +peer 128.4.1.8 # bridgeport.udel.edu +peer 128.4.1.20 prefer # pogo.udel.edu +#peer 128.4.1.22 # malarky.udel.edu +peer 128.4.1.23 # beauregard.udel.edu +peer 128.4.1.24 # baldwin.udel.edu +peer 128.4.1.25 # albert.udel.edu +peer 128.4.1.27 # bunnylou.udel.edu +peer 128.4.1.28 # cowbird.udel.edu +peer 128.4.1.29 # porkypine.udel.edu + +# +# Miscellaneous stuff +# +monitor yes # enable monitoring +precision -18 # clock reading precision (usec) +driftfile /etc/ntp.drift # path for drift file +statsdir /malarky/ntpstats/ # directory for statistics files +filegen peerstats file peerstats type day enable +filegen loopstats file loopstats type day enable +filegen clockstats file clockstats type day enable + +# +# Authentication stuff +# +authenticate yes # enable authentication +keys /usr/local/bin/ntp.keys # path for key file +trustedkey 1 2 3 4 14 15 # define trusted keys +requestkey 15 # key (7) for accessing server variables +controlkey 15 # key (6) for accessing server variables +#authdelay 0.000047 # authentication delay (Sun4c/50 IPX DES) +authdelay 0.000094 # authentication delay (Sun4c/50 IPX MD5) + diff --git a/usr.sbin/xntpd/conf/ntp.conf.gw b/usr.sbin/xntpd/conf/ntp.conf.gw new file mode 100644 index 000000000000..bd5687874f53 --- /dev/null +++ b/usr.sbin/xntpd/conf/ntp.conf.gw @@ -0,0 +1,34 @@ +# +# peers for gw.ccie.utoronto.ca (128.100.63.2, 128.100.49.104, 128.100.224.224) +# +peer 128.4.0.1 key 1 # dcn1.udel.edu +peer 128.8.10.1 key 2 # umd1.umd.edu +peer 128.116.64.3 key 3 # ncarfuzz.ucar.edu +peer 128.9.2.129 key 4 # wwvb.isi.edu +#peer 128.4.0.6 key 1 # dcn6.udel.edu +# +# Don't configure associations with the other secondaries. This is +# the only one in a machine room and will hold itself pretty stable +# when all else fails +# +monitor yes # keep track of traffic + +# +# drift file +# +driftfile /etc/ntp.drift + +# +# authentication stuff. We're running authenticated, tell it +# where the keys are and which to trust. +# +authenticate yes +authdelay 0.000323 # seconds, about right for an RT model 125 +trustedkey 1 2 3 4 21 22 23 24 +keys /etc/ntp.keys + +# +# allow run time reconfiguration using key 65535 +# +requestkey 65535 +controlkey 65535 diff --git a/usr.sbin/xntpd/conf/ntp.conf.ipl b/usr.sbin/xntpd/conf/ntp.conf.ipl new file mode 100644 index 000000000000..1fd5b7d62145 --- /dev/null +++ b/usr.sbin/xntpd/conf/ntp.conf.ipl @@ -0,0 +1,32 @@ +# +# peers for ipl.utcs.utoronto.ca (128.100.102.7) +# +peer 128.4.0.5 key 1 # dcn5.udel.edu +peer 128.8.10.1 key 2 # umd1.umd.edu +peer 192.12.207.1 key 3 # fuzz.sdsc.edu +peer 128.9.2.129 key 4 # wwvb.isi.edu +peer 128.100.63.2 key 21 # gw.ccie +peer 128.100.49.105 key 22 # suzuki.ccie +peer 128.100.102.4 key 23 # shiningtree.utcs +# +monitor yes # keep track of traffic + +# +# drift file +# +driftfile /etc/ntp.drift + +# +# authentication stuff. We're running authenticated, tell it +# where the keys are and which to trust. +# +authenticate yes +authdelay 0.000323 # seconds, about right for an RT model 125 +trustedkey 1 2 3 4 21 22 23 +keys /etc/ntp.keys + +# +# allow run time reconfiguration using key 65535 +# +requestkey 65535 +controlkey 65535 diff --git a/usr.sbin/xntpd/conf/ntp.conf.nsf b/usr.sbin/xntpd/conf/ntp.conf.nsf new file mode 100644 index 000000000000..298bb7a6905e --- /dev/null +++ b/usr.sbin/xntpd/conf/ntp.conf.nsf @@ -0,0 +1,156 @@ +# +# Maybe an alternate xntpd configuration for NSS#17 +# + +# +# precision is supported, but you don't really need it. The code +# will determine a precision from the kernel's value of _hz which +# is fine. Note you shouldn't claim too good a precision on a +# Unix machine even if the clock carries a lot of bits, since +# precision also depends on things like I/O delays and scheduling +# latencies, which Unix machines control poorly. If you claim better +# than -6 or -7 it will make the anti-hop aperture tighter than is +# reasonable for a Unix machine. +# +#precision -7 + +# +# peers are ncarfuzz.ucar.edu umd1.umd.edu dcn5.udel.edu fuzz.sdsc.edu +# syntax is peer addr [ key 1-15 ] [ version 1_or_2 ] +# + +peer 128.116.64.3 # ncarfuzz.ucar.edu +peer 128.8.10.1 # umd1.umd.edu +peer 128.4.0.5 # dcn5.udel.edu +peer 192.12.207.1 # fuzz.sdsc.edu + +# +# Drift file. Put this in a directory which the daemon can write to. +# No symbolic links allowed, either, since the daemon updates the file +# by creating a temporary in the same directory and then rename()'ing +# it to the file. +# +# This is a nice feature. Once you've got the drift computed it hardly +# ever takes more than an hour or so to resync after a restart. +# +driftfile /etc/ntp.drift + +# +# The server statement causes polling to be done in client mode rather +# than symmetric active. It is an alternative to the peer command +# above. Which you use depends on what you want to achieve. Usually +# it doesn't matter. Syntax is: +# +#server 128.100.49.1 key 4 version 1 + +# +# The broadcast statement tells it to start broadcasting time out one +# of its interfaces. Syntax is +# +#broadcast 128.100.49.255 # [ key n ] [ version n ] + +# +# broadcastclient tells the daemon whether it should attempt to sync +# to broadcasts or not. Defaults to `no'. +# +#broadcastclient yes # or no + +# +# broadcastdelay configures in a default round-trip delay to use for +# broadcast time. It may poll to improve this estimate. +# +#broadcastdelay 0.0095 # in seconds + +# +# authenticate configures us into strict authentication mode (or not). +# +#authenticate yes # or no. Default is no + +# +# authdelay is the time it takes to do an NTP encryption on this host. +# The current routine is pretty fast. +# +#authdelay 0.000340 # in seconds + +# +# trustedkey are used when authenticate is on. We only trust (and sync to) +# peers who know these keys. +# +#trustedkey 1 3 4 8 + +# +# monitor turns on the monitoring facility. See xntpdc's monlist command. +# This shows a lot of neat stuff, but I'm not fussy about the implementation. +# Uses up to 20Kb of memory at run time. You could try this. +# +#monitor yes # or no. Default is no + +# +# keys points at the file which holds the authentication keys. +# +#keys /etc/ntp.keys + +# +# requestkey indicates which key is to be used for validating +# runtime reconfiguration requests. If this isn't defined, or the +# key isn't in the keys file, you can't do runtime reconfiguration. +# controlkey indicates which key is to be used for validating +# mode 6 write variables commands. If this isn't defined you can't +# do it. The only thing the latter is used for is to set leap second +# warnings on machines with radio clocks. +# +#requestkey 65535 +#controlkey 65534 + +# +# restrict places restrictions on the punters. This is implemented as +# a sorted address-and-mask list, with each entry including a set of +# flags which define what a host matching the entry *can't* do (the sort +# also saves CPU time searching the table since it needn't be searched +# to the end). The last match in the table defines what the host does. +# The default entry, which everyone matches, is first, most specific +# matches are later in the table. The flags are: +# +# ignore - ignore all traffic from host +# noserve - don't give host any time (but let him make queries?) +# notrust - give host time, let him make queries, but don't sync to him +# noquery - host can have time, but not make queries +# nomodify - allow the host to make queries except those which are +# actually run-time configuration commands. +# notrap - don't allow matching hosts to set traps. If noquery is +# set this isn't needed +# lowpriotrap - if this guy sets a trap make it easy to delete +# ntpport - a different kind of flag. Makes matches for this entry +# possible only if the source port is 123. +# +# To understand this better, take a look at xntpdc's reslist command when the +# server is running. This usually prints in the sorted order. +# +# This should match the NSS 17 stuff. Default mask is all ones. + +restrict default ignore # ignore almost everyone + +# +# These guys can be served time and make non-modifying queries +# +restrict 129.140.0.0 mask 255.255.0.0 notrust nomodify +restrict 35.1.1.42 notrust nomodify + +# +# Rest of 35.1.1 gets to look but not touch +# +restrict 35.1.1.0 mask 255.255.255.0 noserve nomodify + +# +# modifications can be made from local NSS only +# +restrict 129.140.17.0 mask 255.255.255.0 notrust +restrict 127.0.0.1 notrust + +# +# take time from the following peers, but don't let them peek or modify +# +restrict 128.116.64.3 noquery +restrict 128.8.10.1 noquery +restrict 128.4.0.5 noquery +restrict 192.12.207.1 noquery diff --git a/usr.sbin/xntpd/conf/ntp.conf.shiningtree b/usr.sbin/xntpd/conf/ntp.conf.shiningtree new file mode 100644 index 000000000000..1576ebbd072c --- /dev/null +++ b/usr.sbin/xntpd/conf/ntp.conf.shiningtree @@ -0,0 +1,32 @@ +# +# peers for shiningtree.utcs.utoronto.ca (128.100.102.4) +# +peer 128.4.0.1 key 1 # dcn1.udel.edu +peer 130.126.174.40 key 2 # truechimer.cso.uiuc.edu +peer 192.12.207.1 key 3 # fuzz.sdsc.edu +peer 128.116.64.3 key 4 # ncarfuzz.ucar.edu +peer 128.100.63.2 key 21 # gw.ccie +peer 128.100.49.105 key 22 # suzuki.ccie +peer 128.100.102.7 key 23 # ipl.utcs +# +monitor yes # keep track of traffic + +# +# drift file +# +driftfile /etc/ntp.drift + +# +# authentication stuff. We're running authenticated, tell it +# where the keys are and which to trust. +# +authenticate yes +authdelay 0.000323 # seconds, about right for an RT model 125 +trustedkey 1 2 3 4 21 22 23 +keys /etc/ntp.keys + +# +# allow run time reconfiguration using key 65535 +# +requestkey 65535 +controlkey 65535 diff --git a/usr.sbin/xntpd/conf/ntp.conf.suzuki b/usr.sbin/xntpd/conf/ntp.conf.suzuki new file mode 100644 index 000000000000..ee32e7ad87a1 --- /dev/null +++ b/usr.sbin/xntpd/conf/ntp.conf.suzuki @@ -0,0 +1,43 @@ +# +# peers for suzuki.ccie.utoronto.ca (128.100.49.105, 128.100.224.225) +# + +# +# the reference clock, /dev/chu1 +# +server 127.127.7.1 key 4 +# Propagation delay 2.5 ms, sloppy clock flag on +fudge 127.127.7.1 time1 0.0025 flag1 1 + +peer 128.4.0.5 key 1 # dcn5.udel.edu +peer 128.8.10.1 key 2 # umd1.umd.edu +peer 128.116.64.34 key 3 # ncarfuzz.ucar.edu +peer 130.126.174.40 key 4 # truechimer.cso.uiuc.edu +peer 128.100.49.104 key 24 # gw.ccie +peer 128.100.102.4 key 22 # shiningtree.utcs +peer 128.100.102.7 key 22 # ipl.utcs + +peer 128.4.0.6 key 1 # dcn6.udel.edu + +# +monitor yes # keep track of traffic + +# +# drift file +# +driftfile /etc/ntp.drift + +# +# authentication stuff. We're running authenticated, tell it +# where the keys are and which to trust. +# +authenticate yes +authdelay 0.000323 # seconds, about right for an RT model 125 +trustedkey 1 2 3 4 21 22 23 24 +keys /etc/ntp.keys + +# +# allow run time reconfiguration using key 65535 +# +requestkey 65535 +controlkey 65535 diff --git a/usr.sbin/xntpd/conf/pogo.conf b/usr.sbin/xntpd/conf/pogo.conf new file mode 100644 index 000000000000..94ac6c84ea28 --- /dev/null +++ b/usr.sbin/xntpd/conf/pogo.conf @@ -0,0 +1,50 @@ +# +# NTP configuration file (ntp.conf) +# pogo.udel.edu (128.4.1.20) +# +server 127.127.10.1 prefer # austron 2201 gps receiver +#server 127.127.4.1 # spectracom 8170/netclock-2 wwvb receiver +# propagation delay: wwvb 0.0088; receiver delay 0.0017 +#fudge 127.127.4.1 time1 0.0017 + +peer 128.4.1.1 key 3 # rackety.udel.edu (Sun4c/40 IPC) +peer 128.4.1.2 # mizbeaver.udel.edu +peer 128.4.1.4 # barnstable.udel.edu (Sun4c/65 SS1+) +#peer 128.4.1.5 # churchy.udel.edu (Bancomm bc700LAN) +peer 128.4.2.7 key 3 # grundoon.udel.edu (Sun4c/40 IPC) +peer 128.4.1.5 maxpoll 8 # churchy.udel.edu (cisco IGS router) +#peer 128.4.1.8 # bridgeport.udel.edu (Sun4c/40 IPC) +#peer 128.4.1.20 key 3 # pogo.udel.edu (Sun4c/65 SS1+) +#peer 128.4.1.22 # malarky.udel.edu (Sun4c/50 IPX) +#peer 128.4.1.23 # beauregard.udel.edu (Sun4/40 IPC) +peer 128.4.1.24 # baldwin.udel.edu (Sun4/40 IPC) +#peer 128.4.1.25 # albert.udel.edu (Sun4c/60 SS1) +#peer 128.4.1.27 # maccarony.udel.edu (Sun4c/40 IPC) +peer 128.4.1.29 # porkypine.udel.edu +peer 132.163.135.130 maxpoll 8 # time_A.timefreq.bldrdoc.gov (ACTS) +peer 131.188.1.40 maxpoll 8 # ntps1-0.uni-erlangen.de (DCF77) +peer 129.132.2.21 maxpoll 8 # swisstime.ethz.ch (DCF77) +peer 130.155.98.13 maxpoll 8 # terss.ml.csiro.au (OMEGA) + +# +# Miscellaneous stuff +# +monitor yes # enable monitoring +precision -18 # clock reading precision (usec) +driftfile /etc/ntp.drift # path for drift file +statsdir /pogo/ntpstats/ # directory for statistics files +filegen peerstats file peerstats type day enable +filegen loopstats file loopstats type day enable +filegen clockstats file clockstats type day enable + +# +# Authentication stuff +# +authenticate yes # enable authentication +keys /usr/local/bin/ntp.keys # path for keys file +trustedkey 1 2 3 4 14 15 # define trusted keys +requestkey 15 # key (7) for accessing server variables +controlkey 15 # key (6) for accessing server variables +#authdelay 0.000072 # authentication delay (SPARC4c/65 SS1+ DES) +authdelay 0.000159 # authentication delay (SPARC4c/65 SS1+ MD5) + diff --git a/usr.sbin/xntpd/conf/rackety.conf b/usr.sbin/xntpd/conf/rackety.conf new file mode 100644 index 000000000000..1a5181cd4b5c --- /dev/null +++ b/usr.sbin/xntpd/conf/rackety.conf @@ -0,0 +1,75 @@ +# +# NTP configuration file (ntp.conf) +# rackety (128.4.1.1) +# +server 127.127.10.1 prefer # austron 2201 gps receiver +fudge 127.127.10.1 flag4 1 # enable statistics +server 127.127.4.1 # spectracom 8170/netclock-2 wwvb receiver +#propagation delay: wwvb 0.0088; receiver delay 0.0017 +fudge 127.127.4.1 time1 0.0017 value1 2 + +# +# ee vaxen +# +peer 128.175.1.1 # huey.udel.edu +peer 128.175.1.2 # louie.udel.edu +peer 128.175.1.3 # dewey.udel.edu + +# +# munchkins (stratum-1 only) +# +peer 128.4.1.2 # mizbeaver.udel.edu +#peer 128.4.1.5 # churchy.udel.edu +peer 128.4.2.7 key 3 # grundoon.udel.edu +peer 128.4.1.20 key 3 # pogo.udel.edu + +# +# dartnet +# +peer 140.173.112.2 # ames.dart.net +peer 140.173.128.1 # la.dart.net +peer 140.173.64.1 # dc.dart.net +peer 140.173.144.2 # parc.dart.net +peer 140.173.80.1 # sri.dart.net +peer 140.173.96.1 # lbl.dart.net +peer 140.173.128.2 # isi.dart.net +peer 140.173.16.1 # udel.dart.net +peer 140.173.32.1 # bbn.dart.net +peer 140.173.48.2 # mit.dart.net + +# +# nsfnet t3 backbone +# +server 140.222.134.1 version 2 # enss134 (cambridge - mit) +server 140.222.135.1 version 2 # enss135 (san diego - sdsc) +peer 140.222.136.1 version 2 # enss136 (college park - sura) +server 140.222.141.1 version 2 # enss141 (boulder - ncar) +server 140.222.144.1 version 2 # enss144 (sunnyvale - nasa ames) + +# +# famous players +# +#peer 132.163.135.130 # time_A.timefreq.bldrdoc.gov + +# +# Miscellaneous stuff +# +monitor yes # enable monitoring +precision -18 # clock reading precision (usec) +driftfile /etc/ntp.drift # path for drift file +statsdir /rackety/ntpstats/ # directory for statistics files +filegen peerstats file peerstats type day enable +filegen loopstats file loopstats type day enable +filegen clockstats file clockstats type day enable + +# +# Authentication stuff +# +authenticate yes # enable authentication +keys /usr/local/bin/ntp.keys # path for keys file +trustedkey 1 2 3 4 14 15 # define trusted keys +requestkey 15 # key (7) for accessing server variables +controlkey 15 # key (6) for accessing server variables +#authdelay 0.000073 # authentication delay (SPARC4c/40 IPC DES) +authdelay 0.000163 # authentication delay (SPARC4c/40 IPC MD5) + diff --git a/usr.sbin/xntpd/conf/snow-white.conf b/usr.sbin/xntpd/conf/snow-white.conf new file mode 100644 index 000000000000..a86cb4bc5b45 --- /dev/null +++ b/usr.sbin/xntpd/conf/snow-white.conf @@ -0,0 +1,33 @@ +# +# NTP configuration file (ntp.conf) +# snow-white.udel.edu (128.175.2.15) +# +# Stratum-2 peers +# +peer 128.175.1.1 # huey.udel.edu +peer 128.175.1.2 # dewey.udel.edu +#peer 128.175.1.3 # louie.udel.edu +peer 128.175.2.33 # louie.udel.edu +#peer 128.175.7.39 # louie.udel.edu +# +# Stratum-3 peers +# +peer 128.175.7.4 # sol.cis.udel.edu +peer 128.175.7.18 # ra.cis.udel.edu +#peer 128.175.2.15 # snow-white.ee.udel.edu +peer 128.175.2.21 # opus.ee.udel.edu +# +# Miscellaneous stuff +# +monitor yes # enable monitoring +precision -18 # clock reading precision (1 usec) +driftfile /etc/ntp.drift # path for drift file +# +# Authentication stuff +# +authenticate yes # enable authentication +keys /etc/ntp.keys # path for key file +trustedkey 1 2 15 # define trusted keys +requestkey 15 # key (7) for accessing server variables +controlkey 15 # key (6) for accessing server variables +authdelay 0.000077 # authentication delay (SPARC IPC) diff --git a/usr.sbin/xntpd/doc/README.irig b/usr.sbin/xntpd/doc/README.irig new file mode 100644 index 000000000000..f293f4cde160 --- /dev/null +++ b/usr.sbin/xntpd/doc/README.irig @@ -0,0 +1,306 @@ + Audio IRIG Receiver for Precision Timekeeping + + Revised 20 September 1993 + +Note: This information file is included in both the BSD audio driver +distribution (bsd_audio.tar.Z) and NTP Version 3 distribution +(xntp3.tar.Z) as the file README.irig. Both distributions can be +obtained via anonymous ftp from louie.udel.edu in the directory pub/ntp. + +1. Introduction + +This software distribution includes modifications to the BSD audio +driver for the Sun SPARCstation written by Van Jacobson and +collaborators at Lawrence Berkeley National Laboratory. The +modifications provide for the connection of a standard Inter-Range +Instrumentation Group (IRIG) timecode signal generator and the decoding +of the signal to produce data sufficient to synchronize a host clock to +the IRIG signal. There are several timing receivers now on the market +that can produce IRIG signals, including those made by Austron, +TrueTime, Odetics and Spectracom, among others. These data can be used +to precisely synchronize the host computer clock to within a few +microseconds without requiring level converters or pulse generators +necessary with the one-pulse-per-second signals also produced by these +receivers. The current implementation of the Network Time Protocol +Version 3 supports the modified BSD driver when installed in the SunOS +4.1.x kernel. + +The specific IRIG signal format supported by the driver is designated +IRIG-B. It consists of an amplitude-modulated 1000-Hz sinewave, where +each symbol is encoded as ten full carrier cycles, or 10 ms in duration. +The symbols are distinguished using a pulse-width code, where 2 ms +corresponds to logic zero, 5 ms to logic one and 8 ms to a position +identifier used for symbol synchronization. The complete IRIG-B message +consists of a frame of ten fields, each field consisting of a nine +information symbols followed by a position identifier for a total frame +duration of one second. The first symbol in the frame is also a position +identifier to facilitate frame synchronization. + +The IRIG-B signal encodes the day of year and time of day in binary- +coded decimal (BCD) format, together with a set of control functions, +which are not used by the driver, but included in the raw binary +timecode. Either the BCD timecode or the combined raw timecode and BCD +timecode can be returned in response to a read() system call. The BCD +timecode is in handy ASCII format: "ddd hh:mm:ss*" for convenience in +client programs. In this format the "*" status character is " " when the +driver is operating normally and "?" when errors may be present (see +below). In order to reduce residual errors to the greatest extent +possible, the driver computes a timestamp based on the value of the +kernel clock at the on-time epoch of the IRIG-B signal. In addition, the +driver automatically adjusts for slowly varying amplitude levels of the +IRIG-B signal and suppresses noise transients. + +In operation the IRIG driver interprets the IRIG-B signal in real time, +synchronizes to the signal, demodulates the data bits and prepares the +data to be read later. At the on-time epoch a timestamp is captured from +the kernel clock and adjusted for the phase of the IRIG carrier signal +relative to the 8-kHz codec sample clock. When a client program issues a +read() request, the most recent timecode data, including a status byte +and the corrected timestamp, are stored in a structure and returned to +the caller. Depending on the frequency with which the driver is called, +this may result in old data or duplicate data or even invalid data, +should the driver be called before it has computed its first timestamp. + +In practice, the resulting ambiguity causes few problems. The caller +converts the ASCII timecode returned by a read() system call to Unix +timeval format and subtracts it from the kernel timestamp provided by +the driver. The result is an adjustment that can be subtracted from the +kernel time, as returned in a gettimeofday() call, for example, to +correct for the deviation between IRIG time and kernel time. The result +can always be relied on to within plus/minus 128 microseconds, the audio +codec sampling interval, and ordinarily to within a few microseconds, as +determined by the interpolation algorithm. + +2. Programming Interface + +The IRIG driver modifications are integrated in the BSD audio driver +bsd_audio.c without affecting its usual functions in transmitting and +receiving ordinary speech, except when enabled by specific ioctl() +system calls. However, the driver cannot be used for both speech and +IRIG signals at the same time. Once activated by a designated ioctl() +call, the driver remains active until it is explicitly deactivated by +another ioctl() call. This allows applications to configure the audio +device and pass the pre-configured driver to other applications. Since +the driver is currently only a receiver, it does not affect the +operation of the BSD audio output driver. + +Data are read using the standard read() system call. Since the output +formats have constant lengths, the application receives the data into a +fixed-length buffer or structure. The read() call never blocks; it +simply returns the most recent IRIG data received during the last +second. It may happen that, due to unavoidable race conditions in the +kernel, data for other than the most recent second are returned. The +driver's internal data structure is updated as an atomic unit; thus, the +entire structure is valid, even if it contains old data. This should +cause no problems, since in the intended application the driver is +called at regular intervals by a time-synchronization daemon such as +NTP. The daemon can determine the validity of the time indication by +checking the timecode or status byte returned with the data. + +The header file bsd_audioirig.h defines the irig_time structure and +ioctl() codes used by the driver. Following are those codes specific to +the IRIG function of the driver. Unless indicated otherwise, the (third) +argument of the ioctl() system call points to an integer or string. + +AUDIO_IRIG_OPEN + + This command activates the IRIG receiver. The audio driver must be + opened with this command before other commands can be issued. The + argument is ignored. When the IRIG receiver is initialized, all + internal data are purged and any buffered data are lost. + +AUDIO_IRIG_CLOSE + + This command deactivates the IRIG receiver. The argument is + ignored. The buffers are purged and any buffered time data are + lost. The original BSD audio driver functions are enabled and it + resumes operating normally. + +AUDIO_IRIG_SETFORMAT + + The argument is a pointer to an integer designating the output + format for the IRIG data. There are currently two formats defined, + 0 (default) and 1. If an invalid format is selected, the default + format is used. + +The data returned by a read() system call in format 0 is a character +string in the format "ddd hh:mm:ss*\n", which consists of 13 ASCII +characters followed by a newline terminator for a total of 14 +characters. The "*" status character is an ASCII space " " if the status +byte determined by the driver is zero and "?" if not. This format is +intended to be used with simple user programs that care only about the +time to the nearest second. +The data returned by a read() system call in format 1 is a structure +defined in the bsd_audioirig.h header file: + + struct irig_time { + struct timeval stamp; /* timestamp */ + u_char bits[13]; /* 100 irig data bits */ + u_char status; /* status byte */ + char time[14]; /* time string */ + }; + +The irig-time.stamp is a pair of 32-bit longwords in Unix timeval +format, as defined in the sys/time.h header file. The first word is the +number of seconds since 1 January 1970, while the second is the number +of microseconds in the current second. The timestamp is captured at the +most recent on-time instant of the IRIG timecode and applies to all +other values returned in the irig_time structure. + +The irig_time.bits[13] is a vector of 13 bytes to hold the 100-bit, +zero-padded raw binary timecode, packed 8 symbols per byte. The symbol +encoding maps IRIG one to 1 and both IRIG zero and IRIG position +identifier to 0. The order of encoding is illustrated by the following +diagram (the padding bits are represented by xxxx, which are set to +zero): + +IRIG symbol number 00000000001111111111 . . . 8888889999999999xxxx + 01234567890123456789 . . . 4567890123456789xxxx + ----------------------------------------------- +bits byte number <--00--><--01--><---- ----><--11--><--12--> +bits bit in byte 01234567012345670123 . . . 45670123456701234567 + +The irig_time.status is a single byte with bits defined in the +bsd_audioirig.h header file. In ordinary operation all bits of the +status byte are zero and the " " status character is set in the ASCII +timecode. If any of these bits are nonzero, the "?" status character is +set in the ASCII timecode. + +AUDIO_IRIG_BADSIGNAL + + The signal amplitude is outside tolerance limits, either in + amplitude or modulation depth. The indicated time may or may not be + in error. If the signal is too high, it may be clipped by the + codec, so that the pulse width cannot be reliably determined. If + too low, it may be obscured by noise. The nominal expectation is + that the peak amplitude of the signal be maintained by the codec + AGC at about 10 dB below the clipping level and that the modulation + index be at least 0.5 (6 dB). + +AUDIO_IRIG_BADDATA + + An invalid hex code (A through F) has been found where BCD data is + expected. The ASCII representation of the invalid code is set to + "?". Errors of this type are most likely due to noise on the IRIG + signal due to ground loops, coupling to other noise sources, etc. + +AUDIO_IRIG_BADSYNC + + A code element has been found where a position identifier should be + or a position identifier has been found where a code element should + be. The time is meaningless and should be disregarded. Errors of + this type can be due to severe noise on the IRIG signal due to + ground loops, coupling to other noise sources, etc., or during + initial acquisition of the signal. + +AUDIO_IRIG_BADCLOCK + + Some IRIG timecode generators can indicate whether or not the + generator is operating correctly or synchronized to its source of + standard time using a designated field in the raw binary timecode. + Where such information is available and the IRIG decoder can detect + it, this bit is set when the generator reports anything except + normal operating conditions. + +AUDIO_IRIG_OLDDATA + + The IRIG time has not changed since the last time it was returned + in a read() call. This is not normally considered an error, unless + it persists for longer than a few seconds, in which case it + probably indicates a hardware problem. + +The irig_time.time[14] vector is a character string in the format "ddd +hh:mm:ss*\0", which consists of 13 ASCII characters followed by a zero +terminator. The "*" status character is an ASCII space " " if the status +byte is zero and "?" if not. This format is identical to format 0, +except that in format 1 the time string is null-terminated. + +2.1. Programming Example + +The following pseudo-code demonstrates how the IRIG receiver may be used +by a simple user program. Of course, real code should include error +checking after each call to ensure the driver is communicating properly. +It should also verify that the correct fields in the structure are being +filled by the read() call. + + include "bsd_audioirig.h" + + int format = 1; + struct irig_time it; + + Audio_fd = open("/dev/audio", O_RDONLY); + ioctl(Audio_fd, AUDIO_IRIG_OPEN, NULL); + ioctl(Audio_fd, AUDIO_IRIG_SETFORMAT,&format); + while (condition) + read(Audio_fd, &it, sizeof(it); + printf("%s\n", it.time); + ioctl(Audio_fd, AUDIO_IRIG_CLOSE, NULL); + close(Audio_fd); + +3. Implementation and Configuration Notes + +The signal level produced by most IRIG-equipped radios is on the order +of a few volts peak-peak, which is far larger than the audio codec can +accept; therefore, an attenuator in the form of a voltage divider is +needed. The codec can handle IRIG signals at the microphone input from +4.2mV to 230mV peak-peak. A suitable attenuator conists of a series- +connected 100K-Ohm resistor at the input and a parallel-connected 1K-Ohm +resistor at the output, both contained along with suitable connectors in +a small aluminum box. The exact values of these resistors are not +critical, since the IRIG driver includes an automatic level-adjustment +capability. + +For the most accurate time using the IRIG signal and a particular radio, +it may be necessary to adjust the time1 parameter of the fudge command +to compensate for the codec delay and any additional delay due to IRIG +processing in the radio itself. Since the codec samples at an 8-kHz +rate, the average delay is about 62 usec; however, the delays due to the +radios and IRIG signals themselves can vary. For instance, in the +Austron recievers the IRIG delay is essentially zero, while in the +Spectracom receivers the delay is about 240 usec relative to the 1-pps +signal. In addition, the poll interval can be reduced from the usual 64 +seconds to 16 seconds to reduce wander of the local hardware clock. +Finally, the prefer parameter can be used to bias the clock-selection +algorithm to favor the IRIG time, which is ordinarily the best time +available. For example, the following two lines in the NTP configuration +file ntp.conf are appropriate for the Spectracom Netclock/1 WWVB +Synchronized Clock with IRIG Option: + +server 127.127.6.0 prefer minpoll 4 maxpoll 4 # irig audio decoder +fudge 127.127.6.0 time1 0.0005 + +The time1 value of .0005 s (500 usec) was determined by actual +measurement. Since the IRIG delay in Austron receivers is essentially +zero, the fudge command is not necessary with these receivers. The +correct value in case of other radios may have to be determined by +actual measurement. A convenient way of doing this is to configure the +PPSPPS feature in the NTP Version 3 distribution and adjust time1 until +the 1-pps signal and IRIG signal both show the same offset. + +The modified BSD driver includes both the modified driver itself +bsd_audio.c and the IRIG header file bsd_audioirig.h, as well as +modified header files bsd_audiovar.h and bsd_audioio.h. The driver is +installed in the same way as described in the BSD driver documentation, +with the addition of the following define in the kernel configuration +file: + +options AUDIO_IRIG # IRIG driver + +This causes the IRIG code to be included in the BSD driver, as well as a +C-coded codec interrupt routine which replaces the assembly-coded +routine and provides the IRIG functionality. While the C-coded routine +is somewhat slower than the assembly-coded routine, the extra overhead +is not expected to be significant. Note that the IRIG driver calls the +kernel routine microtime() as included in the ppsclock directory of the +NTP Version 3 distribution xntp3. It is highly recommended that this +routine be installed in the kernel configuration as well. The +instructions for doing this are contained in the ppsclock directory of +the xntp3 distribution. + +Roy LeCates <lecates@udel.edu> and David Mills <mills@udel.edu> +Electrical Engineering Department +University of Delaware +Newark, DE 19716 +302 831 8247 fax 302 831 4316 + +24 August 1993 diff --git a/usr.sbin/xntpd/doc/README.kern b/usr.sbin/xntpd/doc/README.kern new file mode 100644 index 000000000000..1b791c325ccf --- /dev/null +++ b/usr.sbin/xntpd/doc/README.kern @@ -0,0 +1,775 @@ + Unix Kernel Modifications for Precision Timekeeping + + Revised 3 December 1993 + +Note: This information file is included in the distributions for the +SunOS, Ultrix and OSF/1 kernels and in the NTP Version 3 distribution +(xntp3.tar.Z) as the file README.kern. Availability of the kernel +distributions, which involve licensed code, will be announced +separately. The NTP Version 3 distribution can be obtained via anonymous +ftp from louie.udel.edu in the directory pub/ntp. In order to utilize +all features of this distribution, the NTP version number should be 3.3 +or later. + +1. Introduction + +This memo describes modifications to certain SunOS, Ultrix and OSF/1 +kernel software that manage the system clock and timer functions. They +provide improved accuracy and stability through the use of a disciplined +clock interface for use with the Network Time Protocol (NTP) or similar +time-synchronization protocol. In addition, for the DEC 3000 AXP (Alpha) +and DECstation 5000/240 machines, the modifications provide improved +precision within one microsecond (us) (SunOS 4.1.x already does provide +precision to this order). The NTP Version 3 daemon xntpd operates with +these kernel modifications to provide synchronization in principle to +within this order, but in practice this is limited by the short-term +stability of the timer oscillator to within the order of 100 usec. + +This memo describes the principles behind the design and operation of +the new software. There are three versions: one that operates with the +SunOS 4.1.x kernels, a second that operates with the Ultrix 4.x kernels +and a third that operates with the OSF/1 V1.x kernels. A detailed +description of the variables and algorithms is given in the hope that +similar functionality can be incorporated in Unix kernels for other +machines. The algorithms involve only minor changes to the system clock +and interval timer routines and include interfaces for application +programs to learn the system clock status and certain statistics of the +time-synchronization process. Detailed installation instructions are +given in a companion README.install file included in the kernel +distributions. The kernel software itself is not provided for public +distribution, since it involves licensed code. Detailed instructions on +how to obtain it for either SunOS, Ultrix or OSF/1 will be given +separately. + +The principal feature added to the Unix kernels is to change the way the +system clock is controlled, in order to provide precision time and +frequency adjustments. Another feature utilizes an undocumented bus- +cycle counter in the DEC 3000 AXP and DECstation 5000/240 to provide +precise time to the microsecond. This feature can in principle be used +with any DEC machine that has this counter, although this has not been +verified. The addition of these features does not affect the operation +of existing Unix system calls such as gettimeofday(), settimeofday() and +adjtime(); however, if the new features are in use, the operations of +adjtime() are controlled instead by a new system call ntp_adjtime(). + +Most Unix programs read the system clock using the gettimeofday() system +call, which returns only the system time and timezone data. For some +applications it is useful to know the maximum error of the reported time +due to all causes, including clock reading errors, oscillator frequency +errors and accumulated latencies on the path to a primary reference +source. However, the new software can adjust the system clock to +compensate for its intrinsic frequency error, so that the timing errors +expected in normal operation will usually be much less than the maximum +error. The user application interface includes a new system call +ntp_gettime(), which returns the system time, as well as the maximum +error and estimated error. This interface is intended to support +applications that need such things, including distributed file systems, +multimedia teleconferencing and other real-time applications. The +protocol daemon application interface includes a new system call +ntp_adjtime(), which can be used to read and write kernel variables used +for precision timekeeping, including time and frequency adjustments, +controlling time constant, leap-second warning and related data. + +In this memo, NTP Version 3 and the Unix implementation xntpd are used +as an example application of the new system calls for use by a protocol +daemon. In principle, the new system calls can be used by other +protocols and daemon implementations as well. Even in cases where the +local time is maintained by periodic exchanges of messages at relatively +long intervals, such as using the NIST Automated Computer Time Service, +the ability to precisely adjust the local clock frequency simplifies the +synchronization procedures and allows the call frequency to be +considerably reduced. + +2. Design Principles + +In order to understand how the new software works, it is useful to +consider how most Unix systems maintain the system time. In the original +design a hardware timer interrupts the kernel at a fixed rate: 100 Hz in +the SunOS kernel, 256 Hz in the Ultrix kernel and 1024 Hz in the OSF/1 +kernel. Since the Ultrix kernel rate does not evenly divide one second +in microseconds, the kernel adds 64 microseconds once each second, so +the timescale consists of 255 advances of 3906 usec plus one of 3970 +usec. Similarly, the OSF/1 kernel adds 576 usec once each second, so its +timescale consists of 1023 advances of 976 usec plus one of 1552 usec. + +In all Unix kernels considered in this memo, it is possible to slew the +system clock to a new offset using the standard Unix adjtime() system +call. To do this the clock frequency is changed by adding or subtracting +a fixed amount (tickadj) at each timer interrupt (tick) for a calculated +number of ticks. Since this calculation involves dividing the requested +offset by tickadj, it is possible to slew to a new offset with a +precision only of tickadj, which is usually in the neighborhood of 5 us, +but sometimes much higher. This results in an amortization error which +can accumulate to unacceptable levels, so that special provisions must +be made in the clock adjustment procedures of the protocol daemon. + +In order to maintain the system clock within specified bounds with this +scheme, it is necessary to call adjtime() on a regular basis. For +instance, let the bound be set at 100 usec, which is a reasonable value +for NTP-synchronized hosts on a local network, and let the onboard +oscillator tolerance be 100 parts-per-million (ppm), which is a +reasonably conservative assumption. This requires that adjtime() be +called at intervals not exceeding 1 second (s), which is in fact what +the unmodified NTP software daemon does. + +In the new software this scheme is replaced by another that extends the +low-order bits of the system clock to provide very precise clock +adjustments. At each timer interrupt a precisely calibrated quantity is +added to the composite time value and overflows handled as required. The +quantity is computed from the measured clock offset and in addition a +frequency adjustment, which is automatically calculated from previous +time adjustments. This implementation operates as an adaptive-parameter +first-order, type-II, phase-lock loop (PLL), which in principle provides +precision control of the system clock phase to within +-1 us and +frequency to within +-5 nanoseconds (ns) per day. + +This PLL model is identical to the one implemented in NTP, except that +in NTP the software daemon has to simulate the PLL using only the +original adjtime() system call. The daemon is considerably complicated +by the need to parcel time adjustments at frequent intervals in order to +maintain the accuracy to specified bounds. The modified kernel routines +do this directly, allowing vast gobs of ugly daemon code to be avoided +at the expense of only a small amount of new code in the kernel. In +fact, the amount of code added to the kernel for the new scheme is about +the amount needed to implement the old scheme. A new system call +ntp_adjtime(), which operates in a way similar to the original +adjtime(), is called only as each new time update is determined, which +in NTP occurs at intervals of from 16 s to 1024 s. In addition, doing +the frequency correction in the kernel means that the system time runs +true even if the daemon were to cease operation or the network paths to +the primary reference source fail. The addition of the new ntp_adjtime() +system call does not affect the original adjtime() system call, which +continues to operate in its traditional fashion. However, the two system +calls canot be used at the same time; only one of the two should be used +on any given system. + +It is the intent in the design that settimeofday() be used for changes +in system time greater than +-128 ms. It has been the Internet +experience that the need to change the system time in increments greater +than +-128 milliseconds is extremely rare and is usually associated with +a hardware or software malfunction or system reboot. Once the system +clock has been set in this way, the ntp_adjtime() system call is used to +provide periodic updates including the time offset, maximum error, +estimated error and PLL time constant. With NTP the update interval +depends on the measured error and time constant; however, the scheme is +quite forgiving and neither moderate loss of updates nor variations in +the length of the polling interval are serious. + +In addition, the kernel adjusts the maximum error to grow by an amount +equal to the oscillator frequency tolerance times the elapsed time since +the last update. The default engineering parameters have been optimized +for intervals not greater than about 16 s. For longer intervals the PLL +time constant can be adjusted to optimize the dynamic response up to +intervals of 1024 s. Normally, this is automatically done by NTP. In any +case, if updates are suspended, the PLL coasts at the frequency last +determined, which usually results in errors increasing only to a few +tens of milliseconds over a day. + +The new code needs to know the initial frequency offset and time +constant for the PLL, and the daemon needs to know the current frequency +offset computed by the kernel for monitoring purposes. These data are +exchanged between the kernel and protocol daemon using ntp_adjtime() as +documented later in this memo. Provisions are made to exchange related +timing information, such as the maximum error and estimated error, +between the kernel and daemon and between the kernel and application +programs. + +In the DEC 3000 AXP, DECstation 5000/240 and possibly other DEC +machines there is an undocumented hardware register that counts system +bus cycles at a rate of 25 MHz. The new kernel microtime() routine tests +for the CPU type and, in the case of these machines, use this register +to interpolate system time between hardware timer interrupts. This +results in a precision of +-1 us for all time values obtained via the +gettimeofday() and ntp_gettime() system calls. These routines call the +microtime() routine, which returns the actual interpolated value but +does not change the kernel time variable. Therefore, other kernel +routines that access the kernel time variable directly and do not call +either gettimeofday(), ntp_gettime() or microtime() will continue their +present behavior. The microtime() feature is independent of other +features described here and is operative even if the kernel PLL or new +system calls have not been implemented. + +While any protocol daemon can in principle be modified to use the new +system calls, the most likely will be users of the NTP Version 3 daemon +xntpd. The xntpd code determines whether the new system calls are +implemented and automatically reconfigures as required. When +implemented, the daemon reads the frequency offset from a file and +provides it and the initial time constant via ntp_adjtime(). In +subsequent calls to ntp_adjtime(), only the time adjustment and time +constant are affected. The daemon reads the frequency from the kernel +using ntp_adjtime() at intervals of about one hour and writes it to the +system log file. This information is recovered when the daemon is +restarted after reboot, for example, so the sometimes extensive training +period to learn the frequency separately for each system can be avoided. + +3. Kernel Interfaces + +This section describes the kernel interfaces to the protocol daemon and +user applications. The ideas are based on suggestions from Jeff Mogul +and Philip Gladstone and a similar interface designed by the latter. It +is important to point out that the functionality of the original Unix +adjtime() system call is preserved, so that the modified kernel will +work as the unmodified one should the kernel PLL not be in use. In this +case the ntp_adjtime() system call can still be used to read and write +kernel variables that might be used by a protocol daemon other than NTP, +for example. + +3.1. The ntp_gettime() System Call + +The syntax and semantics of the ntp_gettime() call are given in the +following fragment of the timex.h header file. This file is identical in +the SunOS, Ultrix and OSF/1 kernel distributions. Note that the timex.h +file calls the syscall.h system header file, which must be modified to +define the SYS_ntp_gettime system call specific to each system type. The +kernel distributions include directions on how to do this. + +/* + * This header file defines the Network Time Protocol (NTP) interfaces + * for user and daemon application programs. These are implemented using + * private system calls and data structures and require specific kernel + * support. + * + * NAME + * ntp_gettime - NTP user application interface + * + * SYNOPSIS + * #include <sys/timex.h> + * + * int system call(SYS_ntp_gettime, tptr) + * + * int SYS_ntp_gettime defined in syscall.h header file + * struct ntptimeval *tptr pointer to ntptimeval structure + * + * NTP user interface - used to read kernel clock values + * Note: maximum error = NTP synch distance = dispersion + delay / 2; + * estimated error = NTP dispersion. + */ +struct ntptimeval { + struct timeval time; /* current time */ + long maxerror; /* maximum error (usec) */ + long esterror; /* estimated error (usec) */ +}; + +The ntp_gettime() system call returns three values in the ntptimeval +structure: the current time in unix timeval format plus the maximum and +estimated errors in microseconds. While the 32-bit long data type limits +the error quantities to something more than an hour, in practice this is +not significant, since the protocol itself will declare an +unsynchronized condition well below that limit. If the protocol computes +either of these values in excess of 16 seconds, they are clamped to that +value and the local clock declared unsynchronized. + +Following is a detailed description of the ntptimeval structure members. + +struct timeval time; + + This member is set to the current system time, expressed as a Unix + timeval structure. The timeval structure consists of two 32-bit + words, one for the number of seconds past 1 January 1970 and the + other the number of microseconds past the most recent second's + epoch. + +long maxerror; + + This member is set to the value of the time_maxerror kernel + variable, which establishes the maximum error of the indicated time + relative to the primary reference source, in microseconds. This + variable can also be set and read by the ntp_adjtime() system call. + For NTP, the value is determined as the synchronization distance, + which is equal to the root dispersion plus one-half the root delay. + It is increased by a small amount (time_tolerance) each second to + reflect the clock frequency tolerance. This variable is computed by + the time-synchronization daemon and the kernel and returned in a + ntp_gettime() system call, but is otherwise not used by the kernel. + +long esterror; + + This member is set to the value of the time_esterror kernel + variable, which establishes the expected error of the indicated + time relative to the primary reference source, in microseconds. + This variable can also be set and read by the ntp_adjtime() system + call. For NTP, the value is determined as the root dispersion, + which represents the best estimate of the actual error of the + system clock based on its past behavior, together with observations + of multiple clocks within the peer group. This variable is computed + by the time-synchronization daemon and returned in a ntp_gettime() + system call, but is otherwise not used by the kernel. + +3.2. The ntp_adjtime() System Call + +The syntax and semantics of the ntp_adjtime() call is given in the +following fragment of the timex.h header file. Note that, as in the +ntp_gettime() system call, the the syscall.h system header file must be +modified to define the SYS_ntp_adjtime system call specific to each +system type. + +/* + * NAME + * ntp_adjtime - NTP daemon application interface + * + * SYNOPSIS + * #include <sys/timex.h> + * + * int system call(SYS_ntp_adjtime, mode, tptr) + * + * int SYS_ntp_adjtime defined in syscall.h header file + * struct timex *tptr pointer to timex structure + * + * NTP daemon interface - used to discipline kernel clock oscillator + */ +struct timex { + int mode; /* mode selector */ + long offset; /* time offset (usec) */ + long frequency; /* frequency offset (scaled ppm) */ + long maxerror; /* maximum error (usec) */ + long esterror; /* estimated error (usec) */ + int status; /* clock command/status */ + long time_constant; /* pll time constant */ + long precision; /* clock precision (usec) (read only) */ + long tolerance; /* clock frequency tolerance (ppm) + * (read only) + */ +}; + +The ntp_adjtime() system call is used to read and write certain time- +related kernel variables summarized in this and subsequent sections. +Writing these variables can only be done in superuser mode. To write a +variable, the mode structure member is set with one or more bits, one of +which is assigned each of the following variables in turn. The current +values for all variables are returned in any case; therefore, a mode +argument of zero means to return these values without changing anything. + +Following is a description of the timex structure members. + +int mode; + + This is a bit-coded variable selecting one or more structure + members, with one bit assigned each member. If a bit is set, the + value of the associated member variable is copied to the + corresponding kernel variable; if not, the member is ignored. The + bits are assigned as given in the following fragment of the timex.h + header file. Note that the precision and tolerance are intrinsic + properties of the kernel configuration and cannot be changed. + + /* + * Mode codes (timex.mode) + */ + #define ADJ_OFFSET 0x0001 /* time offset */ + #define ADJ_FREQUENCY 0x0002 /* frequency offset */ + #define ADJ_MAXERROR 0x0004 /* maximum time error */ + #define ADJ_ESTERROR 0x0008 /* estimated time error */ + #define ADJ_STATUS 0x0010 /* clock status */ + #define ADJ_TIMECONST 0x0020 /* pll time constant */ + +long offset; + + If selected, this member (scaled) replaces the value of the + time_offset kernel variable, which defines the current time offset + of the phase-lock loop. The value must be in the range +-512 ms in + the present implementation. If so, the clock status is + automatically set to TIME_OK. + +long time_constant; + + If selected, this member replaces the value of the time_constant + kernel variable, which establishes the bandwidth of "stiffness" of + the kernel PLL. The value is used as a shift, with the effective + PLL time constant equal to a multiple of (1 << time_constant), in + seconds. The optimum value for the time_constant variable is + log2(update_interval) - 4, where update_interval is the nominal + interval between clock updates, in seconds. With an ordinary crystal + oscillator the optimum value for time_constant is about 2, giving + an update_interval of 4 (64 s). Values of time_constant between zero + and 2 can be used if quick convergence is necessary; values between + 2 and 6 can be used to reduce network load, but at a modest cost in + accuracy. Values above 6 are appropriate only if a precision + oscillator is available. + +long frequency; + + If selected, this member (scaled) replaces the value of the + time_frequency kernel variable, which establishes the intrinsic + frequency of the local clock oscillator. This variable is scaled by + (1 << SHIFT_USEC) in parts-per-million (ppm), giving it a maximum + value of about +-31 ms/s and a minimum value (frequency resolution) + of about 2e-11, which is appropriate for even the best quartz + oscillator. + +long maxerror; + + If selected, this member replaces the value of the time_maxerror + kernel variable, which establishes the maximum error of the + indicated time relative to the primary reference source, in + microseconds. This variable can also be read by the ntp_gettime() + system call. For NTP, the value is determined as the + synchronization distance, which is equal to the root dispersion + plus one-half the root delay. It is increased by a small amount + (time_tolerance) each second to reflect the clock frequency + tolerance. This variable is computed by the time-synchronization + daemon and the kernel and returned in a ntp_gettime() system call, + but is otherwise not used by the kernel. + +long esterror; + + If selected, this member replaces the value of the time_esterror + kernel variable, which establishes the expected error of the + indicated time relative to the primary reference source, in + microseconds. This variable can also be read by the ntp_gettime() + system call. For NTP, the value is determined as the root + dispersion, which represents the best estimate of the actual error + of the system clock based on its past behavior, together with + observations of multiple clocks within the peer group. This + variable is computed by the time-synchronization daemon and + returned in a ntp_gettime() system call, but is otherwise not used + by the kernel. + +int status; + + If selected, this member replaces the value of the time_status + kernel variable, which records whether the clock is synchronized, + waiting for a leap second, etc. In order to set this variable + explicitly, either (a) the current clock status is TIME_OK or (b) + the member value is TIME_BAD; that is, the ntp_adjtime() call can + always set the clock to the unsynchronized state or, if the clock + is running correctly, can set it to any state. In any case, the + ntp_adjtime() call always returns the current state in this member, + so the caller can determine whether or not the request succeeded. + +long precision; + + This member is set equal to the time_precision kernel in + microseconds variable upon return from the system call. The + time_precision variable cannot be written. This variable represents + the maximum error in reading the system clock, which is ordinarily + equal to the kernel variable tick, 10000 usec in the SunOS kernel, + 3906 usec in Ultrix kernel and 976 usec in the OSF/1 kernel. + However, in cases where the time can be interpolated with + microsecond resolution, such as in the SunOS kernel and modified + Ultrix and OSF/1 kernels, the precision is specified as 1 usec. + This variable is computed by the kernel for use by the time- + synchronization daemon, but is otherwise not used by the kernel. + +long tolerance; + + This member is set equal to the time_tolerance kernel variable in + parts-per-million (ppm) upon return from the system call. The + time_tolerance variable cannot be written. This variable represents + the maximum frequency error or tolerance of the particular platform + and is a property of the architecture and manufacturing process. + +3.3. Command/Status Codes + +The kernel routines use the system clock status variable time_status, +which records whether the clock is synchronized, waiting for a leap +second, etc. The value of this variable is returned as the result code +by both the ntp_gettime() and ntp_adjtime() system calls. In addition, +it can be explicitly read and written using the ntp_adjtime() system +call, but can be written only in superuser mode. Values presently +defined in the timex.h header file are as follows: + +/* + * Clock command/status codes (timex.status) + */ +#define TIME_OK 0 /* clock synchronized */ +#define TIME_INS 1 /* insert leap second */ +#define TIME_DEL 2 /* delete leap second */ +#define TIME_OOP 3 /* leap second in progress */ +#define TIME_BAD 4 /* clock not synchronized */ + +A detailed description of these codes as used by the leap-second state +machine is given later in this memo. In case of a negative result code, +the kernel has intercepted an invalid address or (in case of the +ntp_adjtime() system call), a superuser violation. + +4. Technical Summary + +In order to more fully understand the workings of the PLL, a stand-alone +simulator kern.c is included in the kernel distributions. This is an +implementation of an adaptive-parameter, first-order, type-II phase-lock +loop. The system clock is implemented using a set of variables and +algorithms defined in the simulator and driven by explicit offsets +generated by the simulator. The algorithms include code fragments +identical to those in the modified kernel routines and operate in the +same way, but the operations can be understood separately from any +licensed source code into which these fragments may be integrated. The +code segments themselves are not derived from any licensed code. + +4.1. PLL Simulation + +In the simulator the hardupdate() fragment is called by ntp_adjtime() as +each update is computed to adjust the system clock phase and frequency. +Note that the time constant is in units of powers of two, so that +multiplies can be done by simple shifts. The phase variable is computed +as the offset multiplied by the time constant. Then, the time since the +last update is computed and clamped to a maximum (for robustness) and to +zero if initializing. The offset is multiplied (sorry about the ugly +multiply) by the result and by the square of the time constant and then +added to the frequency variable. Finally, the frequency variable is +clamped not to exceed the tolerance. Note that all shifts are assumed to +be positive and that a shift of a signed quantity to the right requires +a little dance. + +With the defines given, the maximum time offset is determined by the +size in bits of the long type (32) less the SHIFT_UPDATE scale factor or +18 bits (signed). The scale factor is chosen so that there is no loss of +significance in later steps, which may involve a right shift up to 14 +bits. This results in a maximum offset of about +-130 ms. Since +time_constant must be greater than or equal to zero, the maximum +frequency offset is determined by the SHIFT_KF (20) scale factor, or +about +-130 ppm. In the addition step, the value of offset * mtemp is +represented in 18 + 10 = 28 bits, which will not overflow a long add. +There could be a loss of precision due to the right shift of up to eight +bits, since time_constant is bounded at 6. This results in a net worst- +case frequency error of about 2^-16 us or well down into the oscillator +phase noise. While the time_offset value is assumed checked before +entry, the time_phase variable is an accumulator, so is clamped to the +tolerance on every call. This helps to damp transients before the +oscillator frequency has been determined, as well as to satisfy the +correctness assertions if the time-synchronization protocol comes +unstuck. + +The hardclock() fragment is inserted in the hardware timer interrupt +routine at the point the system clock is to be incremented. Previous to +this fragment the time_update variable has been initialized to the value +computed by the adjtime() system call in the stock Unix kernel, normally +the value of tick plus/minus the tickadj value, which is usually in the +order of 5 microseconds. When the kernel PLL is in use, adjtime() is +not, so the time_update value at this point is the value of tick. This +value, the phase adjustment (time_adj) and the clock phase (time_phase) +are summed and the total tested for overflow of the microsecond. If an +overflow occurs, the microsecond (tick) is incremented or decremented, +depending on the sign of the overflow. + +The second_overflow() fragment is inserted at the point where the +microseconds field of the system time variable is being checked for +overflow. On rollover of the second the maximum error is increased by +the tolerance and the time offset is divided by the phase weight +(SHIFT_KG) and time constant. The time offset is then reduced by the +result and the result is scaled and becomes the value of the phase +adjustment. The phase adjustment is then corrected for the calculated +frequency offset and a fixed offset determined from the fixtick variable +in some kernel implementations. On rollover of the day, the leap-warning +indicator is checked and the apparent time adjusted +-1 s accordingly. +The microtime() routine insures that the reported time is always +monotonically increasing. + +The simulator has been used to check the PLL operation over the design +envelope of +-128 ms in time error and +-100 ppm in frequency error. +This confirms that no overflows occur and that the loop initially +converges in about 15 minutes for timer interrupt rates from 50 Hz to +1024 Hz. The loop has a normal overshoot of about seven percent and a +final convergence time of several hours, depending on the initial time +and frequency error. + +4.2. Leap Seconds + +It does not seem generally useful in the user application interface to +provide additional details private to the kernel and synchronization +protocol, such as stratum, reference identifier, reference timestamp and +so forth. It would in principle be possible for the application to +independently evaluate the quality of time and project into the future +how long this time might be "valid." However, to do that properly would +duplicate the functionality of the synchronization protocol and require +knowledge of many mundane details of the platform architecture, such as +the subnet configuration, reachability status and related variables. +However, for the curious, the ntp_adjtime() system call can be used to +reveal some of these mysteries. + +However, the user application may need to know whether a leap second is +scheduled, since this might affect interval calculations spanning the +event. A leap-warning condition is determined by the synchronization +protocol (if remotely synchronized), by the timecode receiver (if +available), or by the operator (if awake). This condition is set by the +protocol daemon on the day the leap second is to occur (30 June or 31 +December, as announced) by specifying in a ntp_adjtime() system call a +clock status of either TIME_DEL, if a second is to be deleted, or +TIME_INS, if a second is to be inserted. Note that, on all occasions +since the inception of the leap-second scheme, there has never been a +deletion occasion. If the value is TIME_DEL, the kernel adds one second +to the system time immediately following second 23:59:58 and resets the +clock status to TIME_OK. If the value is TIME_INS, the kernel subtracts +one second from the system time immediately following second 23:59:59 +and resets the clock status to TIME_OOP, in effect causing system time +to repeat second 59. Immediately following the repeated second, the +kernel resets the clock status to TIME_OK. + +Depending upon the system call implementation, the reported time during +a leap second may repeat (with the TIME_OOP return code set to advertise +that fact) or be monotonically adjusted until system time "catches up" +to reported time. With the latter scheme the reported time will be +correct before and shortly after the leap second (depending on the +number of microtime() calls during the leap second itself), but freeze +or slowly advance during the leap second itself. However, Most programs +will probably use the ctime() library routine to convert from timeval +(seconds, microseconds) format to tm format (seconds, minutes,...). If +this routine is modified to use the ntp_gettime() system call and +inspect the return code, it could simply report the leap second as +second 60. + +To determine local midnight without fuss, the kernel simply finds the +residue of the time.tv_sec value mod 86,400, but this requires a messy +divide. Probably a better way to do this is to initialize an auxiliary +counter in the settimeofday() routine using an ugly divide and increment +the counter at the same time the time.tv_sec is incremented in the timer +interrupt routine. For future embellishment. + +4.2. Kernel Variables + +The following kernel variables are defined by the new code: + +long time_offset = 0; /* time adjustment (us) */ + + This variable is used by the PLL to adjust the system time in small + increments. It is scaled by (1 << SHIFT_UPDATE) in binary + microseconds. The maximum value that can be represented is about +- + 512 ms and the minimum value or precision is one microsecond. + +long time_constant = 0; /* pll time constant */ + + This variable determines the bandwidth or "stiffness" of the PLL. + It is used as a shift, with the effective value in positive powers + of two. The default value (0) corresponds to a PLL time constant of + about 4 minutes. + +long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */ + + This variable represents the maximum frequency error or tolerance + of the particular platform and is a property of the architecture. + It is expressed as a positive number greater than zero in parts- + per-million (ppm). The default MAXFREQ (100) is appropriate for + conventional workstations. + +long time_precision = 1000000 / HZ; /* clock precision (us) */ + + This variable represents the maximum error in reading the system + clock. It is expressed as a positive number greater than zero in + microseconds and is usually based on the number of microseconds + between timer interrupts, 3906 usec for the Ultrix kernel, 976 usec + for the OSF/1 kernel. However, in cases where the time can be + interpolated between timer interrupts with microsecond resolution, + such as in the unmodified SunOS kernel and modified Ultrix and + OSF/1 kernels, the precision is specified as 1 usec. This variable + is computed by the kernel for use by the time-synchronization + daemon, but is otherwise not used by the kernel. + +long time_maxerror; /* maximum error */ + + This variable establishes the maximum error of the indicated time + relative to the primary reference source, in microseconds. For NTP, + the value is determined as the synchronization distance, which is + equal to the root dispersion plus one-half the root delay. It is + increased by a small amount (time_tolerance) each second to reflect + the clock frequency tolerance. This variable is computed by the + time-synchronization daemon and the kernel, but is otherwise not + used by the kernel. + +long time_esterror; /* estimated error */ + + This variable establishes the expected error of the indicated time + relative to the primary reference source, in microseconds. For NTP, + the value is determined as the root dispersion, which represents + the best estimate of the actual error of the system clock based on + its past behavior, together with observations of multiple clocks + within the peer group. This variable is computed by the time- + synchronization daemon and returned in system calls, but is + otherwise not used by the kernel. + +long time_phase = 0; /* phase offset (scaled us) */ +long time_freq = 0; /* frequency offset (scaled ppm) */ +time_adj = 0; /* tick adjust (scaled 1 / HZ) */ + + These variables control the phase increment and the frequency + increment of the system clock at each tick. The time_phase variable + is scaled by (1 << SHIFT_SCALE) (24) in microseconds, giving a + maximum adjustment of about +-128 us/tick and a resolution of about + 60 femtoseconds/tick. The time_freq variable is scaled by (1 << + SHIFT_KF) in parts-per-million (ppm), giving it a maximum value of + over +-2000 ppm and a minimum value (frequency resolution) of about + 1e-5 ppm. The time_adj variable is the actual phase increment in + scaled microseconds to add to time_phase once each tick. It is + computed from time_phase and time_freq once per second. + +long time_reftime = 0; /* time at last adjustment (s) */ + + This variable is the second's portion of the system time on the + last call to adjtime(). It is used to adjust the time_freq variable + as the time since the last update increases. + +int fixtick = 1000000 % HZ; /* amortization factor */ + + In some systems such as the Ultrix and OSF/1 kernels, the local + clock runs at some frequency that does not divide the number of + microseconds in the second. In order that the clock runs at a + precise rate, it is necessary to introduce an amortization factor + into the local timescale, in effect a leap-multimicrosecond. This + is not a new kernel variable, but a new use of an existing kernel + variable. + +4.3. Architecture Constants + +Following is a list of the important architecture constants that +establish the response and stability of the PLL and provide maximum +bounds on behavior in order to satisfy correctness assertions made in +the protocol specification. + +#define HZ 256 /* timer interrupt frequency (Hz) */ +#define SHIFT_HZ 8 /* log2(HZ) */ + + The HZ define (a variable in some kernels) establishes the timer + interrupt frequency, 100 Hz for the SunOS kernel, 256 Hz for the + Ultrix kernel and 1024 Hz for the OSF/1 kernel. The SHIFT_HZ define + expresses the same value as the nearest power of two in order to + avoid hardware multiply operations. These are the only parameters + that need to be changed for different kernel timer interrupt + frequencies. + +#define SHIFT_KG 6 /* shift for phase increment */ +#define SHIFT_KF 16 /* shift for frequency increment */ +#define MAXTC 6 /* maximum time constant (shift) */ + + These defines establish the response and stability characteristics + of the PLL model. The SHIFT_KG and SHIFT_KF defines establish the + damping of the PLL and are chosen by analysis for a slightly + underdamped convergence characteristic. The MAXTC define + establishes the maximum time constant of the PLL. + +#define SHIFT_SCALE (SHIFT_KF + SHIFT_HZ) /* shift for scale factor */ +#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* shift for offset scale + * factor */ +#define SHIFT_USEC 16 /* shift for 1 us in external units */ +#define FINEUSEC (1 << SHIFT_SCALE) /* 1 us in scaled units */ + + The SHIFT_SCALE define establishes the decimal point on the + time_phase variable which serves as a an extension to the low-order + bits of the system clock variable. The SHIFT_UPDATE define + establishes the decimal point of the phase portion of the + ntp_adjtime() update. The SHIFT_USEC define represents 1 us in + external units (shift), while the FINEUSEC define represents 1 us + in internal units. + +#define MAXPHASE 128000 /* max phase error (usec) */ +#define MAXFREQ 100 /* max frequency error (ppm) */ +#define MINSEC 16 /* min interval between updates (s) */ +#define MAXSEC 1200 /* max interval between updates (s) */ + + These defines establish the performance envelope of the PLL, one to + bound the maximum phase error, another to bound the maximum + frequency error and two others to bound the minimum and maximum + time between updates. The intent of these bounds is to force the + PLL to operate within predefined limits in order to conform to the + correctness models assumed by time-synchronization protocols like + NTP and DTSS. An excursion which exceeds these bounds is clamped to + the bound and operation proceeds accordingly. In practice, this can + occur only if something has failed or is operating out of + tolerance, but otherwise the PLL continues to operate in a stable + mode. Note that the MAXPHASE define conforms to the maximum offset + allowed in NTP before the system time is reset (by settimeofday(), + rather than incrementally adjusted (by ntp_adjtime(). + +David L. Mills <mills@udel.edu> +Electrical Engineering Department +University of Delaware +Newark, DE 19716 +302 831 8247 fax 302 831 4316 + +1 April 1992 diff --git a/usr.sbin/xntpd/doc/README.magic b/usr.sbin/xntpd/doc/README.magic new file mode 100644 index 000000000000..f473a9220c44 --- /dev/null +++ b/usr.sbin/xntpd/doc/README.magic @@ -0,0 +1,346 @@ + Magic Tricks for Precision Timekeeping + + Revised 19 September 1993 + +Note: This information file is included in the NTP Version 3 +distribution (xntp3.tar.Z) as the file README.magic. This distribution +can be obtained via anonymous ftp from louie.udel.edu in the directory +pub/ntp. + +1. Introduction + +It most cases it is possible using NTP to synchronize a number of hosts +on an Ethernet or moderately loaded T1 network to a radio clock within a +few tens of milliseconds with no particular care in selecting the radio +clock or configuring the servers on the network. This may be adequate +for the majority of applications; however, modern workstations and high +speed networks can do much better than that, generally to within some +fraction of a millisecond, by using special care in the design of the +hardware and software interfaces. + +The timekeeping accuracy of a NTP-synchronized host depends on two +quantities: the delay due to hardware and software processing and the +accumulated jitter due to such things as clock reading precision and +varying latencies in hardware and software queuing. Processing delays +directly affect the timekeeping accuracy, unless minimized by systematic +analysis and adjustment. Jitter, on the other hand, can be essentially +removed, as long as the statistical properties are unbiased, by the low- +pass filtering of the phase-lock loop incorporated in the NTP local +clock model. + +This note discusses issues in the connection of external time sources +such as radio clocks and related timing signals to a primary (stratum-1) +NTP time server. Of principal concern are various techniques that can be +utilized to improve the accuracy and precision of the time accuracy and +frequency stability. Radio clocks are most often connected to a time +server using a serial asynchronous port. Much of the discussion in this +memorandum has to do with ways in which the delay incurred in this type +of connection can be controlled and ways in which the jitter due to +various causes can be minimized. + +However, there are ways other than serial ports to connect a radio +clock, including special purpose hardware devices for some +architectures, and even unusual applications of existing interface +devices, such as the audio codec provided in some systems. Many of these +methods can yield accuracies as good as any attainable with a serial +port. For those radio clocks equipped with an IRIG-B signal output, for +example, a hardware device is available for the Sun SPARCstation; see +the xntpd.8 manual page in the doc directory of the NTP Version 3 +distribution for further information. In addition, it is possible to +decode the IRIG-B signal using the audio codec included in the Sun +SPARCstation and a special kernel driver described in the irig.txt file +in the doc directory of the NTP Version 3 distribution. These devices +will not be discussed further in this memorandum. + +2. Connection via Serial Port + +Most radio clocks produce an ASCII timecode with a precision only to the +millisecond. This results in a maximum peak-to-peak (p-p) jitter in the +clock readings of one millisecond. However, assuming the read requests +are statistically independent of the clock update times, the reading +error is uniformly distributed over the millisecond, so that the average +over a large number of readings will make the clock appear 0.5 ms late. +To compensate for this, it is only necessary to add 0.5 ms to its +reading before further processing by the NTP algorithms. + +Radio clocks are usually connected to the host computer using a serial +port operating at a typical speed of 9600 baud. The on-time reference +epoch for the timecode is usually the start bit of a designated +character, usually <CR>, which is part of the timecode. The UART chip +implementing the serial port most often has a sample clock of eight to +16 times the basic baud rate. Assuming the sample clock starts midway in +the start bit and continues to midway in the first stop bit, this +creates a processing delay of 10.5 baud times, or about 1.1 ms, relative +to the start bit of the character. The jitter contribution is usually no +more than a couple of sample-clock periods, or about 26 usec p-p. This +is small compared to the clock reading jitter and can be ignored. Thus, +the UART delay can be considered constant, so the hardware contribution +to the total mean delay budget is 0.5 + 1.1 = 1.6 ms. + +In some kernel serial port drivers, in particular, the Sun zs driver, +an intentional delay is introduce in input character processing when the +first character is received after an idle period. A batch of characters +is passed to the calling program when either (a) a timeout in the +neighborhood of 10 ms expires or (b) an input buffer fills up. The +intent in this design is to reduce the interrupt load on the processor +by batching the characters where possible. Obviously, this can cause +severe problems for precision timekeeping. It is possible to patch the +zs driver to eliminate the jitter due to this cause; contact the author +for further details. However, there is a better solution which will be +described later in this note. The problem does not appear to be present +in the Serial/Parallel Controller (SPC) for the SBus, which contains +eight serial asynchronous ports along with a parallel port. The +measurements referred to below were made using this controller. + +Good timekeeping depends strongly on the means available to capture an +accurate sample of the local clock or timestamp at the instant the stop +bit of the on-time character is found; therefore, the code path delay +between the character interrupt routine and the first place a timestamp +can be captured is very important, since on some systems such as Sun +SPARCstations, this path can be astonishingly long. The Sun scheduling +mechanisms involve both a hardware interrupt queue and a software +interrupt queue. Entries are made on the hardware queue as the interrupt +is signalled and generally with the lowest latency, estimated at 20-30 +microseconds (usec) for a SPARC 4/65 IPC. Then, after minimal +processing, an entry is made on the software queue for later processing +in order of software interrupt priority. Finally, the software interrupt +unblocks the NTP daemon which calculates the current local clock offset +and introduces corrections as required. + +Opportunities exist to capture timestamps at the hardware interrupt +time, software interrupt time and at the time the NTP daemon is +activated, but these involve various degrees of kernel trespass and +hardware gimmicks. To gain some idea of the severity of the errors +introduced at each of these stages, measurements were made using a Sun +4/65 IPC and a test setup that results in an error between the host +clock and a precision time source (calibrated cesium clock) no greater +than 0.1 ms. The total delay from the on-time epoch to when the NTP +daemon is activated was measured at 8.3 ms in an otherwise idle system, +but increased on rare occasion to over 25 ms under load, even when the +NTP daemon was operated at the highest available software priority +level. Since 1.6 ms of the total delay is due to the hardware, the +remaining 6.7 ms represents the total code path delay accounting for all +software processing from the hardware interrupt to the NTP daemon. + +It is commonly observed that the latency variations (jitter) in typical +real-time applications scale as the processing delay. In the case above, +the ratio of the maximum observed delay (25 ms) to the baseline code +path delay (8.3 ms) is about three. It is natural to expect that this +ratio remain the same or less as the code path between the hardware +interrupt and where the timestamp is captured is reduced. However, in +general this requires trespass on kernel facilities and/or making use of +features not common to all or even most Unix implementations. In order +to assess the cost and benefits of increasingly more aggressive insult +to the hardware and software of the system, it is useful to construct a +budget of the code path delay at each of the timestamp opportunity +times. For instance, on Unix systems which include support for the SIGIO +facility, it is possible to intervene at the time the software interrupt +is serviced. The NTP daemon code uses this facility, when available, to +capture a timestamp and save it along with the data in a buffer for +later processing. This reduces the total code path delay from 6.7 ms to +3.5 ms on an otherwise idle system. This reduction applies to all input +processing, including network interfaces and serial ports. + +3. The CLK Mode + +By far the best place to capture the timestamp is right in the kernel +interrupt routine, but this gerally requires intruding in the code +itself, which can be intricate and architecture dependent. The next best +place is in some routine close to the interrupt routine on the code +path. There are two ways to do this, depending on the ancestry of the +Unix operating system variant. Older systems based primarily on the +original Unix 4.3bsd support what is called a line discipline module, +which is a hunk of code with more-or-less well defined interface +specifications that can get in the way, so to speak, of the code path +between the interrupt routine and the remainder of the serial port +processing. Newer systems based on System V STREAMS can do the same +thing using what is called a streams module. Both approaches are +supported in the NTP Version 3 distribution, as described in the README +files in the kernel directory of the distribution. In either case, +header and source files have to be copied to the kernel build tree and +certain tables in the kernel have to be modified. In neither case, +however, are kernel sources required. In order to take advantage of +this, the clock driver must include code to activate the feature and +extract the timestamp. At present, this support is included in the clock +drivers for the Spectracom WWVB clock (WWVB define), the PSTI/Traconex +WWV/WWVH clock (PST define) and a special one-pulse-per-second (pps) +signal (PPSCLK define) described later. If justified, support can be +easily added to most other clock drivers as well. For future reference, +these modules operating with supported drivers will be called the CLK +support. + +The CLK line discipline and STREAMS modules operate in the same way. +They look for a designated character, usually <CR>, and stuff a Unix +timestamp in the data stream following that character whenever it is +found. Eventually, the data arrive at the particular clock driver +configured in the NTP Version 3 distribution. The driver then uses the +timestamp as a precise reference epoch, subject to the earlier +processing delays and jitter budget, for future reference. In order to +gain some insight as to the effectiveness of this approach, measurements +were made using the same test setup described above. The total delay +from the on-time epoch to the instant when the timestamp is captured was +measured at 3.5 ms. Thus, the code path delay is this value less the +hardware delay 3.5 - 1.6 = 1.9 ms. + +While the improvement in accuracy in the baseline case is significant, +there is another factor, at least in Sun systems, that makes it even +more worthwhile. When processing the code path up to the CLK module, the +priority is apparently higher than for processing beyond it. In case of +heavy CPU activity, this can lead to relatively long tails in the +processing delays for the driver, which of course are avoided by +capturing the timestamp early in the code path. + +4. The PPSCLK Mode + +Many timing receivers can produce a 1-pps signal of considerably better +precision than the ASCII timecode. Using this signal, it is possible to +avoid the 1-ms p-p jitter and 1.6 ms hardware timecode adjustment +entirely. However, a device is required to interface this signal to the +hardware and operating system. In general, this requires some sort of +level converter and pulse generator that can turn the 1-pps signal on- +time transition into a valid character. An example of such a device is +described in the gadget directory of the NTP Version 3 distribution. +Although many different circuit designs could be used as well, this +particular device generates a single 26-usec start bit for each 1-pps +signal on-time transition. This appears to the UART operating at 38.4K +baud as an ASCII DEL (hex FF). + +Now, assuming a serial port can be dedicated to this purpose, a source +of 1-pps character interrupts is available and can be used to provide a +precision reference. The NTP Version 3 daemon can be configured to +utilize this feature by specifying the PPSCLK define, which requires the +CLK module and gadget box described above. The character resulting from +each 1-pps signal on-time transition is intercepted by the CLK module +and a timestamp is inserted in the data stream. An interrupt is created +for the device driver, which reads the timestamp and discards the DEL +character. Since the timestamp is captured at the on-time transition, +the seconds-fraction portion is the offset between the local clock and +the on-time epoch less the UART delay of 273 usec at 38.4K baud. If the +local clock is within +-0.5 second of this epoch, as determined by other +means, the local clock correction is taken as the offset itself, if +between zero and 0.5 s, and the offset minus one second, if between 0.5 +and 1.0 s. In the NTP daemon the resulting correction is first processed +by a multi-stage median/trimmed mean filter to remove residual jitter +and then processed by the usual NTP algorithms. + +The baseline delay between the on-time transition and the timestamp +capture was measured at 400+-10 usec on an otherwise idle test system. +As the UART delay at 38.4K baud is about 270 usec, the difference, 130 +usec, must be due to the hardware interrupt latency plus the time to +call the microtime() routine which actually reads the system clock and +microsecond counter. For these measurements the assembly-coded version +of this routine described in the ppsclock directory of the NTP Version 3 +distribution was used. This routine reduces the time to read the system +clock from 42-85 usec with the native Sun C-coded routine to about 3 +usec using the microtime() assembly-coded routine and can be ignored. +Thus, the 130 usec must be accounted for in interrupt service, register +window, context switching, streams operations and measurement +uncertainty, which is probably not unreasonable. The reason for the +difference between the this figure and the previously calculated value +of 1.9 ms for the CLK module and serial ASCII timecode is probably due +to the fact that all STREAMS modules other than the CLK module were +removed, since the serial port is not used for ordinary ASCII data. + +An interesting feature of this approach is that the 1-pps signal is not +necessarily associated with any particular radio clock and, indeed, +there may be no such clock at all. Some precision timekeeping equipment, +such as cesium clocks, VLF receivers and LORAN-C timing receivers +produce only a precision 1-pps signal and rely on other mechanisms to +resolve the second of the day and day of the year. It is possible for an +NTP-synchronized host to derive the latter information using other NTP +peers, presumably properly synchronized within +-0.5 second, and to +remove residual jitter using the 1-pps signal. This makes it quite +practical to deliver precision time to local clients when the subnet +paths to remote primary servers are heavily congested. In extreme cases +like this, it has been found useful to increase the tracking aperture +from +-128 ms to as high as +-512 ms. + +In the current implementation the radio timecode and 1-pps signal are +separately processed. The timecode capture and CLK support, if provided +by the radio driver, operate the same way whether or not the PPSCLK +support is enabled. If the local clock is reliably synchronized within ++-0.5 s and the 1-pps signal has been valid for some number of seconds, +its offset rather than whatever synchronization source has been selected +is used instead. However, while a this procedure delivers a new offset +estimate every second, the local clock is updated only as each valid +update is computed for the peer selected as the source of +synchronization. + +However, there is a hazard to the use of the 1-pps signal in this way if +the radio generating the 1-pps signal misbehaves or loses +synchronization with its transmitter. In such a case the radio might +indicate the error, but the system has no way to associate the error +with the 1-pps signal. To deal with this problem the prefer parameter +described in the xntpd.8 man page in the doc directory of the NTP +Version 3 distribution can be used both to cause the clock selection +algorithm to choose a preferred peer, all other things being equal, as +well as associate the error indications in such a way that the 1-pps +signal will be disregarded if the peer stops providing valid updates, +such as would occur in an error condition. The prefer parameter can be +used in other situations as well when preference is to be given a +particular source of synchronization. + +5. The PPS Mode + +For the ultimate accuracy and lowest jitter, it would be best to +eliminate the UART and capture the 1-pps on-time transition directly +using an appropriate interface. This is in fact possible using a +modified serial port driver and data lead in the serial port interface +cable. In this scheme, described in detail in the ppsclock directory of +the NTP Version 3 distribution, the 1-pps source is connected via the +previously described gadget box to the carrier-detect lead of a serial +port. Happily, this can be the same port used for a radio clock, for +example, or another unrelated serial device. The scheme, referred to +subsequently as the PPS mode, is specific to the SunOS 4.1.x kernel and +requires a special STREAMS module. Instructions on how to build the +kernel are also included in that directory. + +Except for special-purpose interface modules, such as the KSI/Odetics +TPRO IRIG-B decoder and the modified audio driver for the IRIG-B signal +mentioned previously, the PPS mode provides the most accurate and +precise timestamp available. There is essentially no latency and the +timestamp is captured within 20-30 usec of the on-time epoch. + +The PPS mode requires the PPSPPS define and one of the radio clock +serial ports to be selected as the PPS interface. This is the port which +handles the 1-pps signal; however, the signal path has nothing to do +with the ordinary serial data path; the two signals are not related, +other than by the need to activate the PPS mode and pass the file +descriptor to a common processing routine. Thus, for the port to be +selected for the PPS function, the define for the associated radio clock +needs to have a PPS suffix. In case of multiple radio clocks on a single +time server, the PPS suffix is necessary on only one of them; more than +one PPS suffix would be an error. + +The PPS mode works just like the CLK mode in the treatment of the prefer +parameter and indicated peer errors. As in the CLK mode, only the offset +within the second is used and only when the offset is less than +-0.5 s. +However, the precision of the clock adjustments is usually so fine that +the error budget is dominated by the inherent short-term stability of +typical computer local clock oscillators. Therefore, it is advisable to +reduce the poll interval for the preferred peer from the default 64 s to +something less, like 16 s. This is done using the minpoll and maxpoll +parameters of the peer or server command associated with the clock. +These parameters take as arguments a power of 2, in seconds, which +becomes the poll interval and, indirectly, affects the bandwidth of the +tracking loop. + +6. Results and Conclusions + +It is clear from the above that substantial improvements in timekeeping +accuracy are possible with varying degrees of hardware and software +intrusion. While the ultimate accuracy depends on the jitter and wander +characteristics of the computer local oscillator, it is possible to +reduce jitter to a negligible degree simply by processing with the NTP +phase-lock loop and local clock algorithms. The residual jitter using +the PPS mode on a Sun4 IPC is typically in the 40-100 usec range, while +the wander is rarely more than twice that under typical environmental +room conditions. + +David L. Mills <mills@udel.edu> +Electrical Engineering Department +University of Delaware +Newark, DE 19716 +302 831 8247 fax 302 831 4316 + +25 August 1993 diff --git a/usr.sbin/xntpd/doc/UofT b/usr.sbin/xntpd/doc/UofT new file mode 100644 index 000000000000..54420d5f5252 --- /dev/null +++ b/usr.sbin/xntpd/doc/UofT @@ -0,0 +1,146 @@ +This file is the original README, and is a little out of date. It +is also very specific to UofT, since there was a time when the daemon +was only run here. + +To run this: + +(1) Fix your kernel's value of tickadj. Tickadj sets both the + precision with which time slews can be performed and the amount + of slew you can do in a given interval. Xntpd operates by making + a bunch of little adjustments. Make tickadj too large (the default + value almost always is) and xntpd will perform poorly since the + slews will disappear in the roundoff. Make tickadj too small + and large slews won't complete before the next adjustment is + ready. + + To determine a good value of tickadj to use, first determine your + kernel's value of hz (50 on a Sun 3, 100 on Sun 4's and vaxes). + Divide that number into 500 (i.e. compute 500/hz) and use an + integer near there as tickadj (say, 10 on Sun 3's, 5 on Sun 4's + and vaxes). Then adb your kernel and write the new value. You + should probably do both the running kernel and the disk image. + + If your machine doesn't come with adb, or if the kernel is of a + non-Berkeley flavour, take a look at the util directory, particularly + util/tickadj. + +(2) Edit the Config file in this directory. You *must* tell it whether + your machine uses big endian or little endian byte order. Also, + Suns running SunOS 3.x require special consideration, as well as Vaxes + running Ultrix 2.0 and compilers which don't understand `signed char' + declarations. When you've got all this worked out, type `make makefiles' + to distribute configuration information to Makefiles for individual + programs, followed by `make' to compile everything. + +(2a) Note that, among other things, two programs were made in the authstuff + directory, authcert and authspeed. The last two are utilities for + checking the authentication code. Type `authcert < certdata'. If + this provokes a massive failure you probably got the byte order wrong + in the Config file. Type `authspeed -n 10000 auth.samplekeys', or + something, a couple of times to get a value of authdelay to stick in + the configuration file. The numbers for machines I've tried look like: + + uVax II 0.001450 + Sun 3/180 0.000620 + uVax III 0.000515 + Sun 3/60 0.000455 + IBM RT Mdl 125 0.000323 + Sun 3/280 0.000302 + Sun 4/280 0.000110 + MIPS M/1000 0.000100 + +(3) Typing `make install' will nstall xntpd, xntpdc, ntpdate and ntpq. Watch + the install location in the Config file. + +(4) If you will be running xntpd (see 4a below for the alternative), + configure it (configuration is necessary for all machines now, though + this restriction will go away when I get broadcast time fully tested). + xntpd reads its configuration from /etc/ntp.conf (by default) and + you must tell it which machines it is to get its time from in + here. + + Note that NTP operates in a hierarchy. Machines with radio clocks + (which are stratum 1 servers) are at the top of the heap, in that + all time originates with them. The situation with servers locally + is in a state of flux. We currently have one semi-reliable stratum 1 + server on campus (suzuki.ccie), and maintain three other stratum 2 + servers which (gently) access other people's off-campus stratum 1 + servers. All of these machines are lightly loaded and have good + quality clocks, and so will probably do until we get some more stratum 1 + weight. + + Thus you are probably faced with choosing whether your hosts should + be stratum 2 or stratum 3 (or stratum 3 or 4 when suzuki's clock is down). + The rule of thumb is to make your best clocks and/or your file servers + stratum 2 (or 3) by peering them with the four campus servers, and make + lesser clocks and clients stratum 3 (or 4) by peering them with near + by servers which are synchonized to the campus servers. The second rule + of thumb is that more servers are better. It is quite possible to + synchronize with just a single server, but if you do your xtnpd daemon + won't have any cross checks to tell it when the server has gone + wonky. 3 or 4 lower stratum peers is about right. Note that while + you can also peer with same-stratum peers, you shouldn't do this + unless the same-stratum peer is exchanging time with a lower stratum + peer you don't talk to directly. + + Anyway, for your stratum 2 servers you can probably use ntp.conf + from the conf directory directly. You will have to handcraft the + peer assocations for your stratum 3 servers. + + Oh, and a note about the drift file (see ntp.conf). One of the + things xntpd does is accumulate a correction for the frequency of + the crystal in your computer. It usually takes a day or so of + running to figure this out, after which the value will usually remain + pretty stable, especially if the computer is in a machine room. The + value is printed in your syslog file (once a minute, currently, though + this will change), and can be obtained from the daemon using xntpdc. + + To avoid having to wait a day after restarts before the computer + synchronizes really well, xntpd will optionally write its current + value of the frequency correction into a file, once an hour. When + it is killed and restarted, xntpd reinitializes itself to this + value on start up. This is an advantageous feature, so a driftfile + line should always be included in the configuration file. + +(4a) Xntpd is a daemon. It will keep your time exquisitely precise under + normal conditions (it is quite capable of keeping a good clock within + a millisecond of a good server. Our servers aren't normally this + good, yet, but may become so when we get a few more stable local + stratum 1 peers). Even when cut off entirely from its servers xntpd + will prevent your clock from drifting seriously by continuing to apply + its accumulated frequency correction. The cost of this is that xntpd + will permanently consume memory while it is running, and real memory + at that since xntpd is unlikely to ever swap out. This cost is + currently over 100 kb. + + If you aren't too worried about millisecond timing and feel religious + about keeping memory consumption at a minimum (perhaps on memory-poor + workstations), a passable alternative might be to run ntpdate instead. + Ntpdate is the NTP equivalent of rdate, a one shot date setting + program, and implements the same multiple sample/multiple server + filter algorithms as xntpd. Ntpdate was explicitly designed to be + run repeatly from cron, though it also makes a good boot time date + setter. Running ntpdate from cron on an hourly basis will keep all + but seriously broken clocks within 100 ms of on-time, and for most + clocks will probably do better than 50 ms. If this is an attractive + alternative see the manual page. You should choose ntpdate's servers + as you would the peer associations for a stratum 3 xntpd server. + +(5) Once everything is configured, start the daemon(s). ntpq can be + used to see what xntpd is doing. It runs both interactive and from + the command line, type ? to see the interactive commands and ? command + to see what a command does. The `peers' command is a good one. ntpq + can also be used to see what other peoples' servers are doing, in + particular the fuzzball primary servers. + +(6) If you want to use the authentication facility (this might be useful + if, for example, you were running Kerberos since this prevents people + from setting your time back and doing replay attacks on the server), + you might find a couple of useful programs in the auth_stuff directory. + mkrandkeys will generate some very random keys to use. keyparity + generates odd parity bits for keys (needed for the key file) and will + convert between key formats. + +All bug reports gratefully received. + +Dennis diff --git a/usr.sbin/xntpd/doc/notes.txt b/usr.sbin/xntpd/doc/notes.txt new file mode 100644 index 000000000000..5ea2b3318bb3 --- /dev/null +++ b/usr.sbin/xntpd/doc/notes.txt @@ -0,0 +1,1258 @@ + Notes on Xntpd Configuration + + David L. Mills (mills@udel.edu) + University of Delaware + 14 January 1993 + +Introduction + +This document is a collection of notes concerning the use of xntpd and +related programs, and on coping with the Network Time Protocol (NTP) in +general. It is a major rewrite and update of an earlier document written +by Dennis Ferguson of the University of Toronto dated 5 November 1989. +It includes many changes and additions resulting from the NTP Version 3 +specification and new implementation features. It supersedes the earlier +document, which should no longer be used for new configurations. + +Xntpd is a complete implementation of the NTP Version 3 specification as +defined in RFC 1305. It also retains compatibility with both NTP Version +2, as defined in RFC 1119, and NTP Version 1, as defined in RFC 1059, +although this compatibility is sometimes strained and only +semiautomatic. In order to support in principle the ultimate precision +of about 232 picoseconds in the NTP specification, xntpd does no +floating-point arithmetic and instead manipulates the 64-bit NTP +timestamps as unsigned 64-bit integers. Xntpd fully implements NTP +Versions 2 and 3 authentication and a mode-6 control-message facility. +As extensions to the specification, a flexible address-and-mask +restriction facility has been included, along with a private mode-7 +control-message facility used to remotely reconfigure the system and +monitor a considerable amount of internal detail. + +The code is biased towards the needs of a busy time server with +numerous, possibly hundreds, of clients and other servers. Tables are +hashed to allow efficient handling of many associations, though at the +expense of additional overhead when the number of associations is small. +Many fancy features have been included to permit efficient management +and monitoring of a busy primary server, features which are simply +excess baggage for a server on a high stratum client. The code was +written with near demonic attention to details which can affect +precision and as a consequence should be able to make good use of high +performance, special purpose hardware such as precision oscillators and +radio clocks. The present code supports a number of radio clocks, +including those for the WWV, CHU, WWVB, DCF77, GOES and GPS radio and +satellite services. The server methodically avoids the use of Unix- +specific library routines where possible by implementing local versions, +in order to aid in porting the code to perverse Unix and non-Unix +platforms. + +While this implementation slavishly obeys the NTP specification RFC +1305, it has been specifically tuned to achieve the highest accuracy +possible on whatever hardware and operating-system platform is +available. In general, its precision is limited only by that of the +onboard time-of-day clock maintained by the hardware and operating +system, while its stability is limited only by that of the onboard +frequency source, usually an uncompensated crystal oscillator. On modern +RISC-based processors connected directly to radio clocks via serial- +asynchronous interfaces, the accuracy is usually limited by that of the +radio clock and interface to the order of a few milliseconds. The code +includes special features to support a one-pulse-per-second (1-pps) +signal generated by some radio clocks. When used in conjunction with a +suitable hardware level converter, the accuracy can be improved to the +order of 100 microseconds. Further improvement is possible using an +outboard, stabilized frequency source, in which the accuracy and +stability are limited only by the characteristics of that source. + +The xntp3 distribution includes, in addition to the daemon itself +(xntpd), several utility programs, including two remote-monitoring +programs (ntpq, xntpdc), a remote clock-setting program similar to the +Unix rdate program (ntpdate), a traceback utility useful to discover +suitable synchronization sources (ntptrace), and various programs used +to configure the local platform and calibrate the intrinsic errors. NTP +has been ported to a large number of platforms, including most RISC and +CISC workstations and mainframes manufactured today. Example +configuration files for many models of these machines are included in +the xntp3 distribution. While in most cases the standard version of the +implementation runs with no hardware or operating-system modifications, +not all features of the distribution are available on all platforms. For +instance, a special feature allowing Sun 4s to achieve accuracies in the +order of 100 microseconds requires some minor changes and additions to +the kernel and input/output support. + +There are, however, several drawbacks to all of this. Xntpd is very, +very fat. This is rotten if your intended platform for the daemon is +memory-limited. Xntpd uses SIGIO for all input, a facility which appears +to not enjoy universal support and whose use seems to exercise the parts +of your vendors' kernels which are most likely to have been done poorly. +The code is unforgiving in the face of kernel problems which affect +performance, and generally requires that you repair the problems in +order to achieve acceptable performance. The code has a distinctly +experimental flavour and contains features which could charitably be +termed failed experiments, but which have not been hacked out yet. There +is code which has not been thoroughly tested (e.g. leap-second support) +due to the inconvenience of setting up tests. Much was learned from the +addition of support for a variety of radio clocks, with the result that +this support could use some rewriting. + +How NTP Works + +The approach used by NTP to achieve reliable time synchronization from a +set of possibly unreliable remote time servers is somewhat different +than other such protocols. In particular, NTP does not attempt to +synchronize clocks to each other. Rather, each server attempts to +synchronize to UTC (i.e., Universal Coordinated Time) using the best +available source and available transmission paths to that source. This +is a fine point which is worth understanding. A group of NTP- +synchronized clocks may be close to each other in time, but this is not +a consequence of the clocks in the group having synchronized to each +other, but rather because each clock has synchronized closely to UTC via +the best source it has access to. As such, trying to synchronize a set +of clocks to a set of servers whose time is not in mutual agreement may +not result in any sort of useful synchronization of the clocks, even if +you don't care about UTC. NTP operates on the premise that there is one +true standard time, and that if several servers which claim +synchronization to standard time disagree about what that time is, then +one or more of them must be broken. There is no attempt to resolve +differences more gracefully since the premise is that substantial +differences cannot exist. In essence, NTP expects that the time being +distributed from the root of the synchronization subnet will be derived +from some external source of UTC (e.g. a radio clock). This makes it +somewhat inconvenient (though not impossible) to synchronize hosts +together without a reliable source of UTC to synchronize them to. If +your network is isolated and you cannot access other people's servers +across the Internet, a radio clock may make a good investment. + +Time is distributed through a hierarchy of NTP servers, with each server +adopting a "stratum" which indicates how far away from an external +source of UTC it is operating at. Stratum-1 servers, which are at the +top of the pile (or bottom, depending on your point of view), have +access to some external time source, usually a radio clock synchronized +to time signal broadcasts from radio stations which explicitly provide a +standard time service. A stratum-2 server is one which is currently +obtaining time from a stratum-1 server, a stratum-3 server gets its time +from a stratum-2 server, and so on. To avoid long lived synchronization +loops the number of strata is limited to 15. + +Each client in the synchronization subnet (which may also be a server +for other, higher stratum clients) chooses exactly one of the available +servers to synchronize to, usually from among the lowest stratum servers +it has access to. It is thus possible to construct a synchronization +subnet where each server has exactly one source of lower stratum time to +synchronize to. This is, however, not an optimal configuration, for +indeed NTP operates under another premise as well, that each server's +time should be viewed with a certain amount of distrust. NTP really +prefers to have access to several sources of lower stratum time (at +least three) since it can then apply an agreement algorithm to detect +insanity on the part of any one of these. Normally, when all servers are +in agreement, NTP will choose the best of these, where "best" is defined +in terms of lowest stratum, closest (in terms of network delay) and +claimed precision, along with several other considerations. The +implication is that, while one should aim to provide each client with +three or more sources of lower stratum time, several of these will only +be providing backup service and may be of lesser quality in terms of +network delay and stratum (i.e. a same-stratum peer which receives time +from lower stratum sources the local server doesn't access directly can +also provide good backup service). + +Finally, there is the issue of association modes. There are a number of +modes in which NTP servers can associate with each other, with the mode +of each server in the pair indicating the behaviour the other server can +expect from it. In particular, when configuring a server to obtain time +from other servers, there is a choice of two modes which may be +alternatively used. Configuring an association in symmetric-active mode +(usually indicated by a "peer" declaration in configuration files) +indicates to the remote server that one wishes to obtain time from the +remote server and that one is also willing to supply time to the remote +server if need be. This mode is appropriate in configurations involving +a number of redundant time servers interconnected via diverse network +paths, which is presently the case for most stratum-1 and stratum-2 +servers on the Internet today. Configuring an association in client mode +(usually indicated by a "server" declaration in configuration files) +indicates that one wishes to obtain time from the remote server, but that +one is not willing to provide time to the remote server. This mode is +appropriate for file-server and workstation clients that do not provide +synchronization to other local clients. Client mode is also useful for +boot-date-setting programs and the like, which really have no time to +provide and which don't retain state about associations over the longer +term. + +Configuring Your Subnet + +At startup time the xntpd daemon running on a host reads the initial +configuration information from a file, usually /etc/ntp.conf, unless a +different name has been specified at compile time. Putting something in +this file which will enable the host to obtain time from somewhere else +is usually the first big hurdle after installation of the software +itself, which is described in other documents included in the xntp3 +distribution. At its simplest, what you need to do in the configuration +file is declare the servers that the daemon should poll for time +synchronization. In principle, no such list is needed if some other time +server explicitly mentions the host and is willing to provide +synchronization; however, this is considered dangerous, unless the +access control or authentication features (described later) are in use. + +In the case of a workstation operating in an enterprise network for a +public or private organization, there is often an administrative +department that coordinates network services, including NTP. Where +available, the addresses of appropriate servers can be provided by that +department. However, if this infrastructure is not available, it is +necessary to explore some portion of the existing NTP subnet now running +in the Internet. There are at present many thousands of time servers +running NTP in the Internet, a significant number of which are willing +to provide a public time-synchronization service. Some of these are +listed in a file maintained on the Internet host louie.udel.edu +(128.175.1.3) on the path pub/ntp/doc/clock.txt. This file is updated on +a regular basis using information provided voluntarily by various site +administrators. There are other ways to explore the nearby subnet using +the ntptrace and ntpq programs. See the man pages for further +information on these programs. + +It is vital to carefully consider the issues of robustness and +reliability when selecting the sources of synchronization. Normally, not +less than three sources should be available, preferably selected to +avoid common points of failure. It is usually better to choose sources +which are likely to be "close" to you in terms of network topology, +though you shouldn't worry overly about this if you are unable to +determine who is close and who isn't. Normally, it is much more serious +when a server becomes faulty and delivers incorrect time than when it +simply stops operating, since an NTP-synchronized host normally can +coast for hours or even days without its clock accumulating serious +error over one second, for instance. Selecting at least three sources +from different operating administrations, where possible, is the minimum +recommended, although a lesser number could provide acceptable service +with a degraded degree of robustness. + +Normally, it is not considered good practice for a single workstation to +request synchronization from a primary (stratum-1) time server. At +present, these servers provide synchronization for hundreds of clients +in many cases and could, along with the network access paths, become +seriously overloaded if large numbers of workstation clients requested +synchronization directly. Therefore, workstations located in sparsely +populated administrative domains with no local synchronization +infrastructure should request synchronization from nearby stratum-2 +servers instead. In most cases the keepers of those servers listed in +the clock.txt file provide unrestricted access without prior permission; +however, in all cases it is considered polite to notify the +administrator listed in the file upon commencement of regular service. +In all cases the access mode and notification requirements listed in the +file must be respected. + +In the case of a gateway or file server providing service to a +significant number of workstations or file servers in an enterprise +network it is even more important to provide multiple, redundant sources +of synchronization and multiple, diversity-routed, network access paths. +The preferred configuration is at least three administratively +coordinated time servers providing service throughout the administrative +domain including campus networks and subnetworks. Each of these should +obtain service from at least two different outside sources of +synchronization, preferably via different gateways and access paths. +These sources should all operate at the same stratum level, which is one +less than the stratum level to be used by the local time servers +themselves. In addition, each of these time servers should peer with all +of the other time servers in the local administrative domain at the +stratum level used by the local time servers, as well as at least one +(different) outside source at this level. This configuration results in +the use of six outside sources at a lower stratum level (toward the +primary source of synchronization, usually a radio clock), plus three +outside sources at the same stratum level, for a total of nine outside +sources of synchronization. While this may seem excessive, the actual +load on network resources is minimal, since the interval between polling +messages exchanged between peers usually ratchets back to no more than +one message every 17 minutes. + +The stratum level to be used by the local time servers is an engineering +choice. As a matter of policy, and in order to reduce the load on the +primary servers, it is desirable to use the highest stratum consistent +with reliable, accurate time synchronization throughout the +administrative domain. In the case of enterprise networks serving +hundreds or thousands of client file servers and workstations, +conventional practice is to obtain service from stratum-1 primary +servers such as listed in the clock.txt file. When choosing sources away +from the primary sources, the particular synchronization path in use at +any time can be verified using the ntptrace program included in the +xntp3 distribution. It is important to avoid loops and possible common +points of failure when selecting these sources. Note that, while NTP +detects and rejects loops involving neighboring servers, it does not +detect loops involving intervening servers. In the unlikely case that +all primary sources of synchronization are lost throughout the subnet, +the remaining servers on that subnet can form temporary loops and, if +the loss continues for an interval of many hours, the servers will drop +off the subnet and free-run with respect to their internal (disciplined) +timing sources. + +In many cases the purchase of one or more radio clocks is justified, in +which cases good engineering practice is to use the configurations +described above and connect the radio clock to one of the local servers. +This server is then encouraged to participate in a special primary- +server subnetwork in which each radio-equipped server peers with several +other similarly equipped servers. In this way the radio-equipped server +may provide synchronization, as well as receive synchronization, should +the local or remote radio clock(s) fail or become faulty. Xntpd treats +attached radio clock(s) in the same way as other servers and applies the +same criteria and algorithms to the time indications, so can detect when +the radio fails or becomes faulty and switch to alternate sources of +synchronization. It is strongly advised, and in practice for most +primary servers today, to employ the authentication or access-control +features of the xntp3 distribution in order to protect against hostile +penetration and possible destabilization of the time service. + +Using this or similar strategies, the remaining hosts in the same +administrative domain can be synchronized to the three (or more) +selected time servers. Assuming these servers are synchronized directly +to stratum-1 sources and operate normally as stratum-2, the next level +away from the primary source of synchronization, for instance various +campus file servers, will operate at stratum 3 and dependent +workstations at stratum 4. Engineered correctly, such a subnet will +survive all but the most exotic failures or even hostile penetrations of +the various, distributed timekeeping resources. + +The above arrangement should provide very good, robust time service with +a minimum of traffic to distant servers and with manageable loads on the +local servers. While it is theoretically possible to extend the +synchronization subnet to even higher strata, this is seldom justified +and can make the maintenance of configuration files unmanageable. +Serving time to a higher stratum peer is very inexpensive in terms of +the load on the lower stratum server if the latter is located on the +same concatenated LAN. When justified by the accuracy expectations, NTP +can be operated in broadcast mode, so that clients need only listen for +periodic broadcasts and do not need to send anything. + +When planning your network you might, beyond this, keep in mind a few +generic don'ts, in particular: + +1. Don't synchronize a local time server to another peer at the same + stratum, unless the latter is receiving time from lower stratum + sources the former doesn't talk to directly. This minimizes the + occurance of common points of failure, but does not eliminate them + in cases where the usual chain of associations to the primary + sources of synchronization are disrupted due to failures. +2. Don't configure peer associations with higher stratum servers. Let + the higher strata configure lower stratum servers, but not the + reverse. This greatly simplifies configuration file maintenance, + since there is usually much greater configuration churn in the high + stratum clients such as personal workstations. + +3. Don't synchronize more than one time server in a particular + administrative domain to the same time server outside that domain. + Such a practice invites common points of failure, as well as raises + the possibility of massive abuse, should the configuration file be + automatically distributed do a large number of clients. + +There are many useful exceptions to these rules. When in doubt, however, +follow them. + +Dennis Ferguson writes: Note that mention was made of machines with +"good" clocks versus machines with "bad" ones. There are two things that +make a clock good, the precision of the clock (e.g. how many low order +bits in a time value are actually significant) and the frequency of +occurance (or lack thereof) of such things as lost clock interrupts. +Among the most common computers I have observed there to be a fairly +simple algorithm for determining the goodness of its clock. If the +machine is a Vax, it probably has a good clock (the low order bit in the +time is in the microseconds and most of these seem to manage to get +along without losing clock interrupts). If the machine is a Sun 3 it +probably doesn't (the low order clock bit is at the 10 or 20 millisecond +mark and Sun 3s like to lose clock interrupts, particularly if they have +a screen and particularly if they run SunOS 4.0.x). If you have IBM RTs +running AOS 4.3, they have fair clocks (low order clock bit at about a +millisecond and they don't lose clock interrupts, though they do have +trouble with clock rollovers while reading the low order clock bits) but +I recommend them as low stratum NTP servers anyway since they aren't +much use as anything else. Sun 4s running SunOS 4.1.1 make very good +time servers, once some native foolishness mentioned below is +surmounted. [However, it is very important to avoid using the keyboard +firmware, which can cause severe interrupt latencies, in favor of the +software drivers ordinarily used in conjunction with a windowing system. +- DLM] For other machines you are on your own since I don't have enough +data points to venture an opinion. In any event, if at all possible you +should try to use machines with good clocks for the lower strata. + +Configuring Your Server or Client + +As mentioned previously, the configuration file is usually called +/etc/ntp.conf. This is an ASCII file conforming to the usual comment and +whitespace conventions. A working configuration file might look like (In +this and other examples, do not copy this directly.): + + # peer configuration for 128.100.100.7 + # (expected to operate at stratum 2) + + server 128.4.1.1 # rackety.udel.edu + server 128.8.10.1 # umd1.umd.edu + server 192.35.82.50 # lilben.tn.cornell.edu + driftfile /etc/ntp.drift + +This particular host is expected to operate as a client at stratum 2 by +virtue of the "server" keyward and the fact that two of the three +servers declared (the first two, actually) have radio clocks and usually +run at stratum 1. The third server in the list has no radio clock, but +is known to maintain associations with a number of stratum 1 peers and +usually operates at stratum 2. Of particular importance with the last +host is that it maintains associations with peers besides the two +stratum 1 peers mentioned. This can be verified using the ntpq program +included in the xntp3 distribution. When configured using the "server" +keyword, this host can receive synchronization from any of the listed +servers, but can never provide synchronization to them. + +Unless restricted using facilities described later, this host can +provide synchronization to dependent clients, which do not have to be +listed in the configuration file. Associations maintained for these +clients are transitory and result in no persistent state in the host. +These clients are normally not visible using the ntpq program included +in the xntp3 distribution; however, xntpd includes a monitoring feature +(described later) which caches a minimal amount of client information +useful for debugging administrative purposes. + +A time server expected to both receive synchronization from another +server, as well as to provide synchronization to it, is delared using +the "peer" keyword instead of the "server" keyword. In all other aspects +the server operates the same in either mode and can provide +synchronization to dependent clients or other peers. It is considered +good engineering practice to declare time servers outside the +administrative domain as "peer" and those inside as "server" in order to +provide redundancy in the global Internet, while minimizing the +possibility of instability within the domain itself. A time server in +one domain can in principle heal another domain temporarily isolated +from all other sources of synchronization. However, it is probably +unwise for a casual workstation to bridge fragments of the local domain +which have become temporarily isolated. + +Note the inclusion of a "driftfile" declaration. One of the things the +NTP daemon does when it is first started is to compute the error in the +intrinsic frequency of the clock on the computer it is running on. It +usually takes about a day or so after the daemon is started to compute a +good estimate of this (and it needs a good estimate to synchronize +closely to its server). Once the initial value is computed, it will +change only by relatively small amounts during the course of continued +operation. The "driftfile" declaration indicates to the daemon the name +of a file where it may store the current value of the frequency error so +that, if the daemon is stopped and restarted, it can reinitialize itself +to the previous estimate and avoid the day's worth of time it will take +to recompute the frequency estimate. Since this is a desireable feature, +a "driftfile" declaration should always be included in the configuration +file. + +An implication in the above is that, should xntpd be stopped for some +reason, the local platform time will diverge from UTC by an amount that +depends on the intrinsic error of the clock oscillator and the time +since last synchronized. In view of the length of time necessary to +refine the frequency estimate, every effort should be made to operate +the daemon on a continuous basis and minimize the intervals when for +some reason it is not running. + +Xntpd3 Versus Previous Versions + +There are several items of note when dealing with a mixture of xntp3 and +and previous distributions of xntp (NTP Version 2 xntpd) and ntp3.4 (NTP +Version 1 ntpd). The xntp3 implementation of xntpd is an NTP Version 3 +implementation. As such, by default when no additional information is +available concerning the preferences of the peer, xntpd claims to be +version 3 in the packets that it sends. + +An NTP implementation conforming to a previous version specification +ordinarily discards packets from a later version. However, in most +respects documented in RFC 1305, the previous version is compatible with +the version-3 algorithms and protocol. Ntpd, while implementing most of +the version-2 algorithms, still believes itself to be a version-1 +implementation. The sticky part here is that, when either xntpd version +2 or ntpd version 1 receives a packet claiming to be from a version-3 +server, it discards it without further processing. Hence there is a +danger that in some situations synchronization with previous versions +will fail. + +Xntpd is aware of this problem. In particular, when xntpd is polled +first by a host claiming to be a previous version 1 or version 2 +implementation, xntpd claims to be a version 1 or 2 implementation, +respectively, in packets returned to the poller. This allows xntpd to +serve previous version clients transparently. The trouble occurs when an +previous version is to be included in an xntpd configuration file. With +no further indication, xntpd will send packets claiming to be version 3 +when it polls. To get around this, xntpd allows a qualifier to be added +to configuration entries to indicate which version to use when polling. +Hence the entry + + # specify NTP version 1 + + peer 130.43.2.2 version 1 # apple.com (running ntpd version 1) + peer 130.43.2.2 version 2 # apple.com (running xntpd version 2) + +will cause version 1 packets to be sent to the host address 130.43.2.2. +If you are testing xntpd against previous version servers you will need +to be careful about this. Note that, as indicated in the RFC 1305 +specification, there is no longer support for the original NTP +specification, popularly called NTP Version 0. + +There are a few other items to watch when converting an ntpd +configuration file for use with xntpd. The first is to reconsider the +precision entry from the configuration file, if there is one. There was +a time when the precision claimed by a server was mostly commentary, +with no particularly useful purpose. This is no longer the case, +however, and so changing the precision a server claims should only be +done with some consideration as to how this alters the performance of +the server. The default precision claimed by xntpd will be right for +most situations. A section later on will deal with when and how it is +appropriate to change a server's precision without doing things you +don't intend. + +Second, note that in the example configuration file above numeric +addresses are used in the peer and server declarations. It is also +possible to use names requiring resolution instead, but only if some +additional configuration is done (xntpd doesn't include the resolver +routines itself, and requires that a second program be used to do name +resolution). If you find numeric addresses offensive, see below. + +Finally, "passive" and "client" entries in an ntpd configuration file +have no useful equivalent semantics for xntpd and should be deleted. +Xntpd won't reset the kernel variable tickadj when it starts, so you can +remove anything dealing with this in the configuration file. The +configuration of radio clock peers is done using different language in +xntpd configuration files, so you will need to delete these entries from +your ntpd configuration file and see below for the equivalent language. + +Traffic Monitoring + +Xntpd handles peers whose stratum is higher than the stratum of the +local server and pollers using client mode by a fast path which +minimizes the work done in responding to their polls, and normally +retains no memory of these pollers. Sometimes, however, it is +interesting to be able to determine who is polling the server, and how +often, as well as who has been sending other types of queries to the +server. + +To allow this, xntpd implements a traffic monitoring facility which +records the source address and a minimal amount of other information +from each packet which is received by the server. This can be enabled by +adding the following line to the server's configuration file: + + # enable monitoring feature + + monitor yes + +The recorded information can be displayed using the xntpdc query +program, described briefly below. + +Address-and-Mask Restrictions + +The address-and-mask configuration facility supported by xntpd is quite +flexible and general, but is not an integral part of the NTP Version 3 +specification. The major drawback is that, while the internal +implementation is very nice, the user interface sucks. For this reason +it is probably worth doing an example here. Briefly, the facility works +as follows. There is an internal list, each entry of which holds an +address, a mask and a set of flags. On receipt of a packet, the source +address of the packet is compared to each entry in the list, with a +match being posted when the following is true: + + (source_addr & mask) == (address & mask) + +A particular source address may match several list entries. In this case +the entry with the most one bits in the mask is chosen. The flags +associated with this entry are used to control the access. + +In the current implementation the flags always add restrictions. In +effect, an entry with no flags set leaves matching hosts unrestricted. +An entry can be added to the internal list using a "restrict" +declaration. The flags associated with the entry are specified +textually. For example, the "notrust" flag indicates that hosts matching +this entry, while treated normally in other respects, shouldn't be +trusted to provide synchronization even if otherwise so enabled. The +"nomodify" flag indicates that hosts matching this entry should not be +allowed to do run time configuration. There are many more flags, see the +xntpd.8 man page. + +Now the example. Suppose you are running the server on a host whose +address is 128.100.100.7. You would like to ensure that run time +reconfiguration requests can only be made from the local host and that +the server only ever synchronizes to one of a pair of off-campus servers +or, failing that, a time source on net 128.100. The following entries in +the configuration file would implement this policy: + + # by default, don't trust and don't allow modifications + + restrict default notrust nomodify + + # these guys are trusted for time, but no modifications allowed + + restrict 128.100.0.0 mask 255.255.0.0 nomodify + restrict 128.8.10.1 nomodify + restrict 192.35.82.50 nomodify + + # the local addresses are unrestricted + + restrict 128.100.100.7 + restrict 127.0.0.1 + +The first entry is the default entry, which all hosts match and hence +which provides the default set of flags. The next three entries indicate +that matching hosts will only have the nomodify flag set and hence will +be trusted for time. If the mask isn't specified in the restrict +keyward, it defaults to 255.255.255.255. Note that the address +128.100.100.7 matches three entries in the table, the default entry +(mask 0.0.0.0), the entry for net 128.100 (mask 255.255.0.0) and the +entry for the host itself (mask 255.255.255.255). As expected, the flags +for the host are derived from the last entry since the mask has the most +bits set. + +The only other thing worth mentioning is that the restrict declarations +apply to packets from all hosts, including those that are configured +elsewhere in the configuration file and even including your clock +pseudopeer(s), in any. Hence, if you specify a default set of +restrictions which you don't wish to be applied to your configured +peers, you must remove those restrictions for the configured peers with +additional restrict declarations mentioning each peer separately. + +Authentication + +Xntpd supports the optional authentication procedure specified in the +NTP Version 2 and 3 specifications. Briefly, when an association runs in +authenticated mode, each packet transmitted has appended to it a 32-bit +key ID and a 64-bit crypto checksum of the contents of the packet +computed using either the Data Encryption Standard (DES) or Message +Digest (MD5) algorithms. Note that while either of these algorithms +provide sufficient protection from message-modification attacks, +distribution of the former algorithm implementation is restricted to the +U.S. and Canada, while the latter presently is free from such +restrictions. With either algorithm the receiving peer recomputes the +checksum and compares it with the one included in the packet. For this +to work, the peers must share at least one encryption key and, +furthermore, must associate the shared key with the same key ID. + +This facility requires some minor modifications to the basic packet +processing procedures, as required by the specification. These +modifications are enabled by the "authenticate" configuration +declaration. In particular, in authenticated mode, peers which send +unauthenticated packets, peers which send authenticated packets which +the local server is unable to decrypt and peers which send authenticated +packets encrypted using a key we don't trust are all marked +untrustworthy and unsuitable for synchronization. Note that, while the +server may know many keys (identified by many key IDs), it is possible +to declare only a subset of these as trusted. This allows the server to +share keys with a client which requires authenticated time and which +trusts the server but which is not trusted by the server. Also, some +additional configuration language is required to specify the key ID to +be used to authenticate each configured peer association. Hence, for a +server running in authenticated mode, the configuration file might look +similar to the following: + + # peer configuration for 128.100.100.7 + # (expected to operate at stratum 2) + # fully authenticated this time + + peer 128.100.49.105 key 22 # suzuki.ccie.utoronto.ca + peer 128.8.10.1 key 4 # umd1.umd.edu + peer 192.35.82.50 key 6 # lilben.tn.cornell.edu + authenticate yes # enable authentication + keys /usr/local/bin/ntp.keys # path for key file + trustedkey 1 2 14 15 # define trusted keys + requestkey 15 # key (7) for accessing server variables + controlkey 15 # key (6) for accessing server variables + + #authdelay 0.000047 # authentication delay (Sun4c/50 IPX DES) + authdelay 0.000094 # authentication delay (Sun4c/50 IPX MD5) + +There are a couple of previously unmentioned things in here. The +"authenticate yes" line enables authentication processing, while the +"keys /usr/local/bin/ntp.keys" specifies the path to the keys file (see +below and the xntpd.8 man page for detaiils of the file format). The +"trustedkey" declaration identifies those keys that are known to be +uncompromised; the remainder presumably represent the expired or +possibly compromised keys. Both sets of keys must be declared by key +identifier in the ntp.keys file described below. This provides a way to +retire old keys while minimrequestkey 15izing the frequency of delicate +key-distribution procedures. The "requestkey 15" line establishes the +key to be used for mode-6 control messages as specified in RFC 1305 and +used by the ntpq utility program, while the "controlkey 15" establishes +the key to be used for mode-7 private control messages used by the +xntpdc utility program these keys are used to prevent unauthorized +modification of daemon variables. + +The "authdelay" declaration is an estimate of the amount of processing +time taken between the freezing of a transmit timestamp and the actual +transmission of the packet when authentication is enabled (i.e. more or +less the time it takes for the DES or MD5 routine to encrypt a single +block), and is used as a correction for the transmit timestamp. This can +be computed for your CPU by the authspeed program included in the +authstuff directory in the xntp3 distribution. The usage is illustrated +to the following: + + # for DES keys + + authspeed -n 30000 auth.samplekeys + + # for MD5 keys + + authspeed -nd 30000 auth.samplekeys + +Additional utility programs included in the authstuff directory can be +used to generate random keys, certify implementation correctness and +display sample keys. As a general rule, keys should be chosen randomly, +except possibly the request and control keys, which must be entered by +the user as a password. + +The ntp.keys file contains the list of keys and associated key IDs the +server knows about (for obvious reasons this file is better left +unreadable by anyone except the server). The contents of this file might +look like: + + # ntp keys file (ntp.keys) + + 1 N 29233E0461ECD6AE # des key in NTP format + 2 M RIrop8KPPvQvYotM # md5 key as an ASCII random string + 14 M sundial # md5 key as an ASCII string + 15 A sundial # des key as an ASCII string + + # the following 3 keys are identical + + 10 A SeCReT + 10 N d3e54352e5548080 + 10 S a7cb86a4cba80101 + +In the keys file the first token on each line indicates the key ID, the +second token the format of the key and the third the key itself. There +are four key formats. An "A" indicates a DES key written as a 1-to-8 +character string in 7-bit ASCII representation, with each character +standing for a key octet (like a Unix password). An "S" indicates a DES +key written as a hex number in the DES standard format, with the low +order bit (LSB) of each octet being the (odd) parity bit. An "N" +indicates a DES key again written as a hex number, but in NTP standard +format with the high order bit of each octet being the (odd) parity bit +(confusing enough?). An "M" indicates an MD5 key written as a 1-to-31 +character ASCII string in the "A" format. Note that, because of the +simple tokenizing routine, the characters ' ', '#', '\t', '\n' and '\0' +can't be used in either a DES or MD5 ASCII key. Everything else is fair +game, though. Key 0 (zero) is used for special purposes and should not +appear in this file. + +The big trouble with the authentication facility is the keys file. It is +a maintenance headache and a security problem. This should be fixed some +day. Presumably, this whole bag of worms goes away if/when a generic +security regime for the Internet is established. + +Query Programs + +Three utility query programs are included with the xntp3 distribution, +ntpq, ntptrace and xntpdc. Ntpq is a rather handy program which sends +queries and receives responses using NTP standard mode-6 control +messages. Since it uses the standard control protocol specified in RFC +1305, it may be used with NTP Version 2 and Version 3 implementations +for both Unix and Fuzzball, but not Version 1 implementations. It is +most useful to query remote NTP implementations to assess timekeeping +accuracy and expose bugs in configuration or operation. + +Ntptrace can be used to display the current synchronization path from a +selected host through possibly intervening servers to the primary source +of synchronization, usually a radio clock. It works with both version 2 +and version 3 servers, but not version 1. + +Xnptdc is a horrid program which uses NTP private mode-7 control +messages to query local or remote servers. The format and and contents +of these messages are specific to xntpd. The program does allow +inspection of a wide variety of internal counters and other state data, +and hence does make a pretty good debugging tool, even if it is +frustrating to use. The other thing of note about xntpdc is that it +provides a user interface to the run time reconfiguration facility. + +See the respective man pages for details on the use of these programs. +The primary reason for mentioning them here is to point out an +inconsistancy which can be awfully annoying if it catches you, and which +is worth keeping firmly in mind. Both xntpdc and xntpd demand that +anything which has dimensions of time be specified in units of seconds, +both in the configuration file and when doing run time reconfiguration. +Both programs also print the values in seconds. Ntpq on the other hand, +obeys the standard by printing all time values in milliseconds. This +makes the process of looking at values with ntpq and then changing them +in the configuration file or with xntpdc very prone to errors (by three +orders of magnitude). I wish this problem didn't exist, but xntpd and +its love of seconds predate the mode-6 protocol and the latter's +(Fuzzball-inspired) millisecond orientation, making the inconsistancy +irresolvable without considerable work. + +Run Time Reconfiguration + +Xntpd was written specifically to allow its configuration to be fully +modifiable at run time. Indeed, the only way to configure the server is +at run time. The configuration file is read only after the rest of the +server has been initialized into a running, but default unconfigured, +state. This facility was included not so much for the benefit of Unix, +where it is handy but not strictly essential, but rather for dedicated +platforms where the feature is more important for maintenance. +Nevertheless, run time configuration works very nicely for Unix servers +as well. + +Nearly all of the things it is possible to configure in the +configuration file may be altered via NTP mode-7 messages using the +xntpdc program. Mode-6 messages may also provide some limited +configuration functionality (though the only thing you can currently do +with mode-6 messages is set the leap-second warning bits) and the ntpq +program provides generic support for the latter. The leap bits that can be +set in the leap_warning variable (up to one month ahead) and in the +leap_indication variable have a slighly different encoding than the +usual interpretation: + + Value Action + 00 The daemon passes the leap bits of its + synchronisation source (usual mode of operation) + 01/10 A leap second is added/deleted + 11 Leap information from the sychronisation source + is ignored (thus LEAP_NOWARNING is passed on) + +Mode-6 and mode-7 messages which would modify the configuration of the +server are required to be authenticated using standard NTP +authentication. To enable the facilities one must, in addition to +specifying the location of a keys file, indicate in the configuration +file the key IDs to be used for authenticating reconfiguration commands. +Hence the following fragment might be added to a configuration file to +enable the mode-6 (ntpq) and mode-7 (xntpdc) facilities in the daemon: + + # specify mode-6 and mode-7 trusted keys + + requestkey 65535 # for mode-7 requests + controlkey 65534 # for mode-6 requests + +If the "requestkey" and/or the "controlkey" configuration declarations +are omitted from the configuration file, the corresponding run time +reconfiguration facility is disabled. + +The query programs require the user to specify a key ID and a key to use +for authenticating requests to be sent. The key ID provided should be +the same as the one mentioned in the configuration file, while the key +should match that corresponding to the key ID in the keys file. As the +query programs prompt for the key as a password, it is useful to make +the request and control authentication keys typable (in ASCII format) +from the keyboard. + +Name Resolution + +Xntpd includes the cability to specify host names requiring resolution +in "peer" and "server" declarations in the configuration file. There are +several reasons why this was not permitted in the past. Chief among +these is the fact that name service is unreliable and the interface to +the Unix resolver routines is synchronous. The hangups and delays +resulting from name-resolver clanking can be unacceptable once the NTP +server is running (and remember it is up and running before the +configuration file is read). However, it is advantageous to resolve time +server names, since their addresses are occasionally changed. + +Instead of running the resolver itself the daemon can defer this task to +a separate program, xntpres. When the daemon comes across a "peer" or +"server" entry with a non-numeric host address it records the relevant +information in a temporary file and continues on. When the end of the +configuration file has been reached and one or more entries requiring +name resolution have been found, the server runs an instance of xntpres +with the temporary file as an argument. The server then continues on +normally but with the offending peers/servers omitted from its +configuration. + +When xntpres successfully resolves a name from this file, it configures +the associated entry into the server using the same mode-7 run time +reconfiguration facility that xntpdc uses. If temporary resolver +failures occur, xntpres will periodically retry the offending requests +until a definite response is received. The program will continue to run +until all entries have been resolved. +There are several configuration requirements if xntpres is to be used. +The path to the xntpres program must be made known to the daemon via a +"resolver" configuration entry, and mode-7 run time reconfiguration must +be enabled. The following fragment might be used to accomplish this: + + # specify host name resolver data + + resolver /local/etc/xntpres + keys /etc/ntp.keys + requestkey 65535 + +Note that xntpres sends packets to the server with a source address of +127.0.0.1. You should obviously avoid "restrict" modification requests +from this address or xntpres will fail. + +Dealing with Frequency Tolerance Violations (Tickadj and Friends) + +The NTP Version 3 specification RFC 1305 calls for a maximum oscillator +frequency tolerance of +-100 parts-per-million (ppm), which is +representative of those components suitable for use in relatively +inexpensive workstation platforms. For those platforms meeting this +tolerance, NTP will automatically compensate for the frequency errors of +the individual oscillator and no further adjustments are required, +either to the configuration file or to various kernel variables. + +However, in the case of certain notorious platforms, in particular Sun +4s, the 100-ppm tolerance is routinely violated. In such cases it may be +necessary to adjust the values of certain kernel variables; in +particular, "tick" and "tickadj". The variable tick is the increment in +microseconds added to the system time on each interval-timer interrupt, +while the variable tickadj is used by the time adjustment code as a slew +rate. When the time is being adjusted via a call to the system routine +adjtime(), the kernel increases or reduces tick by tickadj microseconds +until the specified adjustment has been completed. Unfortunately, in +most Unix implementations the tick increment must be either zero or +plus/minus exactly tickadj microseconds, meaning that adjustments are +truncated to be an integral multiple of tickadj (this latter behaviour +is a misfeature, and is the only reason the xntpd code needs to concern +itself with the internal implementation of adjtime() at all). In +addition, the stock Unix implementation considers it an error to request +another adjustment before a prior one has completed. + +Thus, to make very sure it avoids problems related to the roundoff, the +xntpd daemon reads the values of tick and tickadj from /dev/kmem when it +starts. It then ensures that all adjustments given to adjtime() are an +even multiple of tickadj microseconds and computes the largest +adjustment that can be completed in the adjustment interval (using both +the value of tickadj and the value of tick) so it can avoid exceeding +this limit. + +Unfortunately, the value of tickadj set by default is almost always too +large for xntpd. NTP operates by continuously making small adjustments +to the clock, usually at one-second intervals. If tickadj is set too +large, the adjustments will disappear in the roundoff; while, if tickadj +is too small, NTP will have difficulty if it needs to make an occasional +large adjustment. While the daemon itself will read the kernel's values +of tick and tickadj, it will not change the values, even if they are +unsuitable. You must do this yourself before the daemon is started, +either with adb or, in the running kernel only, with the tickadj program +included in the util directory of the xntp3 distribution. Note that the +latter program will also computes an optimal value of tickadj for NTP +use based on the kernel's value of tick. + +The tickadj program can reset several other kernel variables if asked. +It can also change the value of tick if asked, this being necessary on a +few machines with very broken clocks, like Sun 4s. With these machines +it should also set the value of the kernel dosynctodr variable to zero. +This variable controls whether to synchronize the system clock to the +time-of-day clock, something you really don't want to be happen when +xntpd is trying to keep it under control. + +In order to maintain reasonable correctness bounds, as well as +reasonably good accuracy with acceptable polling intervals, xntpd will +complain if the frequency error is greater than 100 ppm. For machines +with a value of tick in the 10-ms range, a change of one in the value of +tick will change the frequency by about 100 ppm. In order to determine +the value of tick for a particular CPU, disconnect the machine from all +sources of time (dosynctodr = 0) and record its actual time compared to +an outside source (eyeball-and-wristwatch will do) over a day or more. +Multiply the time change over the day by 0.116 and add or subtract the +result to tick, depending on whether the CPU is fast or slow. An example +call to tickadj useful on Sun 4s is: + + tickadj -t 9999 -a 5 -s + +which sets tick 100 ppm fast, tickadj to 5 microseconds and turns off +the clock/calendar chip fiddle. This line can be added to the rc.local +configuration file to automatically set the kernel variables at boot +time. + +All this stuff about diddling kernel variables so the NTP daemon will +work is really silly. If vendors would ship machines with clocks that +kept reasonable time and would make their adjtime() system call apply +the slew it is given exactly, independent of the value of tickadj, all +this could go away. + +Tuning Your Subnet + +There are several parameters available for tuning the NTP subnet for +maximum accuracy and minimum jitter. Two important parameters are the +the "precision" and "prefer" configuration declarations. The precision +declaration specifies the number of significant bits of the system clock +representation relative to one second. For instance, the default value +of -6 corresponds to 1/64 second or about 16 milliseconds. + +The NTP protocol makes use of the precision parameter in several places. +It is included in packets sent to peers and is used by them to calculate +the maximum absolute error and maximum statistical error. When faced +with selecting one of several servers of the same stratum and about the +same network path delay for synchronization purposes, clients will +usually prefer to synchronize to those servers claiming the smallest +(most negative) precision, since this maximizes the accuracy and +minimizes the jitter apparent to application programs running on the +client platform. Therefore, when the maximum attainable accuracy is +required, it is important that every platform configure an accurate +value for the precision variable. This can be done using the optional +"precision" declaration in the configuration file: + + # precision declaration + + precision -18 # for microsecond clocks (Sun 4s, DEC 5000/240) + +When more than one eligible server exists, the NTP clock-selection and +combining algorithms act to winnow out all except the "best" set of +servers using several criteria based on differences between the readings +of different servers and between successive readings of the same server. +The result is usually a set of surviving servers that are apparently +statistically equivalent in accuracy, jitter and stability. The +population of survivors remaining in this set depends on the individual +server characteristics measured during the selection process and may +vary from time to time as the result of normal statistical variations. +In LANs with high speed RISC-based time servers, the population can +become somewhat unstable, with individual servers popping in and out of +the surviving population, generally resulting in a regime called +clockhopping. + +When only the smallest residual jitter can be tolerated, it may be +convenient to elect one of the servers at each stratum level as the +preferred one using the keyword "prefer" on the configuration +declaration for the selected server: + + # prefered server declaration + + peer 128.4.1.1 prefer # preferred server + +The preferred server will always be included in the surviving +population, regardless of its characteristics and as long as it survives +preliminary sanity checks and validation procedures. + +The most useful application of the prefer keyword is in high speed LANs +equipped with precision radio clocks, such as a GPS receiver. In order +to insure robustness, the hosts need to include outside peers as well as +the GPS-equipped server; however, as long as that server is running, the +synchronization preference should be that server. The keyword should +normally be used in all cases in order to prefer an attached radio +clock. It is probably inadvisable to use this keyword for peers outside +the LAN, since it interferes with the carefully crafted judgement of the +selection and combining algorithms. + +Provisions for Leap Seconds and Accuracy Metrics + +Xntpd understands leap seconds and will attempt to take appropriate +action when one occurs. In principle, every host running xntpd will +insert a leap second in the local timescale in precise synchronization +with UTC. This requires that the leap-warning bits be manually activated +some time prior to the occurance of a leap second at the primary +(stratum 1) servers. Subsequently, these bits are propagated throughout +the subnet depending on these servers by the NTP protocol itself and +automatically implemented by xntpd and the time-conversion routines of +each host. The implementation is independent of the idiosyncracies of +the particular radio clock, which vary widely among the various devices, +as long as the idiosyncratic behavior does not last for more than about +20 minutes following the leap. Provisions are included to modify the +behavior in cases where this cannot be guaranteed. + +While provisions for leap seconds have been carefully crafted so that +correct timekeeping immediately before, during and after the occurance +of a leap second is scrupulously correct, stock Unix systems are mostly +inept in responding to the available information. This caveat goes also +for the maximum-error and statistical-error bounds carefully calculated +for all clients and servers, which could be very useful for application +programs needing to calibrate the delays and offsets to achieve a near- +simulataneous commit procedure, for example. While this information is +maintained in the xntpd data structures, there is at present no way for +application programs to access it. This may be a topic for further +development. + +Clock Support Overview + +Xntpd was designed to support radio (and other external) clocks and does +some parts of this function with utmost care. Clocks are treated by the +protocol as ordinary NTP peers, even to the point of referring to them +with an (invalid) IP host address. Clock addresses are of the form +127.127.t.u, where t specifies the particular type of clock (i.e. refers +to a particular clock driver) and u is a unit number whose +interpretation is clock-driver dependent. This is analogous to the use +of major and minor device numbers by Unix and permits multiple +instantiations of clocks of the same type on the same server, should +such magnificant redundancy be required. + +Because clocks look much like peers, both configuration file syntax and +run time reconfiguration commands can be be used to control clocks in +the same way as ordinary peers. Clocks are configured via "server" +declarations in the configuration file, can be started and stopped using +xntpdc and are subject to address-and-mask restrictions much like a +normal peer, should this stretch of imagination ever be useful. As a +concession to the need to sometimes transmit additional information to +clock drivers, an additional configuration file is available: the +"fudge" statement. This enables one to specify the values two time +quantities, two integral values and two flags, the use of which is +dependent on the particular clock driver. For example, to configure a +PST radio clock which can be accessed through the serial device +/dev/pst1, with propagation delays to WWV and WWVH of 7.5 and 26.5 +milliseconds, respectively, on a machine with an imprecise system clock +and with the driver set to disbelieve the radio clock once it has gone +30 minutes without an update, one might use the following configuration +file entries: + + # radio clock fudge fiddles + + server 127.127.3.1 + fudge 127.127.3.1 time1 0.0075 time2 0.0265 + fudge 127.127.3.1 value2 30 flag1 1 + +Additional information on the interpretation of these data with respect +to various radio clock drivers is given in the xntpd.8 man page. + +Towards the Ultimate Tick + +This section consideres issues in providing precision time +synchronization in NTP subnets which need the highest quality time +available in the present technology. These issues are important in +subnets supporting real-time services such as distributed multimedia +conferencing and wide-are experiment control and monitoring. + +In the Internet of today synchronization paths often span continents and +oceans with moderate to high variations in delay due to traffic spasms. +NTP is specifically designed to minimize timekeeping jitter due to delay +variations using intricately crafted filtering and selection algorithms; +however, in cases where these variations are as much as a second or +more, the residual jitter following these algorithms may still be +excessive. Sometimes, as in the case of some isolated NTP subnets where +a local source of precision time is available, such as a 1-pps signal +produced by a calibrated cesium clock, it is possible to remove the +jitter and retime the local clock oscillator of the NTP server. This has +turned out to be a useful feature to improve the synchronization quality +of time distributed in remote places where radio clocks are not +available. In these cases special features of the xntp3 distribution are +used together with the 1-pps signal to provide a jitter-free timing +signal, while NTP itself is used to provide the coarse timing and +resolve the seconds numbering. + +Most available radio clocks can provide time to an accuracy in the order +of milliseconds, depending on propagation conditions, local noise levels +and so forth. However, as a practical matter, all clocks can +occasionally display errors significantly exceeding nominal +specifications. Usually, the algorithms used by NTP for ordinary network +peers, as well as radio clock "peers" will detect and discard these +errors as discrepancies between the disciplined local clock oscillator +and the decoded time message produced by the radio clock. Some radio +clocks can produce a special 1-pps signal which can be interfaced to the +server platform in a number of ways and used to substantially improve +the (disciplined) clock oscillator jitter and wander characteristics by +at least an order of magnitude. Using these features it is possible to +achieve accuracies in the order of 100 microseconds with a fast RISC- +based platform. + +There are three ways to implement 1-pps support, depending on the radio +clock model, platform model and serial line interface. Each of these +requires circuitry to convert the TTL signal produced by most clocks to +the the EIA levels used by most serial interfaces. An example of a +device designed to do this is presented in the gadget subdirectory +included in the xntp3 distribtuion. Besides being useful for this +purpose, this device includes an inexpensive modem designed for use with +the Canadian CHU time/frequency radio station. + +In order to select the appropriate implementation, it is important to +understand the underlying 1-pps mechanism used by xntpd. The 1-pps +suport depends on a continuous source of 1-pps pulses used to calculate +an offset within +-500 milliseconds relative to the local clock. The +serial timecode produced by the radio or the time determined by NTP in +absence of the radio is used to adjust the local clock within +-128 +milliseconds of the actual time. As long as the local clock is within +this interval the 1-pps support is used to discipline the local clock +and the timecode used only to verify that the local clock is in fact +within the interval. Outside this interval the 1-pps support is disabled +and the timecode used directly to control the local clock. + +The first method of implementation uses a dedicated serial port and +either the bsd line discipline or System V streams module, which can be +found in the kernel directory of the xntp3 distribution. This method can +be used with any radio clock or in the absence of any clock. The line +discipline and streams modules take receive timestamps in the kernel, +specifically the interrupt routine of the serial port hardware driver. +Using this method the port is dedicated to serve the 1-pps signal and +cannot be used for other purposes. Instructions for implementing the +feature, which requires rebuilding the kernel, are included in the +modules themselves. Note that xndpd must be compiled with the -DPPSDEV +compiler switch in this case. There is an inherent error in this method +due to the latency of the interrupt system and remaining serial-line +protocol modules in the order of a millisecond with Sun 4s. While the +jitter in this latency is unavoidable, the systematic component can be +calibrated out using a special configuration declaration: + + # pps delay and baud rate + + pps delay .0017 baud 19200 # pps delay (ms) and baud rate + +Note that the delay defaults to zero and the baud to 38400. + +The second method uses mechanisms embedded in the radio clock driver, +which call the 1-pps support directly and do not require a dedicated +serial port. Currently, only the DCF77 (German radio time service) +driver uses this method. Instructions for implementing this are given in +README files in the xntp3 distribution. + +The third method and the most accurate and intrusive of all uses the +carrier-detect modem-control lead monitored by the serial port driver. +This method can be used with any radio clock and 1-pps interface +mentioned above. It requires in addition to a special streams module, +replacement of the kernel high resolution time-of-day clock routine. +This method is applicable only to Sun 4 platforms running SunOS 4.1.1 +and then only with either of the two onboard serial ports. It does not +work with other platforms, operating systems or external (SBus) serial +multiplexors. + +Swatting Bugs + +Let's say you have compiled and installed the code and put up an +apparently relevant configuration file. In many Unix systems the xntpd +daemon and utility programs (ntpq, ntptrace and xntpdc) are usually +installed in the /usr/local directory along with the key file +(ntp.keys), while the configuration file (ntp.conf) and drift file +(ntp.drift) are installed in the /etc directory. The daemon can is +usually started from the rc.local shell script at system boot time, but +could be started (and stopped) at other times for debugging, etc. How do +you verify that the daemon can form associations with remote peers and +verify correct synchronization? For this you need the ntpq utility +described in the ntpq.8 man page. + +After starting the daemon, run the ntpq program using the -n switch, +which will avoid possible distractions due to name resolutions. Use the +peer command to display a billboard showing the status of configured +peers and possibly other clients poking the daemon. After operating for +a few minutes, the display should be something like: + + remote refid st when poll reach delay offset disp +======================================================================== ++128.4.2.6 132.249.16.1 2 131 256 373 9.89 16.28 23.25 +*128.4.1.20 .WWVB. 1 137 256 377 280.62 21.74 20.23 +-128.8.2.88 128.8.10.1 2 49 128 376 294.14 5.94 17.47 ++128.4.2.17 .WWVB. 1 173 256 377 279.95 20.56 16.40 + +The hosts shown in the "remote" column should agree with the entries in +the configuration file, plus any peers not mentioned in the file at the +same or lower than your stratum that happen to be configured to peer +with you. The "refid" entry shows the current source of synchronization +for that peer, while the "st" reveals its stratum and the "poll" entry +the polling interval, in seconds. The "when" entry shows the time since +the peer was last heard, in seconds, while the "reach" entry shows the +status of the reachability register (see specification), which is in +octal format. The remaining entries show the latest delay, offset and +dispersion computed for the peer, in milliseconds. + +*** This section incomplete. Soon. + +status=0664 leap_none, sync_ntp, 6 events, event_peer/strat_chg +system="UNIX", leap=00, stratum=2, rootdelay=280.62, +rootdispersion=45.26, peer=11673, refid=128.4.1.20, +reftime=af00bb42.56111000 Fri, Jan 15 1993 4:25:38.336, poll=8, +clock=af00bbcd.8a5de000 Fri, Jan 15 1993 4:27:57.540, phase=21.147, +freq=13319.46, compliance=2 + +status=7414 reach, auth, sel_sync, 1 event, event_reach +srcadr=128.4.2.6, srcport=123, dstadr=128.4.2.7, dstport=123, keyid=1, +stratum=2, precision=-10, rootdelay=362.00, rootdispersion=21.99, +refid=132.249.16.1, +reftime=af00bb44.849b0000 Fri, Jan 15 1993 4:25:40.517, +delay= 9.89, offset= 16.28, dispersion=23.25, reach=373, valid=8, +hmode=2, pmode=1, hpoll=8, ppoll=10, leap=00, flash=0x0, +org=af00bb48.31a90000 Fri, Jan 15 1993 4:25:44.193, +rec=af00bb48.305e3000 Fri, Jan 15 1993 4:25:44.188, +xmt=af00bb1e.16689000 Fri, Jan 15 1993 4:25:02.087, +filtdelay= 16.40 9.89 140.08 9.63 9.72 9.22 10.79 122.99, +filtoffset= 13.24 16.28 -49.19 16.04 16.83 16.49 16.95 -39.43, +filterror= 16.27 20.17 27.98 31.89 35.80 39.70 43.61 47.52 + +ind assID status conf reach auth condition last_event cnt +=========================================================== + 1 11670 7414 no yes ok synchr. reachable 1 + 2 11673 7614 no yes ok sys.peer reachable 1 + 3 11833 7314 no yes ok outlyer reachable 1 + 4 11868 7414 no yes ok synchr. reachable 1 + +Parting Shots + +There are several undocumented programs which are useful if you are +trying to set up a clock. They can be found in the clockstuff directory +of the xntp3 distribution. The most useful of these is the propdelay +program, which can compute high frequency radio propagation delays +between any two points whose latitude and longitude are known. The +program understands something about the phenomena which allow high +frequency radio propagation to occur, and will generally provide a +better estimate than a calculation based on the great circle distance. +The other two programs in the directory are clktest, which allows one to +exercise the generic clock line discipline, and chutest, which runs the +basic reduction algorithms used by the daemon on data received from a +serial port. diff --git a/usr.sbin/xntpd/doc/ntpdate.8 b/usr.sbin/xntpd/doc/ntpdate.8 new file mode 100644 index 000000000000..05be737fd88c --- /dev/null +++ b/usr.sbin/xntpd/doc/ntpdate.8 @@ -0,0 +1,185 @@ +''' $Header +''' +.de Sh +.br +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(bs-|\(bv\*(Tr +.ie n \{\ +.ds -- \(bs- +.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +.ds L' ' +.ds R' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds L' ` +.ds R' ' +'br\} +.TH NTPDATE 8 LOCAL +.SH NAME +ntpdate - set the date and time via NTP +.SH SYNOPSIS +.B ntpdate +[ +.B -bdos +] [ +.B -a +.I key# +] [ +.B -e +.I authdelay +] [ +.B -k +.I keyfile +] [ +.B -p +.I samples +] [ +.B -t +.I timeout +] +server ... +.SH DESCRIPTION +.I Ntpdate +sets the local date and time by polling the Network Time Protocol +server(s) on the host(s) given as arguments to determine +the correct time. It must be run as root on the local host. A number +of samples are obtained from each of the servers specified and the +standard NTP clock filter and selection algorithms are applied to select +the best of these. Typically, +.I ntpdate +can be inserted in the +.I /etc/rc.local +startup up script to set the time of day at boot time and/or can be run +from time\-to\-time via +.IR cron (8). +Note that +.IR ntpdate 's +reliability and precision will improve dramatically with greater numbers +of servers. While a single server may be used, better performance and +greater resistance to insanity on the part of any one server +will be obtained by providing at least three or four servers, if not more. +.PP +Time adjustments are made by +.I ntpdate +in one of two ways. If +.I ntpdate +determines your clock is off by more than 0.5 seconds it will simply +step the time by calling +.IR settimeofday (2). +If the error is less than 0.5 seconds, however, it will by default slew +the clock's time via a call to +.IR adjtime (2) +with the offset. The latter technique is less disruptive and more +accurate when the offset is small, and works quite well when +.I ntpdate +is run by +.I cron (8) +every hour or two. The adjustment made in the latter +case is actually 50% larger than the measured offset since this will +tend to keep a badly drifting clock more accurate (at some expense to +stability, though this tradeoff is usually advantageous). At boot time, +however, it is usually better to always step the time. This can be forced +in all cases by specifying the +.B -b +switch on the command line. The +.B -s +switch tells +.I ntpdate +to log its actions via the +.IR syslog (3) +facility rather than to the standard output, a useful option when +running the program from +.IR cron (8). +.PP +The +.B -d +flag may be used to determine what +.I ntpdate +will do without it actually doing it. Information useful for general +debugging will also be printed. By default +.I ntpdate +claims to be an NTP version 2 implementation in its outgoing packets. As +some older software will decline to respond to version 2 queries, the +.B -o +switch can be used to force the program to poll as a version 1 implementation +instead. +.PP +The number of samples +.I ntpdate +acquires from each server can be set to between 1 and 8 inclusive +using the +.B -p +switch. The default is 4. The time it will spend waiting for a +response can be set using the +.B -t +switch, and will be rounded to a multiple of 0.2 seconds. The default +is 1 second, a value suitable for polling across a LAN. +.PP +.I Ntpdate +will authenticate its transactions if need be. The +.B -a +switch specifies that all packets should be authenticated using the +key number indicated. The +.B -k +switch allows the name of the file from which the keys may be read +to be modified from the default of +.I /etc/ntp.keys. +This file should be in the format described in +.IR xntpd (8). +The +.B -e +option allows the specification of an authentication processing delay, +in seconds (see +.IR xntpd (8) +for details). This number is usually small enough to be negligible for +.IR ntpdate 's +purposes, though specifying a value may improve timekeeping on very slow +CPU's. +.PP +.I Ntpdate +will decline to set the date if an NTP server daemon (e.g. +.IR xntpd (8)) +is running on the same host. When running +.I ntpdate +on a regular basis from +.IR cron (8) +as an alternative to running a daemon, doing so once every hour or two +will result in precise enough timekeeping to avoid stepping the clock. +.SH FILES +.nf +/etc/ntp.keys\0\0contains the encription keys used by \fIntpdate\fP. +.fi +.SH SEE ALSO +xntpd(8) +.SH HISTORY +Written by Dennis Ferguson at the University of Toronto +.SH BUGS +The technique used for improving accuracy by compensating for clock +oscillator errors sucks, but doing better would require the program +to save state from previous runs. diff --git a/usr.sbin/xntpd/doc/ntpq.8 b/usr.sbin/xntpd/doc/ntpq.8 new file mode 100644 index 000000000000..81aca09ac183 --- /dev/null +++ b/usr.sbin/xntpd/doc/ntpq.8 @@ -0,0 +1,566 @@ +''' $Header +''' +.de Sh +.br +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(bs-|\(bv\*(Tr +.ie n \{\ +.ds -- \(bs- +.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +.ds L' ' +.ds R' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds L' ` +.ds R' ' +'br\} +.TH NTPQ 8 LOCAL +.SH NAME +ntpq - standard Network Time Protocol query program +.SH SYNOPSIS +.B ntpq +[ +.B -inp +] [ +.B -c +.I command +] [ +.I host +] [ +.I ... +] +.SH DESCRIPTION +.I Ntpq +is used to query NTP servers which implement the recommended NTP +mode 6 control message format about current state and to request +changes in that state. The +program may be run either in interactive mode or controlled using +command line arguments. Requests to read and write arbitrary +variables can be assembled, with raw and pretty\-printed output +options being available. +.I Ntpq +can also obtain and print a list of peers in a common format +by sending multiple queries to the server. +.PP +If one or more request options is included on the command line when +.I ntpq +is executed, each of the requests will be sent to the NTP servers running +on each of the hosts given as command line arguments, or on +.I localhost +by default. If no request options are given, +.I ntpq +will attempt to read commands from the standard input and execute these +on the NTP server running on the first host given on the command line, again +defaulting to +.I localhost +when no other host is specified. +.I Ntpq +will prompt for commands if the standard input is a terminal device. +.PP +.I Ntpq +uses NTP mode 6 packets to communicate with the NTP server, and hence +can be used to query any compatable server on the network which permits +it. Note that since NTP is a UDP protocol this communication will be +somewhat unreliable, especially over large distances in terms of network +topology. +.I Ntpq +makes one attempt to retransmit requests, and will time requests out if +the remote host is not heard from within a suitable time out time. +.PP +Command line options are described following. Specifying a command +line option other than +.B -i +or +.B -n +will cause the specified query (queries) to be sent to the indicated +host(s) immediately. Otherwise, +.I ntpq +will attempt to read interactive format commands from the standard input. +.Ip -c 8 +The following argument is interpreted as an interactive format command +and is added to the list of commands to be executed on the specified +host(s). Multiple +.B -c +options may be given. +.Ip -i 8 +Force +.I ntpq +to operate in interactive mode. Prompts will be written to the +standard output and commands read from the standard input. +.Ip -n 8 +Output all host addresses in dotted\-quad numeric format rather than +converting to the canonical host names. +.Ip -p 8 +Print a list of the peers known to the server as well as a summary +of their state. This is equivalent to the \*(L"peers\*(R" interactive +command. +.SH INTERNAL COMMANDS +.PP +Interactive format commands consist of a keyword followed by zero +to four arguments. Only enough characters of the full keyword to +uniquely identify the command need be typed. The output of a command +is normally sent to the standard output, but optionally the output of +individual commands may be sent to a file by appending a \*(L">\*(R", +followed by a file name, to the command line. +.PP +A number of interactive format commands are executed entirely within the +.I ntpq +program itself and do not result in NTP mode 6 requests being sent +to a server. These are described following. +.PP +.B ? +[ +.I command_keyword +} +.PP +A \*(L"?\*(R" by itself will print a list of all the command keywords +known to this incarnation of +.IR ntpq . +A \*(L"?\*(R" followed by a command keyword will print funcation and +usage information about the command. This command is probably a better +source of information about +.I ntpq +than this manual page. +.PP +.B timeout +.I millseconds +.PP +Specify a time out period for responses to server queries. The default +is about 5000 milliseconds. Note that since +.I ntpq +retries each query once after a time out the total waiting time for a +time out will be twice the time out value set. +.PP +.B delay +.I milliseconds +.PP +Specify a time interval to be added to timestamps included in requests +which require authentication. This is used to enable (unreliable) server +reconfiguration over long delay network paths or between machines whose +clocks are unsynchronized. Actually the server does not now require +time stamps in authenticated requests, so this command may be obsolete. +.PP +.B host +.I hostname +.PP +Set the host to which future queries will be sent. +.I Hostname +may be either a host name or a numeric +address. +.PP +.B poll +[ +.I # +] [ +.B verbose +] +.PP +Poll the current server in client mode. The first argument is the +number of times to poll (default is 1) while the second argument may +be given to obtain a more detailed output of the results. This command +is currently just wishful thinking. +.PP +.B keyid +.I # +.PP +This command allows the specification of a key number to be used to +authenticate configuration requests. This must correspond to a +key number the server has been configured to use for this purpose. +.PP +.B passwd +.PP +This command prompts you to type in a password (which will not be +echoed) which will be used to authenticate configuration requests. The +password must correspond to the key configured for use by the NTP +server for this purpose if such requests are to be successful. +.PP +.B "hostnames yes|no" +.PP +If \*(L"yes\*(R" is specified, host names are printed in information +displays. If \*(L"no\*(R" is given, numeric addresses are printed +instead. The default is \*(L"yes\*(R" unless modified using the command +line +.B -n +switch. +.PP +.B raw +.PP +Causes all output from query commands is printed as received from the +remote server. The only formating/intepretation done on the data is +to transform nonascii data into a printable (but barely understandable) +form. +.PP +.B cooked +.PP +Causes output from query commands to be \*(L"cooked\*(R". Variables +which are recognized by the server will have their values reformatted +for human consumption. Variables which +.I ntpq +thinks should have a decodeable value but didn't are marked with a +trailing \*(L"?\*(R". +.PP +.B ntpversion +.B 1|2|3 +.PP +Sets the NTP version number which +.I ntpq +claims in packets. Defaults to 3, Note that mode 6 control messages (and modes, +for that matter) didn't exist in NTP version 1. There appear to be no +servers left which demand version 1. +.PP +.B authenticate +.B yes|no +.PP +Normally +.I ntpq +does not authenticate requests unless they are write requests. The command +.B authenticate yes +causes +.I ntpq +to send authentication with all requests it makes. Authenticated requests +causes some servers to handle requests slightly differently, and can +occasionally melt the CPU in fuzzballs if you turn authentication on before +doing a peer display. +.PP +.B addvars +.IR <variable_name>[=<value>] [,...] +.B rmvars +.IR <variable_name> [,...] +.B clearvars +.PP +The data carried by NTP mode 6 messages consists of a list of items +of the form +.IP "" 8 +<variable_name>=<value> +.PP +where the \*(L"=<value>\*(R" is ignored, and can be omitted, in requests +to the server to read variables. +.I Ntpq +maintains an internal list in which data to be included in control messages +can be assembled, and sent using +the +.B readlist +and +.B writelist +commands described below. The +.B addvars +command allows variables and their optional values to be added to the +list. If more than one variable is to be added, the list should be +comma\-separated and not contain white space. The +.B rmvars +command can be used to remove individual variables from the list, while +the +.B clearlist +command removes all variables from the list. +.PP +.B debug +.I more|less|off +.PP +Turns internal query program debugging on and off. +.PP +.B quit +.PP +Exit +.IR ntpq . +.SH CONTROL MESSAGE COMMANDS +.PP +Each peer known to an NTP server has a 16 bit integer +.I association +.I identifier +assigned to it. NTP control messages which carry peer variables +must identify the peer the values correspond to by including +its association ID. An association ID of 0 is special, and indicates +the variables are system variables, whose names are drawn from a +separate name space. +.PP +Control message commands result in one or more NTP mode 6 +messages being sent to the server, and cause the data returned to be +printed in some format. Most commands currently implemented send a single +message and expect a single response. The current exceptions are the +.B peers +command, which will send a preprogrammed series of messages to obtain +the data it needs, and the +.B mreadlist +and +.B mreadvar +commands, which will iterate over a range of associations. +.PP +.B associations +.PP +Obtains and prints a list of association identifiers and +peer statuses for in\-spec +peers of the server being queried. The list is printed in +columns. The first of these is an index numbering the associations +from 1 for internal use, the second the actual association identifier +returned by the server and the third the status word for the peer. This +is followed by a number of columns containing data decoded from the +status word. Note +that the data returned by the \*(L"associations\*(R" command is cached +internally in +.IR ntpq . +The index is then of use when dealing with stupid servers which use +association identifiers which are hard for humans to type, in that +for any subsequent commands which require an association identifier +as an argument, the form +.I &index +may be used as an alternative. +.PP +.B lassocations +.PP +Obtains and prints a list of association identifiers and peer statuses +for all associations for which the server is maintaining state. This +command differs from the +\*(L"associations\*(R" +command only for servers which retain state for out\-of\-spec client +associations (i.e. fuzzballs). Such associations are normally omitted +from the display when the +\*(L"associations\*(R" +command is used, but are included in the output of +\*(L"lassociations\*(R". +.PP +.B passociations +.PP +Prints association data concerning in\-spec peers from the internally cached +list of associations. This command performs +identically to the \*(L"associations\*(R" except that it displays the +internally stored data rather than making a new query. +.PP +.B lpassociations +.PP +Print data for all associations, including out\-of\-spec client +associations, from the internally cached list of associations. This command +differs from \*(L"passociations\*(R" only when dealing with fuzzballs. +.PP +.B pstatus +.I assocID +.PP +Sends a read status request to the server for the given association. +The names and values of the peer variables returned will be printed. Note +that the status word from the header is displayed preceding the variables, +both in hexidecimal and in pidgeon English. +.PP +.B readvar +[ +.I assocID +] [ +.IR <variable_name>[=<value>] [,...] +] +.PP +Requests that the values of the specified variables be returned by the +server by sending a read variables request. If the association ID +is omitted or is given as zero the variables +are system variables, otherwise they +are peer variables and the values returned will be those +of the corresponding peer. Omitting the variable list will send a +request with no data which should induce the server to return a +default display. +.PP +.B rv +[ +.I assocID +] [ +.IR <variable_name>[=<value>] [,...] +] +.PP +An easy\-to\-type short form for the +.B readvar +command. +.PP +.B writevar +.I assocID +.IR <variable_name>=<value> [,...] +.PP +Like the +.B readvar +request, except the specified variables are written instead of read. +.PP +.B readlist +[ +.I assocID +] +.PP +Requests that the values of the variables in the internal variable +list be returned by the server. If the association ID is omitted +or is 0 the variables are assumed to be system variables. Otherwise +they are treated as peer variables. If the internal variable list +is empty a request is sent without data, which should induce the remote +server to return a default display. +.PP +.B rl +[ +.I assocID +] +.PP +An easy\-to\-type short form of the +.B readlist +command. +.PP +.B writelist +[ +.I assocID +] +.PP +Like the +.B readlist +request, except the internal list variables are written instead of +read. +.PP +.B mreadvar +.I assocID +.I assocID +[ +.IR <variable_name>[=<value>] [,...] +] +.PP +Like the +.B readvar +command except the query is done for each of a range of (nonzero) +association IDs. This range is determined from the association list +cached by the most recent +.B associations +command. +.PP +.B mrv +.I assocID +.I assocID +[ +.IR <variable_name>[=<value>] [,...] +] +.PP +An easy\-to\-type short form of the +.B mreadvar +command. +.PP +.B mreadlist +.I assocID +.I assocID +.PP +Like the +.B readlist +command except the query is done for each of a range of (nonzero) +association IDs. This range is determined from the association list +cached by the most recent +.B associations +command. +.PP +.B mrl +.I assocID +.I assocID +.PP +An easy\-to\-type short form of the +.B mreadlist +command. +.PP +.B clockvar +[ +.I assocID +] +[ +.IR <variable_name>[=<value>] [,...] +] +.PP +Requests that a list of the server's clock variables be sent. Servers +which have a radio clock or other external synchronization will respond +positively to this. If the association identifier is omitted or zero +the request is for the variables of the \*(L"system clock\*(R" and will +generally get a positive response from all servers with a clock. If the +server treats clocks as pseudo\-peers, and hence can possibly have more than +one clock connected at once, referencing the appropriate +peer association ID will show the variables of a particular clock. Omitting +the variable list will cause the server to return a default variable display. +.PP +.B cv +[ +.I assocID +] +[ +.IR <variable_name>[=<value>] [,...] +] +.PP +An easy\-to\-type short form of the +.B clockvar +command. +.PP +.B peers +.PP +Obtains a list of in\-spec peers of the server, along +with a summary of each peer's state. Summary information includes the address +of the remote peer, the reference ID (0.0.0.0 if the refID is unknown), +the stratum of the remote peer, the polling interval, +in seconds, the reachability +register, in octal, and the current estimated delay, offset and dispersion +of the peer, all in seconds. +.PP +The character in the left margin indicates the fate of this peer in the +clock selection process. The codes mean: <sp> discarded due to high stratum +and/or failed sanity checks; \*(L"x\*(R" designated falsticker by the +intersection algorithm; \*(L".\*(R" culled from the end of the candidate +list; \*(L"-\*(R" discarded by the clustering algorithmi; \*(L"+\*(R" +included in the final selection set; \*(L"#\*(R" selected for synchronizatio;n +but distance exceeds maximum; \*(L"*\*(R" selected for synchronization; and +\*(L"o\*(R" selected for synchronization, pps signal in use. +.PP +Note that since the +.B peers +command depends on the ability to parse the values in the +responses it gets it may fail to work from time to time with servers +which poorly control the data formats. +.PP +The contents of the host field may be one of four forms. It may be a host name, +an IP address, a reference clock implementation name with its parameter or +\*(L"REFCLK(<implementation number>, <parameter>)\*(R". On \*(L"hostnames no\*(R" +only IP\-addresses will be displayed. +.PP +.B lpeers +.PP +Like +.BR peers , +except a summary of all associations for which the server is maintaining +state is printed. This can produce a much longer list of peers from +fuzzball servers. +.PP +.B opeers +.PP +An old form of the \*(L"peers\*(R" command with the reference ID +replaced by the local interface address. +.SH HISTORY +.PP +Written by Dennis Ferguson at the University of Toronto. +.SH BUGS +.PP +The +.B peers +command is non\-atomic and may occasionally result in spurious error +messages about invalid associations occuring and terminating the +command. +.PP +The timeout time is a fixed constant, which means you wait a long time +for time outs since it assumes sort of a worst case. The program +should improve the time out estimate as it sends queries to a particular +host, but doesn't. diff --git a/usr.sbin/xntpd/doc/ntptrace.8 b/usr.sbin/xntpd/doc/ntptrace.8 new file mode 100644 index 000000000000..fb93ebb4df72 --- /dev/null +++ b/usr.sbin/xntpd/doc/ntptrace.8 @@ -0,0 +1,104 @@ +''' $Header +''' +.de Sh +.br +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(bs-|\(bv\*(Tr +.ie n \{\ +.ds -- \(bs- +.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +.ds L' ' +.ds R' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds L' ` +.ds R' ' +'br\} +.TH NTPTRACE 8 LOCAL +.SH NAME +ntptrace - trace a chain of NTP hosts back to their master time source +.SH SYNOPSIS +.B ntptrace +[ +.B -vdn +] [ +.B -r +.I retries +] [ +.B -t +.I timeout +] [ +.I server +] +.SH DESCRIPTION +.I Ntptrace +determines where a given Network Time Protocol (NTP) server gets +its time from, and follows the chain of NTP servers back to their +master time source. +If given no arguments, it starts with ``localhost.'' +.PP +Here is an example of the output from +.IR ntptrace : +.RS 2 +.nf + +% ntptrace +localhost: stratum 4, offset 0.0019529, synch distance 0.144135 +server2.bozo.com: stratum 2, offset 0.0124263, synch distance 0.115784 +usndh.edu: stratum 1, offset 0.0019298, synch distance 0.011993, refid 'WWVB' + +.fi +.RE +On each line, the fields are (left to right): the host name, the +host's stratum, +the time offset between that host and the local host +(as measured by +.IR ntptrace ; +this is why it is not always zero for ``localhost''), +the host's ``synchronization distance,'' +and (only for stratum-1 servers) the reference clock ID. All times +are given in seconds. (Synchronization distance is a measure of the +goodness of the clock's time.) +.SH OPTIONS +.IP "\-d" 5 +Turns on some debugging output. +.IP "\-n" 5 +Turns off the printing of host names; instead, host IP addresses +are given. This may be necessary if a nameserver is down. +.IP "\-r retries" 5 +Sets the number of retransmission attempts for each host; default = 5. +.IP "\-t timeout" 5 +Sets the retransmission timeout (in seconds); default = 2. +.IP "\-v" 5 +Prints verbose information about the NTP servers. +.SH SEE ALSO +xntpd(8), xntpdc(8) +.SH BUGS +This program makes no attempt to improve accuracy by doing multiple +samples. diff --git a/usr.sbin/xntpd/doc/tickadj.8 b/usr.sbin/xntpd/doc/tickadj.8 new file mode 100644 index 000000000000..5fce0884f892 --- /dev/null +++ b/usr.sbin/xntpd/doc/tickadj.8 @@ -0,0 +1,143 @@ +''' $Header +''' +.de Sh +.br +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(bs-|\(bv\*(Tr +.ie n \{\ +.ds -- \(bs- +.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +.ds L' ' +.ds R' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds L' ` +.ds R' ' +'br\} +.TH TICKADJ 8 LOCAL +.SH NAME +tickadj - fiddle time\-related variables in the kernel +.SH SYNOPSIS +.B tickadj +[ +.B -Aqs +] [ +.B -a +.I new_tickadj +] [ +.B -t +.I new_tick +] +.SH DESCRIPTION +The +.I tickadj +program reads, and optionally modifies, several time\-keeping\-related +variables in the running kernel, via +.IR /dev/kmem . +The particular variables it is concerned with are +.IR tick , +which is the number of microseconds added to the system time during a +clock interrupt, +.IR tickadj , +which sets the slew rate and resolution used by the +.IR adjtime (2) +system call, and +.IR dosynctodr , +which indicates to the kernels on some machines whether they should internally +adjust the system clock to keep it in line with with time\-of\-day clock +or not. +.PP +By default, with no arguments, +.I tickadj +reads the variables of interest in the kernel and prints them. At the +same time it determines an \*(L"optimal\*(R" value for the value of the +.I tickadj +variable if the intent is to run the +.IR xntpd (8) +Network Time Protocol daemon, and prints this as well. Since the operation +of +.I tickadj +when reading the kernel mimics the operation of similar parts of the +.IR xntpd (8) +program fairly closely, this is useful for doing debugging of problems +with +.IR xntpd (8). +.PP +Various flags may be specified to change the variables of interest in +the running kernel. The +.B -a +flag allows one to set the the variable +.I tickadj +to the value specified as an argument. The +.B -A +flag will also cause +.I tickadj +to be modified, but instead will set it to the internally computed +\*(L"optimal\*(R" value. The +.B -t +flag may be used to reset the kernel's value of +.IR tick , +a capability which is useful on machines with very broken clocks. The +.B -s +flag tells the program to set the value of the variable +.I dosynctodr +to zero, a prerequisite for running the +.IR xntpd (8) +daemon under SunOS 4.0. Normally +.I tickadj +is quite verbose about what it is doing. The +.B -q +flag tells it to shut up about everything except errors. +.PP +Note that +.I tickadj +should be run with some caution when being used for the first time on +different types of machines. The operations which +.I tickadj +trys to perform are not guaranteed to work on all Unix machines. +.SH FILES +.nf +/vmunix +/unix +/dev/kmem +.fi +.SH SEE ALSO +xntpd(8) +.SH HISTORY +Written by Dennis Ferguson at the University of Toronto +.SH BUGS +Fiddling with kernel variables at run time as a part of ordinary +operations is a hideous practice which is only necessary to make +up for deficiencies in the implementation of +.IR adjtime (8) +in many kernels and/or brokenness of the system clock in some +vendors' kernels. It would be much better if the kernels were fixed +and the +.I tickadj +program went away. diff --git a/usr.sbin/xntpd/doc/xntpd.8 b/usr.sbin/xntpd/doc/xntpd.8 new file mode 100644 index 000000000000..b02101980d97 --- /dev/null +++ b/usr.sbin/xntpd/doc/xntpd.8 @@ -0,0 +1,1352 @@ +''' $Header +''' +.de Sh +.br +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp +.if t .sp .5v +.if n .sp +.. +.de Ip +.br +.ie \\n.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +''' +''' Set up \*(-- to give an unbreakable dash; +''' string Tr holds user defined translation string. +''' Bell System Logo is used as a dummy character. +''' +.tr \(bs-|\(bv\*(Tr +.ie n \{\ +.ds -- \(bs- +.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch +.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch +.ds L" "" +.ds R" "" +.ds L' ' +.ds R' ' +'br\} +.el\{\ +.ds -- \(em\| +.tr \*(Tr +.ds L" `` +.ds R" '' +.ds L' ` +.ds R' ' +'br\} +.TH XNTPD 8 LOCAL +.SH NAME +xntpd - Network Time Protocol daemon +.SH SYNOPSIS +.B xntpd +[ +.B -ab +] [ +.B -c +.I conffile +] [ +.B -e +.I authdelay +] [ +.B -f +.I driftfile +] [ +.B -k +.I keyfile +] [ +.B -l +.I loopfile +] [ +.B -p +.I pidfile +] [ +.B -r +.I broaddelay +] [ +.B -s +.I statsdir +] [ +.B -t +.I trustedkey +] +.SH DESCRIPTION +.I Xntpd +is a daemon which maintains a Unix system's time\-of\-day in agreement +with Internet standard time servers. +.I Xntpd +is a complete implementation of the Network Time Protocol (NTP) version +3 standard as defined by RFC 1305 and also retains +compatability with version 1 and 2 servers as defined +by RFC 1059 and RFC 1119, respectively. +.I Xntpd +does all computations in fixed point arithmetic and is entirely free of +floating point code. The computations done in the protocol and clock +adjustment code are carried out with high precision and with attention +to the details which might introduce systematic bias into the integrations, +to try to maintain an accuracy suitable for synchronizing with even the +most precise external time source. +.PP +Ordinarily, +.I xntpd +reads its configuration from a file at startup time. The default configuration +file is +.I /etc/ntp.conf, +though this may be overridden from the command line. It is also possible to +specify a working, though limited, +.I xntpd +configuration entirely on the command line, obviating the need for a +configuration file. This may be particularly appropriate when xntpd is +to be configured as a broadcast client, with all peers being determined +by listening to broadcasts at run time. Various internal +.I xntpd +variables can be displayed, and configuration options altered, while the +daemon is running through use of the +.IR ntpq (8) +and +.IR xntpdc (8) +programs. +.PP +The following command line arguments are understood by +.I xntpd +(see the configuration file description for a more complete functional +description): +.Ip -a 8 +run in \*(L"authenticate\*(R" mode +.Ip -b 8 +listen for broadcast NTP and sync to this if available +.Ip -c 8 +specify an alternate configuration file +.Ip -d 8 +specify debugging options +.Ip -e 8 +specify the time (in seconds) it takes to compute the NTP encryption field +on this computer +.Ip -f 8 +specify the location of the drift file +.Ip -k 8 +specify the location of the file which contains the NTP authentication keys +.Ip -p 8 +specify the name of the file to record the daemon's process id +.Ip -r 8 +specify the default round trip delay (in seconds) +to be used when synchronizing to broadcasts +.Ip -s 8 +specify a directory to be used for creating statistics files +.Ip -t 8 +add a key number to the trusted key list +.SH "CONFIGURATION FILE OPTIONS" +.IR Xntpd 's +configuration file is relatively free format. Comments, which may be +freely inserted, begin with a \*(L"#\*(R" character +and extend to the end of the line. Blank lines are ignored. Configuration +statements include an initial keyword followed by white space separated +arguments, some of which may be optional. Configuration statements +may not be continued over multiple lines. Arguments may be network +numbers (which must be written in numeric, dotted\-quad form), integers, +floating point numbers (when specifying times in seconds) and text +strings. Optional arguments are delimited by \*(L"[]\*(R" in the following +descriptions, while alternatives are separated by \*(L"|\*(R". +.PP +.B peer +.I host_address +[ +.B key +.I # +] [ +.B version +.I # +] [ +.B prefer +] +.br +.B server +.I host_address +[ +.B key +.I # +] [ +.B version +.I # +] [ +.B prefer +] +.br +.B broadcast +.I host_address +[ +.B key +.I # +] [ +.B version +.I # +] [ +.B prefer +] +.PP +These three statements specify various time servers to be used and/or +time services to be provided. The +.B peer +statement specifies that the given host is to be polled in +\*(L"symmetric active\*(R" mode, i.e. that the host is requested to +provide time which you might synchronize to and, in addition, indicates +that you are willing to have to remote host synchronize to your time +if need be. The +.B server +statement specifies that the given host is to be polled in +\*(L"client\*(R" mode, i.e. that the host is requested to provide +time which you might synchronize with but that you are unwilling to have +the remote host synchronize to your own time. The +.B broadcast +statement requests your local daemon to transmit broadcast NTP to +the specified address. The latter is usually the broadcast address +on [one of] your local network[s]. +.PP +The +.B key +option, when included, indicates that all packets sent to the address +are to include authentication fields encrypted using the specified key +number (the range of which is that of an unsigned 32 bit integer). The +default is to not include an encryption field. The +.B version +option allows one to specify the version number to be used for outgoing +NTP packets. Versions 1, 2, and 3 are the choices, version 3 is the default. +The +.B prefer +option marks the host as a preferred host. All other things being equal, this +host will be chosen for synchronization among a set of correctly operating +hosts. +.PP +.B precision +.I # +.PP +Indicates the precision of local timekeeping. The value is an integer +which is approximately the base 2 logarithm of the local timekeeping +precision in seconds. By default this value is set to -6. +.PP +The precision declared by an implementation can affect several aspects +of server operation, and can be used as a tuning parameter for your +synchronization subnet. It should probably not be changed from the +default value, however, unless there is a good reason to do so. +.PP +.B logfile +.I filename +.PP +Gives the file which is to be used instead of syslog output. This +configuration option is also a compile time option (SYSLOG_FILE). +So in order to be able to use this xntpd must be compiled with +-DSYSLOG_FILE. +.PP +.B driftfile +.I filename +.PP +Specifies the name of the file used to record the \*(L"drift\*(R" (or +frequency error) value +.I xntpd +has computed. If the file exists on startup, it is read and the value +used to initialize +.IR xntpd 's +internal value of the frequency error. The file is then updated once +every hour by replacing the old file with a new one containing the +current value of the frequency error. Note that the file is updated +by first writing the current drift value into a temporary file and +then using +.IR rename (3) +to replace the old version. This implies that +.I xntpd +must have write permission for the directory the drift file is located +in, and that file system links, symbolic or otherwise, should probably +be avoided. +.PP +.B "monitor yes|no" +.PP +Indicates whether the +.I xntpd +traffic monitoring function should be enabled or not. When enabled, +this causes the origin address of each packet received by the server +to be recorded along with a limited amount of additional information, such +as the mode of the request and whether it originated from an NTP server port +or not. Traffic monitoring data may be inspected using the +.IR xntpdc (8) +.I monlist +command. The default is \*(L"no\*(R", i.e. traffic monitoring should not +be done. +.PP +Note that the traffic monitoring facility will increase the CPU used +by +.IR xntpd , +as well as increasing the daemon's memory utilization by as much as +8.5 kilobytes. This facility is normally useful for the detection of +peers with malfunctioning software or which are sending bogus data. It +is primarily intended for very popular servers which exchange time with +large numbers of peers, though it may also be useful for access monitoring +of local servers if you are willing to accept the overhead. +.PP +.B "broadcastclient yes|no" +.PP +This indicates whether the local server should listen for, and attempt to +synchonize to, broadcast NTP. The default is \*(L"no\*(R". +.PP +.B broadcastdelay +.I seconds +.PP +Specifies the default round trip delay to the host whose broadcasts +are being synchronized to. The value is specified in seconds and is +typically (for ethernet) a number between 0.007 and 0.015 seconds. This +initial estimate may be improved by polling each server to determine a +more accurate value. Defaults to 0.008 seconds. +.PP +.B "authenticate yes|no" +.PP +Indicates whether the local server should operate in authenticate mode +or not. If \*(L"yes\*(R", only peers which include an authentication field +encrypted with one of our trusted keys (see below) will be considered +as candidates for synchonizing to. The default is \*(L"no\*(R". +.PP +.B authdelay +.I seconds +.PP +Indicates the amount of time it takes to encrypt an NTP authentication +field on the local computer. This value is used to correct transmit +timestamps when the authentication is used on outgoing packets. The +value usually lies somewhere in the range 0.0001 seconds to 0.003 seconds, +though it is very dependent on the CPU speed of the host computer. The +value is usually computed using the +.I authspeed +program included with the distribution. +.PP +.B keys +.I filename +.PP +Specifies the name of a file which contains the encryption keys which +are to be used by +.IR xntpd . +The format of this file is described below. +.PP +.B trustedkey +.I # +[ +.I "# ..." +] +.PP +Allows the specification of the encryption key numbers which are trusted +for the purposes of determining peers suitable for time sychonization, +when authentication is enabled. Only peers using one of these keys for +encryption of the authentication field, and whose authenticity can be +verified by successful decryption, will be considered as synchonization +candidates. The arguments are 32 bit unsigned integers. Note, however, +that NTP key 0 is fixed and globally known. If meaningful authentication +is to be performed the 0 key should not be trusted. +.PP +.B requestkey +.I # +.PP +.I Xntpd +allows run time reconfiguration to be performed using the +.IR xntpdc (8) +program. Such requests must be authenticated. The +.B requestkey +statement allows the specification of a 32 bit unsigned integer +key number to be used for authenticating such requests. Note that +if no +.B requestkey +statement is included in the configuration file the run time reconfiguration +facility will be disabled. +.PP +.B controlkey +.I # +.PP +Certain changes can be made to the +.I xntpd +server via mode 6 control messages, in particular the setting of +leap second indications in a server with a radio clock. The +.B controlkey +statement specifies an encription key number to be used for authenticating +such messages. Omitting this statement will cause control messages +which would change the state of the server to be ignored. +.PP +.B restrict +.I address +[ +.B mask +.I numeric_mask +] [ +.I flag +] [ +.I ... +] +.PP +.I Xntpd +implements a general purpose address\-and\-mask based restriction +list. The list is sorted by address and by mask, and the list is +searched in this order for matches, with the last match found defining +the restriction flags associated with the incoming packets. The source +address of incoming packets is used for the match, with the 32 bit address +being and'ed with the mask associated with the restriction entry and +then compared with the entry's address (which has also been and'ed with +the mask) to look for a match. The \*(L"mask\*(R" argument defaults +to 255.255.255.255, meaning that the \*(L"address\*(R" is treated as the +address of an individual host. A default entry (address 0.0.0.0, mask +0.0.0.0) is always included and, given the sort algorithm, is always the +first entry in the list. Note that, while \*(L"address\*(R" is normally +given as a dotted\-quad address, the text string \*(L"default\*(R", with +no mask option, may be used to indicate the default entry. +.PP +In the current implementation flags always restrict access, i.e. an entry +with no flags indicates that free access to the server is to be given. The +flags are not orthogonal, in that more restrictive flags will often make +less restrictive ones redundant. The flags can generally be classed into +two catagories, those which restrict time service and those which restrict +informational queries and attempts to do run time reconfiguration of the +server. One or more of the following flags may be specified: +.Ip ignore 10 +Ignore all packets from hosts which match this entry. If this flag +is specified neither queries nor time server polls will be responded +to. +.Ip noquery 10 +Ignore all NTP mode 6 and 7 packets (i.e. information queries and configuration +requests) from the source. Time service is not affected. +.Ip nomodify 10 +Ignore all NTP mode 6 and 7 packets which attempt to modify the state of the +server (i.e. run time reconfiguration). Queries which return information +are permitted. +.Ip notrap 10 +Decline to provide mode 6 control message trap service to matching +hosts. The trap service is a subsystem of the mode 6 control message +protocol which is intended for use by remote event logging programs. +.Ip lowpriotrap 10 +Declare traps set by matching hosts to be low priority. The number +of traps a server can maintain is limited (the current limit is 3). +Traps are usually assigned on a first come, first served basis, with +later trap requestors being denied service. This flag modifies the +assignment algorithm by allowing low priority traps to be overridden +by later requests for normal priority traps. +.Ip noserve 10 +Ignore NTP packets whose mode is other than 6 or 7. In effect, time service is +denied, though queries may still be permitted. +.Ip nopeer 10 +Provide stateless time service to polling hosts, but do not allocate peer +memory resources to these hosts even if they otherwise might be considered +useful as future synchronization partners. +.Ip notrust 10 +Treat these hosts normally in other respects, but never use them as +synchronization sources. +.Ip ntpport 10 +This is actually a match algorithm modifier, rather than a restriction +flag. Its presence causes the restriction entry to be matched only if +the source port in the packet is the standard NTP UDP port (123). Both +\*(L"ntpport\*(R" and non\-\*(L"ntpport\*(R" may be specified. The +\*(L"ntpport\*(R" is considered more specific and is sorted later in the +list. +.PP +Default restriction list entries, with the flags \*(L"ignore, ntpport\*(R", +for each of the local host's interface addresses are inserted into the +table at startup to prevent the server from attempting to synchronize to +its own time. A default entry is also always present, though if it is +otherwise unconfigured no flags are associated with the default entry (i.e. +everything besides your own NTP server is unrestricted). +.PP +The restriction facility was added to allow the current access policies +of the time servers running on the NSFnet backbone to be implemented with +.I xntpd +as well. While this facility may be otherwise useful for keeping unwanted or +broken remote time servers from affecting your own, it should not be +considered an alternative to the standard NTP authentication facility. Source +address based restrictions are easily circumvented by a determined cracker. +.PP +.B trap +.I host_address +[ +.B port +.I port_number +] [ +.B interface +.I interface_addess +] +.PP +Configures a trap receiver at the given host address and port number, +sending messages with the specified local interface address. If the +port number is unspecified a value of 18447 is used. If the interface +address is not specified the message is sent with a source address +which is that of the local interface the message is sent through. Note +that on a multihomed host the interface used may vary from time to time +with routing changes. +.PP +The trap receiver will generally log event messages and other information +from the server in a log file. While such monitor programs may also +request their own trap dynamically, configuring a trap receiver will +ensure that no messages are lost when the server is started. +.PP +.B maxskew +.I seconds +.PP +This command is obsolete and not available in this version of +.I xntpd. +.PP +.B select +.I algorithm_number +.PP +This command is obsolete and not available in this version of +.I xntpd. +.PP +.B resolver +.I /path/xntpres +.PP +Normally, names requiring resolution (rather than numeric addresses) +in the configuration file are resolved by code internal to +.I xntpd; +However, in those cases that require it, the code can be installed +in a standalone program called +.I xntpres. +In these cases the full path to the +.I xntpres +program is given as the argument the command. +As +.I xntpres +makes use of mode 7 runtime reconfiguration, this facility must also be +enabled if the procedure is to exceed (see the +.B requestkey +and +.B keys +statements above). +.PP +.B statsdir +.I /directory path/ +.PP +Indicates the full path of a directory where statistics files should +be created (see below). This keyword allows the (otherwise constant) filegen +filename prefix to be modified for file generation sets used for +handling statistics logs (see +.B filegen +statement below). +.PP +.B statistics +.IR name \.\.\. +.PP +Enables writing of statistics records. +Currently, three kinds of statistics are supported. +.Ip loopstats 10 +enables recording of loop filter statistics information. +Each update of the local clock outputs a line of the +following form to the file generation set named \*(L"loopstats\*(R": +.PP +.RS 5 +48773 10847.650 0.0001307 17.3478 2 +.RE + +.RS 10 +The first two fields show the date (Modified Julian Day) and time (seconds +and fraction past UTC midnight). The next three fields show time offset +in seconds, frequency offset in parts-per-million and time constant of +the clock-discipline algorithm at each update of the clock. +.RE +.Ip peerstats 10 +enables recording of peer statistics information. This includes +statistics records of all peers of a NTP server and of the 1-pps signal, +where present and configured. Each +valid update appends a line of the following form to the current +element of a file generation set named \*(L"peerstats\*(R": +.PP +.RS 5 +48773 10847.650 127.127.4.1 9714 -0.001605 0.00000 0.00142 +.RE + +.RS 10 +The first two fields show the date (Modified Julian Day) and time (seconds +and fraction past UTC midnight). The next two fields show the peer +address in dotted-quad notation and status, +respectively. The status field is encoded in hex in the format described +in Appendix A of the NTP specification RFC 1305. The final three fields +show the offset, delay and dispersion, all in seconds. +.RE +.Ip clockstats 10 +enables recording of clock driver statistics information. Each update +received from a clock driver outputs a line of the following form to the +file generation set named \*(L"clockstats\*(R": +.PP +.RS 5 +49213 525.624 127.127.4.1 93 226 00:08:29.606 D +.RE + +.RS 10 +The first two fields show the date (Modified Julian Day) and time (seconds +and fraction past UTC midnight). The next field shows the clock +address in dotted-quad notation, The final field shows the last timecode +received from the clock in decoded ASCII format, where meaningful. In +some clock drivers a good deal of additional information can be gathered +and displayed as well. See information specific to each clock +for further details. +.RE +.PP +Statistic files are managed using file generation sets (see +.B filegen +below). The information obtained by enabling statistics recording +allows analysis of temporal properties of a +.I xntpd +server. It is usually only useful to primary servers or maybe main +campus servers. +.PP +.B filegen +.I name +[ +.B file +.I filename +] [ +.B type +.I typename +] [ +.B flag +.I flagval +] [ +.BR link \| nolink +] [ +.BR enable \| disable +] +.PP +Configures setting of generation file set +.IR name . +Generation file sets provide a means for handling files that are +continously growing during the lifetime of a server. Server statistics +are a typical example for such files. Generation file sets provide +access to a set of files used to store the actual data. At any time at +most one element of the set is being written to. The +.I type +given specifies when and how data will be directed to a new element +of the set. This way, information stored in elements of a file set +that are currently unused are available for administrational +operations +without the risc of desturbing the operation of +.IR xntpd . +(Most important: they can be removed to free space for new data +produced.) +Filenames of set members are built from three elements. +.Ip prefix 10 +This is a constant filename path. It is not subject to modifications +via the +.B filegen +statement. It is defined by the server, usually specified as a compile +time constant. It may, however, be configurable for individual file +generation sets via other commands. For example, the prefix used with +"loopstats" and "peerstats" filegens can be configured using the +.B statsdir +statement explained above. +.Ip filename 10 +This string is directly concatenated to the +.I prefix +mentioned above (no intervening \*(L'/\*(R' (slash)). This can be +modified using the \*(L"file\*(R" argument to the \*(L"filegen\*(R" +statement. No \*(L"..\*(R" elements are allowed in this component to +prevent filenames referring to parts outside the filesystem hierarchy +denoted by \*(L"prefix\*(R". +.Ip suffix 10 +This part is reflects individual elements of a file set. It is generated +according to the +.I type +of a file set as explained below. +.PP +A file generation set is characterized by its type. +The following types are supported: +.Ip none 10 +The file set is actually a single plain file. +.Ip pid 10 +One element of file set is used per incarnation of a +.I xntpd +server. This type does not perform any changes to file set members +during runtime, however it provides an easy way of seperating files +belonging to different +.I xntpd +server incarnations. +The set member filename is built by appending a dot (\*(L'.\*(R') to +concatentated \*(L"prefix\*(R" and \*(L"filename\*(R" strings, and +appending the decimal representation of the process id of the +.I xntpd +server process. +.Ip day 10 +One file generation set element is created per day. The term +.I day +is based on +.IR UTC . +A day is defined as the period between 00:00 and 24:00 UTC. +The file set member suffix consists of a dot \*(L".\*(R" +and a day specification in the form +.RI < YYYYMMDD >. +.I YYYY +is a 4 digit year number (e.g. 1992). +.I MM +is a two digit month number. +.I DD +is a two digit day number. +Thus, all information written at December 10th, 1992 would end up +in a file named +\*(L"<prefix><filename>.19921210\*(R". +.Ip week 10 +Any file set member contains data related to a certain week of a year. +The term +.I week +is definied by computing \*(L"day of year\*(R" modulo 7. Elements of +such a file generation set are distinguished by appending the +following suffix to the file set filename base: +A dot, a four digit year number, the letter \*(L"W\*(R", +and a two digit week number. For example, information from Jamuary, +10th 1992 would end up in a file with suffix \*(L".1992W1\*(R". +.Ip month 10 +One generation file set element is generated per month. The file name +suffix consists of a dot, a four digit year number, and a two digit +month. +.Ip year 10 +One generation file elment is generated per year. The filename suffix +consists of a dot and a 4 digit year number. +.Ip age 10 +This type of file generation sets changes to a new element of the file +set every 24 hours of server operation. The filename suffix consists +of a dot, the letter \*(L"a\*(R", and an eight digit number. This +number is taken to be the number of seconds the server is running at +the start of the corresponding 24 hour period. +.PP +Information is only written to a file generation set when this set is +\*(L"enabled\*(R". Output is prevented by specifying +\*(L"disabled\*(R". +.PP +It is convenient to be able to access the +.I current +element of a file generation set by a fixed name. This feature is +enabled by specifying \*(L"link\*(R" and disabled using +\*(L"nolink\*(R". If \*(L"link\*(R" is specified, a hard link from the +current file set element to a file without suffix is created. When +there is already a file with this name and the number of links of this +file is one, it is renamed appending a dot, the letter \*(L"C\*(R", +and the pid of the +.I xntpd +server process. When the number of links is greater than one, the file +is unlinked. This allows the current file to be accessed by a constant +name. +.SH "AUTHENTICATION KEY FILE FORMAT" +.PP +The NTP standard specifies an extension allowing +verification of the authenticity of received NTP packets, and to provide +an indication of authenticity in outgoing packets. This is implemented +in +.I xntpd +using the DES encryption algorithm. The specification +allows any one of a possible 4 billion keys, numbered with 32 bit unsigned +integers, to be used to +authenticate an association. The servers involved in an association +must agree on the value of the key used to authenticate their data, though +they must each learn the key independently. The keys are standard 56 bit +DES keys. +.PP +Addionally, a new experimental authentication algorithm is available which +uses an MD5 message digest to compute an authenticator. Currently the length +of the key or password is limited to 8 characters, but this will eventually +be changed to accomodate an effectively unlimited password phrase. +.I Xntpd +reads its keys from a file specified using the +.B -k +command line option or the +.B keys +statement in the configuration file. While key number 0 is fixed by the +NTP standard (as 56 zero bits) and may not be changed, one or more of +the keys numbered 1 through 15 may be arbitrarily set in the keys file. +.PP +The key file uses the same comment conventions as the configuration +file. Key entries use a fixed format of the form +.Ip "" 5 +.I "keyno type key" +.PP +where \*(L"keyno\*(R" is a positive integer, +\*(L"type\*(R" is a single character which defines the format the key +is given in, and \*(L"key\*(R" is the key itself. +.PP +The key may be given in one of three different formats, controlled by +the \*(L"type\*(R" character. The three key types, and corresponding +formats, are listed following. +.Ip "S" 5 +The \*(L"key\*(R" is a 64 bit hexadecimal number in the format specified +in the DES document, that is the high order 7 bits of each octet are used +to form the 56 bit key while the low order bit of each octet is given a +value such that odd parity is maintained for the octet. Leading zeroes +must be specified (i.e. the key must be exactly 16 hex digits long) and +odd parity must be maintained. Hence a zero key, in standard format, +would be given as +.I 0101010101010101 . +.Ip "N" 5 +The \*(L"key\*(R" is a 64 bit hexadecimal number in the format specified +in the NTP standard. This is the same as the DES format except the bits +in each octet have been rotated one bit right so that the parity bit is +now the high order bit of the octet. Leading zeroes must be specified +and odd parity must be maintained. A zero key in NTP format would be specified +as +.I 8080808080808080 +.Ip "A" 5 +The \*(L"key\*(R" is a 1\-to\-8 character ASCII string. A key is formed +from this by using the lower order 7 bits of the ASCII representation +of each character in the string, with zeroes being added on the right +when necessary to form a full width 56 bit key, in the same way that +encryption keys are formed from Unix passwords. +.Ip "M" 5 +The \*(L"key\*(R" is a 1\-to\-8 character ASCII string, using the MD5 +authentication scheme. Note that both the keys and the authentication +schemes (DES or MD5) must be identical between a set of peers sharing +the same key number. +.PP +One of the keys may be chosen, +by way of the configuration file +.B requestkey +statement, to authenticate run time configuration +requests made using the +.IR xntpdc (8) +program. The latter program obtains the key from the terminal as +a password, so it is generally appropriate to specify the key chosen +to be used for this purpose in ASCII format. +.SH PRIMARY CLOCK SUPPORT +.PP +.I Xntpd +can be optionally compiled to include support for a number of types +of reference clocks. A reference clock will generally (though +not always) be a radio timecode receiver which is synchronized to a +source of standard time such as the services offered by the NRC in +Canada and NIST in the U.S. The interface between the computer and +the timecode receiver is device dependent and will vary, but is +often a serial port. +.PP +For the purposes of configuration, +.I xntpd +treats reference clocks in a manner analogous to normal NTP peers +as much as possible. Reference clocks are referred to by address, +much as a normal peer is, though an invalid IP address is used to +distinguish them from normal peers. Reference clock addresses are +of the form +.I 127.127.t.u +where +.I t +is an integer denoting the clock type and +.I u +indicates the type\-specific unit number. Reference clocks are normally +enabled by configuring the clock as a server using a +.B server +statement in the configuration file which references the clock's +address (configuring a reference clock with a +.B peer +statement can also be done, though with some clock drivers this may cause +the clock to be treated somewhat differently and by convention is used +for debugging purposes). Clock addresses may generally +be used anywhere else in the configuration file a normal IP address +can be used, for example in +.B restrict +statements. +.PP +There is one additional configuration statement which becomes valid +when reference clock support has been compiled in. Its format is: +.PP +.B fudge +.I 127.127.t.u +[ +.B time1 +.I secs +] [ +.B time2 +.I secs +] [ +.B value1 +.I int +] [ +.B value2 +.I int +] [ +.B flag1 +.I 0|1 +] [ +.B flag2 +.I 0|1 +] +.PP +There are two times (whose values are specified in fixed point seconds), +two integral values and two binary flags available for customizing +the operation of a clock. The interpretation of these values, and +whether they are used at all, is a function of the needs of the particular +clock driver. +.PP +.I Xntpd +on Unix machines currently supports several different types of clock hardware +plus a special pseudo\-clock used for backup or when no other clock +source is available. In the case of most of the clock drivers, support +for a 1-pps precision timing signal is available as described in the +pps.txt file in the doc directory of the xntp3 distribution. +The clock drivers, and the addresses used to configure +them, are described following: +.PP +.B 127.127.1.u +\- Local synchronization clock driver +.PP +This driver doesn't support an actual clock, but rather allows the +server to synchronize to its own clock, in essence to free run without +its stratum increasing to infinity. This can be used to run an +isolated NTP synchronization network where no standard time source is +available, by allowing a free running clock to appear as if it has +external synchronization to other servers. By running the local clock +at an elevated stratum it can also be used to prevent a server's stratum +from rising above a fixed value, this allowing a synchronization subnet +to synchonize to a single local server for periods when connectivity +to the primary servers is lost. +.PP +The unit number of the clock (the least significant octet in the address) +must lie in the range 0 through 15 inclusive and is used as the stratum +the local clock will run at. Note that the server, when synchronized +to the local clock, will advertise a stratum one greater than the clock +peer's stratum. More than one local clock may be configured (indeed all +16 units may be active at once), though this hardly seems useful. +.PP +The local clock driver uses only the fudge time1 parameter. This parameter +provides read and write access to the local clock drift compensation +register. This value, which actually provides a fine resolution speed +adjustment for the local clock, is settable but will remain unchanged +from any set value +when the clock is free running without external synchronization. The +fudge time1 parameter thus provides a way to manually adjust the speed of the +clock to maintain reasonable synchronization with, say, a voice +time announcement. It is actually more useful to manipulate this value +with the +.IR xntpdc (8) +program. +.PP +.B 127.127.3.u +\- Precision Standard Time/Traconex 1010/1020 WWV/H Receiver +.PP +This driver can be used with a PST/Traconex Time Source 1010 or 1020 WWV/WWVH +Synchronized Clock connected via a serial port. Up to +four units, with unit numbers in the range 0 through 3, can be +configured. The driver assumes the serial port device name is +/dev/pst%d (i.e. unit 1, at 127.127.3.1, opens the clock at +/dev/pst1) and that the clock is configured for 9600-baud operation. +.PP +The fudge time1 and time2 parameters are configured directly into the receiver +as nominal propagation delays when synchronized to WWV and WWVH, +respectively; the internal DIPswitches ordinarily used for that purpose +are disabled. The default values are 0.0075 and 0.0265 seconds, +respectively, which are about right for Toronto. Values for other +locations can be calculated using the +.I propdelay +program in the util directory of the xntp3 distribution or equivalent +means described in the user's manual. +.PP +The fudge value1 parameter can be used to set the stratum at which +the peer operates. The default is 0, which is correct if you want the +clock to be considered for synchonization whenever it is operating, though +higher values may be assigned if you only want the clock to provide backup +service when all other primary sources have failed. The value2 parameter +is set to the number of minutes which the daemon will allow the clock to go +without synchronization before it starts disbelieving it. The default +is 20, which is suitable if you have good quality backup NTP peers. If +your network is isolated or your network connections are poor it might +be advantageous to increase this value substantially. +.PP +The fudge flag1 can be used to modifiy the averaging algorithm used +to smooth the clock indications. Ordinarily, the algorithm picks the +median of a set of samples, which is appropriate under conditions +of poor to fair radio propagation conditions. If the clock is located +relatively close to the WWV or WWVH transmitters, setting this flag +will cause the algorithm to average the set of samples, which can +reduce the residual jitter and improve accuracy. +.PP +The fudge flag2 can be used to force the driver to send to +the clock the commands required to reprogram the current WWV and WWVH fudge +delays into it. This is normally done only when the values are to be changed, +such as during inital setup and calibration. Setting +the (otherwise undocumented) fudge flag3 will cause the driver to reset +the clock. The latter two flags are generally useful primarily for debugging. +.PP +127.127.4.u +\- Spectracom 8170 and Netclock/2 WWVB Synchronized Clocks +.PP +This driver can be used with a Spectracom 8170 or Netclock/2 WWVB +Synchronized Clock connected via a serial port. Up to +four units, with unit numbers in the range 0 through 3, can be +configured. The driver assumes the serial port device name is +/dev/wwvb%d (i.e., unit 1 at 127.127.4.1 opens the clock at +/dev/wwvb1) and that the clock is configured for 9600-baud operation. +.PP +The fudge time1 parameter can be used to compensate for inherent +latencies in the serial port hardware and operating system. +The value, which defaults to zero, is in addition to the value +programmed by the propagation switches on the receiver. The +fudge value1 parameter can be used to specify the stratum of the clock +in the same way described above for the WWV/WWVH clock 127.127.3.u. +.PP +.B 127.127.5.u +\- Kinemetrics/TrueTime Timing Receivers +.PP +This driver can be used with at least two models of Kinemetrics/TrueTime +Timing Receivers, the 468-DC MK III GOES Synchronized Clock and GPS-DC +MK III GPS Synchronized Clock and very likely others in the same model +family that use the same timecode formats. The clocks are connected +via a serial port. Up to +four units, with unit numbers in the range 0 through 3, can be +configured. The driver assumes the serial port device name is +/dev/goes%d (i.e., unit 1 at 127.127.5.1 opens the clock at +/dev/goes1) and that the clock is configured for 9600-baud operation. +.PP +The fudge time1 parameter can be used to compensate for inherent +latencies in the serial port hardware and operating system in the same +way as described above for the WWVB clock 127.127.4.u. +The fudge value1 parameter can be used to specify the stratum of the clock +in the same way described above for the WWV/WWVH clock 127.127.3.u. +.PP +.B 127.127.6.0 +\- IRIG-B Audio Decoder +.PP +This driver can be used in conjuction with the Inter-Range Instrumentation +Group standard time-distribution signal IRIG-B. This signal is generated +by several radio clocks, including those made by Austron, TrueTime, Odetics +and Spectracom, among others, although it is generally an add-on option. +The signal is connected via an attenuator box and cable to the audio +codec input on a Sun SPARCstation and requires a specially modified +kernel audio driver. Details are in the irig.txt file in the doc +directory of the xntp3 distribution. As only a single audio codec +is built into a workstation, the driver assumes the device name is /dev/irig. +.PP +Timing jitter using the decoder and a Sun IPC is in the order of a few +microseconds, although the overal timing accuracy is limited by the +wander of the CPU oscillator used for timing purposes to a few hundred +microseconds. These figures are comparable with what can be achieved +using the 1-pps signal described in the pps.txt file in the doc +directory of the xntp3 distribution. +.PP +.B 127.127.7.u +\- CHU Modem Decoder +.PP +This driver can be used with a shortwave receiver and special modem +circuitry described in the gadget directory of the xntp3 distribution. +It requires the chu-clk line discipline or chu_clk STREAMS module +described in the kernel directory of that distribution. It is connected +via a serial port operating at 300 baud. Up to +four units, with unit numbers in the range 0 through 3, can be +configured. The driver assumes the serial port device name is +/dev/chu%d (i.e., unit 1 at 127.127.7.1 opens the clock at +/dev/chu1). +.PP +Unlike the NIST time services, whose timecode requires quite specialized +hardware to interpret, the CHU timecode can be received directly via +a serial port after demodulation. While there are currently no commercial +CHU receivers, the hardware required to receive the CHU timecode is fairly +simple to build. While it is possible to configure several CHU units +simultaneously this is not recommended as the character interrupts from all +units will be occuring at the same time and will interfere with each other. +.PP +The fudge time1 parameter is used to specify the propagation delay between +the CHU transmitter at Ottawa, Ontario, and the receiver. The default +value is 0.0025 seconds, which is about right for Toronto. Values for other +locations can be calculated using the +.I propdelay +program in the util directory of the xntp3 distribution or equivalent +means. +The fudge time2 +parameter is used to compensate for inherent latencies in the modem, +serial port hardware and operating system in the same way as described +above for the WWVB clock 127.127.4.u. The default value is +0.0002 seconds, which is about right for typical telephone modem chips. +The fudge value1 parameter can be used to specify the stratum of the clock +in the same way described above for the WWV/WWVH clock 127.127.3.u. +The fudge flag1 can be used to modify the averaging algorithm in the +same way as described for that clock. +.PP +.B 127.127.8.u +\- Synchronisation to several receivers (DCF77, GPS) +.PP +The timecode of +the receivers will be sampled via a STREAMS module in the kernel (The STREAMS module +has been designed for use with SUN Systems under SunOS 4.1.x. It can be +linked directly into the kernel or loaded via the loadable driver mechanism) +This STREAMS module can be adepted to be able to convert different time code +formats. +If the daemon is compiled without the STREAM definition synchronisation +will work without the Sun streams module, though accuracy is significantly +degraded. +.br +The actual receiver status is mapped into various synchronisation +states generally used by receivers. The STREAMS module is configured to +interpret the time codes of DCF U/A 31, PZF535, GPS166, Trimble SV6 GPS, ELV DCF7000, +Schmid and low cost receivers (see list below). +.br +The reference clock support in xntp contains the necessary configuration tables +for those receivers. In addition to supporting up to 32 different clock types and +4 devices the generation a a PPS signal is also provided as an configuration +option. The PPS configuration option uses the receiver generated time stamps +for feeding the PPS loopfilter control for much finer clock synchronisation. +.br +CAUTION: The PPS configuration option is different from the hardware PPS signal, +which is also supported (see below), as it controls the way xntpd is synchronised +to the reference clock, while the hardware PPS signal controls the way time +offsets are determined. +.br +The use of the PPS option requires receivers with an accuracy of better than 1ms. +.PP +Fudge factors +.PP +Only two fudge factors are utilized. The +.I time1 +fudge factor defines the phase offset of the sychnronisation character to the actual +time. +On the availability of PPS information the +.I time2 +fudge factor show the difference betwteen the PPS time stamp and the reception +time stamp of the serial signal. This parameter is read only attempts to +set this parameter will be ignored. +The +.I flag0 +enables input filtering. This a median filter with continuous sampling. The +.I flag1 +selects averaging of the samples remaining after the filtering. Leap second +handling is controlled with the +.I flag2. +When set a leap second will be deleted on receipt of a leap second indication +from the receiver. Otherwise the leap second will be added (which is the default). +.PP +.I ntpq +timecode variable +.PP +The timecode variable in the ntpq read clock variable command contains several +fields. The first field is the local time in Unix format. The second field is +the offset to UTC (format HHMM). The currently active receiver flags are listed +next. Additional feature flags of the receiver are optionally listed in paranthesis. +The actual time code is enclosed in angle brackets < >. A qualification of the +decoded time code format is following the time code. The last piece of information +is the overall running time and the accumulated times for the clock event states. +.PP +Unit encoding +.PP +The unit field <u> encodes the device, clock type and the PPS generation option. +There are 4 possible devices which are encoded in the lower 2 bits of the <u> +field. The devices are named +.IR /dev/refclock-0 +through +.IR /dev/refclock-3 . +Bits 2 thru 6 encode the clock type. The fudge factors +of the clock type are take from a table +.I clockinfo +in refclock_parse.c. The generation of PPS information for disciplining the +local NTP clock is encoded in bit 7 of <u>. +.PP +Currently nine clock types (devices /dev/refclock-0 - /dev/refclock-3) are supported. +.Ip 127.127.8.0-3 16 +Meinberg PZF535 receiver (FM demodulation/TCXO / 50us) +.Ip 127.127.8.4-7 16 +Meinberg PZF535 receiver (FM demodulation/OCXO / 50us) +.Ip 127.127.8.8-11 16 +Meinberg DCF U/A 31 receiver (AM demodulation / 4ms) +.Ip 127.127.8.12-15 16 +ELV DCF7000 (sloppy AM demodulation / 50ms) +.Ip 127.127.8.16-19 16 +Walter Schmid DCF receiver Kit (AM demodulation / 1ms) +.Ip 127.127.8.20-23 16 +RAW DCF77 100/200ms pulses (Conrad DCF77 receiver module / 5ms) +.Ip 127.127.8.24-27 16 +RAW DCF77 100/200ms pulses (TimeBrick DCF77 receiver module / 5ms) +.Ip 127.127.8.28-31 16 +Meinberg GPS166 receiver (GPS / <<1us) +.Ip 127.127.8.32-35 16 +Trimble SV6 GPS receiver (GPS / <<1us) +.PP +The reference clock support carefully monitors the state transitions of +the receiver. All state changes and exceptional events such as loss of time code +transmission are logged via the +.I syslog +facility. +Every hour a summary of the accumulated times for the clock states is +listed via syslog. +.PP +PPS support is only available when the receiver is completely +synchronised. The receiver is believed to deliver correct time for an additional +period of time after losing sychronisation unless a disruption in time code +transmission is detected (possible power loss). The trust period is dependent +on the receiver oscillator and thus a function of clock type. This is one of +the parameters in the +.I clockinfo +field of the reference clock implementation. This parameter cannot be +configured by xntpdc. +.PP +In addition to the PPS loopfilter control a true PPS hardware signal can be applied +on Sun Sparc stations via the CPU serial ports on the CD pin. This signal is +automatically detected and will be used for offset calculation. The input signal +must be the time mark for the following time code. (The edge sensitivity can be +selected - look into the appropriate kernel/parsestreams.c for details). +Meinberg receivers can be connected by feeding the PPS pulse of the receiver via +a 1488 level converter to Pin 8 (CD) of a Sun serial zs\-port. +.PP +There exists a special firmware release for the PZF535 Meinberg receivers. +This release (PZFUERL 4.6 (or higher - The UERL is important)) is absolutely +recommended for XNTP use, as it provides LEAP warning, time code time zone information +and alternate antenna indication. Please check with Meinberg for this +firmware release. +For the Meinberg GPS166 receiver is also a special firmaware release available +(Uni-Erlangen). This release must be used for proper operation. +.PP +The raw DCF77 pulses can be fed via a level converter directly into Pin 3 (Rx) +of the Sun. The telegrams will be decoded an used for synchronisation. +AM DCF77 receivers are running as low as $25. The accuracy is dependent on +the receiver and is somewhere between 2ms (expensive) to 10ms (cheap). +Upon bad signal reception of DCF77 sychronisation will cease as no backup +oscillator is available as usually found in other reference clock receivers. +So it is important to have a good place for the DCF77 antenna. For transmitter +shutdowns you are out of luck unless you have other NTP servers with alternate +time sources available. +.PP +127.127.9.u +\- Magnavox MX4200 Navigation Receiver used as GPS Synchronized Clocks +.PP +This driver can be used with a Magnavox MX4200 Navigation Receiver +adapted to precision timing applications. This requires an interface +box described in the ppsclock directory of the xntp3 distribution. +It is connected via a serial port and requires the ppsclock STREAMS +module described in the same directory. Up to +four units, with unit numbers in the range 0 through 3, can be +configured. The driver assumes the serial port device name is +/dev/gps%d (i.e., unit 1 at 127.127.9.1 opens the clock at +/dev/gps1) and that the clock is configured for 9600-baud operation. +.PP +The fudge time1 parameter can be used to compensate for inherent +latencies in the serial port hardware and operating system in the +same way described above for the WWVB clock 127.127.4.u. The +fudge value1 parameter can be used to specify the stratum of the clock +in the same way described above for the WWV/WWVH clock 127.127.3.u. +.PP +127.127.10.u +\- Austron 2200A/2201A GPS/LORAN Synchronized Clock and Timing Receiver +.PP +This driver can be used with an Austron 2200A/2201A GPS/LORAN Synchronized +Clock and Timing Receiver connected via a serial port. It supports +several special features of the clock, including the Input Burffer Module, +Output Buffer Module, IRIG-B Interface Module and LORAN Assist Module. It +requires the RS232 Serial Interface module for communication with +the driver. Up to four units (which hardly seems affordable), with unit +numbers in the range 0 through 3, can be +configured. The driver assumes the serial port device name is +/dev/gps%d (i.e., unit 1 at 127.127.10.1 opens the clock at +/dev/gps1) and that the clock is configured for 9600-baud operation. +.PP +The fudge time1 parameter can be used to compensate for inherent +latencies in the serial port hardware and operating system in the +same way described above for the WWVB clock 127.127.4.u. The +fudge value1 parameter can be used to specify the stratum of the clock +in the same way described above for the WWV/WWVH clock 127.127.3.u. +.PP +This receiver is capable of a comprehensive and large volume of +statistics and operational data. The specific data-collection +commands and attributes are embedded in the driver source code; +however, the collection process can be enabled or disabled +using the flag4 flag. If set, collection is enabled; if not, +which is the default, it is disabled. A comprehensive suite of data reduction +and summary scripts is in the ./scripts/stats directory of the xntp +distribution. +.PP +127.127.11.u +\- Kinemetrics/TrueTime OMEGA-DC OMEGA Synchronized Clock +.PP +This driver can be used with a Kinemetrics/TrueTime OMEGA-DC OMEGA +Synchronized Clock connected via a serial port. This clock is +sufficiently different than other Kinemetrics/TrueTime models +to require a separate driver. Up to +four units, with unit numbers in the range 0 through 3, can be +configured. The driver assumes the serial port device name is +/dev/omega%d (i.e., unit 1 at 127.127.11.1 opens the clock at +/dev/omega1) and that the clock is configured for 9600-baud operation. +.PP +The fudge time1 parameter can be used to compensate for inherent +latencies in the serial port hardware and operating system in the +same way described above for the WWVB clock 127.127.4.u. The +fudge value1 parameter can be used to specify the stratum of the clock +in the same way described above for the WWV/WWVH clock 127.127.3.u. +.PP +127.127.12.0 +\- KSI/Odeteics TPRO IRIG-B Decoder +.PP +This driver can be used with a KSI/Odeteics TPRO or TPRO-SAT IRIG-B +Decoder, which is a module connected directly to the SBus of a +Sun workstation. The module works with the IRIG-B signal generated +by several radio clocks, including those made by Austron, TrueTime, Odetics +and Spectracom, among others, although it is generally an add-on option. +In the case of the TPRO-SAT, the module is an integral part of a GPS +receiver, which serves as the primary timing source. +As only a single module of this type can be +used on a single workstation, only the unit number 0 is acceptable. +The driver |