Remove files not present in 4.1.1a import.

This commit is contained in:
Ollivier Robert 2002-10-29 20:11:45 +00:00
parent ce265a549d
commit eaabcee53b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/ntp/dist/; revision=106167
svn path=/vendor/ntp/4.1.1a/; revision=106165; tag=vendor/ntp/4.1.1a
25 changed files with 0 additions and 3978 deletions

View File

@ -1,207 +0,0 @@
-------------
INTRODUCTION:
-------------
Last revision 27 July 1999 Version 4.0.95.
This version compiles under WINNT with Visual C 6.0.
Greg Brackley and Sven Dietrich
Significant changes:
-Visual Studio v6.0 support
-Winsock 2.0 support
-Use of I/O completion ports for sockets and comm port I/O
-Removed the use of multimedia timers (from ntpd, others need removing)
-Use of waitable timers (with user mode APC) and performance counters to fake getting a better time
-Trimble Palisade NTP Reference Clock support
-General cleanup, prototyping of functions
-Moved receiver buffer code to a separate module (removed unused members from the recvbuff struct)
-Moved io signal code to a separate module
Compiling Instructions:
1. Requires Perl to be installed, and the Perl environment variable to be set correctly
2. Open the .\ports\winnt\ntp.dsw
3. Batch build of all debug projects compile
Last revision: 20-Oct-1996
This version corrects problems with building the XNTP
version 3.5-86 distribution under Windows NT.
The following files were modified:
blddbg.bat
bldrel.bat
include\ntp_machine.h
xntpd\ntp_unixclock.c
xntpd\ntp_refclock.c
scripts\wininstall\build.bat
scripts\wininstall\setup.rul
scripts\wininstall\readme.nt
scripts\wininstall\distrib\ntpog.wri
html\hints\winnt (this file)
In order to build the entire Windows NT distribution you
need to modify the file scripts\wininstall\build.bat
with the installation directory of the InstallShield
software. Then, simply type "bldrel" for non-debug
or "blddbg" for debug executables.
Greg Schueman
<schueman@acm.org>
Last revision: 07-May-1996
This set of changes fixes all known bugs, and it includes
several major enhancements.
Many changes have been made both to the build environment as
well as the code. There is no longer an ntp.mak file, instead
there is a buildntall.bat file that will build the entire
release in one shot. The batch file requires Perl. Perl
is easily available from the NT Resource Kit or on the Net.
The multiple interface support was adapted from Larry Kahn's
work on the BIND NT port. I have not been able to test it
adequately as I only have NT servers with one network
interfaces on which to test.
Enhancements:
* Event Logging now works correctly.
* Version numbers now work (requires Perl during build)
* Support for multiple network interface cards (untested)
* NTP.CONF now default, but supports ntp.ini if not found
* Installation procedure automated.
* All paths now allow environment variables such as %windir%
Bug fixes:
* INSTSRV replaced, works correctly
* Cleaned up many warnings
* Corrected use of an uninitialized variable in XNTPD
* Fixed ntpdate -b option
* Fixed ntpdate to accept names as well as IP addresses
(Winsock WSAStartup was called after a gethostbyname())
* Fixed problem with "longjmp" in xntpdc/ntpdc.c that
caused a software exception on doing a Control-C in xntpdc.
A Cntrl-C now terminates the program.
See below for more detail:
Note: SIGINT is not supported for any Win32 application including
Windows NT and Windows 95. When a CTRL+C interrupt occurs, Win32
operating systems generate a new thread to specifically handle that
interrupt. This can cause a single-thread application such as UNIX,
to become multithreaded, resulting in unexpected behavior.
Possible enhancements and things left to do:
* Reference clock drivers for NT (at least Local Clock support)
* Control Panel Applet
* InstallShield based installation, like NT BIND has
* Integration with NT Performance Monitor
* SNMP integration
* Fully test multiple interface support
Known problems:
* bug in ntptrace - if no Stratum 1 servers are available,
such as on an IntraNet, the application crashes.
Last revision: 12-Apr-1995
This NTPv3 distribution includes a sample configuration file and the project
makefiles for WindowsNT 3.5 platform using Microsoft Visual C++ 2.0 compiler.
Also included is a small routine to install the NTP daemon as a "service"
on a WindowsNT box. Besides xntpd, the utilities that have been ported are
ntpdate and xntpdc. The port to WindowsNT 3.5 has been tested using a Bancomm
TimeServe2000 GPS receiver clock that acts as a strata 1 NTP server with no
authentication (it has not been tested with any refclock drivers compiled in).
Following are the known flaws in this port:
1) currently, I do not know of a way in NT to get information about multiple
network interface cards. The current port uses just one socket bound to
INADDR_ANY address. Therefore when dealing with a multihomed NT time server,
clients should point to the default address on the server (otherwise the
reply is not guaranteed to come from the same interface to which the
request was sent). Working with Microsoft to get this resolved.
2) There is some problem with "longjmp" in xntpdc/ntpdc.c that causes a
software exception on doing a Control-C in xntpdc. Be patient!
3) The error messages logged by xntpd currently contain only the numerical
error code. Corresponding error message string has to be looked up in
"Books Online" on Visual C++ 2.0 under the topic "Numerical List of Error
Codes".
----------------------------------------------------
MAKING XNTPD FOR WindowsNT 3.5 using Visual C++ 2.0:
----------------------------------------------------
Separate projects are needed for xntpd, ntpdate, xntpdc, and the library
containing routines used by them.
1) First build the static library composed of routines in the lib
subdirectory of the distribution. Load the project by opening the
corresponding makefile libntp.mak (in the lib subdirectory of the
distribution) by choosing the Open option in the File menu. This should
display a list of files contained in this project. Then choose the
"Rebuild All" option from the Project menu in order to compile the
routines into a library. The libntp.lib static library is created in
the lib/WinDebug directory
You can now choose to build xntpd, ntpdate, and xntpdc in any order.
2) To build xntpd, load the project by opening the corresponding makefile
xntpd.mak (in the xntpd subdirectory of the distribution), and rebuild
all files. The xntpd.exe executable is created in the xntpd/WinDebug
directory.
3) repeat the above step for ntpdate and xntpdc
-------------------------------------------------
INSTALLING XNTPD AS A SERVICE UNDER WindowsNT 3.5
-------------------------------------------------
At this point you need to install 'xntpd' as a service. First modify the
sample configuration file conf/config.winnt35 in the distribution to
suit your needs. Then install it as "%SystemRoot%\NTP.INI" (%SystemRoot%
is an environmental variable that can be determined by typing "set" at
the "Command Prompt" or from the "System" icon in the "Control Panel",
NTP.INI is the suggested name for the "ntp.conf" file in Windows environment).
The instsrv.c program in the util subdirectory of the distribution can
be used to install 'xntpd' as a service and start automatically at boot
time. Compile instsrv.c, and enter form the command prompt
"instsrv.exe NetWorkTimeProtocol <pathname_for_xntd.exe>"
Clicking on the "Services" icon in the "Control Panel" ("Main" group
in the "Program Manager") will display the list of currently installed
services in a dialog box. The NetworkTimeProtocol service should show
up in this list. Select it in the list and hit the "Start" button in
the dialog box. The NTP service should start. View the event log by
clicking on the "Event Viewer" icon in the "Administrative Tools" group
of the "Program Manager", there should be several successful startup
messages from NTP. NTP will keep running and restart automatically when
the machine is rebooted.
You can change the start mode (automatic/manual) and other startup
parameters correponding to the NTP service (eg. location of conf file)
also in the "Services" dialog box if you wish.
There is no clean way to run 'ntpdate' before starting 'xntpd' at boot
time, unlike the Unix environment. 'xntpd' will step the clock upto
a 1000 seconds. While there is no reason that the system clock should
be that much off during bootup if 'xntpd' was running before bootup,
you may want to increase the CLOCK_WAYTOOBIG parameter in include/ntp.h
from 1000 to, say, MAXINT.
You can also use instsrv.c to delete the NTP service
"instsrv.exe NetworkTimeProtocol remove"
Viraj Bais
<vbais@mailman1.intel.com>

View File

@ -1,153 +0,0 @@
<HTML>
<HEAD>
<TITLE>vxWorks Port of NTP</TITLE>
</HEAD>
<BODY LINK="#00008B" VLINK="#8B0000">
<H1>VxWorks port of NTP </H1>
<P>Creating a port for vxWorks posed some problems. This port may help
as a starting point for similar ports to real-time OS's and other embeddable
kernels, particularly where main() is not allowed, and where the configure
scripts need to be altered. </P>
<H1><B>Configuration issues</B></H1>
<P>I decided to do as little invasive surgery as possible on the NTP code,
so I brought the vxWorks header tree in line with the standard unix tree.
The following changes were needed, as a side effect these changes will
allow for easy porting of other autoconfigure enabled code. </P>
<P>Where I have 386 you will need to put in your target type. The vxWorks
tree entry point is /usr/wind. If these are the same for your system, you
should be able to cut and paste the changes. </P>
<P><BLINK>WARNING: Check you are not overwriting files, before entering
the following: there should be no conflict, but check first... </BLINK></P>
<P>export CC=&quot;cc386 -nostdlib -m486 -DCPU=I80486 -I/usr/wind/target/h&quot;
<BR>
export RANLIB=ranlib386 <BR>
export AR=ar386 <BR>
export VX_KERNEL=/usr/wind/target/config/ims_std_bsp/vxWorks <BR>
cd /usr/wind/target/sys <BR>
ln -s ../signal.h <BR>
ln -s ../time.h <BR>
ln -s socket.h sockio.h <BR>
ln -s ../selectLib.h select.h <BR>
ln -s ../timers.h <BR>
touch file.h param.h resource.h utsname.h var.h ../netdb.h ../a.out.h ../termios.h
<BR>
echo &quot; ******ADD #include \&quot;sys/times.h\&quot; to sys/time.h
&quot; </P>
<P>The configure script must be changed in the following way to get the
linking tests to work, once in the correct directory issue the following
commands: <BR>
sed -e 's%main.*()%vxmain()%' configure &gt; configure.vxnew <BR>
mv configure.vxnew configure <BR>
chmod 755 configure </P>
<P>The new version 4 of NTP requires some maths functions so it links in the
maths library (-lm) in the ntpd <a href="../ntpd/Makefile.am">Makefile.am</a>
change the line "ntpd_LDADD = $(LDADD) -lm" by removing the "-lm".<BR>
You are now ready to compile</P>
<P><BR>
The <A HREF="../configure.in">configure.in </A>file needed to be altered
to allow for a host-target configuration to take place. </P>
<UL>
<LI>The define SYS_VXWORKS was added to the compilation flags. </LI>
<LI>Little endianess is set if the target is of type iX86. </LI>
<LI>The size of char, integer, long values are all set. If Wind River ever
changes these values they will need to be updated. </LI>
<LI>clock_settime() is defined to be used for setting the clock. </LI>
<LI>The Linking flags have -r added to allow for relinking into the vxWorks
kernel </LI>
</UL>
<P>Unfortunately I have had to make use of the <A HREF="../include/ntp_machine.h">ntp_machine.h
</A>file to add in the checks that would have been checked at linking stage
by autoconf, a better method should be devised. </P>
<UL>
<LI>There is now a NO_MAIN_ALLOWED define that simulates command line args,
this allows the use of the normal startup sysntax. </LI>
<LI>POSIX timers have been added. </LI>
<LI>Structures normally found in netdb.h have been added with, the corresponding
code is in <A HREF="../libntp/machines.c">machines.c </A>. Where possible
the defines for these have been kept non-vxWorks specific.</LI>
</UL>
<P>Unfortunately there are still quite a few SYS_VXWORKS type defines in
the source, but I have eliminated as many as possible. You have the choice
of using the usrtime.a library avaliable from the vxworks archives or forgoing
adjtime() and using the clock_[get|set]time().The <A HREF="../include/ntp_machine.h">ntp_machine.h
</A>file clearly marks how to do this. </P>
<H1><B>Compilation issues</B> </H1>
<P>You will need autoconf and automake ... available free from the gnu
archives worldwide. </P>
<P>The variable arch is the target architecture (e.g. i486) </P>
<P>mkdir A.vxworks (or whatever....) <BR>
cd A.vxworks <BR>
../configure --target=arch-wrs-vxworks [any other options] <BR>
make </P>
<P>Options I normally use are the --disable-all-clocks --enable-LOCAL-CLOCK flags.
The program should proceed to compile without problem. The daemon ntpd,
ntpdate, ntptrace, ntpdc, ntpq programs and of course the libraries are
all fully ported. The other utilities are not, but they should be easy
to port. </P>
<H1>Running the software </H1>
<P>Load in the various files, call them in the normal vxWorks function
type manner. Here are some examples. Refer to the man pages for further
information. </P>
<P>ld &lt; ntpdate/ntpdate <BR>
ld &lt; ntpd/ntpd <BR>
ld &lt; ntptrace/ntptrace <BR>
ld &lt; ntpq/ntpq <BR>
ld &lt; ntpdc/ntpdc <BR>
ntpdate (&quot;-b&quot;, &quot;192.168.0.245&quot;) <BR>
sp(ntpd, &quot;-c&quot;, &quot;/export/home/casey/ntp/ntp.conf&quot;)
<BR>
ntpdc(&quot;-c&quot;, &quot;monlist&quot;, &quot;192.168.0.244&quot;)
<BR>
ntpq(&quot;-c&quot;, &quot;peers&quot;, &quot;192.168.0.244&quot;) <BR>
ntptrace(&quot;192.168.0.244&quot;) <BR>
</P>
<H1>Bugs and such </H1>
<P>Should you happen across any bugs, please let me know, or better yet
fix them and submit a patch. Remember to make you patch general for Vxworks,
not just for your particular architecture.
<A HREF="http://www.ccii.co.za">CCII Systems
(Pty) Ltd</A>, my ex employers, sponsored the time to this port.
Please let me know how it goes, I would be most interested in offsets
and configurations. </P>
<P><BR>
</P>
<P>Casey Crellin</A> <BR>
<A HREF="mailto:casey@csc.co.za">casey@csc.co.za</A> </P>
<P><BR>
</P>
</BODY>
</HTML>

