diff options
author | roberto <roberto@FreeBSD.org> | 1999-12-09 13:01:21 +0000 |
---|---|---|
committer | roberto <roberto@FreeBSD.org> | 1999-12-09 13:01:21 +0000 |
commit | ef64b99e8412f2273dd2e8b3291c2f78ffc4667f (patch) | |
tree | fc0cfa1aab0ff6b228f511b410733ef4f35d1ead /contrib/ntp/ntptrace | |
download | FreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.zip FreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.tar.gz |
Virgin import of ntpd 4.0.98f
Diffstat (limited to 'contrib/ntp/ntptrace')
-rw-r--r-- | contrib/ntp/ntptrace/Makefile.am | 19 | ||||
-rw-r--r-- | contrib/ntp/ntptrace/Makefile.in | 349 | ||||
-rw-r--r-- | contrib/ntp/ntptrace/README | 7 | ||||
-rw-r--r-- | contrib/ntp/ntptrace/ntptrace.c | 784 | ||||
-rw-r--r-- | contrib/ntp/ntptrace/ntptrace.h | 36 |
5 files changed, 1195 insertions, 0 deletions
diff --git a/contrib/ntp/ntptrace/Makefile.am b/contrib/ntp/ntptrace/Makefile.am new file mode 100644 index 0000000..f7106ec --- /dev/null +++ b/contrib/ntp/ntptrace/Makefile.am @@ -0,0 +1,19 @@ +#AUTOMAKE_OPTIONS = ../util/ansi2knr no-dependencies +AUTOMAKE_OPTIONS = ../util/ansi2knr +bin_PROGRAMS = ntptrace +INCLUDES = -I$(top_srcdir)/include +# LDADD might need RESLIB and ADJLIB +LDADD = version.o ../libntp/libntp.a +DISTCLEANFILES = .version version.c +noinst_HEADERS = ntptrace.h +#EXTRA_DIST = ntptrace.mak README TAGS save +ETAGS_ARGS = Makefile.am + +$(PROGRAMS): $(LDADD) + +../libntp/libntp.a: + cd ../libntp && $(MAKE) + +version.o: $(ntptrace_OBJECTS) ../libntp/libntp.a Makefile + $(top_builddir)/scripts/mkver ntptrace + $(COMPILE) -c version.c diff --git a/contrib/ntp/ntptrace/Makefile.in b/contrib/ntp/ntptrace/Makefile.in new file mode 100644 index 0000000..70d151c --- /dev/null +++ b/contrib/ntp/ntptrace/Makefile.in @@ -0,0 +1,349 @@ +# Makefile.in generated automatically by automake 1.4a from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_FLAG = +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +AMTARFLAGS = @AMTARFLAGS@ +AWK = @AWK@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CHUTEST = @CHUTEST@ +CLKTEST = @CLKTEST@ +CPP = @CPP@ +DCFD = @DCFD@ +LDFLAGS = @LDFLAGS@ +LIBPARSE = @LIBPARSE@ +LIBRSAREF = @LIBRSAREF@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +MAKE_ADJTIMED = @MAKE_ADJTIMED@ +MAKE_CHECK_Y2K = @MAKE_CHECK_Y2K@ +MAKE_LIBPARSE = @MAKE_LIBPARSE@ +MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ +MAKE_LIBRSAREF = @MAKE_LIBRSAREF@ +MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ +MAKE_TICKADJ = @MAKE_TICKADJ@ +PACKAGE = @PACKAGE@ +PATH_SH = @PATH_SH@ +PROPDELAY = @PROPDELAY@ +RANLIB = @RANLIB@ +RSAREF = @RSAREF@ +TESTDCF = @TESTDCF@ +U = @U@ +VERSION = @VERSION@ + +#AUTOMAKE_OPTIONS = ../util/ansi2knr no-dependencies + + +AUTOMAKE_OPTIONS = ../util/ansi2knr +bin_PROGRAMS = ntptrace +INCLUDES = -I$(top_srcdir)/include +# LDADD might need RESLIB and ADJLIB +LDADD = version.o ../libntp/libntp.a +DISTCLEANFILES = .version version.c +noinst_HEADERS = ntptrace.h +#EXTRA_DIST = ntptrace.mak README TAGS save +ETAGS_ARGS = Makefile.am +subdir = ntptrace +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LIBS = @LIBS@ +ANSI2KNR = ../util/ansi2knr +ntptrace_SOURCES = ntptrace.c +ntptrace_OBJECTS = ntptrace$U.o +ntptrace_LDADD = $(LDADD) +ntptrace_DEPENDENCIES = version.o ../libntp/libntp.a +ntptrace_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = ntptrace.c +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = README $(noinst_HEADERS) Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +GZIP_ENV = --best +SOURCES = ntptrace.c +OBJECTS = ntptrace$U.o + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .c .o +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps ntptrace/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(bindir)/$$f; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f="`echo $$p|sed -e 's/$(EXEEXT)$$//' -e '$(transform)' -e 's/$$/$(EXEEXT)/'`"; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done + +.c.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: +../util/ansi2knr: ../util/ansi2knr.o + cd ../util && $(MAKE) $(AM_MAKEFLAGS) ansi2knr + +../util/ansi2knr.o: + cd ../util && $(MAKE) $(AM_MAKEFLAGS) ansi2knr.o + + +mostlyclean-kr: + -rm -f *_.c + +clean-kr: + +distclean-kr: + +maintainer-clean-kr: +ntptrace$U.o: + +ntptrace: $(ntptrace_OBJECTS) $(ntptrace_DEPENDENCIES) + @rm -f ntptrace + $(LINK) $(ntptrace_LDFLAGS) $(ntptrace_OBJECTS) $(ntptrace_LDADD) $(LIBS) +ntptrace_.c: ntptrace.c $(ANSI2KNR) + $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntptrace.c; then echo $(srcdir)/ntptrace.c; else echo ntptrace.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntptrace_.c +ntptrace_.o : $(ANSI2KNR) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + ${AWK:-awk} ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + ${AWK:-awk} ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +ntptrace.o: ntptrace.c ../include/ntp_fp.h ../include/ntp_types.h \ + ../include/ntp_machine.h ../config.h ../include/ntp_proto.h \ + ../include/ntp.h ../include/ntp_io.h ../include/ntp_unixtime.h \ + ntptrace.h ../include/ntp_string.h ../include/ntp_syslog.h \ + ../include/ntp_select.h ../include/ntp_stdlib.h \ + ../include/l_stdlib.h ../include/recvbuff.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-kr mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-compile clean-kr clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-kr \ + distclean-tags distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-kr \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-kr distclean-kr clean-kr \ +maintainer-clean-kr tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all install-strip installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +$(PROGRAMS): $(LDADD) + +../libntp/libntp.a: + cd ../libntp && $(MAKE) + +version.o: $(ntptrace_OBJECTS) ../libntp/libntp.a Makefile + $(top_builddir)/scripts/mkver ntptrace + $(COMPILE) -c version.c + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/ntp/ntptrace/README b/contrib/ntp/ntptrace/README new file mode 100644 index 0000000..523f840 --- /dev/null +++ b/contrib/ntp/ntptrace/README @@ -0,0 +1,7 @@ +README file for directory ./ntptrace of the NTP Version 4 distribution + +This directory contains the sources for the ntptrace utility program. See +the README and RELNOTES files in the parent directory for directions on +how to make and install this program. The current version number of this +program is in the version.c file. + diff --git a/contrib/ntp/ntptrace/ntptrace.c b/contrib/ntp/ntptrace/ntptrace.c new file mode 100644 index 0000000..d7a4140 --- /dev/null +++ b/contrib/ntp/ntptrace/ntptrace.c @@ -0,0 +1,784 @@ +/* + * ntptrace - show the chain from an NTP host leading back to + * its source of time + * + * Jeffrey Mogul DECWRL 13 January 1993 + * + * Inspired by a script written by Glenn Trewitt + * + * Large portions stolen from ntpdate.c + */ +#include <stdio.h> +#include <signal.h> +#include <ctype.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/signal.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/resource.h> + +#if defined(SYS_HPUX) +#include <utmp.h> +#endif + +#include "ntp_fp.h" +#include "ntp.h" +#include "ntp_io.h" +#include "ntp_unixtime.h" +#include "ntptrace.h" +#include "ntp_string.h" +#include "ntp_syslog.h" +#include "ntp_select.h" +#include "ntp_stdlib.h" +#include "recvbuff.h" +/* + * only 16 stratums, so this is more than enough. + */ +int maxhosts = 20; + +/* + * Debugging flag + */ +volatile int debug = 0; + +#ifndef SYS_VXWORKS +int nonames = 0; /* if set, don't print hostnames */ +#else +int nonames = 1; /* if set, don't print hostnames */ +#endif +/* + * Program name. + */ +char *progname; + +/* + * Systemwide parameters and flags + */ +int sys_retries = 5; /* # of retry attempts per server */ +int sys_timeout = 2; /* timeout time, in seconds */ +struct server **sys_servers; /* the server list */ +int sys_numservers = 0; /* number of servers to poll */ +int sys_maxservers = NTP_MAXSTRATUM+1; /* max number of servers to deal with */ +int sys_version = NTP_OLDVERSION; /* version to poll with */ + + +/* + * File descriptor masks etc. for call to select + */ +int fd; +fd_set fdmask; + +/* + * Miscellaneous flags + */ +int verbose = 0; +int always_step = 0; + +int ntptracemain P((int, char **)); +static void DoTrace P((struct server *)); +static void DoTransmit P((struct server *)); +static int DoReceive P((struct server *)); +static int ReceiveBuf P((struct server *, struct recvbuf *)); +static struct server *addserver P((struct in_addr *)); +static struct server *addservbyname P((const char *)); +static void setup_io P((void)); +static void sendpkt P((struct sockaddr_in *, struct pkt *, int)); +static int getipaddr P((const char *, u_int32 *)); +static int decodeipaddr P((const char *, u_int32 *)); +static void printserver P((struct server *, FILE *)); +static void printrefid P((FILE *, struct server *)); + +#ifdef SYS_WINNT +int on = 1; +WORD wVersionRequested; +WSADATA wsaData; + +HANDLE TimerThreadHandle = NULL; /* 1998/06/03 - Used in ntplib/machines.c */ +void timer(void) { ; }; /* 1998/06/03 - Used in ntplib/machines.c */ +#endif /* SYS_WINNT */ + +void +input_handler(l_fp * x) +{ ; +} + +#ifdef NO_MAIN_ALLOWED +CALL(ntptrace,"ntptrace",ntptracemain); +#endif + +/* + * Main program. Initialize us and loop waiting for I/O and/or + * timer expiries. + */ +#ifndef NO_MAIN_ALLOWED +int +main( + int argc, + char *argv[] + ) +{ + return ntptracemain(argc, argv); +} +#endif + +int +ntptracemain( + int argc, + char *argv[] + ) +{ + struct server *firstserver; + int errflg; + int c; + + errflg = 0; + progname = argv[0]; + + /* + * Decode argument list + */ + while ((c = ntp_getopt(argc, argv, "dm:no:r:t:v")) != EOF) + switch (c) { + case 'd': + ++debug; + break; + case 'm': + maxhosts = atoi(ntp_optarg); + break; + case 'n': + nonames = 1; + break; + case 'o': + sys_version = atoi(ntp_optarg); + break; + case 'r': + sys_retries = atoi(ntp_optarg); + if (sys_retries < 1) { + (void)fprintf(stderr, + "%s: retries (%d) too small\n", + progname, sys_retries); + errflg++; + } + break; + case 't': + sys_timeout = atoi(ntp_optarg); + if (sys_timeout < 1) { + (void)fprintf(stderr, + "%s: timeout (%d) too short\n", + progname, sys_timeout); + errflg++; + } + break; + case 'v': + verbose = 1; + break; + case '?': + ++errflg; + break; + default: + break; + } + + if (errflg || (argc - ntp_optind) > 1) { + (void) fprintf(stderr, + "usage: %s [-dnv] [-m maxhosts] [-o version#] [-r retries] [-t timeout] [server]\n", + progname); + exit(2); + } + +#ifdef SYS_WINNT + wVersionRequested = MAKEWORD(1,1); + if (WSAStartup(wVersionRequested, &wsaData)) { + msyslog(LOG_ERR, "No useable winsock.dll: %m"); + exit(1); + } +#endif /* SYS_WINNT */ + + sys_servers = (struct server **) + emalloc(sys_maxservers * sizeof(struct server *)); + + if (debug) { +#ifdef HAVE_SETVBUF + static char buf[BUFSIZ]; + setvbuf(stdout, buf, _IOLBF, BUFSIZ); +#else + setlinebuf(stdout); +#endif + } + + if (debug || verbose) + msyslog(LOG_NOTICE, "%s", Version); + + if ((argc - ntp_optind) == 1) + firstserver = addservbyname(argv[ntp_optind]); + else + firstserver = addservbyname("localhost"); + + if (firstserver == NULL) { + /* a message has already been printed */ + exit(2); + } + + /* + * Initialize the time of day routines and the I/O subsystem + */ + setup_io(); + + DoTrace(firstserver); + +#ifdef SYS_WINNT + WSACleanup(); +#endif + return(0); +} /* main end */ + + +static void +DoTrace( + register struct server *server + ) +{ + int retries = sys_retries; + + if (!verbose) { + if (nonames) + printf("%s: ", ntoa(&server->srcadr)); + else + printf("%s: ", ntohost(&server->srcadr)); + fflush(stdout); + } + while (retries-- > 0) { + DoTransmit(server); + if (DoReceive(server)) + return; + } + if (verbose) { + if (nonames) + printf("%s:\t*Timeout*\n", ntoa(&server->srcadr)); + else + printf("%s:\t*Timeout*\n", ntohost(&server->srcadr)); + } + else + printf("\t*Timeout*\n"); +} + +/* + * Dotransmit - transmit a packet to the given server + */ +static void +DoTransmit( + register struct server *server + ) +{ + struct pkt xpkt; + + if (debug) + printf("DoTransmit(%s)\n", ntoa(&server->srcadr)); + + /* + * Fill in the packet and let 'er rip. + */ + xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, + sys_version, MODE_CLIENT); + xpkt.stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); + xpkt.ppoll = NTP_MINPOLL; + xpkt.precision = NTPTRACE_PRECISION; + xpkt.rootdelay = htonl(NTPTRACE_DISTANCE); + xpkt.rootdispersion = htonl(NTPTRACE_DISP); + xpkt.refid = htonl(NTPTRACE_REFID); + L_CLR(&xpkt.reftime); + L_CLR(&xpkt.org); + L_CLR(&xpkt.rec); + + /* + * just timestamp packet and send it away. + */ + get_systime(&(server->xmt)); + HTONL_FP(&server->xmt, &xpkt.xmt); + sendpkt(&(server->srcadr), &xpkt, LEN_PKT_NOMAC); + + if (debug) + printf("DoTransmit to %s\n", ntoa(&(server->srcadr))); +} + +/* + * DoReceive - attempt to receive a packet from a specific server + */ +static int +DoReceive( + register struct server *server + ) +{ + register int n; + fd_set fds; + struct timeval timeout; + l_fp ts; + register struct recvbuf *rb; + int fromlen; + int status; + + /* + * Loop until we see the packet we want or until we time out + */ + for (;;) { + fds = fdmask; + timeout.tv_sec = sys_timeout; + timeout.tv_usec = 0; + n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0, &timeout); + + if (n == 0) { /* timed out */ + if (debug) + printf("timeout\n"); + return(0); + } + else if (n == -1) { + msyslog(LOG_ERR, "select() error: %m"); + return(0); + } + get_systime(&ts); + + if (free_recvbuffs() == 0) { + msyslog(LOG_ERR, "no buffers"); + exit(1); + } + + rb = get_free_recv_buffer(); + + fromlen = sizeof(struct sockaddr_in); + rb->recv_length = recvfrom(fd, (char *)&rb->recv_pkt, + sizeof(rb->recv_pkt), 0, + (struct sockaddr *)&rb->recv_srcadr, &fromlen); + if (rb->recv_length == -1) { + freerecvbuf(rb); + continue; + } + + /* + * Got one. Mark how and when it got here, + * put it on the full list. + */ + rb->recv_time = ts; + add_full_recv_buffer(rb); + + status = ReceiveBuf(server, rb); + + freerecvbuf(rb); + + return(status); + } +} + +/* + * receive - receive and process an incoming frame + * Return 1 on success, 0 on failure + */ +static int +ReceiveBuf( + struct server *server, + struct recvbuf *rbufp + ) +{ + register struct pkt *rpkt; + register s_fp di; + l_fp t10, t23; + l_fp org; + l_fp rec; + l_fp ci; + struct server *nextserver; + struct in_addr nextia; + + + if (debug) { + printf("ReceiveBuf(%s, ", ntoa(&server->srcadr)); + printf("%s)\n", ntoa(&rbufp->recv_srcadr)); + } + + /* + * Check to see if the packet basically looks like something + * intended for us. + */ + if (rbufp->recv_length < LEN_PKT_NOMAC) { + if (debug) + printf("receive: packet length %d\n", + rbufp->recv_length); + return(0); /* funny length packet */ + } + if (rbufp->recv_srcadr.sin_addr.s_addr != server->srcadr.sin_addr.s_addr) { + if (debug) + printf("receive: wrong server\n"); + return(0); /* funny length packet */ + } + + rpkt = &(rbufp->recv_pkt); + + if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION) { + if (debug) + printf("receive: version %d\n", PKT_VERSION(rpkt->li_vn_mode)); + return(0); + } + if (PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) { + if (debug) + printf("receive: version %d\n", PKT_VERSION(rpkt->li_vn_mode)); + return(0); + } + + if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER + && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) + || rpkt->stratum > NTP_MAXSTRATUM) { + if (debug) + printf("receive: mode %d stratum %d\n", + PKT_MODE(rpkt->li_vn_mode), rpkt->stratum); + return(0); + } + + /* + * Decode the org timestamp and make sure we're getting a response + * to our last request. + */ + NTOHL_FP(&rpkt->org, &org); + if (!L_ISEQU(&org, &server->xmt)) { + if (debug) + printf("receive: pkt.org and peer.xmt differ\n"); + return(0); + } + + /* + * Looks good. Record info from the packet. + */ + + server->leap = PKT_LEAP(rpkt->li_vn_mode); + server->stratum = PKT_TO_STRATUM(rpkt->stratum); + server->precision = rpkt->precision; + server->rootdelay = ntohl(rpkt->rootdelay); + server->rootdispersion = ntohl(rpkt->rootdispersion); + server->refid = rpkt->refid; + NTOHL_FP(&rpkt->reftime, &server->reftime); + NTOHL_FP(&rpkt->rec, &rec); + NTOHL_FP(&rpkt->xmt, &server->org); + + /* + * Make sure the server is at least somewhat sane. If not, try + * again. + */ + if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) { + return(0); + } + + /* + * Calculate the round trip delay (di) and the clock offset (ci). + * We use the equations (reordered from those in the spec): + * + * d = (t2 - t3) - (t1 - t0) + * c = ((t2 - t3) + (t1 - t0)) / 2 + */ + t10 = server->org; /* pkt.xmt == t1 */ + L_SUB(&t10, &rbufp->recv_time); /* recv_time == t0*/ + + t23 = rec; /* pkt.rec == t2 */ + L_SUB(&t23, &org); /* pkt->org == t3 */ + + /* now have (t2 - t3) and (t0 - t1). Calculate (ci) and (di) */ + ci = t10; + L_ADD(&ci, &t23); + L_RSHIFT(&ci); + + /* + * Calculate di in t23 in full precision, then truncate + * to an s_fp. + */ + L_SUB(&t23, &t10); + di = LFPTOFP(&t23); + + server->offset = ci; + server->delay = di; + + printserver(server, stdout); + + /* + * End of recursion if we reach stratum 1 or a local refclock + */ + if ((server->stratum <= 1) || (--maxhosts <= 0) || ((server->refid & 0xff) == 127)) + return(1); + + nextia.s_addr = server->refid; + nextserver = addserver(&nextia); + if (nextserver) + DoTrace(nextserver); + return(1); +} + +/* XXX ELIMINATE addserver (almost) identical to ntpdate.c, ntptrace.c */ +/* + * addserver - Allocate a new structure for server. + * Returns a pointer to that structure. + */ +static struct server * +addserver( + struct in_addr *iap + ) +{ + register struct server *server; + static int toomany = 0; + + if (sys_numservers >= sys_maxservers) { + if (!toomany) { + toomany = 1; + msyslog(LOG_ERR, + "too many servers (> %d) specified, remainder not used", + sys_maxservers); + } + return(NULL); + } + + server = (struct server *)emalloc(sizeof(struct server)); + memset((char *)server, 0, sizeof(struct server)); + + server->srcadr.sin_family = AF_INET; + server->srcadr.sin_addr = *iap; + server->srcadr.sin_port = htons(NTP_PORT); + + sys_servers[sys_numservers++] = server; + + return(server); +} + + +/* + * addservbyname - determine a server's address and allocate a new structure + * for it. Returns a pointer to that structure. + */ +static struct server * +addservbyname( + const char *serv + ) +{ + u_int32 ipaddr; + struct in_addr ia; + + if (!getipaddr(serv, &ipaddr)) { + msyslog(LOG_ERR, "can't find host %s\n", serv); + return(NULL); + } + + ia.s_addr = ipaddr; + return(addserver(&ia)); +} + + +static void +setup_io(void) +{ + /* + * Init buffer free list and stat counters + */ + init_recvbuff(sys_maxservers + 2); + + /* create a datagram (UDP) socket */ + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) +#ifndef SYS_WINNT + < 0 +#else + == INVALID_SOCKET +#endif + ) { + msyslog(LOG_ERR, "socket() failed: %m"); + exit(1); + /*NOTREACHED*/ + } + + FD_ZERO(&fdmask); + FD_SET(fd, &fdmask); +} + + + +/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */ +/* + * sendpkt - send a packet to the specified destination + */ +static void +sendpkt( + struct sockaddr_in *dest, + struct pkt *pkt, + int len + ) +{ + int cc; + + cc = sendto(fd, (char *)pkt, len, 0, (struct sockaddr *)dest, + sizeof(struct sockaddr_in)); + if (cc == -1) { +#ifndef SYS_WINNT + if (errno != EWOULDBLOCK && errno != ENOBUFS) +#else /* SYS_WINNT */ + int iSockErr = WSAGetLastError(); + if (iSockErr != WSAEWOULDBLOCK && iSockErr != WSAENOBUFS) +#endif /* SYS_WINNT */ + msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest)); + } +} + +/* + * getipaddr - given a host name, return its host address + */ +static int +getipaddr( + const char *host, + u_int32 *num + ) +{ + struct hostent *hp; + + if (decodeipaddr(host, num)) { + return 1; + } else if ((hp = gethostbyname(host)) != 0) { + memmove((char *)num, hp->h_addr, sizeof(long)); + return 1; + } + return 0; +} + +/* + * decodeipaddr - return a host address (this is crude, but careful) + */ +static int +decodeipaddr( + const char *num, + u_int32 *ipaddr + ) +{ + register const char *cp; + register char *bp; + register int i; + register int temp; + char buf[80]; /* will core dump on really stupid stuff */ + + cp = num; + *ipaddr = 0; + for (i = 0; i < 4; i++) { + bp = buf; + while (isdigit((int)*cp)) + *bp++ = *cp++; + if (bp == buf) + break; + + if (i < 3) { + if (*cp++ != '.') + break; + } else if (*cp != '\0') + break; + + *bp = '\0'; + temp = atoi(buf); + if (temp > 255) + break; + *ipaddr <<= 8; + *ipaddr += temp; + } + + if (i < 4) + return 0; + *ipaddr = htonl(*ipaddr); + return 1; +} + + +/* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c */ +/* + * printserver - print detail information for a server + */ +static void +printserver( + register struct server *pp, + FILE *fp + ) +{ + u_fp synchdist; + + synchdist = pp->rootdispersion + (pp->rootdelay/2); + + if (!verbose) { + (void) fprintf(fp, "stratum %d, offset %s, synch distance %s", + pp->stratum, lfptoa(&pp->offset, 6), ufptoa(synchdist, 5)); + if (pp->stratum == 1) { + (void) fprintf(fp, ", refid "); + printrefid(fp, pp); + } + (void) fprintf(fp, "\n"); + return; + } + + (void) fprintf(fp, "server %s, port %d\n", ntoa(&pp->srcadr), + ntohs(pp->srcadr.sin_port)); + + (void) fprintf(fp, "stratum %d, precision %d, leap %c%c\n", + pp->stratum, pp->precision, pp->leap & 0x2 ? '1' : '0', + pp->leap & 0x1 ? '1' : '0'); + + (void) fprintf(fp, "refid "); + printrefid(fp, pp); + + (void) fprintf(fp, " delay %s, dispersion %s ", fptoa(pp->delay, 5), + ufptoa(pp->dispersion, 5)); + (void) fprintf(fp, "offset %s\n", lfptoa(&pp->offset, 6)); + (void) fprintf(fp, "rootdelay %s, rootdispersion %s", + ufptoa(pp->rootdelay, 5), ufptoa(pp->rootdispersion, 5)); + (void) fprintf(fp, ", synch dist %s\n", ufptoa(synchdist, 5)); + + (void) fprintf(fp, "reference time: %s\n", + prettydate(&pp->reftime)); + (void) fprintf(fp, "originate timestamp: %s\n", + prettydate(&pp->org)); + (void) fprintf(fp, "transmit timestamp: %s\n", + prettydate(&pp->xmt)); + + (void) fprintf(fp, "\n"); + +} + +static void +printrefid( + FILE *fp, + struct server *pp + ) +{ + char junk[5]; + char *str; + + if (pp->stratum == 1) { + junk[4] = 0; + memmove(junk, (char *)&pp->refid, 4); + str = junk; + (void) fprintf(fp, "'%s'", str); + } else { + if (nonames) { + str = numtoa(pp->refid); + (void) fprintf(fp, "[%s]", str); + } + else { + str = numtohost(pp->refid); + (void) fprintf(fp, "%s", str); + } + } +} + +#if !defined(HAVE_VSPRINTF) +int +vsprintf( + char *str, + const char *fmt, + va_list ap + ) +{ + FILE f; + int len; + + f._flag = _IOWRT+_IOSTRG; + f._ptr = str; + f._cnt = 32767; + len = _doprnt(fmt, ap, &f); + *f._ptr = 0; + return (len); +} +#endif diff --git a/contrib/ntp/ntptrace/ntptrace.h b/contrib/ntp/ntptrace/ntptrace.h new file mode 100644 index 0000000..53cbe01 --- /dev/null +++ b/contrib/ntp/ntptrace/ntptrace.h @@ -0,0 +1,36 @@ +/* + * ntptrace.h - declarations for the ntptrace program + */ + +/* + * The server structure is a much simplified version of the + * peer structure, for ntptrace's use. Since we always send + * in client mode and expect to receive in server mode, this + * leaves only a very limited number of things we need to + * remember about the server. + */ +struct server { + struct sockaddr_in srcadr; /* address of remote host */ + u_char leap; /* leap indicator */ + u_char stratum; /* stratum of remote server */ + s_char precision; /* server's clock precision */ + u_fp rootdelay; /* distance from primary clock */ + u_fp rootdispersion; /* peer clock dispersion */ + u_int32 refid; /* peer reference ID */ + l_fp reftime; /* time of peer's last update */ + l_fp org; /* peer's originate time stamp */ + l_fp xmt; /* transmit time stamp */ + s_fp delay; /* filter estimated delay */ + u_fp dispersion; /* filter estimated dispersion */ + l_fp offset; /* filter estimated clock offset */ +}; + + +/* + * Since ntptrace isn't aware of some of the things that normally get + * put in an NTP packet, we fix some values. + */ +#define NTPTRACE_PRECISION (-6) /* use this precision */ +#define NTPTRACE_DISTANCE FP_SECOND /* distance is 1 sec */ +#define NTPTRACE_DISP FP_SECOND /* so is the dispersion */ +#define NTPTRACE_REFID (0) /* reference ID to use */ |