View File

@ -1,141 +0,0 @@
<html><head<title>
Network Time Protocol Year 2000 Conformance Statement
</title></head><body><h3>
Network Time Protocol Year 2000 Conformance Statement
</h3>
<img align=left src=pic/alice15.gif>
from <i>Alice's Adventures in Wonderland</i>, by Lewis Carroll,
illustrations by Sir John Tenniel
<p>The Mad Hatter and the March Hare are discussing whether the Teapot
serial number should have two or four digits.
<br clear=left><hr>
<h4>Introduction</h4>
By the year 2000, the Network Time Protocol (NTP) will have been in
use for over two decades and remain the longest running, continuously
operating application protocol in the Internet. There is some concern,
especially in government and financial institutions, that NTP might
cause Internet applications to misbehave in terrible ways on the epoch
of the next century. This document presents an analysis of the various
hazards that might result in incorrect time values upon this epoch. It
concludes that incorrect time values due to the NTP timescale, protocol
design and reference implementation are highly unlikely. However, it is
possible that external reference time sources used by NTP could
misbehave and cause NTP servers to distribute incorrect time values to
significant portions of the Internet. Note that, while this document
addresses the issues specifically with respect to Unix systems, the
issues are equally applicable to Windows and VMS systems.
<h4>The NTP Timescale</h4>
It will be helpful in understanding the issues raised in this document
to consider the concept of a universal timescale. The conventional civil
timescale used in most parts of the world is based on Universal
Coordinated Time (UTC sic), formerly known as Greenwich Mean Time (GMT).
UTC is based on International Atomic Time (TAI sic), which is derived
from hundreds of cesium clocks in the national standards laboratories of
many countries. Deviations of UTC from TAI are implemented in the form
of leap seconds, which occur on average every eighteen months. For
almost every computer application today, UTC represents the universal
timescale extending into the indefinite past and indefinite future. We
know of course that the UTC timescale did not exist prior to 1972, the
Gregorian calendar did not exist prior to 1582, the Julian calendar did
not exist prior to 54 BC and we cannot predict exactly when the next
leap second will occur. Nevertheless, most folks would prefer that, even
if we can't get future seconds numbering right beyond the next leap
second, at least we can get the days numbering right until the end of
reason.
<p>The universal timescale can be implemented using a binary counter of
indefinite width and with the unit seconds bit placed somewhere in the
middle. The counter is synchronized to UTC such that it runs at the same
rate and the units increment coincides with the UTC seconds tick. The
NTP timescale is constructed from 64 bits of this counter, of which 32
bits number the seconds and 32 bits represent the fraction. With this
design, the counter runs in 136-year cycles, called eras, the latest of
which began with a counter value of zero at 0h 1 January 1900. The
design assumption is that further low order bits, if required, are
provided by local interpolation, while further high order bits, when
required, are provided by external means. The important point to be made
here is that the high order bits must ultimately be provided by
astronomers and disseminated to the population by international means.
Ultimately, should a need exist to align a particular NTP era to the
current calendar, the operating system in which NTP is embedded must
provide the necessary high order bits, most conveniently from the file
system or flash memory.
<h4>The Year 2000 Era</h4>
With respect to the year 2000 issue, the most important thing to observe
about the NTP timescale is that it knows nothing about days, years or
centuries, only the seconds since the beginning of the latest era, the
current one of which began on 1 January 1900. On 1 January 1970 when
Unix life began, the NTP timescale showed 2,208,988,800 and on 1 January
1972 when UTC life began, it showed 2,272,060,800. On the last second of
year 1999, the NTP timescale will show 3,155,672,599 and one second
later on the first second of the next century will show 3,155,672,600.
Other than this observation, the NTP timescale has no knowledge of or
provision for any of these eclectic seconds.
<p>The NTP timescale is almost never used directly by system or
application programs. The generic Unix kernel keeps time in seconds and
microseconds (or nanoseconds) to provide both time of day and interval
timer functions. In order to synchronize the Unix clock, NTP must
convert to and from its representation and Unix representation. Unix
kernels implement the time of day function using two 32-bit counters,
one representing the seconds since Unix life began and the other the
microseconds or nanoseconds of the second. In principle, the seconds
counter will wrap around in 136-year eras, the next of which will begin
in 2106. How the particular Unix semantics interprets the counter values
is of concern, but is beyond the scope of discussion here.
<p>While incorrect time values due to the NTP timescale and protocol
design or reference implementation upon the epoch of the next century
are highly unlikely, hazards remain due to incorrect software external
to NTP. These hazards include the Unix kernel and library routines which
convert Unix time to and from conventional civil time in seconds,
minutes, hours, days and years. Although NTP uses these routines to
format monitoring data displays, they are not used to read or set the
NTP clock. They may in fact cause problems with certain application
programs, but this is not an issue which concerns NTP correctness.
<p>While it is extremely unlikely that NTP will produce incorrect time
values upon the epoch, it is possible that some external source to which
NTP synchronizes may produce a discontinuity which could then induce a
NTP discontinuity. The NTP primary (stratum 1) time servers, which are
the ultimate time references for the entire NTP population, obtain time
from various sources, including radio and satellite receivers and
telephone modems. Not all sources provide year information and not all
of these provide time in four-digit form. In point of fact, the NTP
reference implementation does not use the year information, even if
available. Instead, the year information is provided from the file
system, which itself depends on the Unix clock.
<p>The NTP protocol specification requires the apparent NTP time derived
from external servers to be compared to the file system time before the
clock is set. If the discrepancy is over 1000 seconds, an error alarm is
raised requiring manual intervention. This makes it very unlikely that
even a clique of seriously corrupted NTP servers will result in
incorrect time values. In the case of embedded computers with no file
system, the design assumption is that the current era be established
from flash memory or a clock chip previously set by manual means.
<p>It is essential that any clock synchronization protocol, including
NTP, include provisions for multiple-server redundancy and multiple-
route diversity. Past experience has demonstrated the wisdom of this
approach, which protects clients against hardware and software faults,
as well as incorrectly operating reference sources and sometimes even
buggy software. For the most reliable service, we recommend multiple
reference sources for primary servers, including a backup radio or
satellite receiver or telephone modem. We also recommend that primary
servers run NTP with other primary servers to provide additional
redundancy and mutual backup should the reference sources themselves
fail or operate incorrectly.
<hr><a href=index.htm><img align=left src=pic/home.gif></a><address><a
href=mailto:mills@udel.edu> David L. Mills &lt;mills@udel.edu&gt;</a>
</address></a></body></html>

View File

@ -1,34 +0,0 @@
/*
* mexit - Used to exit the NTPD daemon
*
*/
#ifdef SYS_WINNT
#include <stdio.h>
#include <windows.h>
HANDLE hServDoneEvent = NULL;
void
service_exit(
int status
)
{
extern int debug;
if (debug) /* did not become a service, simply exit */
ExitThread((DWORD)status);
else {
/* service mode, need to have the service_main routine
* register with the service control manager that the
* service has stopped running, before exiting
*/
if ((status > 0) && (hServDoneEvent != NULL))
SetEvent(hServDoneEvent);
ExitThread((DWORD)status);
}
}
#else /* not SYS_WINNT */
int mexit_bs;
#endif /* not SYS_WINNT */

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_computime.c,v 4.2 1998/07/11 10:05:27 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 09:58:27 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_computime.c"
/*
* kclk_computime.c,v
* Revision 4.2 1998/07/11 10:05:27 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:09:27 kardel
* hack to compile the source for kernel/user-land
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_dcf7000.c,v 4.2 1998/07/11 10:05:27 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 09:59:11 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_dcf7000.c"
/*
* kclk_dcf7000.c,v
* Revision 4.2 1998/07/11 10:05:27 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:09:28 kardel
* hack to compile the source for kernel/user-land
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_hopf6021.c,v 4.2 1998/07/11 10:05:28 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 09:59:57 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_hopf6021.c"
/*
* kclk_hopf6021.c,v
* Revision 4.2 1998/07/11 10:05:28 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:09:29 kardel
* hack to compile the source for kernel/user-land
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_meinberg.c,v 4.2 1998/07/11 10:05:28 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:00:28 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_meinberg.c"
/*
* kclk_meinberg.c,v
* Revision 4.2 1998/07/11 10:05:28 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:09:29 kardel
* hack to compile the source for kernel/user-land
*/

View File

@ -1,15 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_rawdcf.c,v 4.1 1998/06/13 12:07:55 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:03:35 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_rawdcf.c"
/*
* kclk_rawdcf.c,v
* Revision 4.1 1998/06/13 12:07:55 kardel
* standard format
*
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_rcc8000.c,v 4.2 1998/07/11 10:05:28 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:01:11 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_rcc8000.c"
/*
* kclk_rcc8000.c,v
* Revision 4.2 1998/07/11 10:05:28 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:09:29 kardel
* hack to compile the source for kernel/user-land
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_schmid.c,v 4.2 1998/07/11 10:05:28 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:01:42 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_schmid.c"
/*
* kclk_schmid.c,v
* Revision 4.2 1998/07/11 10:05:28 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:09:30 kardel
* hack to compile the source for kernel/user-land
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_trimtaip.c,v 4.2 1998/07/11 10:05:29 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:02:35 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_trimtaip.c"
/*
* kclk_trimtaip.c,v
* Revision 4.2 1998/07/11 10:05:29 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:09:30 kardel
* hack to compile the source for kernel/user-land
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_trimtsip.c,v 4.2 1998/07/11 10:05:29 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:04:12 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_trimtsip.c"
/*
* kclk_trimtsip.c,v
* Revision 4.2 1998/07/11 10:05:29 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:08:02 kardel
* standard format
*/

View File

@ -1,28 +0,0 @@
/*
* $Header: /cvs/ntp/libparse/kclk_varitext.c,v 1.1 1999/07/25 09:21:16 stenn Exp $
*
* $Created: Sat Jun 13 09:58:27 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_varitext.c"
/*
* $Log: kclk_varitext.c,v $
* Revision 1.1 1999/07/25 09:21:16 stenn
* * configure.in: 4.0.94b
*
* * acconfig.h:
* * configure.in:
* * libparse/Makefile.am:
* * libparse/parse_conf.c:
* * libparse/clk_varitext.c:
* * libparse/kclk_varitext.c:
* * ntpd/refclock_parse.c: VARITEXT parse clock
* * ntpdate/ntpdate.c: bugfix
* From: Tony McConnell <tonym@datel-technology.co.uk>
*
* Revision 4.1 1998/06/13 12:09:27 kardel
* hack to compile the source for kernel/user-land
*
*/

View File

@ -1,15 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kclk_wharton.c,v 4.1 1999/02/28 15:50:08 kardel RELEASE_19990228_A
*
* $Created: Sun Feb 28 16:46:14 MET 1999 $
*
* Copyright (C) 1999 by Frank Kardel
*/
#define PARSESTREAM
#include "clk_wharton.c"
/*
* kclk_wharton.c,v
* Revision 4.1 1999/02/28 15:50:08 kardel
* new clock input machine
*
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kparse.c,v 4.2 1998/07/11 10:05:29 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:04:47 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "parse.c"
/*
* kparse.c,v
* Revision 4.2 1998/07/11 10:05:29 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:08:12 kardel
* standard format
*/

View File

@ -1,17 +0,0 @@
/*
* /src/NTP/ntp-4/libparse/kparse_conf.c,v 4.2 1998/07/11 10:05:30 kardel RELEASE_19990228_A
*
* $Created: Sat Jun 13 10:05:32 1998 $
*
* Copyright (C) 1998 by Frank Kardel
*/
#define PARSESTREAM
#include "parse_conf.c"
/*
* kparse_conf.c,v
* Revision 4.2 1998/07/11 10:05:30 kardel
* Release 4.0.73d reconcilation
*
* Revision 4.1 1998/06/13 12:08:12 kardel
* standard format
*/

View File

@ -1,987 +0,0 @@
/*
** Ancestor was ripped off from ../ntpres/ntpres.c by Greg Troxel 4/2/92
**
** The previous resolver only needed to do forward lookups, and all names
** were known before we started the resolver process.
**
** The new code must be able to handle reverse lookups, and the requests can
** show up at any time.
**
** Here's the drill for the new logic.
**
** We want to be able to do forward or reverse lookups. Forward lookups
** require one set of information to be sent back to the daemon, reverse
** lookups require a different set of information. The caller knows this.
**
** The daemon must not block. This includes communicating with the resolver
** process (if the resolver process is a separate task).
**
** Current resolver code blocks waiting for the response, so the
** alternatives are:
**
** - Find a nonblocking resolver library
** - Do each (initial) lookup in a separate process
** - - subsequent lookups *could* be handled by a different process that has
** a queue of pending requests
**
** We could use nonblocking lookups in a separate process (just to help out
** with timers).
**
** If we don't have nonblocking resolver calls we have more opportunities
** for denial-of-service problems.
**
** - too many fork()s
** - communications path
**
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_request.h"
#include "ntp_stdlib.h"
#include "ntp_syslog.h"
#include <stdio.h>
#include <ctype.h>
#include <netdb.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
/*
* Each item we are to resolve and configure gets one of these
* structures defined for it.
*/
struct dns_entry {
int de_done;
#define DE_NAME 001
#define DE_ADDR 002
#define DE_NA (DE_NAME | DE_ADDR)
#define DE_PENDING 000
#define DE_GOT 010
#define DE_FAIL 020
#define DE_RESULT (DE_PENDING | DE_GOT | DE_FAIL)
struct dns_entry *de_next;
struct info_dns_assoc de_info; /* DNS info for peer */
};
#define de_associd de_info.associd
#define de_peeraddr de_info.peeraddr
#define de_hostname de_info.hostname
/*
* dns_entries is a pointer to the list of configuration entries
* we have left to do.
*/
static struct dns_entry *dns_entries = NULL;
/*
* We take an interrupt every thirty seconds, at which time we decrement
* config_timer and resolve_timer. The former is set to 2, so we retry
* unsucessful reconfigurations every minute. The latter is set to
* an exponentially increasing value which starts at 2 and increases to
* 32. When this expires we retry failed name resolutions.
*
* We sleep SLEEPTIME seconds before doing anything, to give the server
* time to arrange itself.
*/
#define MINRESOLVE 2
#define MAXRESOLVE 32
#define CONFIG_TIME 2
#define ALARM_TIME 30
#define SLEEPTIME 2
static volatile int config_timer = 0;
static volatile int resolve_timer = 0;
static int resolve_value; /* next value of resolve timer */
/*
* Big hack attack
*/
#define LOCALHOST 0x7f000001 /* 127.0.0.1, in hex, of course */
#define SKEWTIME 0x08000000 /* 0.03125 seconds as a l_fp fraction */
/*
* Select time out. Set to 2 seconds. The server is on the local machine,
* after all.
*/
#define TIMEOUT_SEC 2
#define TIMEOUT_USEC 0
/*
* File descriptor for ntp request code.
*/
static int sockfd = -1;
/*
* Pipe descriptors
*/
int p_fd[2] = { -1, -1 };
/* stuff to be filled in by caller */
extern keyid_t req_keyid; /* request keyid */
/* end stuff to be filled in */
void ntp_res P((void));
static RETSIGTYPE bong P((int));
static void checkparent P((void));
static void removeentry P((struct dns_entry *));
static void addentry P((char *, u_int32, u_short));
static void findhostaddr P((struct dns_entry *));
static void openntp P((void));
static int tell_ntpd P((struct info_dns_assoc *));
static void doconfigure P((int));
struct ntp_res_t_pkt { /* Tagged packet: */
void *tag; /* For the caller */
u_int32 paddr; /* IP to look up, or 0 */
char name[NTP_MAXHOSTNAME]; /* Name to look up (if 1st byte is not 0) */
};
struct ntp_res_c_pkt { /* Control packet: */
char name[NTP_MAXHOSTNAME];
u_int32 paddr;
int mode;
int version;
int minpoll;
int maxpoll;
int flags;
int ttl;
keyid_t keyid;
u_char keystr[MAXFILENAME];
};
/*
* ntp_res_name
*/
void
ntp_res_name(
u_int32 paddr, /* Address to resolve */
u_short associd /* Association ID */
)
{
pid_t pid;
/*
* fork.
* - parent returns
* - child stuffs data and calls ntp_res()
*/
for (pid = -1; pid == -1;) {
#ifdef RES_TEST
pid = 0;
#else
pid = fork();
#endif
if (pid == -1) {
msyslog(LOG_ERR, "ntp_res_name: fork() failed: %m");
sleep(2);
}
}
switch (pid) {
case -1: /* Error */
msyslog(LOG_INFO, "ntp_res_name: error...");
/* Can't happen */
break;
case 0: /* Child */
closelog();
kill_asyncio();
(void) signal_no_reset(SIGCHLD, SIG_DFL);
#ifndef LOG_DAEMON
openlog("ntp_res", LOG_PID);
# else /* LOG_DAEMON */
# ifndef LOG_NTP
# define LOG_NTP LOG_DAEMON
# endif
openlog("ntp_res_name", LOG_PID | LOG_NDELAY, LOG_NTP);
#endif
addentry(NULL, paddr, associd);
ntp_res();
break;
default: /* Parent */
/* Nothing to do. (In Real Life, this never happens.) */
return;
}
}
/*
* ntp_res needs;
*
* req_key(???), req_keyid valid
* syslog still open
*/
void
ntp_res(void)
{
#ifdef HAVE_SIGSUSPEND
sigset_t set;
sigemptyset(&set);
#endif /* HAVE_SIGSUSPEND */
#ifdef DEBUG
if (debug) {
msyslog(LOG_INFO, "NTP_RESOLVER running");
}
#endif
/* check out auth stuff */
if (sys_authenticate) {
if (!authistrusted(req_keyid)) {
msyslog(LOG_ERR, "invalid request keyid %08x",
req_keyid );
exit(1);
}
}
/*
* Make a first cut at resolving the bunch
*/
doconfigure(1);
if (dns_entries == NULL) {
if (debug) {
msyslog(LOG_INFO, "NTP_RESOLVER done!");
}
#if defined SYS_WINNT
ExitThread(0); /* Don't want to kill whole NT process */
#else
exit(0); /* done that quick */
#endif
}
/*
* Here we've got some problem children. Set up the timer
* and wait for it.
*/
resolve_value = resolve_timer = MINRESOLVE;
config_timer = CONFIG_TIME;
#ifndef SYS_WINNT
(void) signal_no_reset(SIGALRM, bong);
alarm(ALARM_TIME);
#endif /* SYS_WINNT */
for (;;) {
if (dns_entries == NULL)
exit(0);
checkparent();
if (resolve_timer == 0) {
if (resolve_value < MAXRESOLVE)
resolve_value <<= 1;
resolve_timer = resolve_value;
#ifdef DEBUG
msyslog(LOG_INFO, "resolve_timer: 0->%d", resolve_timer);
#endif
config_timer = CONFIG_TIME;
doconfigure(1);
continue;
} else if (config_timer == 0) {
config_timer = CONFIG_TIME;
#ifdef DEBUG
msyslog(LOG_INFO, "config_timer: 0->%d", config_timer);
#endif
doconfigure(0);
continue;
}
#ifndef SYS_WINNT
/*
* There is a race in here. Is okay, though, since
* all it does is delay things by 30 seconds.
*/
# ifdef HAVE_SIGSUSPEND
sigsuspend(&set);
# else
sigpause(0);
# endif /* HAVE_SIGSUSPEND */
#else
if (config_timer > 0)
config_timer--;
if (resolve_timer > 0)
resolve_timer--;
sleep(ALARM_TIME);
#endif /* SYS_WINNT */
}
}
#ifndef SYS_WINNT
/*
* bong - service and reschedule an alarm() interrupt
*/
static RETSIGTYPE
bong(
int sig
)
{
if (config_timer > 0)
config_timer--;
if (resolve_timer > 0)
resolve_timer--;
alarm(ALARM_TIME);
}
#endif /* SYS_WINNT */
/*
* checkparent - see if our parent process is still running
*
* No need to worry in the Windows NT environment whether the
* main thread is still running, because if it goes
* down it takes the whole process down with it (in
* which case we won't be running this thread either)
* Turn function into NOP;
*/
static void
checkparent(void)
{
#if !defined (SYS_WINNT) && !defined (SYS_VXWORKS)
/*
* If our parent (the server) has died we will have been
* inherited by init. If so, exit.
*/
if (getppid() == 1) {
msyslog(LOG_INFO, "parent died before we finished, exiting");
exit(0);
}
#endif /* SYS_WINNT && SYS_VXWORKS*/
}
/*
* removeentry - we are done with an entry, remove it from the list
*/
static void
removeentry(
struct dns_entry *entry
)
{
register struct dns_entry *de;
de = dns_entries;
if (de == entry) {
dns_entries = de->de_next;
return;
}
while (de != NULL) {
if (de->de_next == entry) {
de->de_next = entry->de_next;
return;
}
de = de->de_next;
}
}
/*
* addentry - add an entry to the configuration list
*/
static void
addentry(
char *name,
u_int32 paddr,
u_short associd
)
{
register struct dns_entry *de;
#ifdef DEBUG
if (debug > 1) {
struct in_addr si;
si.s_addr = paddr;
msyslog(LOG_INFO,
"ntp_res_name: <%s> %s associd %d\n",
(name) ? name : "", inet_ntoa(si), associd);
}
#endif
de = (struct dns_entry *)emalloc(sizeof(struct dns_entry));
if (name) {
strncpy(de->de_hostname, name, sizeof de->de_hostname);
de->de_done = DE_PENDING | DE_ADDR;
} else {
de->de_hostname[0] = 0;
de->de_done = DE_PENDING | DE_NAME;
}
de->de_peeraddr = paddr;
de->de_associd = associd;
de->de_next = NULL;
if (dns_entries == NULL) {
dns_entries = de;
} else {
register struct dns_entry *dep;
for (dep = dns_entries; dep->de_next != NULL;
dep = dep->de_next)
/* nothing */;
dep->de_next = de;
}
}
/*
* findhostaddr - resolve a host name into an address (Or vice-versa)
*
* sets entry->de_done appropriately when we're finished. We're finished if
* we either successfully look up the missing name or address, or if we get a
* "permanent" failure on the lookup.
*
*/
static void
findhostaddr(
struct dns_entry *entry
)
{
struct hostent *hp;
checkparent(); /* make sure our guy is still running */
/*
* The following should never trip - this subroutine isn't
* called if hostname and peeraddr are "filled".
*/
if (entry->de_hostname[0] && entry->de_peeraddr) {
struct in_addr si;
si.s_addr = entry->de_peeraddr;
msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are defined: <%s>/%s: state %#x",
&entry->de_hostname[0], inet_ntoa(si), entry->de_done);
return;
}
/*
* The following should never trip.
*/
if (!entry->de_hostname[0] && !entry->de_peeraddr) {
msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are undefined!");
entry->de_done |= DE_FAIL;
return;
}
if (entry->de_hostname[0]) {
#ifdef DEBUG
if (debug > 2)
msyslog(LOG_INFO, "findhostaddr: Resolving <%s>",
&entry->de_hostname[0]);
#endif /* DEBUG */
hp = gethostbyname(&entry->de_hostname[0]);
} else {
#ifdef DEBUG
if (debug > 2) {
struct in_addr si;
si.s_addr = entry->de_peeraddr;
msyslog(LOG_INFO, "findhostaddr: Resolving %s",
inet_ntoa(si));
}
#endif
hp = gethostbyaddr((const char *)&entry->de_peeraddr,
sizeof entry->de_peeraddr,
AF_INET);
}
if (hp == NULL) {
/*
* Bail if we should TRY_AGAIN.
* Otherwise, we have a permanent failure.
*/
if (h_errno == TRY_AGAIN)
return;
entry->de_done |= DE_FAIL;
} else {
entry->de_done |= DE_GOT;
}
if (entry->de_done & DE_GOT) {
switch (entry->de_done & DE_NA) {
case DE_NAME:
#ifdef DEBUG
if (debug > 2)
msyslog(LOG_INFO,
"findhostaddr: name resolved.");
#endif
/*
* Use the first address. We don't have any way to
* tell preferences and older gethostbyname()
* implementations only return one.
*/
memmove((char *)&(entry->de_peeraddr),
(char *)hp->h_addr,
sizeof(struct in_addr));
break;
case DE_ADDR:
#ifdef DEBUG
if (debug > 2)
msyslog(LOG_INFO,
"findhostaddr: address resolved.");
#endif
strncpy(&entry->de_hostname[0], hp->h_name,
sizeof entry->de_hostname);
break;
default:
msyslog(LOG_ERR, "findhostaddr: Bogus de_done: %#x",
entry->de_done);
break;
}
} else {
#ifdef DEBUG
if (debug > 2) {
struct in_addr si;
const char *hes;
#ifndef HAVE_HSTRERROR
char hnum[20];
switch (h_errno) {
case HOST_NOT_FOUND:
hes = "Authoritive Answer Host not found";
break;
case TRY_AGAIN:
hes = "Non-Authoritative Host not found, or SERVERFAIL";
break;
case NO_RECOVERY:
hes = "Non recoverable errors, FORMERR, REFUSED, NOTIMP";
break;
case NO_DATA:
hes = "Valid name, no data record of requested type";
break;
default:
snprintf(hnum, sizeof hnum, "%d", h_errno);
hes = hnum;
break;
}
#else
hes = hstrerror(h_errno);
#endif
si.s_addr = entry->de_peeraddr;
msyslog(LOG_INFO,
"findhostaddr: Failed resolution on <%s>/%s: %s",
entry->de_hostname, inet_ntoa(si), hes);
}
#endif
/* Send a NAK message back to the daemon */
}
return;
}
/*
* openntp - open a socket to the ntp server
*/
static void
openntp(void)
{
struct sockaddr_in saddr;
if (sockfd >= 0)
return;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
msyslog(LOG_ERR, "socket() failed: %m");
exit(1);
}
memset((char *)&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(NTP_PORT); /* trash */
saddr.sin_addr.s_addr = htonl(LOCALHOST); /* garbage */
/*
* Make the socket non-blocking. We'll wait with select()
*/
#ifndef SYS_WINNT
# if defined(O_NONBLOCK)
if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) {
msyslog(LOG_ERR, "fcntl(O_NONBLOCK) failed: %m");
exit(1);
}
# else
# if defined(FNDELAY)
if (fcntl(sockfd, F_SETFL, FNDELAY) == -1) {
msyslog(LOG_ERR, "fcntl(FNDELAY) failed: %m");
exit(1);
}
# else
# include "Bletch: NEED NON BLOCKING IO"
# endif /* FNDDELAY */
# endif /* O_NONBLOCK */
#else /* SYS_WINNT */
{
int on = 1;
if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) {
msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m");
exit(1); /* Windows NT - set socket in non-blocking mode */
}
}
#endif /* SYS_WINNT */
if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
msyslog(LOG_ERR, "openntp: connect() failed: %m");
exit(1);
}
}
/*
* tell_ntpd: Tell ntpd what we discovered.
*/
static int
tell_ntpd(
struct info_dns_assoc *conf
)
{
fd_set fdset;
struct timeval tvout;
struct req_pkt reqpkt;
l_fp ts;
int n;
#ifdef SYS_WINNT
HANDLE hReadWriteEvent = NULL;
BOOL ret;
DWORD NumberOfBytesWritten, NumberOfBytesRead, dwWait;
OVERLAPPED overlap;
#endif /* SYS_WINNT */
checkparent(); /* make sure our guy is still running */
if (sockfd < 0)
openntp();
#ifdef SYS_WINNT
hReadWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#endif /* SYS_WINNT */
/*
* Try to clear out any previously received traffic so it
* doesn't fool us. Note the socket is nonblocking.
*/
tvout.tv_sec = 0;
tvout.tv_usec = 0;
FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
while (select(sockfd + 1, &fdset, (fd_set *)0, (fd_set *)0, &tvout) >
0) {
recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0);
FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
}
/*
* Make up a request packet with the configuration info
*/
memset((char *)&reqpkt, 0, sizeof(reqpkt));
reqpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0);
reqpkt.auth_seq = AUTH_SEQ(1, 0); /* authenticated, no seq */
reqpkt.implementation = IMPL_XNTPD; /* local implementation */
reqpkt.request = REQ_HOSTNAME_ASSOCID; /* Hostname for associd */
reqpkt.err_nitems = ERR_NITEMS(0, 1); /* one item */
reqpkt.mbz_itemsize = MBZ_ITEMSIZE(sizeof(struct info_dns_assoc));
memmove(reqpkt.data, (char *)conf, sizeof(struct info_dns_assoc));
reqpkt.keyid = htonl(req_keyid);
get_systime(&ts);
L_ADDUF(&ts, SKEWTIME);
HTONL_FP(&ts, &reqpkt.tstamp);
n = 0;
if (sys_authenticate)
n = authencrypt(req_keyid, (u_int32 *)&reqpkt, REQ_LEN_NOMAC);
/*
* Done. Send it.
*/
#ifndef SYS_WINNT
n = send(sockfd, (char *)&reqpkt, (unsigned)(REQ_LEN_NOMAC + n), 0);
if (n < 0) {
msyslog(LOG_ERR, "send to NTP server failed: %m");
return 0; /* maybe should exit */
}
#else
/* In the NT world, documentation seems to indicate that there
* exist _write and _read routines that can be used to do blocking
* I/O on sockets. Problem is these routines require a socket
* handle obtained through the _open_osf_handle C run-time API
* of which there is no explanation in the documentation. We need
* nonblocking write's and read's anyway for our purpose here.
* We're therefore forced to deviate a little bit from the Unix
* model here and use the ReadFile and WriteFile Win32 I/O API's
* on the socket
*/
overlap.Offset = overlap.OffsetHigh = (DWORD)0;
overlap.hEvent = hReadWriteEvent;
ret = WriteFile((HANDLE)sockfd, (char *)&reqpkt, REQ_LEN_NOMAC + n,
(LPDWORD)&NumberOfBytesWritten, (LPOVERLAPPED)&overlap);
if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) {
msyslog(LOG_ERR, "send to NTP server failed: %m");
return 0;
}
dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000);
if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) {
if (dwWait == WAIT_FAILED)
msyslog(LOG_ERR, "WaitForSingleObject failed: %m");
return 0;
}
#endif /* SYS_WINNT */
/*
* Wait for a response. A weakness of the mode 7 protocol used
* is that there is no way to associate a response with a
* particular request, i.e. the response to this configuration
* request is indistinguishable from that to any other. I should
* fix this some day. In any event, the time out is fairly
* pessimistic to make sure that if an answer is coming back
* at all, we get it.
*/
for (;;) {
FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
tvout.tv_sec = TIMEOUT_SEC;
tvout.tv_usec = TIMEOUT_USEC;
n = select(sockfd + 1, &fdset, (fd_set *)0,
(fd_set *)0, &tvout);
if (n < 0)
{
msyslog(LOG_ERR, "select() fails: %m");
return 0;
}
else if (n == 0)
{
if(debug)
msyslog(LOG_INFO, "select() returned 0.");
return 0;
}
#ifndef SYS_WINNT
n = recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0);
if (n <= 0) {
if (n < 0) {
msyslog(LOG_ERR, "recv() fails: %m");
return 0;
}
continue;
}
#else /* Overlapped I/O used on non-blocking sockets on Windows NT */
ret = ReadFile((HANDLE)sockfd, (char *)&reqpkt, (DWORD)REQ_LEN_MAC,
(LPDWORD)&NumberOfBytesRead, (LPOVERLAPPED)&overlap);
if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) {
msyslog(LOG_ERR, "ReadFile() fails: %m");
return 0;
}
dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000);
if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) {
if (dwWait == WAIT_FAILED) {
msyslog(LOG_ERR, "WaitForSingleObject fails: %m");
return 0;
}
continue;
}
n = NumberOfBytesRead;
#endif /* SYS_WINNT */
/*
* Got one. Check through to make sure it is what
* we expect.
*/
if (n < RESP_HEADER_SIZE) {
msyslog(LOG_ERR, "received runt response (%d octets)",
n);
continue;
}
if (!ISRESPONSE(reqpkt.rm_vn_mode)) {
#ifdef DEBUG
if (debug > 1)
msyslog(LOG_INFO, "received non-response packet");
#endif
continue;
}
if (ISMORE(reqpkt.rm_vn_mode)) {
#ifdef DEBUG
if (debug > 1)
msyslog(LOG_INFO, "received fragmented packet");
#endif
continue;
}
if ( ( (INFO_VERSION(reqpkt.rm_vn_mode) < 2)
|| (INFO_VERSION(reqpkt.rm_vn_mode) > NTP_VERSION))
|| INFO_MODE(reqpkt.rm_vn_mode) != MODE_PRIVATE) {
#ifdef DEBUG
if (debug > 1)
msyslog(LOG_INFO,
"version (%d/%d) or mode (%d/%d) incorrect",
INFO_VERSION(reqpkt.rm_vn_mode),
NTP_VERSION,
INFO_MODE(reqpkt.rm_vn_mode),
MODE_PRIVATE);
#endif
continue;
}
if (INFO_SEQ(reqpkt.auth_seq) != 0) {
#ifdef DEBUG
if (debug > 1)
msyslog(LOG_INFO,
"nonzero sequence number (%d)",
INFO_SEQ(reqpkt.auth_seq));
#endif
continue;
}
if (reqpkt.implementation != IMPL_XNTPD ||
reqpkt.request != REQ_HOSTNAME_ASSOCID) {
#ifdef DEBUG
if (debug > 1)
msyslog(LOG_INFO,
"implementation (%d/%d) or request (%d/%d) incorrect",
reqpkt.implementation, IMPL_XNTPD,
reqpkt.request, REQ_HOSTNAME_ASSOCID);
#endif
continue;
}
if (INFO_NITEMS(reqpkt.err_nitems) != 0 ||
INFO_MBZ(reqpkt.mbz_itemsize) != 0 ||
INFO_ITEMSIZE(reqpkt.mbz_itemsize) != 0) {
#ifdef DEBUG
if (debug > 1)
msyslog(LOG_INFO,
"nitems (%d) mbz (%d) or itemsize (%d) nonzero",
INFO_NITEMS(reqpkt.err_nitems),
INFO_MBZ(reqpkt.mbz_itemsize),
INFO_ITEMSIZE(reqpkt.mbz_itemsize));
#endif
continue;
}
n = INFO_ERR(reqpkt.err_nitems);
switch (n) {
case INFO_OKAY:
/* success */
return 1;
case INFO_ERR_IMPL:
msyslog(LOG_ERR,
"server reports implementation mismatch!!");
return 0;
case INFO_ERR_REQ:
msyslog(LOG_ERR,
"server claims configuration request is unknown");
return 0;
case INFO_ERR_FMT:
msyslog(LOG_ERR,
"server indicates a format error occurred(!!)");
return 0;
case INFO_ERR_NODATA:
msyslog(LOG_ERR,
"server indicates no data available (shouldn't happen)");
return 0;
case INFO_ERR_AUTH:
msyslog(LOG_ERR,
"server returns a permission denied error");
return 0;
default:
msyslog(LOG_ERR,
"server returns unknown error code %d", n);
return 0;
}
}
}
/*
* doconfigure - attempt to resolve names/addresses
*/
static void
doconfigure(
int dores
)
{
register struct dns_entry *de;
register struct dns_entry *deremove;
char *done_msg = "";
de = dns_entries;
while (de != NULL) {
#ifdef DEBUG
if (debug > 1) {
struct in_addr si;
si.s_addr = de->de_peeraddr;
msyslog(LOG_INFO,
"doconfigure: name: <%s> peeraddr: %s",
de->de_hostname, inet_ntoa(si));
}
#endif
if (dores && (de->de_hostname[0] == 0 || de->de_peeraddr == 0)) {
findhostaddr(de);
}
switch (de->de_done & DE_RESULT) {
case DE_PENDING:
done_msg = "";
break;
case DE_GOT:
done_msg = "succeeded";
break;
case DE_FAIL:
done_msg = "failed";
break;
default:
done_msg = "(error - shouldn't happen)";
break;
}
if (done_msg[0]) {
/* Send the answer */
if (tell_ntpd(&de->de_info)) {
struct in_addr si;
si.s_addr = de->de_peeraddr;
#ifdef DEBUG
if (debug > 1) {
msyslog(LOG_INFO,
"DNS resolution on <%s>/%s %s",
de->de_hostname, inet_ntoa(si),
done_msg);
}
#endif
deremove = de;
de = deremove->de_next;
removeentry(deremove);
}
} else {
de = de->de_next;
}
}
}

View File

@ -1,38 +0,0 @@
#! /usr/local/bin/perl
#
# drift of 104.8576 -> +1 tick. Base of 10000 ticks.
#
# 970306 HMS Deal with nanoseconds. Fix sign of adjustments.
$df="/etc/ntp.drift";
# Assumes a 100Hz box with "tick" of 10000
# Someday, we might call "tickadj" for better values...
$base=10000; # tick: 1,000,000 / HZ
$cvt=104.8576; # 2 ** 20 / $base
$v1=0.;
$v2="";
if (open(DF, $df))
{
if ($_=<DF>)
{
($v1, $v2) = split;
}
while ($v1 < 0)
{
$v1 += $cvt;
$base--;
}
while ($v1 > $cvt)
{
$v1 -= $cvt;
$base++;
}
}
printf("%.3f (drift)\n", $v1);
printf("%d usec; %d nsec\n", $base, ($base + ($v1/$cvt)) * 1000);

View File

@ -1,79 +0,0 @@
#!/usr/local/bin/perl
#!/usr/local/bin/perl -d
#
# This script compares the time of several machines with the
# time on the local host.
#
# Use or modify it as you wish.
#
# As the original author is only expecting 14 minutes of fame,
# leaving his name attached would be appreciated.
#
# R. Gary Cutbill <rgary@chrysalis.com>
# 21 April 1999
#
$tol=2.0;
$|=1;
print "Time Check";
open(HOSTS,"ypcat hosts.byaddr |"); # get a list of hosts from the yp server.
while ($line=<HOSTS>) { # loop for each host getting the offset compared to localhost
($addr,$host,$aliases)=split(/\s+/,$line,3);
$res=`/usr/local/bin/ntptrace -m 1 -r 1 -t 1 $host`;
print ".";
chop $res;
push (@results,$res);
}
print "\n";
#
# Sort the list of hosts, and print out there offsets
# from the local host.
#
@list=sort appropriately @results;
foreach $i ( @list ) {
@dargs=split(/\s+/,$i);
if ( $dargs[1] eq "\*Timeout\*" ) {
print "$i\n";
chop $dargs[0];
push(@down,$dargs[0]);
} else {
printf "%-25s %7s %3s %6s %10s %5s %8s %8s\n",@dargs;
if ( ( $dargs[4] > $tol ) || ( $dargs[4] < -$tol ) ) {
chop $dargs[0];
push(@toofarout,$dargs[0]); }
}
}
#
# When the above list finishes, hosts that are different by +/- $tol (two seconds)
# are in @toofarout. Hosts that are down are in @down. They are treated the same
# way here, but you might want to do something different depending on your site.
#
# print a set of suggested rsh commands to run on the hosts that
# don't have "good" time. "restartntp" is left as an excersize to the reader.
# I usually use it to kill a running xntpd, ntpdate some server, and the start xntp
# again.
#
print "\nConsider:\n";
foreach $i ( (@down,@toofarout) ) {
print " rsh $i sudo restartntp\n";
}
#
# sort the results from the list. First by stratum, then by time deviation
# Put hosts that didn't respond (timed out) on the bottom.
#
sub appropriately {
@af=split(/\s+/,$a);
@bf=split(/\s+/,$b);
$aba= ($af[4]<0)?-$af[4]:$af[4];
$abb= ($bf[4]<0)?-$bf[4]:$bf[4];
( $af[1] ne $bf[1] ) ? $bf[1] cmp $af[1] :
( ( $af[2] != $bf[2] ) ? ( $bf[2] <=> $af[2] ) :
( ( $aba != $abb ) ? ( $abb <=> $aba ) : ($af[0] cmp $bf[0] ) ) );
}

View File

@ -1,97 +0,0 @@
#! /usr/bin/perl -w
die "perl5 needed\n" unless ($] > 5);
use Getopt::Std;
use vars qw($opt_n);
getopts('d:nt:');
#chop($ncpu = `sysctl -n hw.ncpu`);
#die "Found $ncpu CPUs; can only be run on systems with 1 CPU.\n" if ($ncpu > 1);
$driftfile = "/etc/ntp.drift";
$driftfile = $opt_d if defined($opt_d);
chop($timer = `sysctl -n kern.timecounter.hardware 2> /dev/null`);
$timer =~ tr/\U/\L/;
if ($timer eq '') {
open(DM, "/var/run/dmesg.boot");
while(<DM>) {
# Timecounter "i8254" frequency 1193182 Hz
if (/^Timecounter "(\w+)"\s+/) {
$timer = $1;
last;
}
}
close(DM);
}
$opt_t = $timer if !defined($opt_t);
if ($timer ne '') { # $timer found...
if ($opt_t ne '') { # - and $opt_t found
if ($timer ne $opt_t) { # - - and they differ
warn "You specified a $opt_t timer but I detected a $timer timer.\n";
usage();
exit 1;
} else { # - - and they are the same
;
}
} else { # - but no $opt_t specified; this is OK
;
}
} else { # No $timer found...
if ($opt_t ne '') { # - but $opt_t was specified
$timer = $opt_t; # - - so use it.
} else { # - and neither was $opt_t
warn "I can't tell what timer you have. Please specify one.\n";
usage();
exit 1;
}
}
open(DF, $driftfile) || die "Can't open driftfile ($driftfile): $!\n";
while(<DF>) {
chop;
if (/^(-?\d+\.\d+)(\s\d)?$/) {
$drift = $1;
} else {
die "Bogus value in driftfile $driftfile: <$_>\n";
}
}
close(DF);
print "NTP drift is <$drift>\n";
# Convert from NTP's idea of PPM to a decimal equivalent
$freq_adj = int ( $drift * ( 10 ** 6 / 2 ** 20) );
print "normalized freq_adj is <$freq_adj>\n";
$freq_adj = int ( ( $freq_adj - 1 ) / 2 );
print "Applying freq_adj of <".-$freq_adj.">\n";
$sysctl = "machdep.".$timer."_freq";
chop($mach_freq = `sysctl -n $sysctl`);
print "$sysctl is <$mach_freq>\n";
$n_mach_freq = $mach_freq - $freq_adj;
if (defined($opt_n)) {
print "$sysctl $mach_freq -> $n_mach_freq\n";
} else {
print "i8254: ".`sysctl -w $sysctl=$n_mach_freq`;
}
sub usage {
print STDERR <<EOUsage
Usage: $0 [-d drift_file] [-n] [-t timer]
where "drift_file" defaults to /etc/ntp.drift
and "timer" is usually "tsc" or "i8254"
and "-n" says "don't really change anything, just say what would happen".
EOUsage
}

View File

@ -1,301 +0,0 @@
#!/usr/local/bin/perl -w
#
# $Id: ntpsweep,v 1.3 2000/01/15 07:37:52 stenn Exp $
#
# DISCLAIMER
#
# Copyright (C) 1999,2000 Hans Lambermont and Origin B.V.
#
# 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. This software is supported as is and without
# any express or implied warranties, including, without limitation, the
# implied warranties of merchantability and fitness for a particular
# purpose. The name Origin B.V. must not be used to endorse or promote
# products derived from this software without prior written permission.
#
# Hans Lambermont <Hans.Lambermont@nl.origin-it.com>/<H.Lambermont@chello.nl>
# 14 Jan 2000
require 5.0; # But actually tested on 5.004 ;)
use Getopt::Long; # GetOptions()
use strict;
my $version = 1.3;
(my $program = $0) =~ s%.*/(.+?)(.pl)?$%$1%;
# Hardcoded paths/program names
my $ntpdate = "ntpdate";
my $ntpq = "ntpq";
# no STDOUT buffering
$| = 1;
my ($help, $single_host, $showpeers, $maxlevel, $strip, $askversion);
my $res = GetOptions("help!" => \$help,
"host=s" => \$single_host,
"peers!" => \$showpeers,
"maxlevel=s" => \$maxlevel,
"strip=s" => \$strip,
"version!" => \$askversion);
if ($askversion) {
print("$version\n");
exit 0;
}
if ($help || ((@ARGV != 1) && !$single_host)) {
warn <<EOF;
This is $program, version $version
Copyright (C) 1999,2000 Hans Lambermont and Origin B.V. Disclaimer inside.
Usage:
$program [--help|--peers|--strip <string>|--maxlevel <level>|--version] \\
<file>|[--host <hostname>]
Description:
$program prints per host given in <file> the NTP stratum level, the
clock offset in seconds, the daemon version, the operating system and
the processor. Optionally recursing through all peers.
Options:
--help
Print this short help text and exit.
--version
Print version ($version) and exit.
<file>
Specify hosts file. File format is one hostname or ip number per line.
Lines beginning with # are considered as comment.
--host <hostname>
Speficy a single host, bypassing the need for a hosts file.
--peers
Recursively list all peers a host synchronizes to.
An '= ' before a peer means a loop. Recursion stops here.
--maxlevel <level>
Traverse peers up to this level (4 is a reasonable number).
--strip <string>
Strip <string> from hostnames.
Examples:
$program myhosts.txt --strip .foo.com
$program --host some.host --peers --maxlevel 4
EOF
exit 1;
}
my $hostsfile = shift;
my (@hosts, @known_hosts);
my (%known_host_info, %known_host_peers);
sub read_hosts()
{
local *HOSTS;
open (HOSTS, $hostsfile) ||
die "$program: FATAL: unable to read $hostsfile: $!\n";
while (<HOSTS>) {
next if /^\s*(#|$)/; # comment/empty
chomp;
push(@hosts, $_);
}
close(HOSTS);
}
# translate IP to hostname if possible
sub ip2name {
my($ip) = @_;
my($addr, $name, $aliases, $addrtype, $length, @addrs);
$addr = pack('C4', split(/\./, $ip));
($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr($addr, 2);
if ($name) {
# return lower case name
return("\L$name");
} else {
return($ip);
}
}
# item_in_list($item, @list): returns 1 if $item is in @list, 0 if not
sub item_in_list {
my($item, @list) = @_;
my($i);
foreach $i (@list) {
return 1 if ($item eq $i);
}
return 0;
}
sub scan_host($;$;$) {
my($host, $level, @trace) = @_;
my $stratum = 0;
my $offset = 0;
my $daemonversion = "";
my $system = "";
my $processor = "";
my @peers;
my $known_host = 0;
if (&item_in_list($host, @known_hosts)) {
$known_host = 1;
} else {
# ntpdate part
open(NTPDATE, "$ntpdate -bd $host 2>/dev/null |") ||
die "Cannot open ntpdate pipe: $!\n";
while (<NTPDATE>) {
/^stratum\s+(\d+).*$/ && do {
$stratum = $1;
};
/^offset\s+([0-9.-]+)$/ && do {
$offset = $1;
};
}
close(NTPDATE);
# got answers ? If so, go on.
if ($stratum) {
# ntpq part
my $ntpqparams = "-c 'rv 0 processor,system,daemon_version'";
open(NTPQ, "$ntpq $ntpqparams $host 2>/dev/null |") ||
die "Cannot open ntpq pipe: $!\n";
while (<NTPQ>) {
/daemon_version="(.*)"/ && do {
$daemonversion = $1;
};
/system="([^"]*)"/ && do {
$system = $1;
};
/processor="([^"]*)"/ && do {
$processor = $1;
};
}
close(NTPQ);
# Shorten daemon_version string.
$daemonversion =~ s/(;|Mon|Tue|Wed|Thu|Fri|Sat|Sun).*$//;
$daemonversion =~ s/version=//;
$daemonversion =~ s/(x|)ntpd //;
$daemonversion =~ s/(\(|\))//g;
$daemonversion =~ s/beta/b/;
$daemonversion =~ s/multicast/mc/;
# Shorten system string
$system =~ s/UNIX\///;
$system =~ s/RELEASE/r/;
$system =~ s/CURRENT/c/;
# Shorten processor string
$processor =~ s/unknown//;
}
# got answers ? If so, go on.
if ($daemonversion) {
# ntpq again, find out the peers this time
if ($showpeers) {
my $ntpqparams = "-pn";
open(NTPQ, "$ntpq $ntpqparams $host 2>/dev/null |") ||
die "Cannot open ntpq pipe: $!\n";
while (<NTPQ>) {
/^No association ID's returned$/ && do {
last;
};
/^ remote/ && do {
next;
};
/^==/ && do {
next;
};
/^( |x|\.|-|\+|#|\*|o)([^ ]+)/ && do {
push(@peers, ip2name($2));
next;
};
print "ERROR: $_";
}
close(NTPQ);
}
}
# Add scanned host to known_hosts array
push(@known_hosts, $host);
if ($stratum) {
$known_host_info{$host} = sprintf("%2d %9.3f %-11s %-12s %s",
$stratum, $offset, substr($daemonversion,0,11),
substr($system,0,12), substr($processor,0,9));
} else {
# Stratum level 0 is consider invalid
$known_host_info{$host} = sprintf(" ?");
}
$known_host_peers{$host} = [@peers];
}
if ($stratum || $known_host) { # Valid or known host
my $printhost = ' ' x $level . $host;
# Shorten host string
if ($strip) {
$printhost =~ s/$strip//;
}
# append number of peers in brackets if requested and valid
if ($showpeers && ($known_host_info{$host} ne " ?")) {
$printhost .= " (" . @{$known_host_peers{$host}} . ")";
}
# Finally print complete host line
printf("%-32s %s\n",
substr($printhost,0,32), $known_host_info{$host});
if ($showpeers && (eval($maxlevel ? $level < $maxlevel : 1))) {
my $peer;
push(@trace, $host);
# Loop through peers
foreach $peer (@{$known_host_peers{$host}}) {
if (&item_in_list($peer, @trace)) {
# we've detected a loop !
$printhost = ' ' x ($level + 1) . "= " . $peer;
# Shorten host string
if ($strip) {
$printhost =~ s/$strip//;
}
printf("%-32s %s\n",
substr($printhost,0,32));
} else {
if (substr($peer,0,3) ne "127") {
&scan_host($peer, $level + 1, @trace);
}
}
}
}
} else { # We did not get answers from this host
my $printhost = ' ' x $level . $host;
# Shorten host string
if ($strip) {
$printhost =~ s/$strip//;
}
printf("%-32s ?\n", substr($printhost,0,32));
}
}
sub scan_hosts()
{
my $host;
for $host (@hosts) {
my @trace;
push(@trace, $host);
scan_host($host, 0, @trace);
}
}
# Main program
if ($single_host) {
push(@hosts, $single_host);
} else {
&read_hosts($hostsfile);
}
# Print header
print <<EOF;
Host st offset(s) version system processor
--------------------------------+--+---------+-----------+------------+---------
EOF
&scan_hosts();
exit 0;

View File

@ -1,337 +0,0 @@
#!/usr/bin/perl -w
# $Id: plot_summary.pl,v 1.2 1999/12/02 01:59:05 stenn Exp $
#
# Use Gnuplot to display data in summary files produced by summary.pl.
# This script requires GNUPLOT 3.7!
#
# Copyright (c) 1997, 1999 by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
require 5.003; # "never tested with any other version of Perl"
use strict;
use Time::Local;
use Getopt::Long;
# parse command line
my $summary_dir = "/tmp";
my $identifier = "host " . `hostname`; # origin of these data
chomp $identifier; # remove newline
my $offset_limit = 0.128; # limit of absolute offset
my $output_file = ""; # output file defaults to stdout
my $output_file_number = 1; # numbering of output files
my $gnuplot_terminal = $ENV{DISPLAY} ? "x11" : "dumb";
my $wait_after_plot = 1;
my @peer_list = ();
my %options = ("directory|input-directory=s" => \$summary_dir,
"identifier=s" => \$identifier,
"offset-limit=f" => \$offset_limit,
"output-file=s" => \$output_file,
"peer=s@" => \@peer_list,
"plot-term|gnuplot-term=s" => \$gnuplot_terminal,
"wait-after-plot!" => \$wait_after_plot,
);
if ( !GetOptions(%options) )
{
print STDERR "valid options for $0 are:\n";
my $opt;
foreach $opt (sort(keys %options)) {
print STDERR "\t--$opt\t(default is ";
if ( ref($options{$opt}) eq "ARRAY" ) {
print STDERR join(", ", map { "'$_'" } @{$options{$opt}});
} else {
print STDERR "'${$options{$opt}}'";
}
print STDERR ")\n";
}
print STDERR "\n";
die;
}
chomp $identifier;
die "illegal offset-limit: $offset_limit" unless $offset_limit > 0.0;
$offset_limit *= 1e6; # scale to microseconds
# return the smallest value in the given list
sub min
{
my ($result, @rest) = @_;
map { $result = $_ if ($_ < $result) } @rest;
return($result);
}
# return the largest value in the given list
sub max
{
my ($result, @rest) = @_;
map { $result = $_ if ($_ > $result) } @rest;
return($result);
}
# maybe open alternate output file
sub open_output
{
my $file;
if ($output_file) {
while ( -r ($file = "$output_file$output_file_number") ) {
++$output_file_number;
}
open TOUCH, ">$file" and close TOUCH or die "$file: $!";
print "set output \"$file\"\n";
}
}
# make Gnuplot wait
sub maybe_add_pause
{
print "pause -1 \"Press key to continue...\"\n" if $wait_after_plot;
}
# plot data from loop summary
sub do_loop
{
my $fname = shift;
my $line;
my $out_file = "/tmp/tempdata$$";
my $cmd_file = "/tmp/tempcmd$$";
my ($first_day, $day_out) = ("", 0);
my ($lower_bound, $upper_bound, $rms);
my ($min_offs, $max_offs) = (1e9, -1e9);
my ($min_rms, $max_rms) = (1e9, -1e9);
open INPUT, "$fname" or die "$fname: $!";
open OUTPUT, ">$out_file" or die "$out_file: $!";
my @Fld;
while (<INPUT>) {
chop; # strip record separator
@Fld = split;
if ($#Fld == 0) {
# loops.19960405
$_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/;
m/(\d{4})(\d{2})(\d{2})/;
$line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0);
$line = int $line / 86400; # days relative to 1970
$first_day = "$1-$2-$3 ($line)" unless $day_out;
next;
}
if ($#Fld != 8) {
warn "Illegal number of fields in file $fname, line $.";
next;
}
# loop 216, 856106+/-874041.5, rms 117239.8, freq 67.52+/-10.335, var 4.850
$_ = $Fld[1]; s/,/ /; $line .= " $_";
$_ = $Fld[2]; m:(.+?)\+/-(.+),:;
$lower_bound = $1 - $2;
$upper_bound = $1 + $2;
$line .= "$1 $lower_bound $upper_bound";
$min_offs = min($min_offs, $lower_bound);
$max_offs = max($max_offs, $upper_bound);
$_ = $Fld[4]; s/,/ /; $rms = $_;
$min_rms = min($min_rms, $rms);
$max_rms = max($max_rms, $rms);
$line .= " $rms";
$_ = $Fld[6]; m:(.+?)\+/-(.+),:;
$line .= " $1 " . ($1-$2) . " " . ($1+$2);
$line .= " $Fld[8]";
print OUTPUT "$line\n";
$day_out = 1;
# 9621 216 856106 -17935.5 1730147.5 117239.8 67.52 57.185 77.855 4.850
}
close INPUT;
close OUTPUT or die "close failed on $out_file: $!";
my $ylimit = "[";
if ($min_offs < -$offset_limit) {
$ylimit .= "-$offset_limit";
}
$ylimit .= ":";
if ($max_offs > $offset_limit) {
$ylimit .= "$offset_limit";
}
if ( $ylimit eq "[:" ) {
$ylimit = "";
} else {
$ylimit = "[] $ylimit]";
}
# build command file for GNUplot
open OUTPUT, "> $cmd_file" or die "$cmd_file: $!";
my $oldfh = select OUTPUT;
print "set term $gnuplot_terminal\n";
open_output;
print "set grid\n";
print "set title \"Loop Summary for $identifier: " .
"Daily mean values since $first_day\\n" .
"(Offset limit is $offset_limit microseconds)\"\n";
print "set ylabel \"[us]\"\n";
print "set data style yerrorbars\n";
print "set multiplot\n";
print "set size 1, 0.5\n";
print "set lmargin 8\n";
print "set origin 0, 0.5\n";
print "plot $ylimit \"$out_file\"" .
" using 1:3:4:5 title \"mean offset\", ";
print "\"$out_file\" using 1:(\$3-\$6/2) " .
"title \"(sigma low)\" with lines, ";
print "\"$out_file\" using 1:3 smooth bezier " .
"title \"(Bezier med)\" with lines, ";
print "\"$out_file\" using 1:(\$3+\$6/2) " .
"title \"(sigma high)\" with lines\n";
print "set ylabel \"[ppm]\"\n";
print "set origin 0, 0.0\n";
print "set title\n";
print "set xlabel \"Days relative to 1970\"\n";
print "plot \"$out_file\" using 1:7:8:9 title \"mean frequency\", ";
print "\"$out_file\" using 1:(\$7-\$10/2) " .
"title \"(sigma low)\" with lines, ";
print "\"$out_file\" using 1:7 smooth bezier " .
"title \"(Bezier med)\" with lines, ";
print "\"$out_file\" using 1:(\$7+\$10/2) " .
"title \"(sigma high)\" with lines\n";
print "set nomultiplot\n";
maybe_add_pause;
$ylimit = "[";
if ($min_rms < -$offset_limit) {
$ylimit .= "-$offset_limit";
}
$ylimit .= ":";
if ($max_rms > $offset_limit) {
$ylimit .= "$offset_limit";
}
if ( $ylimit eq "[:" ) {
$ylimit ="";
} else {
$ylimit = "[] $ylimit]";
}
open_output;
print "set title \"Loop Summary for $identifier: " .
"Standard deviation since $first_day\\n" .
"(Offset limit is $offset_limit microseconds)\"\n";
print "set xlabel\n";
print "set ylabel \"[us]\"\n";
print "set origin 0, 0.5\n";
print "set data style linespoints\n";
print "set multiplot\n";
print "plot $ylimit \"$out_file\" using 1:6 title \"Offset\", ";
print "\"$out_file\" using 1:6 smooth bezier " .
"title \"(Bezier)\" with lines\n";
print "set title\n";
print "set origin 0, 0.0\n";
print "set xlabel \"Days relative to 1970\"\n";
print "set ylabel \"[ppm]\"\n";
print "plot \"$out_file\" using 1:10 title \"Frequency\", ";
print "\"$out_file\" using 1:10 smooth bezier " .
"title \"(Bezier)\" with lines\n";
print "set nomultiplot\n";
maybe_add_pause;
close OUTPUT or die "close failed on $cmd_file: $!";
select $oldfh;
print `gnuplot $cmd_file`;
unlink $cmd_file;
unlink $out_file;
}
# plot data form peer summary
sub do_peer
{
my $fname = shift;
my $peer = shift;
my $out_file = "/tmp/tempdata$$";
my $cmd_file = "/tmp/tempcmd$$";
my $line;
my ($first_day, $day_out) = ("", 0);
open INPUT, "$fname" or die "$fname: $!";
open OUTPUT, ">$out_file" or die "$out_file: $!";
my @Fld;
while (<INPUT>) {
chop; # strip record separator
@Fld = split;
if ($#Fld == 0) {
# peers.19960405
$_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/;
m/(\d{4})(\d{2})(\d{2})/ or next;
$line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0);
$line = int $line / 86400; # days relative to 1970
$first_day = "$1-$2-$3 ($line)" unless $day_out;
next;
}
if ($#Fld != 7) {
warn "Illegal number of fields in file $fname, line $.";
next;
}
next if ($Fld[0] ne $peer);
# ident cnt mean rms max delay dist disp
# 127.127.8.1 38 30.972 189.867 1154.607 0.000 879.760 111.037
$Fld[0] = $line;
print OUTPUT join(' ', @Fld) . "\n";
# 9969 38 30.972 189.867 1154.607 0.000 879.760 111.037
$day_out = 1;
}
close INPUT;
close OUTPUT or die "close failed on $out_file: $!";
die "no data found for peer $peer" if !$day_out;
open OUTPUT, "> $cmd_file" or die "$cmd_file: $!";
my $oldfh = select OUTPUT;
print "set term $gnuplot_terminal\n";
open_output;
print "set grid\n";
print "set multiplot\n";
print "set lmargin 8\n";
print "set size 1, 0.34\n";
print "set origin 0, 0.66\n";
print "set title " .
"\"Peer Summary for $peer on $identifier since $first_day\"\n";
print "set data style linespoints\n";
print "set ylabel \"[us]\"\n";
print "plot \"$out_file\" using 1:3 title \"mean offset\", ";
print "\"$out_file\" using 1:3 smooth bezier " .
"title \"(Bezier)\" with lines, ";
print "\"$out_file\" using 1:(\$3-\$7/2) " .
"title \"(sigma low)\" with lines, ";
print "\"$out_file\" using 1:(\$3+\$7/2) " .
"title \"(sigma high)\" with lines\n";
print "set title\n";
print "set origin 0, 0.34\n";
print "set size 1, 0.32\n";
print "set ylabel\n";
print "plot \"$out_file\" using 1:7 title \"dist\", ";
print "\"$out_file\" using 1:7 smooth bezier " .
"title \"(Bezier)\" with lines\n";
print "set origin 0, 0.00\n";
print "set size 1, 0.35\n";
print "set xlabel \"Days relative to 1970\"\n";
print "plot \"$out_file\" using 1:8 title \"disp\", ";
print "\"$out_file\" using 1:8 smooth bezier " .
"title \"(Bezier)\" with lines\n";
print "set nomultiplot\n";
maybe_add_pause;
select $oldfh;
close OUTPUT or die "close failed on $cmd_file: $!";
print `gnuplot $cmd_file`;
unlink $cmd_file;
unlink $out_file;
}
my $loop_summary ="$summary_dir/loop_summary";
my $peer_summary ="$summary_dir/peer_summary";
my $clock_summary="$summary_dir/clock_summary";
do_loop $loop_summary;
map { do_peer $peer_summary, $_ } @peer_list;

File diff suppressed because it is too large Load Diff

View File

@ -1,373 +0,0 @@
#!/usr/bin/perl -w
# $Id: summary.pl,v 1.2 1999/12/02 01:59:07 stenn Exp $
# Perl version of (summary.sh, loop.awk, peer.awk):
# Create summaries from xntpd's loop and peer statistics.
#
# Copyright (c) 1997, 1999 by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
require 5.003; # "never tested with any other version of Perl"
use strict;
use Getopt::Long;
my $log_date_pattern = '[12]\d{3}[01]\d[0-3]\d';
my $statsdir = "/var/log/ntp"; # directory with input files
my $outputdir = "/tmp"; # directory for output files
my $skip_time_steps = 3600.0; # ignore time offsets larger that this
my $startdate = "19700101"; # first data file to use (YYYYMMDD)
my $enddate=`date -u +%Y%m%d`; chomp $enddate; --$enddate;
my $peer_dist_limit = 400.0;
my %options = ("directory|input-directory=s" => \$statsdir,
"output-directory=s" => \$outputdir,
"skip-time-steps:f" => \$skip_time_steps,
"start-date=s" => \$startdate,
"end-date=s" => \$enddate,
"peer-dist-limit=f" => \$peer_dist_limit);
if ( !GetOptions(%options) )
{
print STDERR "valid options for $0 are:\n";
my $opt;
foreach $opt (sort(keys %options)) {
print STDERR "\t--$opt\t(default is ";
if ( ref($options{$opt}) eq "ARRAY" ) {
print STDERR join(", ", map { "'$_'" } @{$options{$opt}});
} else {
print STDERR "'${$options{$opt}}'";
}
print STDERR ")\n";
}
print STDERR "\n";
die;
}
# check possibly current values of options
die "$statsdir: no such directory" unless (-d $statsdir);
die "$outputdir: no such directory" unless (-d $outputdir);
die "$skip_time_steps: skip-time-steps must be positive"
unless ($skip_time_steps >= 0.0);
die "$startdate: invalid start date|$`|$&|$'"
unless ($startdate =~ m/.*$log_date_pattern$/);
die "$enddate: invalid end date"
unless ($enddate =~ m/.*$log_date_pattern$/);
$skip_time_steps = 0.128 if ($skip_time_steps == 0);
sub min
{
my ($result, @rest) = @_;
map { $result = $_ if ($_ < $result) } @rest;
return($result);
}
sub max
{
my ($result, @rest) = @_;
map { $result = $_ if ($_ > $result) } @rest;
return($result);
}
# calculate mean, range, and standard deviation for offset and frequency
sub do_loop
{
my ($directory, $fname, $out_file) = @_;
print "$directory/$fname\n";
open INPUT, "$directory/$fname" or warn "can't open $directory/$fname: $!";
open OUTPUT, ">>$out_file" or die "can't open $out_file: $!";
print OUTPUT "$fname\n";
my ($loop_tmax, $loop_fmax) = (-1e9, -1e9);
my ($loop_tmin, $loop_fmin) = (1e9, 1e9);
my ($loop_time_rms, $loop_freq_rms) = (0, 0);
my $loop_count = 0;
my $loop_time = 0;
my $loop_freq = 0;
my ($freq, $offs);
my @Fld;
while (<INPUT>) {
chop; # strip record separator
@Fld = split;
next if ($#Fld < 4);
#NTPv3: 50529 74356.259 -0.000112 16.1230 8
#NTPv3: day, sec.msec, offset, drift_comp, sys_poll
#NTPv4: 51333 54734.582 0.000001648 16.981964 0.000001094 0.020938 6
#NTPv4: day, sec.msec, offset, drift_comp, sys_error, clock_stabil, sys_poll
if ($Fld[2] > $skip_time_steps || $Fld[2] < -$skip_time_steps) {
warn "ignoring loop offset $Fld[2] (file $fname, line $.)\n";
next
}
$loop_count++;
($offs, $freq) = ($Fld[2], $Fld[3]);
$loop_tmax = max($loop_tmax, $offs);
$loop_tmin = min($loop_tmin, $offs);
$loop_fmax = max($loop_fmax, $freq);
$loop_fmin = min($loop_fmin, $freq);
$loop_time += $offs;
$loop_time_rms += $offs * $offs;
$loop_freq += $freq;
$loop_freq_rms += $freq * $freq;
}
close INPUT;
if ($loop_count > 1) {
$loop_time /= $loop_count;
$loop_time_rms = $loop_time_rms / $loop_count - $loop_time * $loop_time;
if ($loop_time_rms < 0) {
warn "loop_time_rms: $loop_time_rms < 0";
$loop_time_rms = 0;
}
$loop_time_rms = sqrt($loop_time_rms);
$loop_freq /= $loop_count;
$loop_freq_rms = $loop_freq_rms / $loop_count - $loop_freq * $loop_freq;
if ($loop_freq_rms < 0) {
warn "loop_freq_rms: $loop_freq_rms < 0";
$loop_freq_rms = 0;
}
$loop_freq_rms = sqrt($loop_freq_rms);
printf OUTPUT
("loop %d, %.0f+/-%.1f, rms %.1f, freq %.2f+/-%0.3f, var %.3f\n",
$loop_count, ($loop_tmax + $loop_tmin) / 2 * 1e6,
($loop_tmax - $loop_tmin) / 2 * 1e6, $loop_time_rms * 1e6,
($loop_fmax + $loop_fmin) / 2, ($loop_fmax - $loop_fmin) / 2,
$loop_freq_rms);
}
else {
warn "no valid lines in $directory/$fname";
}
close OUTPUT
}
# calculate mean, standard deviation, maximum offset, mean dispersion,
# and maximum distance for each peer
sub do_peer
{
my ($directory, $fname, $out_file) = @_;
print "$directory/$fname\n";
open INPUT, "$directory/$fname" or warn "can't open $directory/$fname: $!";
open OUTPUT, ">>$out_file" or die "can't open $out_file: $!";
print OUTPUT "$fname\n";
# we toss out all distances greater than one second on the assumption the
# peer is in initial acquisition
my ($n, $MAXDISTANCE) = (0, 1.0);
my %peer_time;
my %peer_time_rms;
my %peer_count;
my %peer_delay;
my %peer_disp;
my %peer_dist;
my %peer_ident;
my %peer_tmin;
my %peer_tmax;
my @Fld;
my ($i, $j);
my ($dist, $offs);
while (<INPUT>) {
chop; # strip record separator
@Fld = split;
next if ($#Fld < 6);
#NTPv3: 50529 83316.249 127.127.8.1 9674 0.008628 0.00000 0.00700
#NTPv3: day, sec.msec, addr, status, offset, delay, dispersion
#NTPv4: 51333 56042.037 127.127.8.1 94f5 -0.000014657 0.000000000 0.000000000 0.000013214
#NTPv4: day, sec.msec, addr, status, offset, delay, dispersion, skew
$dist = $Fld[6] + $Fld[5] / 2;
next if ($dist > $MAXDISTANCE);
$offs = $Fld[4];
if ($offs > $skip_time_steps || $offs < -$skip_time_steps) {
warn "ignoring peer offset $offs (file $fname, line $.)\n";
next
}
$i = $n;
for ($j = 0; $j < $n; $j++) {
if ($Fld[2] eq $peer_ident{$j}) {
$i = $j; # peer found
last;
}
}
if ($i == $n) { # add new peer
$peer_ident{$i} = $Fld[2];
$peer_tmax{$i} = $peer_dist{$i} = -1e9;
$peer_tmin{$i} = 1e9;
$peer_time{$i} = $peer_time_rms{$i} = 0;
$peer_delay{$i} = $peer_disp{$i} = 0;
$peer_count{$i} = 0;
$n++;
}
$peer_count{$i}++;
$peer_tmax{$i} = max($peer_tmax{$i}, $offs);
$peer_tmin{$i} = min($peer_tmin{$i}, $offs);
$peer_dist{$i} = max($peer_dist{$i}, $dist);
$peer_time{$i} += $offs;
$peer_time_rms{$i} += $offs * $offs;
$peer_delay{$i} += $Fld[5];
$peer_disp{$i} += $Fld[6];
}
close INPUT;
print OUTPUT
" ident cnt mean rms max delay dist disp\n";
print OUTPUT
"==========================================================================\n";
my @lines = ();
for ($i = 0; $i < $n; $i++) {
next if $peer_count{$i} < 2;
$peer_time{$i} /= $peer_count{$i};
eval { $peer_time_rms{$i} = sqrt($peer_time_rms{$i} / $peer_count{$i} -
$peer_time{$i} * $peer_time{$i}); };
$peer_time_rms{$i} = 0, warn $@ if $@;
$peer_delay{$i} /= $peer_count{$i};
$peer_disp{$i} /= $peer_count{$i};
$peer_tmax{$i} = $peer_tmax{$i} - $peer_time{$i};
$peer_tmin{$i} = $peer_time{$i} - $peer_tmin{$i};
if ($peer_tmin{$i} > $peer_tmax{$i}) { # can this happen at all?
$peer_tmax{$i} = $peer_tmin{$i};
}
push @lines, sprintf
"%-15s %4d %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
$peer_ident{$i}, $peer_count{$i}, $peer_time{$i} * 1e3,
$peer_time_rms{$i} * 1e3, $peer_tmax{$i} * 1e3,
$peer_delay{$i} * 1e3, $peer_dist{$i} * 1e3, $peer_disp{$i} * 1e3;
}
print OUTPUT sort @lines;
close OUTPUT;
}
sub do_clock
{
my ($directory, $fname, $out_file) = @_;
print "$directory/$fname\n";
open INPUT, "$directory/$fname";
open OUTPUT, ">>$out_file" or die "can't open $out_file: $!";
print OUTPUT "$fname\n";
close INPUT;
close OUTPUT;
}
sub peer_summary
{
my $in_file = shift;
my ($i, $j, $n);
my (%peer_ident, %peer_count, %peer_mean, %peer_var, %peer_max);
my (%peer_1, %peer_2, %peer_3, %peer_4);
my $dist;
my $max;
open INPUT, "<$in_file" or die "can't open $in_file: $!";
my @Fld;
$n = 0;
while (<INPUT>) {
chop; # strip record separator
@Fld = split;
next if ($#Fld < 7 || $Fld[0] eq 'ident');
$i = $n;
for ($j = 0; $j < $n; $j++) {
if ($Fld[0] eq $peer_ident{$j}) {
$i = $j;
last; # peer found
}
}
if ($i == $n) { # add new peer
$peer_count{$i} = $peer_mean{$i} = $peer_var{$i} = 0;
$peer_max{$i} = 0;
$peer_1{$i} = $peer_2{$i} = $peer_3{$i} = $peer_4{$i} = 0;
$peer_ident{$i} = $Fld[0];
++$n;
}
$dist = $Fld[6] - $Fld[5] / 2;
if ($dist < $peer_dist_limit) {
$peer_count{$i}++;
$peer_mean{$i} += $Fld[2];
$peer_var{$i} += $Fld[3] * $Fld[3];
$max = $Fld[4];
$peer_max{$i} = max($peer_max{$i}, $max);
if ($max > 1) {
$peer_1{$i}++;
if ($max > 5) {
$peer_2{$i}++;
if ($max > 10) {
$peer_3{$i}++;
if ($max > 50) {
$peer_4{$i}++;
}
}
}
}
}
else {
warn "dist exceeds limit: $dist (file $in_file, line $.)\n";
}
}
close INPUT;
my @lines = ();
print
" host days mean rms max >1 >5 >10 >50\n";
print
"==================================================================\n";
for ($i = 0; $i < $n; $i++) {
next if ($peer_count{$i} < 2);
$peer_mean{$i} /= $peer_count{$i};
eval { $peer_var{$i} = sqrt($peer_var{$i} / $peer_count{$i} -
$peer_mean{$i} * $peer_mean{$i}); };
$peer_var{$i} = 0, warn $@ if $@;
push @lines, sprintf
"%-15s %3d %9.3f% 9.3f %9.3f %3d %3d %3d %3d\n",
$peer_ident{$i}, $peer_count{$i}, $peer_mean{$i}, $peer_var{$i},
$peer_max{$i}, $peer_1{$i}, $peer_2{$i}, $peer_3{$i}, $peer_4{$i};
}
print sort @lines;
}
my $loop_summary="$outputdir/loop_summary";
my $peer_summary="$outputdir/peer_summary";
my $clock_summary="$outputdir/clock_summary";
my (@loopfiles, @peerfiles, @clockfiles);
print STDERR "Creating summaries from $statsdir ($startdate to $enddate)\n";
opendir SDIR, $statsdir or die "directory ${statsdir}: $!";
rewinddir SDIR;
@loopfiles=sort grep /loop.*$log_date_pattern/, readdir SDIR;
rewinddir SDIR;
@peerfiles=sort grep /peer.*$log_date_pattern/, readdir SDIR;
rewinddir SDIR;
@clockfiles=sort grep /clock.*$log_date_pattern/, readdir SDIR;
closedir SDIR;
# remove old summary files
map { unlink $_ if -f $_ } ($loop_summary, $peer_summary, $clock_summary);
my $date;
map {
$date = $_; $date =~ s/.*($log_date_pattern)$/$1/;
if ($date ge $startdate && $date le $enddate) {
do_loop $statsdir, $_, $loop_summary;
}
} @loopfiles;
map {
$date = $_; $date =~ s/.*($log_date_pattern)$/$1/;
if ($date ge $startdate && $date le $enddate) {
do_peer $statsdir, $_, $peer_summary;
}
} @peerfiles;
map {
$date = $_; $date =~ s/.*($log_date_pattern)$/$1/;
if ($date ge $startdate && $date le $enddate) {
do_clock $statsdir, $_, $clock_summary;
}
} @clockfiles;
print STDERR "Creating peer summary with limit $peer_dist_limit\n";
peer_summary $peer_summary if (-f $peer_summary);