summaryrefslogtreecommitdiff
path: root/ntpdc
diff options
context:
space:
mode:
authorOllivier Robert <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
committerOllivier Robert <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
commitcce65f439697627afbccf5a67035a957bb4d784a (patch)
tree16d100fbc9dae63888d48b464e471ba0e5065193 /ntpdc
parent8c24a1e0ffd629427f94da1b681600008030c41a (diff)
Notes
Diffstat (limited to 'ntpdc')
-rw-r--r--ntpdc/Makefile.am45
-rw-r--r--ntpdc/Makefile.in508
-rw-r--r--ntpdc/README6
-rw-r--r--ntpdc/layout.std417
-rwxr-xr-xntpdc/nl.pl37
-rw-r--r--ntpdc/nl.pl.in37
-rw-r--r--ntpdc/nl_in.c3
-rw-r--r--ntpdc/ntpdc-layout.c21
-rw-r--r--ntpdc/ntpdc.c1894
-rw-r--r--ntpdc/ntpdc.h64
-rw-r--r--ntpdc/ntpdc_ops.c3012
11 files changed, 6044 insertions, 0 deletions
diff --git a/ntpdc/Makefile.am b/ntpdc/Makefile.am
new file mode 100644
index 0000000000000..f7a4d2afce5c1
--- /dev/null
+++ b/ntpdc/Makefile.am
@@ -0,0 +1,45 @@
+#AUTOMAKE_OPTIONS = ../util/ansi2knr no-dependencies
+AUTOMAKE_OPTIONS = ../util/ansi2knr
+bin_PROGRAMS= ntpdc
+EXTRA_PROGRAMS= ntpdc-layout
+EXTRA_DATA= check-layout
+BUILT_SOURCES= maybe-layout
+INCLUDES= -I$(top_srcdir)/include
+# LDADD might need RESLIB and ADJLIB
+ntpdc_LDADD= version.o ../libntp/libntp.a @READLINE_LIBS@
+# ntpdc-layout doesn't need any additional libraries at all
+ntpdc_layout_LDADD=
+DISTCLEANFILES= .version version.c
+CLEANFILES= check-layout layout.here nl.c ntpdc-layout
+noinst_HEADERS= ntpdc.h
+EXTRA_DIST= nl_in.c nl.pl layout.std
+ETAGS_ARGS= Makefile.am
+
+ntpdc_SOURCES = ntpdc.c ntpdc_ops.c
+
+maybe-layout:
+ @case "${PATH_PERL}" in \
+ /*) ${MAKE} check-layout ;; \
+ esac
+
+ntpdc-layout.o: nl.c
+
+layout.here: ntpdc-layout
+ ./ntpdc-layout > $@
+
+check-layout: ntpdc-layout layout.std layout.here
+ cmp $(srcdir)/layout.std layout.here && echo stamp > $@
+
+$(PROGRAMS): $(LDADD)
+
+../libntp/libntp.a:
+ cd ../libntp && $(MAKE)
+
+version.o: $(ntpdc_OBJECTS) ../libntp/libntp.a Makefile $(top_srcdir)/version
+ env CSET=`cat $(top_srcdir)/version` $(top_builddir)/scripts/mkver ntpdc
+ $(COMPILE) -c version.c
+
+# I ran nl_in.c (attached, to be installed into ntpdc) through
+# $(CC) -E nl_in.c | nl.pl > nl.c
+nl.c: nl_in.c nl.pl
+ $(CC) -E $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(srcdir)/nl_in.c | ./nl.pl > nl.c
diff --git a/ntpdc/Makefile.in b/ntpdc/Makefile.in
new file mode 100644
index 0000000000000..8ad0e0565649a
--- /dev/null
+++ b/ntpdc/Makefile.in
@@ -0,0 +1,508 @@
+# Makefile.in generated by automake 1.7.7 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# 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.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+ARLIB_DIR = @ARLIB_DIR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHUTEST = @CHUTEST@
+CLKTEST = @CLKTEST@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCFD = @DCFD@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EF_LIBS = @EF_LIBS@
+EF_PROGS = @EF_PROGS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCRYPTO = @LCRYPTO@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPARSE = @LIBPARSE@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_ADJTIMED = @MAKE_ADJTIMED@
+MAKE_CHECK_Y2K = @MAKE_CHECK_Y2K@
+MAKE_LIBNTPSIM = @MAKE_LIBNTPSIM@
+MAKE_LIBPARSE = @MAKE_LIBPARSE@
+MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
+MAKE_NTPDSIM = @MAKE_NTPDSIM@
+MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_KEYGEN = @MAKE_NTP_KEYGEN@
+MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
+MAKE_SNTP = @MAKE_SNTP@
+MAKE_TICKADJ = @MAKE_TICKADJ@
+MAKE_TIMETRIM = @MAKE_TIMETRIM@
+OBJEXT = @OBJEXT@
+OPENSSL = @OPENSSL@
+OPENSSL_INC = @OPENSSL_INC@
+OPENSSL_LIB = @OPENSSL_LIB@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PERL = @PATH_PERL@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PATH_SH = @PATH_SH@
+PROPDELAY = @PROPDELAY@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TESTDCF = @TESTDCF@
+U = @U@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+#AUTOMAKE_OPTIONS = ../util/ansi2knr no-dependencies
+AUTOMAKE_OPTIONS = ../util/ansi2knr
+bin_PROGRAMS = ntpdc
+EXTRA_PROGRAMS = ntpdc-layout
+EXTRA_DATA = check-layout
+BUILT_SOURCES = maybe-layout
+INCLUDES = -I$(top_srcdir)/include
+# LDADD might need RESLIB and ADJLIB
+ntpdc_LDADD = version.o ../libntp/libntp.a @READLINE_LIBS@
+# ntpdc-layout doesn't need any additional libraries at all
+ntpdc_layout_LDADD =
+DISTCLEANFILES = .version version.c
+CLEANFILES = check-layout layout.here nl.c ntpdc-layout
+noinst_HEADERS = ntpdc.h
+EXTRA_DIST = nl_in.c nl.pl layout.std
+ETAGS_ARGS = Makefile.am
+
+ntpdc_SOURCES = ntpdc.c ntpdc_ops.c
+subdir = ntpdc
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = nl.pl
+EXTRA_PROGRAMS = ntpdc-layout$(EXEEXT)
+bin_PROGRAMS = ntpdc$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+
+am_ntpdc_OBJECTS = ntpdc$U.$(OBJEXT) ntpdc_ops$U.$(OBJEXT)
+ntpdc_OBJECTS = $(am_ntpdc_OBJECTS)
+ntpdc_DEPENDENCIES = version.o ../libntp/libntp.a
+ntpdc_LDFLAGS =
+ntpdc_layout_SOURCES = ntpdc-layout.c
+ntpdc_layout_OBJECTS = ntpdc-layout$U.$(OBJEXT)
+ntpdc_layout_DEPENDENCIES =
+ntpdc_layout_LDFLAGS =
+
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/ntpdc$U.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/ntpdc-layout$U.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/ntpdc_ops$U.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(ntpdc_SOURCES) ntpdc-layout.c
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.in \
+ Makefile.am nl.pl.in
+SOURCES = $(ntpdc_SOURCES) ntpdc-layout.c
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu ntpdc/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+nl.pl: $(top_builddir)/config.status nl.pl.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+ntpdc$(EXEEXT): $(ntpdc_OBJECTS) $(ntpdc_DEPENDENCIES)
+ @rm -f ntpdc$(EXEEXT)
+ $(LINK) $(ntpdc_LDFLAGS) $(ntpdc_OBJECTS) $(ntpdc_LDADD) $(LIBS)
+ntpdc-layout$(EXEEXT): $(ntpdc_layout_OBJECTS) $(ntpdc_layout_DEPENDENCIES)
+ @rm -f ntpdc-layout$(EXEEXT)
+ $(LINK) $(ntpdc_layout_LDFLAGS) $(ntpdc_layout_OBJECTS) $(ntpdc_layout_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+ANSI2KNR = ../util/ansi2knr
+../util/ansi2knr:
+ cd ../util && $(MAKE) $(AM_MAKEFLAGS) ansi2knr
+
+mostlyclean-kr:
+ -test "$U" = "" || rm -f *_.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntpdc$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntpdc-layout$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntpdc_ops$U.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+ntpdc_.c: ntpdc.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntpdc.c; then echo $(srcdir)/ntpdc.c; else echo ntpdc.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+ntpdc-layout_.c: ntpdc-layout.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntpdc-layout.c; then echo $(srcdir)/ntpdc-layout.c; else echo ntpdc-layout.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+ntpdc_ops_.c: ntpdc_ops.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntpdc_ops.c; then echo $(srcdir)/ntpdc_ops.c; else echo ntpdc_ops.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+ntpdc_.$(OBJEXT) ntpdc-layout_.$(OBJEXT) ntpdc_ops_.$(OBJEXT) : \
+$(ANSI2KNR)
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f $(CONFIG_CLEAN_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic mostlyclean-kr
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am info \
+ info-am install install-am install-binPROGRAMS install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-kr pdf pdf-am ps ps-am tags \
+ uninstall uninstall-am uninstall-binPROGRAMS uninstall-info-am
+
+
+maybe-layout:
+ @case "${PATH_PERL}" in \
+ /*) ${MAKE} check-layout ;; \
+ esac
+
+ntpdc-layout.o: nl.c
+
+layout.here: ntpdc-layout
+ ./ntpdc-layout > $@
+
+check-layout: ntpdc-layout layout.std layout.here
+ cmp $(srcdir)/layout.std layout.here && echo stamp > $@
+
+$(PROGRAMS): $(LDADD)
+
+../libntp/libntp.a:
+ cd ../libntp && $(MAKE)
+
+version.o: $(ntpdc_OBJECTS) ../libntp/libntp.a Makefile $(top_srcdir)/version
+ env CSET=`cat $(top_srcdir)/version` $(top_builddir)/scripts/mkver ntpdc
+ $(COMPILE) -c version.c
+
+# I ran nl_in.c (attached, to be installed into ntpdc) through
+# $(CC) -E nl_in.c | nl.pl > nl.c
+nl.c: nl_in.c nl.pl
+ $(CC) -E $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(srcdir)/nl_in.c | ./nl.pl > nl.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/ntpdc/README b/ntpdc/README
new file mode 100644
index 0000000000000..618e846cd39ff
--- /dev/null
+++ b/ntpdc/README
@@ -0,0 +1,6 @@
+README file for directory ./xntpdc of the NTP Version 4 distribution
+
+This directory contains the sources for the xntpdc 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/ntpdc/layout.std b/ntpdc/layout.std
new file mode 100644
index 0000000000000..0a67b73e6325f
--- /dev/null
+++ b/ntpdc/layout.std
@@ -0,0 +1,417 @@
+sizeof(struct req_pkt) = 212
+offsetof(rm_vn_mode) = 0
+offsetof(auth_seq) = 1
+offsetof(implementation) = 2
+offsetof(request) = 3
+offsetof(err_nitems) = 4
+offsetof(mbz_itemsize) = 6
+offsetof(data) = 8
+offsetof(tstamp) = 184
+offsetof(keyid) = 192
+offsetof(mac) = 196
+
+sizeof(struct req_pkt_tail) = 28
+offsetof(tstamp) = 0
+offsetof(keyid) = 8
+offsetof(mac) = 12
+
+sizeof(struct resp_pkt) = 508
+offsetof(rm_vn_mode) = 0
+offsetof(auth_seq) = 1
+offsetof(implementation) = 2
+offsetof(request) = 3
+offsetof(err_nitems) = 4
+offsetof(mbz_itemsize) = 6
+offsetof(data) = 8
+
+sizeof(struct info_peer_list) = 32
+offsetof(addr) = 0
+offsetof(port) = 4
+offsetof(hmode) = 6
+offsetof(flags) = 7
+offsetof(v6_flag) = 8
+offsetof(unused1) = 12
+offsetof(addr6) = 16
+
+sizeof(struct info_peer_summary) = 72
+offsetof(dstadr) = 0
+offsetof(srcadr) = 4
+offsetof(srcport) = 8
+offsetof(stratum) = 10
+offsetof(hpoll) = 11
+offsetof(ppoll) = 12
+offsetof(reach) = 13
+offsetof(flags) = 14
+offsetof(hmode) = 15
+offsetof(delay) = 16
+offsetof(offset) = 20
+offsetof(dispersion) = 28
+offsetof(v6_flag) = 32
+offsetof(unused1) = 36
+offsetof(dstadr6) = 40
+offsetof(srcadr6) = 56
+
+sizeof(struct info_peer) = 280
+offsetof(dstadr) = 0
+offsetof(srcadr) = 4
+offsetof(srcport) = 8
+offsetof(flags) = 10
+offsetof(leap) = 11
+offsetof(hmode) = 12
+offsetof(pmode) = 13
+offsetof(stratum) = 14
+offsetof(ppoll) = 15
+offsetof(hpoll) = 16
+offsetof(precision) = 17
+offsetof(version) = 18
+offsetof(unused8) = 19
+offsetof(reach) = 20
+offsetof(unreach) = 21
+offsetof(flash) = 22
+offsetof(ttl) = 23
+offsetof(flash2) = 24
+offsetof(associd) = 26
+offsetof(keyid) = 28
+offsetof(pkeyid) = 32
+offsetof(refid) = 36
+offsetof(timer) = 40
+offsetof(rootdelay) = 44
+offsetof(rootdispersion) = 48
+offsetof(reftime) = 52
+offsetof(org) = 60
+offsetof(rec) = 68
+offsetof(xmt) = 76
+offsetof(filtdelay) = 84
+offsetof(filtoffset) = 116
+offsetof(order) = 180
+offsetof(delay) = 188
+offsetof(dispersion) = 192
+offsetof(offset) = 196
+offsetof(selectdisp) = 204
+offsetof(unused1) = 208
+offsetof(unused2) = 212
+offsetof(unused3) = 216
+offsetof(unused4) = 220
+offsetof(unused5) = 224
+offsetof(unused6) = 228
+offsetof(unused7) = 232
+offsetof(estbdelay) = 236
+offsetof(v6_flag) = 240
+offsetof(unused9) = 244
+offsetof(dstadr6) = 248
+offsetof(srcadr6) = 264
+
+sizeof(struct info_peer_stats) = 120
+offsetof(dstadr) = 0
+offsetof(srcadr) = 4
+offsetof(srcport) = 8
+offsetof(flags) = 10
+offsetof(timereset) = 12
+offsetof(timereceived) = 16
+offsetof(timetosend) = 20
+offsetof(timereachable) = 24
+offsetof(sent) = 28
+offsetof(unused1) = 32
+offsetof(processed) = 36
+offsetof(unused2) = 40
+offsetof(badauth) = 44
+offsetof(bogusorg) = 48
+offsetof(oldpkt) = 52
+offsetof(unused3) = 56
+offsetof(unused4) = 60
+offsetof(seldisp) = 64
+offsetof(selbroken) = 68
+offsetof(unused5) = 72
+offsetof(candidate) = 76
+offsetof(unused6) = 77
+offsetof(unused7) = 78
+offsetof(unused8) = 79
+offsetof(v6_flag) = 80
+offsetof(unused9) = 84
+offsetof(dstadr6) = 88
+offsetof(srcadr6) = 104
+
+sizeof(struct info_loop) = 24
+offsetof(last_offset) = 0
+offsetof(drift_comp) = 8
+offsetof(compliance) = 16
+offsetof(watchdog_timer) = 20
+
+sizeof(struct info_sys) = 80
+offsetof(peer) = 0
+offsetof(peer_mode) = 4
+offsetof(leap) = 5
+offsetof(stratum) = 6
+offsetof(precision) = 7
+offsetof(rootdelay) = 8
+offsetof(rootdispersion) = 12
+offsetof(refid) = 16
+offsetof(reftime) = 20
+offsetof(poll) = 28
+offsetof(flags) = 32
+offsetof(unused1) = 33
+offsetof(unused2) = 34
+offsetof(unused3) = 35
+offsetof(bdelay) = 36
+offsetof(frequency) = 40
+offsetof(authdelay) = 44
+offsetof(stability) = 52
+offsetof(v6_flag) = 56
+offsetof(unused4) = 60
+offsetof(peer6) = 64
+
+sizeof(struct info_sys_stats) = 44
+offsetof(timeup) = 0
+offsetof(timereset) = 4
+offsetof(denied) = 8
+offsetof(oldversionpkt) = 12
+offsetof(newversionpkt) = 16
+offsetof(unknownversion) = 20
+offsetof(badlength) = 24
+offsetof(processed) = 28
+offsetof(badauth) = 32
+offsetof(received) = 36
+offsetof(limitrejected) = 40
+
+sizeof(struct old_info_sys_stats) = 40
+offsetof(timeup) = 0
+offsetof(timereset) = 4
+offsetof(denied) = 8
+offsetof(oldversionpkt) = 12
+offsetof(newversionpkt) = 16
+offsetof(unknownversion) = 20
+offsetof(badlength) = 24
+offsetof(processed) = 28
+offsetof(badauth) = 32
+offsetof(wanderhold) = 36
+
+sizeof(struct info_mem_stats) = 148
+offsetof(timereset) = 0
+offsetof(totalpeermem) = 4
+offsetof(freepeermem) = 6
+offsetof(findpeer_calls) = 8
+offsetof(allocations) = 12
+offsetof(demobilizations) = 16
+offsetof(hashcount) = 20
+
+sizeof(struct info_io_stats) = 40
+offsetof(timereset) = 0
+offsetof(totalrecvbufs) = 4
+offsetof(freerecvbufs) = 6
+offsetof(fullrecvbufs) = 8
+offsetof(lowwater) = 10
+offsetof(dropped) = 12
+offsetof(ignored) = 16
+offsetof(received) = 20
+offsetof(sent) = 24
+offsetof(notsent) = 28
+offsetof(interrupts) = 32
+offsetof(int_received) = 36
+
+sizeof(struct info_timer_stats) = 16
+offsetof(timereset) = 0
+offsetof(alarms) = 4
+offsetof(overflows) = 8
+offsetof(xmtcalls) = 12
+
+sizeof(struct old_conf_peer) = 16
+offsetof(peeraddr) = 0
+offsetof(hmode) = 4
+offsetof(version) = 5
+offsetof(minpoll) = 6
+offsetof(maxpoll) = 7
+offsetof(flags) = 8
+offsetof(ttl) = 9
+offsetof(unused) = 10
+offsetof(keyid) = 12
+
+sizeof(struct conf_peer) = 168
+offsetof(peeraddr) = 0
+offsetof(hmode) = 4
+offsetof(version) = 5
+offsetof(minpoll) = 6
+offsetof(maxpoll) = 7
+offsetof(flags) = 8
+offsetof(ttl) = 9
+offsetof(unused1) = 10
+offsetof(keyid) = 12
+offsetof(keystr) = 16
+offsetof(v6_flag) = 144
+offsetof(unused2) = 148
+offsetof(peeraddr6) = 152
+
+sizeof(struct conf_unpeer) = 24
+offsetof(peeraddr) = 0
+offsetof(v6_flag) = 4
+offsetof(peeraddr6) = 8
+
+sizeof(struct conf_sys_flags) = 4
+offsetof(flags) = 0
+
+sizeof(struct info_restrict) = 56
+offsetof(addr) = 0
+offsetof(mask) = 4
+offsetof(count) = 8
+offsetof(flags) = 12
+offsetof(mflags) = 14
+offsetof(v6_flag) = 16
+offsetof(unused1) = 20
+offsetof(addr6) = 24
+offsetof(mask6) = 40
+
+sizeof(struct conf_restrict) = 48
+offsetof(addr) = 0
+offsetof(mask) = 4
+offsetof(flags) = 8
+offsetof(mflags) = 10
+offsetof(v6_flag) = 12
+offsetof(addr6) = 16
+offsetof(mask6) = 32
+
+sizeof(struct info_monitor_1) = 72
+offsetof(lasttime) = 0
+offsetof(firsttime) = 4
+offsetof(lastdrop) = 8
+offsetof(count) = 12
+offsetof(addr) = 16
+offsetof(daddr) = 20
+offsetof(flags) = 24
+offsetof(port) = 28
+offsetof(mode) = 30
+offsetof(version) = 31
+offsetof(v6_flag) = 32
+offsetof(unused1) = 36
+offsetof(addr6) = 40
+offsetof(daddr6) = 56
+
+sizeof(struct info_monitor) = 48
+offsetof(lasttime) = 0
+offsetof(firsttime) = 4
+offsetof(lastdrop) = 8
+offsetof(count) = 12
+offsetof(addr) = 16
+offsetof(port) = 20
+offsetof(mode) = 22
+offsetof(version) = 23
+offsetof(v6_flag) = 24
+offsetof(unused1) = 28
+offsetof(addr6) = 32
+
+sizeof(struct old_info_monitor) = 40
+offsetof(lasttime) = 0
+offsetof(firsttime) = 4
+offsetof(count) = 8
+offsetof(addr) = 12
+offsetof(port) = 16
+offsetof(mode) = 18
+offsetof(version) = 19
+offsetof(v6_flag) = 20
+offsetof(addr6) = 24
+
+sizeof(struct reset_flags) = 4
+offsetof(flags) = 0
+
+sizeof(struct info_auth) = 36
+offsetof(timereset) = 0
+offsetof(numkeys) = 4
+offsetof(numfreekeys) = 8
+offsetof(keylookups) = 12
+offsetof(keynotfound) = 16
+offsetof(encryptions) = 20
+offsetof(decryptions) = 24
+offsetof(expired) = 28
+offsetof(keyuncached) = 32
+
+sizeof(struct info_trap) = 64
+offsetof(local_address) = 0
+offsetof(trap_address) = 4
+offsetof(trap_port) = 8
+offsetof(sequence) = 10
+offsetof(settime) = 12
+offsetof(origtime) = 16
+offsetof(resets) = 20
+offsetof(flags) = 24
+offsetof(v6_flag) = 28
+offsetof(local_address6) = 32
+offsetof(trap_address6) = 48
+
+sizeof(struct conf_trap) = 48
+offsetof(local_address) = 0
+offsetof(trap_address) = 4
+offsetof(trap_port) = 8
+offsetof(unused) = 10
+offsetof(v6_flag) = 12
+offsetof(local_address6) = 16
+offsetof(trap_address6) = 32
+
+sizeof(struct info_control) = 60
+offsetof(ctltimereset) = 0
+offsetof(numctlreq) = 4
+offsetof(numctlbadpkts) = 8
+offsetof(numctlresponses) = 12
+offsetof(numctlfrags) = 16
+offsetof(numctlerrors) = 20
+offsetof(numctltooshort) = 24
+offsetof(numctlinputresp) = 28
+offsetof(numctlinputfrag) = 32
+offsetof(numctlinputerr) = 36
+offsetof(numctlbadoffset) = 40
+offsetof(numctlbadversion) = 44
+offsetof(numctldatatooshort) = 48
+offsetof(numctlbadop) = 52
+offsetof(numasyncmsgs) = 56
+
+sizeof(struct info_clock) = 52
+offsetof(clockadr) = 0
+offsetof(type) = 4
+offsetof(flags) = 5
+offsetof(lastevent) = 6
+offsetof(currentstatus) = 7
+offsetof(polls) = 8
+offsetof(noresponse) = 12
+offsetof(badformat) = 16
+offsetof(baddata) = 20
+offsetof(timestarted) = 24
+offsetof(fudgetime1) = 28
+offsetof(fudgetime2) = 36
+offsetof(fudgeval1) = 44
+offsetof(fudgeval2) = 48
+
+sizeof(struct conf_fudge) = 20
+offsetof(clockadr) = 0
+offsetof(which) = 4
+offsetof(fudgetime) = 8
+offsetof(fudgeval_flags) = 16
+
+sizeof(struct info_clkbug) = 332
+offsetof(clockadr) = 0
+offsetof(nvalues) = 4
+offsetof(ntimes) = 5
+offsetof(svalues) = 6
+offsetof(stimes) = 8
+offsetof(values) = 12
+offsetof(times) = 76
+
+sizeof(struct info_kernel) = 60
+offsetof(offset) = 0
+offsetof(freq) = 4
+offsetof(maxerror) = 8
+offsetof(esterror) = 12
+offsetof(status) = 16
+offsetof(shift) = 18
+offsetof(constant) = 20
+offsetof(precision) = 24
+offsetof(tolerance) = 28
+offsetof(ppsfreq) = 32
+offsetof(jitter) = 36
+offsetof(stabil) = 40
+offsetof(jitcnt) = 44
+offsetof(calcnt) = 48
+offsetof(errcnt) = 52
+offsetof(stbcnt) = 56
+
+sizeof(struct info_dns_assoc) = 32
+offsetof(peeraddr) = 0
+offsetof(associd) = 4
+offsetof(hostname) = 6
+
diff --git a/ntpdc/nl.pl b/ntpdc/nl.pl
new file mode 100755
index 0000000000000..6974fe2996b56
--- /dev/null
+++ b/ntpdc/nl.pl
@@ -0,0 +1,37 @@
+#! /usr/local/bin/perl -w
+
+$found = 0;
+$last = 0;
+$debug = 0;
+
+while (<>) {
+ next if /^#/;
+ next if /^\s*$/;
+ if (/^struct req_pkt/) {
+ $found = 1;
+ }
+ if (/^struct info_dns_assoc/) {
+ $last = 1;
+ }
+ if ($found) {
+ if (/^(struct\s*\w*)\s*{\s*$/) {
+ $type = $1;
+ print STDERR "type = '$type'\n" if $debug;
+ printf " printf(\"sizeof($type) = %%d\\n\", \n\t (int) sizeof($type));\n";
+ next;
+ }
+ if (/\s*\w+\s*(\w*)(\[.*\])?\s*;\s*$/) {
+ $field = $1;
+ print STDERR "\tfield = '$field'\n" if $debug;
+ printf " printf(\"offsetof($field) = %%d\\n\", \n\t (int) offsetof($type, $field));\n";
+ next;
+ }
+ if (/^};$/) {
+ printf " printf(\"\\n\");\n\n";
+ $found = 0 if $last;
+ next;
+ }
+ print STDERR "Unmatched line: $_";
+ exit 1;
+ }
+}
diff --git a/ntpdc/nl.pl.in b/ntpdc/nl.pl.in
new file mode 100644
index 0000000000000..dfa79c26abf2e
--- /dev/null
+++ b/ntpdc/nl.pl.in
@@ -0,0 +1,37 @@
+#! @PATH_PERL@ -w
+
+$found = 0;
+$last = 0;
+$debug = 0;
+
+while (<>) {
+ next if /^#/;
+ next if /^\s*$/;
+ if (/^struct req_pkt/) {
+ $found = 1;
+ }
+ if (/^struct info_dns_assoc/) {
+ $last = 1;
+ }
+ if ($found) {
+ if (/^(struct\s*\w*)\s*{\s*$/) {
+ $type = $1;
+ print STDERR "type = '$type'\n" if $debug;
+ printf " printf(\"sizeof($type) = %%d\\n\", \n\t (int) sizeof($type));\n";
+ next;
+ }
+ if (/\s*\w+\s*(\w*)(\[.*\])?\s*;\s*$/) {
+ $field = $1;
+ print STDERR "\tfield = '$field'\n" if $debug;
+ printf " printf(\"offsetof($field) = %%d\\n\", \n\t (int) offsetof($type, $field));\n";
+ next;
+ }
+ if (/^};$/) {
+ printf " printf(\"\\n\");\n\n";
+ $found = 0 if $last;
+ next;
+ }
+ print STDERR "Unmatched line: $_";
+ exit 1;
+ }
+}
diff --git a/ntpdc/nl_in.c b/ntpdc/nl_in.c
new file mode 100644
index 0000000000000..3df8c7880b280
--- /dev/null
+++ b/ntpdc/nl_in.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#include "ntpdc.h"
+#include "ntp_request.h"
diff --git a/ntpdc/ntpdc-layout.c b/ntpdc/ntpdc-layout.c
new file mode 100644
index 0000000000000..b05fbf3848e7f
--- /dev/null
+++ b/ntpdc/ntpdc-layout.c
@@ -0,0 +1,21 @@
+/*
+ * ntpdc-layout - print layout of NTP mode 7 request/response packets
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+
+#include "ntpdc.h"
+#include "ntp_stdlib.h"
+
+#if defined(IMPL_XNTPD_OLD) && IMPL_XNTPD != 3
+#error Unexpected IMPL_XNTPD
+#endif
+
+int
+main(void)
+{
+#include "nl.c"
+
+ return (EXIT_SUCCESS);
+}
diff --git a/ntpdc/ntpdc.c b/ntpdc/ntpdc.c
new file mode 100644
index 0000000000000..aa4f188a603a7
--- /dev/null
+++ b/ntpdc/ntpdc.c
@@ -0,0 +1,1894 @@
+/*
+ * ntpdc - control and monitor your ntpd daemon
+ */
+
+#include <stdio.h>
+
+#include "ntpdc.h"
+#include "ntp_select.h"
+#include "ntp_io.h"
+#include "ntp_stdlib.h"
+/* Don't include ISC's version of IPv6 variables and structures */
+#define ISC_IPV6_H 1
+#include "isc/net.h"
+#include "isc/result.h"
+
+#include <ctype.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <netdb.h>
+
+#ifdef SYS_WINNT
+# include <io.h>
+#else
+# define closesocket close
+#endif /* SYS_WINNT */
+
+#if defined(HAVE_LIBREADLINE) || defined (HAVE_LIBEDIT)
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif /* HAVE_LIBREADLINE || HAVE_LIBEDIT */
+
+#ifdef SYS_VXWORKS
+/* vxWorks needs mode flag -casey*/
+#define open(name, flags) open(name, flags, 0777)
+#define SERVER_PORT_NUM 123
+#endif
+
+/*
+ * Because we now potentially understand a lot of commands (and
+ * it requires a lot of commands to talk to ntpd) we will run
+ * interactive if connected to a terminal.
+ */
+static int interactive = 0; /* set to 1 when we should prompt */
+static const char * prompt = "ntpdc> "; /* prompt to ask him about */
+
+/*
+ * Keyid used for authenticated requests. Obtained on the fly.
+ */
+static u_long info_auth_keyid;
+
+/*
+ * Type of key md5
+ */
+#define KEY_TYPE_MD5 4
+
+static int info_auth_keytype = KEY_TYPE_MD5; /* MD5 */
+u_long current_time; /* needed by authkeys; not used */
+
+int ntpdcmain P((int, char **));
+/*
+ * Built in command handler declarations
+ */
+static int openhost P((const char *));
+static int sendpkt P((char *, int));
+static void growpktdata P((void));
+static int getresponse P((int, int, int *, int *, char **, int));
+static int sendrequest P((int, int, int, int, int, char *));
+static void getcmds P((void));
+static RETSIGTYPE abortcmd P((int));
+static void docmd P((const char *));
+static void tokenize P((const char *, char **, int *));
+static int findcmd P((char *, struct xcmd *, struct xcmd *, struct xcmd **));
+static int getarg P((char *, int, arg_v *));
+static int getnetnum P((const char *, struct sockaddr_storage *, char *, int));
+static void help P((struct parse *, FILE *));
+#ifdef QSORT_USES_VOID_P
+static int helpsort P((const void *, const void *));
+#else
+static int helpsort P((char **, char **));
+#endif
+static void printusage P((struct xcmd *, FILE *));
+static void timeout P((struct parse *, FILE *));
+static void my_delay P((struct parse *, FILE *));
+static void host P((struct parse *, FILE *));
+static void keyid P((struct parse *, FILE *));
+static void keytype P((struct parse *, FILE *));
+static void passwd P((struct parse *, FILE *));
+static void hostnames P((struct parse *, FILE *));
+static void setdebug P((struct parse *, FILE *));
+static void quit P((struct parse *, FILE *));
+static void version P((struct parse *, FILE *));
+static void warning P((const char *, const char *, const char *));
+static void error P((const char *, const char *, const char *));
+static u_long getkeyid P((const char *));
+
+
+
+/*
+ * Built-in commands we understand
+ */
+static struct xcmd builtins[] = {
+ { "?", help, { OPT|NTP_STR, NO, NO, NO },
+ { "command", "", "", "" },
+ "tell the use and syntax of commands" },
+ { "help", help, { OPT|NTP_STR, NO, NO, NO },
+ { "command", "", "", "" },
+ "tell the use and syntax of commands" },
+ { "timeout", timeout, { OPT|UINT, NO, NO, NO },
+ { "msec", "", "", "" },
+ "set the primary receive time out" },
+ { "delay", my_delay, { OPT|INT, NO, NO, NO },
+ { "msec", "", "", "" },
+ "set the delay added to encryption time stamps" },
+ { "host", host, { OPT|NTP_STR, OPT|NTP_STR, NO, NO },
+ { "-4|-6", "hostname", "", "" },
+ "specify the host whose NTP server we talk to" },
+ { "passwd", passwd, { OPT|NTP_STR, NO, NO, NO },
+ { "", "", "", "" },
+ "specify a password to use for authenticated requests"},
+ { "hostnames", hostnames, { OPT|NTP_STR, NO, NO, NO },
+ { "yes|no", "", "", "" },
+ "specify whether hostnames or net numbers are printed"},
+ { "debug", setdebug, { OPT|NTP_STR, NO, NO, NO },
+ { "no|more|less", "", "", "" },
+ "set/change debugging level" },
+ { "quit", quit, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "exit ntpdc" },
+ { "exit", quit, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "exit ntpdc" },
+ { "keyid", keyid, { OPT|UINT, NO, NO, NO },
+ { "key#", "", "", "" },
+ "set/show keyid to use for authenticated requests" },
+ { "keytype", keytype, { OPT|NTP_STR, NO, NO, NO },
+ { "(md5|des)", "", "", "" },
+ "set/show key authentication type for authenticated requests (des|md5)" },
+ { "version", version, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "print version number" },
+ { 0, 0, { NO, NO, NO, NO },
+ { "", "", "", "" }, "" }
+};
+
+
+/*
+ * Default values we use.
+ */
+#define DEFTIMEOUT (5) /* 5 second time out */
+#define DEFSTIMEOUT (2) /* 2 second time out after first */
+#define DEFDELAY 0x51EB852 /* 20 milliseconds, l_fp fraction */
+#define DEFHOST "localhost" /* default host name */
+#define LENHOSTNAME 256 /* host name is 256 characters long */
+#define MAXCMDS 100 /* maximum commands on cmd line */
+#define MAXHOSTS 200 /* maximum hosts on cmd line */
+#define MAXLINE 512 /* maximum line length */
+#define MAXTOKENS (1+1+MAXARGS+2) /* maximum number of usable tokens */
+ /* command + -4|-6 + MAXARGS + */
+ /* redirection */
+
+/*
+ * Some variables used and manipulated locally
+ */
+static struct timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */
+static struct timeval tvsout = { DEFSTIMEOUT, 0 }; /* secondary time out */
+static l_fp delay_time; /* delay time */
+static char currenthost[LENHOSTNAME]; /* current host name */
+int showhostnames = 1; /* show host names by default */
+
+static int ai_fam_templ; /* address family */
+static int ai_fam_default; /* default address family */
+static SOCKET sockfd; /* fd socket is opened on */
+static int havehost = 0; /* set to 1 when host open */
+int s_port = 0;
+
+#if defined (SYS_WINNT) || defined (SYS_VXWORKS)
+char password[9];
+#endif /* SYS_WINNT || SYS_VXWORKS */
+
+#ifdef SYS_WINNT
+DWORD NumberOfBytesWritten;
+
+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 */
+
+/*
+ * Holds data returned from queries. We allocate INITDATASIZE
+ * octets to begin with, increasing this as we need to.
+ */
+#define INITDATASIZE (sizeof(struct resp_pkt) * 16)
+#define INCDATASIZE (sizeof(struct resp_pkt) * 8)
+
+static char *pktdata;
+static int pktdatasize;
+
+/*
+ * These are used to help the magic with old and new versions of ntpd.
+ */
+int impl_ver = IMPL_XNTPD;
+static int req_pkt_size = REQ_LEN_NOMAC;
+
+/*
+ * For commands typed on the command line (with the -c option)
+ */
+static int numcmds = 0;
+static const char *ccmds[MAXCMDS];
+#define ADDCMD(cp) if (numcmds < MAXCMDS) ccmds[numcmds++] = (cp)
+
+/*
+ * When multiple hosts are specified.
+ */
+static int numhosts = 0;
+static const char *chosts[MAXHOSTS];
+#define ADDHOST(cp) if (numhosts < MAXHOSTS) chosts[numhosts++] = (cp)
+
+/*
+ * Error codes for internal use
+ */
+#define ERR_INCOMPLETE 16
+#define ERR_TIMEOUT 17
+
+/*
+ * Macro definitions we use
+ */
+#define ISSPACE(c) ((c) == ' ' || (c) == '\t')
+#define ISEOL(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+/*
+ * For converting time stamps to dates
+ */
+#define JAN_1970 2208988800 /* 1970 - 1900 in seconds */
+
+/*
+ * Jump buffer for longjumping back to the command level
+ */
+static jmp_buf interrupt_buf;
+static volatile int jump = 0;
+
+/*
+ * Pointer to current output unit
+ */
+static FILE *current_output;
+
+/*
+ * Command table imported from ntpdc_ops.c
+ */
+extern struct xcmd opcmds[];
+
+char *progname;
+volatile int debug;
+
+#ifdef NO_MAIN_ALLOWED
+CALL(ntpdc,"ntpdc",ntpdcmain);
+#else
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ return ntpdcmain(argc, argv);
+}
+#endif
+
+#ifdef SYS_VXWORKS
+void clear_globals(void)
+{
+ extern int ntp_optind;
+ extern char *ntp_optarg;
+ showhostnames = 0; /* show host names by default */
+ ntp_optind = 0;
+ ntp_optarg = 0;
+ havehost = 0; /* set to 1 when host open */
+ numcmds = 0;
+ numhosts = 0;
+}
+#endif
+
+/*
+ * main - parse arguments and handle options
+ */
+int
+ntpdcmain(
+ int argc,
+ char *argv[]
+ )
+{
+ int c;
+ int errflg = 0;
+ extern int ntp_optind;
+ extern char *ntp_optarg;
+
+ delay_time.l_ui = 0;
+ delay_time.l_uf = DEFDELAY;
+
+#ifdef SYS_VXWORKS
+ clear_globals();
+ taskPrioritySet(taskIdSelf(), 100 );
+#endif
+
+#ifdef SYS_WINNT
+ if (!Win32InitSockets())
+ {
+ fprintf(stderr, "No useable winsock.dll:");
+ exit(1);
+ }
+#endif /* SYS_WINNT */
+
+ /* Check to see if we have IPv6. Otherwise force the -4 flag */
+ if (isc_net_probeipv6() != ISC_R_SUCCESS) {
+ ai_fam_default = AF_INET;
+ }
+
+ progname = argv[0];
+ ai_fam_templ = ai_fam_default;
+ while ((c = ntp_getopt(argc, argv, "46c:dilnps")) != EOF)
+ switch (c) {
+ case '4':
+ ai_fam_templ = AF_INET;
+ break;
+ case '6':
+ ai_fam_templ = AF_INET6;
+ break;
+ case 'c':
+ ADDCMD(ntp_optarg);
+ break;
+ case 'd':
+ ++debug;
+ break;
+ case 'i':
+ interactive = 1;
+ break;
+ case 'l':
+ ADDCMD("listpeers");
+ break;
+ case 'n':
+ showhostnames = 0;
+ break;
+ case 'p':
+ ADDCMD("peers");
+ break;
+ case 's':
+ ADDCMD("dmpeers");
+ break;
+ default:
+ errflg++;
+ break;
+ }
+ if (errflg) {
+ (void) fprintf(stderr,
+ "usage: %s [-46dilnps] [-c cmd] host ...\n",
+ progname);
+ exit(2);
+ }
+ if (ntp_optind == argc) {
+ ADDHOST(DEFHOST);
+ } else {
+ for (; ntp_optind < argc; ntp_optind++)
+ ADDHOST(argv[ntp_optind]);
+ }
+
+ if (numcmds == 0 && interactive == 0
+ && isatty(fileno(stdin)) && isatty(fileno(stderr))) {
+ interactive = 1;
+ }
+
+#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */
+ if (interactive)
+ (void) signal_no_reset(SIGINT, abortcmd);
+#endif /* SYS_WINNT */
+
+ /*
+ * Initialize the packet data buffer
+ */
+ pktdata = (char *)malloc(INITDATASIZE);
+ if (pktdata == NULL) {
+ (void) fprintf(stderr, "%s: malloc() failed!\n", progname);
+ exit(1);
+ }
+ pktdatasize = INITDATASIZE;
+
+ if (numcmds == 0) {
+ (void) openhost(chosts[0]);
+ getcmds();
+ } else {
+ int ihost;
+ int icmd;
+
+ for (ihost = 0; ihost < numhosts; ihost++) {
+ if (openhost(chosts[ihost]))
+ for (icmd = 0; icmd < numcmds; icmd++) {
+ if (numhosts > 1)
+ printf ("--- %s ---\n",chosts[ihost]);
+ docmd(ccmds[icmd]);
+ }
+ }
+ }
+#ifdef SYS_WINNT
+ WSACleanup();
+#endif
+ return(0);
+} /* main end */
+
+
+/*
+ * openhost - open a socket to a host
+ */
+static int
+openhost(
+ const char *hname
+ )
+{
+ char temphost[LENHOSTNAME];
+ int a_info, i;
+ struct addrinfo hints, *ai = NULL;
+ register const char *cp;
+ char name[LENHOSTNAME];
+ char service[5];
+
+ /*
+ * We need to get by the [] if they were entered
+ */
+
+ cp = hname;
+
+ if (*cp == '[') {
+ cp++;
+ for(i = 0; *cp != ']'; cp++, i++)
+ name[i] = *cp;
+ name[i] = '\0';
+ hname = name;
+ }
+
+ /*
+ * First try to resolve it as an ip address and if that fails,
+ * do a fullblown (dns) lookup. That way we only use the dns
+ * when it is needed and work around some implementations that
+ * will return an "IPv4-mapped IPv6 address" address if you
+ * give it an IPv4 address to lookup.
+ */
+ strcpy(service, "ntp");
+ memset((char *)&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = ai_fam_templ;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_NUMERICHOST;
+
+ a_info = getaddrinfo(hname, service, &hints, &ai);
+ if (a_info == EAI_NONAME || a_info == EAI_NODATA) {
+ hints.ai_flags = AI_CANONNAME;
+#ifdef AI_ADDRCONFIG
+ hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+ a_info = getaddrinfo(hname, service, &hints, &ai);
+ }
+ /* Some older implementations don't like AI_ADDRCONFIG. */
+ if (a_info == EAI_BADFLAGS) {
+ hints.ai_flags = AI_CANONNAME;
+ a_info = getaddrinfo(hname, service, &hints, &ai);
+ }
+ if (a_info != 0) {
+ (void) fprintf(stderr, "%s\n", gai_strerror(a_info));
+ return 0;
+ }
+
+ if (ai->ai_canonname == NULL) {
+ strncpy(temphost, stoa((struct sockaddr_storage *)ai->ai_addr),
+ LENHOSTNAME);
+ temphost[LENHOSTNAME-1] = '\0';
+ } else {
+ strncpy(temphost, ai->ai_canonname, LENHOSTNAME);
+ temphost[LENHOSTNAME-1] = '\0';
+ }
+
+ if (debug > 2)
+ printf("Opening host %s\n", temphost);
+
+ if (havehost == 1) {
+ if (debug > 2)
+ printf("Closing old host %s\n", currenthost);
+ (void) closesocket(sockfd);
+ havehost = 0;
+ }
+ (void) strcpy(currenthost, temphost);
+
+ /* port maps to the same in both families */
+ s_port = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port;
+#ifdef SYS_VXWORKS
+ ((struct sockaddr_in6 *)&hostaddr)->sin6_port = htons(SERVER_PORT_NUM);
+ if (ai->ai_family == AF_INET)
+ *(struct sockaddr_in *)&hostaddr=
+ *((struct sockaddr_in *)ai->ai_addr);
+ else
+ *(struct sockaddr_in6 *)&hostaddr=
+ *((struct sockaddr_in6 *)ai->ai_addr);
+#endif /* SYS_VXWORKS */
+
+#ifdef SYS_WINNT
+ {
+ int optionValue = SO_SYNCHRONOUS_NONALERT;
+ int err;
+ err = setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue));
+ if (err != NO_ERROR) {
+ (void) fprintf(stderr, "cannot open nonoverlapped sockets\n");
+ exit(1);
+ }
+ }
+
+ sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);
+ if (sockfd == INVALID_SOCKET) {
+ error("socket", "", "");
+ exit(-1);
+ }
+#else
+ sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);
+ if (sockfd == -1)
+ error("socket", "", "");
+#endif /* SYS_WINNT */
+
+
+#ifdef NEED_RCVBUF_SLOP
+# ifdef SO_RCVBUF
+ {
+ int rbufsize = INITDATASIZE + 2048; /* 2K for slop */
+
+ if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
+ &rbufsize, sizeof(int)) == -1)
+ error("setsockopt", "", "");
+ }
+# endif
+#endif
+
+#ifdef SYS_VXWORKS
+ if (connect(sockfd, (struct sockaddr *)&hostaddr,
+ sizeof(hostaddr)) == -1)
+#else
+ if (connect(sockfd, (struct sockaddr *)ai->ai_addr,
+ ai->ai_addrlen) == -1)
+#endif /* SYS_VXWORKS */
+ error("connect", "", "");
+ if (a_info)
+ freeaddrinfo(ai);
+ havehost = 1;
+ req_pkt_size = REQ_LEN_NOMAC;
+ impl_ver = IMPL_XNTPD;
+ return 1;
+}
+
+
+/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
+/*
+ * sendpkt - send a packet to the remote host
+ */
+static int
+sendpkt(
+ char *xdata,
+ int xdatalen
+ )
+{
+ if (send(sockfd, xdata, (size_t)xdatalen, 0) == -1) {
+ warning("write to %s failed", currenthost, "");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * growpktdata - grow the packet data area
+ */
+static void
+growpktdata(void)
+{
+ pktdatasize += INCDATASIZE;
+ pktdata = (char *)realloc(pktdata, (unsigned)pktdatasize);
+ if (pktdata == 0) {
+ (void) fprintf(stderr, "%s: realloc() failed!\n", progname);
+ exit(1);
+ }
+}
+
+
+/*
+ * getresponse - get a (series of) response packet(s) and return the data
+ */
+static int
+getresponse(
+ int implcode,
+ int reqcode,
+ int *ritems,
+ int *rsize,
+ char **rdata,
+ int esize
+ )
+{
+ struct resp_pkt rpkt;
+ struct timeval tvo;
+ int items;
+ int i;
+ int size;
+ int datasize;
+ char *datap;
+ char *tmp_data;
+ char haveseq[MAXSEQ+1];
+ int firstpkt;
+ int lastseq;
+ int numrecv;
+ int seq;
+ fd_set fds;
+ int n;
+ int pad;
+
+ /*
+ * This is pretty tricky. We may get between 1 and many packets
+ * back in response to the request. We peel the data out of
+ * each packet and collect it in one long block. When the last
+ * packet in the sequence is received we'll know how many we
+ * should have had. Note we use one long time out, should reconsider.
+ */
+ *ritems = 0;
+ *rsize = 0;
+ firstpkt = 1;
+ numrecv = 0;
+ *rdata = datap = pktdata;
+ lastseq = 999; /* too big to be a sequence number */
+ memset(haveseq, 0, sizeof(haveseq));
+ FD_ZERO(&fds);
+
+ again:
+ if (firstpkt)
+ tvo = tvout;
+ else
+ tvo = tvsout;
+
+ FD_SET(sockfd, &fds);
+ n = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvo);
+
+ if (n == -1) {
+ warning("select fails", "", "");
+ return -1;
+ }
+ if (n == 0) {
+ /*
+ * Timed out. Return what we have
+ */
+ if (firstpkt) {
+ (void) fprintf(stderr,
+ "%s: timed out, nothing received\n", currenthost);
+ return ERR_TIMEOUT;
+ } else {
+ (void) fprintf(stderr,
+ "%s: timed out with incomplete data\n",
+ currenthost);
+ if (debug) {
+ printf("Received sequence numbers");
+ for (n = 0; n <= MAXSEQ; n++)
+ if (haveseq[n])
+ printf(" %d,", n);
+ if (lastseq != 999)
+ printf(" last frame received\n");
+ else
+ printf(" last frame not received\n");
+ }
+ return ERR_INCOMPLETE;
+ }
+ }
+
+ n = recv(sockfd, (char *)&rpkt, sizeof(rpkt), 0);
+ if (n == -1) {
+ warning("read", "", "");
+ return -1;
+ }
+
+
+ /*
+ * Check for format errors. Bug proofing.
+ */
+ if (n < RESP_HEADER_SIZE) {
+ if (debug)
+ printf("Short (%d byte) packet received\n", n);
+ goto again;
+ }
+ if (INFO_VERSION(rpkt.rm_vn_mode) > NTP_VERSION ||
+ INFO_VERSION(rpkt.rm_vn_mode) < NTP_OLDVERSION) {
+ if (debug)
+ printf("Packet received with version %d\n",
+ INFO_VERSION(rpkt.rm_vn_mode));
+ goto again;
+ }
+ if (INFO_MODE(rpkt.rm_vn_mode) != MODE_PRIVATE) {
+ if (debug)
+ printf("Packet received with mode %d\n",
+ INFO_MODE(rpkt.rm_vn_mode));
+ goto again;
+ }
+ if (INFO_IS_AUTH(rpkt.auth_seq)) {
+ if (debug)
+ printf("Encrypted packet received\n");
+ goto again;
+ }
+ if (!ISRESPONSE(rpkt.rm_vn_mode)) {
+ if (debug)
+ printf("Received request packet, wanted response\n");
+ goto again;
+ }
+ if (INFO_MBZ(rpkt.mbz_itemsize) != 0) {
+ if (debug)
+ printf("Received packet with nonzero MBZ field!\n");
+ goto again;
+ }
+
+ /*
+ * Check implementation/request. Could be old data getting to us.
+ */
+ if (rpkt.implementation != implcode || rpkt.request != reqcode) {
+ if (debug)
+ printf(
+ "Received implementation/request of %d/%d, wanted %d/%d",
+ rpkt.implementation, rpkt.request,
+ implcode, reqcode);
+ goto again;
+ }
+
+ /*
+ * Check the error code. If non-zero, return it.
+ */
+ if (INFO_ERR(rpkt.err_nitems) != INFO_OKAY) {
+ if (debug && ISMORE(rpkt.rm_vn_mode)) {
+ printf("Error code %d received on not-final packet\n",
+ INFO_ERR(rpkt.err_nitems));
+ }
+ return (int)INFO_ERR(rpkt.err_nitems);
+ }
+
+ /*
+ * Collect items and size. Make sure they make sense.
+ */
+ items = INFO_NITEMS(rpkt.err_nitems);
+ size = INFO_ITEMSIZE(rpkt.mbz_itemsize);
+ if (esize > size)
+ pad = esize - size;
+ else
+ pad = 0;
+ if ((datasize = items*size) > (n-RESP_HEADER_SIZE)) {
+ if (debug)
+ printf(
+ "Received items %d, size %d (total %d), data in packet is %d\n",
+ items, size, datasize, n-RESP_HEADER_SIZE);
+ goto again;
+ }
+
+ /*
+ * If this isn't our first packet, make sure the size matches
+ * the other ones.
+ */
+ if (!firstpkt && esize != *rsize) {
+ if (debug)
+ printf("Received itemsize %d, previous %d\n",
+ size, *rsize);
+ goto again;
+ }
+ /*
+ * If we've received this before, +toss it
+ */
+ seq = INFO_SEQ(rpkt.auth_seq);
+ if (haveseq[seq]) {
+ if (debug)
+ printf("Received duplicate sequence number %d\n", seq);
+ goto again;
+ }
+ haveseq[seq] = 1;
+
+ /*
+ * If this is the last in the sequence, record that.
+ */
+ if (!ISMORE(rpkt.rm_vn_mode)) {
+ if (lastseq != 999) {
+ printf("Received second end sequence packet\n");
+ goto again;
+ }
+ lastseq = seq;
+ }
+
+ /*
+ * So far, so good. Copy this data into the output array.
+ */
+ if ((datap + datasize + (pad * items)) > (pktdata + pktdatasize)) {
+ int offset = datap - pktdata;
+ growpktdata();
+ *rdata = pktdata; /* might have been realloced ! */
+ datap = pktdata + offset;
+ }
+ /*
+ * We now move the pointer along according to size and number of
+ * items. This is so we can play nice with older implementations
+ */
+
+ tmp_data = (char *)rpkt.data;
+ for(i = 0; i <items; i++){
+ memmove(datap, tmp_data, (unsigned)size);
+ tmp_data += size;
+ memset(datap + size, 0, pad);
+ datap += size + pad;
+ }
+
+ if (firstpkt) {
+ firstpkt = 0;
+ *rsize = size + pad;
+ }
+ *ritems += items;
+
+ /*
+ * Finally, check the count of received packets. If we've got them
+ * all, return
+ */
+ ++numrecv;
+ if (numrecv <= lastseq)
+ goto again;
+ return INFO_OKAY;
+}
+
+
+/*
+ * sendrequest - format and send a request packet
+ */
+static int
+sendrequest(
+ int implcode,
+ int reqcode,
+ int auth,
+ int qitems,
+ int qsize,
+ char *qdata
+ )
+{
+ struct req_pkt qpkt;
+ int datasize;
+
+ memset((char *)&qpkt, 0, sizeof qpkt);
+
+ qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0);
+ qpkt.implementation = (u_char)implcode;
+ qpkt.request = (u_char)reqcode;
+
+ datasize = qitems * qsize;
+ if (datasize != 0 && qdata != NULL) {
+ memmove((char *)qpkt.data, qdata, (unsigned)datasize);
+ qpkt.err_nitems = ERR_NITEMS(0, qitems);
+ qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize);
+ } else {
+ qpkt.err_nitems = ERR_NITEMS(0, 0);
+ qpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
+ }
+
+ if (!auth) {
+ qpkt.auth_seq = AUTH_SEQ(0, 0);
+ return sendpkt((char *)&qpkt, req_pkt_size);
+ } else {
+ l_fp ts;
+ int maclen = 0;
+ const char *pass = "\0";
+ struct req_pkt_tail *qpktail;
+
+ qpktail = (struct req_pkt_tail *)((char *)&qpkt + req_pkt_size
+ + MAX_MAC_LEN - sizeof(struct req_pkt_tail));
+
+ if (info_auth_keyid == 0) {
+ maclen = getkeyid("Keyid: ");
+ if (maclen == 0) {
+ (void) fprintf(stderr,
+ "Invalid key identifier\n");
+ return 1;
+ }
+ info_auth_keyid = maclen;
+ }
+ if (!authistrusted(info_auth_keyid)) {
+ pass = getpass("MD5 Password: ");
+ if (*pass == '\0') {
+ (void) fprintf(stderr,
+ "Invalid password\n");
+ return (1);
+ }
+ }
+ authusekey(info_auth_keyid, info_auth_keytype, (const u_char *)pass);
+ authtrust(info_auth_keyid, 1);
+ qpkt.auth_seq = AUTH_SEQ(1, 0);
+ qpktail->keyid = htonl(info_auth_keyid);
+ get_systime(&ts);
+ L_ADD(&ts, &delay_time);
+ HTONL_FP(&ts, &qpktail->tstamp);
+ maclen = authencrypt(info_auth_keyid, (u_int32 *)&qpkt,
+ req_pkt_size);
+ if (maclen == 0) {
+ (void) fprintf(stderr, "Key not found\n");
+ return (1);
+ }
+ return sendpkt((char *)&qpkt, (int)(req_pkt_size + maclen));
+ }
+ /*NOTREACHED*/
+}
+
+
+/*
+ * doquery - send a request and process the response
+ */
+int
+doquery(
+ int implcode,
+ int reqcode,
+ int auth,
+ int qitems,
+ int qsize,
+ char *qdata,
+ int *ritems,
+ int *rsize,
+ char **rdata,
+ int quiet_mask,
+ int esize
+ )
+{
+ int res;
+ char junk[512];
+ fd_set fds;
+ struct timeval tvzero;
+
+ /*
+ * Check to make sure host is open
+ */
+ if (!havehost) {
+ (void) fprintf(stderr, "***No host open, use `host' command\n");
+ return -1;
+ }
+
+ /*
+ * Poll the socket and clear out any pending data
+ */
+again:
+ do {
+ tvzero.tv_sec = tvzero.tv_usec = 0;
+ FD_ZERO(&fds);
+ FD_SET(sockfd, &fds);
+ res = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);
+
+ if (res == -1) {
+ warning("polling select", "", "");
+ return -1;
+ } else if (res > 0)
+
+ (void) recv(sockfd, junk, sizeof junk, 0);
+ } while (res > 0);
+
+
+ /*
+ * send a request
+ */
+ res = sendrequest(implcode, reqcode, auth, qitems, qsize, qdata);
+ if (res != 0)
+ return res;
+
+ /*
+ * Get the response. If we got a standard error, print a message
+ */
+ res = getresponse(implcode, reqcode, ritems, rsize, rdata, esize);
+
+ /*
+ * Try to be compatible with older implementations of ntpd.
+ */
+ if (res == INFO_ERR_FMT && req_pkt_size != 48) {
+ int oldsize;
+
+ oldsize = req_pkt_size;
+
+ switch(req_pkt_size) {
+ case REQ_LEN_NOMAC:
+ req_pkt_size = 160;
+ break;
+ case 160:
+ req_pkt_size = 48;
+ break;
+ }
+ if (impl_ver == IMPL_XNTPD) {
+ fprintf(stderr,
+ "***Warning changing to older implementation\n");
+ return INFO_ERR_IMPL;
+ }
+
+ fprintf(stderr,
+ "***Warning changing the request packet size from %d to %d\n",
+ oldsize, req_pkt_size);
+ goto again;
+ }
+
+ /* log error message if not told to be quiet */
+ if ((res > 0) && (((1 << res) & quiet_mask) == 0)) {
+ switch(res) {
+ case INFO_ERR_IMPL:
+ /* Give us a chance to try the older implementation. */
+ if (implcode == IMPL_XNTPD)
+ break;
+ (void) fprintf(stderr,
+ "***Server implementation incompatable with our own\n");
+ break;
+ case INFO_ERR_REQ:
+ (void) fprintf(stderr,
+ "***Server doesn't implement this request\n");
+ break;
+ case INFO_ERR_FMT:
+ (void) fprintf(stderr,
+ "***Server reports a format error in the received packet (shouldn't happen)\n");
+ break;
+ case INFO_ERR_NODATA:
+ (void) fprintf(stderr,
+ "***Server reports data not found\n");
+ break;
+ case INFO_ERR_AUTH:
+ (void) fprintf(stderr, "***Permission denied\n");
+ break;
+ case ERR_TIMEOUT:
+ (void) fprintf(stderr, "***Request timed out\n");
+ break;
+ case ERR_INCOMPLETE:
+ (void) fprintf(stderr,
+ "***Response from server was incomplete\n");
+ break;
+ default:
+ (void) fprintf(stderr,
+ "***Server returns unknown error code %d\n", res);
+ break;
+ }
+ }
+ return res;
+}
+
+
+/*
+ * getcmds - read commands from the standard input and execute them
+ */
+static void
+getcmds(void)
+{
+#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)
+ char *line;
+
+ for (;;) {
+ if ((line = readline(interactive?prompt:"")) == NULL) return;
+ if (*line) add_history(line);
+ docmd(line);
+ free(line);
+ }
+#else /* not (HAVE_LIBREADLINE || HAVE_LIBEDIT) */
+ char line[MAXLINE];
+
+ for (;;) {
+ if (interactive) {
+#ifdef VMS /* work around a problem with mixing stdout & stderr */
+ fputs("",stdout);
+#endif
+ (void) fputs(prompt, stderr);
+ (void) fflush(stderr);
+ }
+
+ if (fgets(line, sizeof line, stdin) == NULL)
+ return;
+
+ docmd(line);
+ }
+#endif /* not HAVE_LIBREADLINE || HAVE_LIBEDIT */
+}
+
+
+#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */
+/*
+ * abortcmd - catch interrupts and abort the current command
+ */
+static RETSIGTYPE
+abortcmd(
+ int sig
+ )
+{
+
+ if (current_output == stdout)
+ (void) fflush(stdout);
+ putc('\n', stderr);
+ (void) fflush(stderr);
+ if (jump) longjmp(interrupt_buf, 1);
+}
+#endif /* SYS_WINNT */
+
+/*
+ * docmd - decode the command line and execute a command
+ */
+static void
+docmd(
+ const char *cmdline
+ )
+{
+ char *tokens[1+MAXARGS+2];
+ struct parse pcmd;
+ int ntok;
+ int i, ti;
+ int rval;
+ struct xcmd *xcmd;
+
+ ai_fam_templ = ai_fam_default;
+ /*
+ * Tokenize the command line. If nothing on it, return.
+ */
+ tokenize(cmdline, tokens, &ntok);
+ if (ntok == 0)
+ return;
+
+ /*
+ * Find the appropriate command description.
+ */
+ i = findcmd(tokens[0], builtins, opcmds, &xcmd);
+ if (i == 0) {
+ (void) fprintf(stderr, "***Command `%s' unknown\n",
+ tokens[0]);
+ return;
+ } else if (i >= 2) {
+ (void) fprintf(stderr, "***Command `%s' ambiguous\n",
+ tokens[0]);
+ return;
+ }
+
+ /*
+ * Save the keyword, then walk through the arguments, interpreting
+ * as we go.
+ */
+ pcmd.keyword = tokens[0];
+ pcmd.nargs = 0;
+ ti = 1;
+ for (i = 0; i < MAXARGS && xcmd->arg[i] != NO;) {
+ if ((i+ti) >= ntok) {
+ if (!(xcmd->arg[i] & OPT)) {
+ printusage(xcmd, stderr);
+ return;
+ }
+ break;
+ }
+ if ((xcmd->arg[i] & OPT) && (*tokens[i+ti] == '>'))
+ break;
+ rval = getarg(tokens[i+ti], (int)xcmd->arg[i], &pcmd.argval[i]);
+ if (rval == -1) {
+ ti++;
+ continue;
+ }
+ if (rval == 0)
+ return;
+ pcmd.nargs++;
+ i++;
+ }
+
+ i += ti;
+ if (i < ntok && *tokens[i] == '>') {
+ char *fname;
+
+ if (*(tokens[i]+1) != '\0')
+ fname = tokens[i]+1;
+ else if ((i+1) < ntok)
+ fname = tokens[i+1];
+ else {
+ (void) fprintf(stderr, "***No file for redirect\n");
+ return;
+ }
+
+ current_output = fopen(fname, "w");
+ if (current_output == NULL) {
+ (void) fprintf(stderr, "***Error opening %s: ", fname);
+ perror("");
+ return;
+ }
+ } else {
+ current_output = stdout;
+ }
+
+ if (interactive && setjmp(interrupt_buf)) {
+ return;
+ } else {
+ jump = 1;
+ (xcmd->handler)(&pcmd, current_output);
+ jump = 0;
+ if (current_output != stdout)
+ (void) fclose(current_output);
+ current_output = NULL;
+ }
+}
+
+
+/*
+ * tokenize - turn a command line into tokens
+ */
+static void
+tokenize(
+ const char *line,
+ char **tokens,
+ int *ntok
+ )
+{
+ register const char *cp;
+ register char *sp;
+ static char tspace[MAXLINE];
+
+ sp = tspace;
+ cp = line;
+ for (*ntok = 0; *ntok < MAXTOKENS; (*ntok)++) {
+ tokens[*ntok] = sp;
+ while (ISSPACE(*cp))
+ cp++;
+ if (ISEOL(*cp))
+ break;
+ do {
+ *sp++ = *cp++;
+ } while (!ISSPACE(*cp) && !ISEOL(*cp));
+
+ *sp++ = '\0';
+ }
+}
+
+
+
+/*
+ * findcmd - find a command in a command description table
+ */
+static int
+findcmd(
+ register char *str,
+ struct xcmd *clist1,
+ struct xcmd *clist2,
+ struct xcmd **cmd
+ )
+{
+ register struct xcmd *cl;
+ register int clen;
+ int nmatch;
+ struct xcmd *nearmatch = NULL;
+ struct xcmd *clist;
+
+ clen = strlen(str);
+ nmatch = 0;
+ if (clist1 != 0)
+ clist = clist1;
+ else if (clist2 != 0)
+ clist = clist2;
+ else
+ return 0;
+
+ again:
+ for (cl = clist; cl->keyword != 0; cl++) {
+ /* do a first character check, for efficiency */
+ if (*str != *(cl->keyword))
+ continue;
+ if (strncmp(str, cl->keyword, (unsigned)clen) == 0) {
+ /*
+ * Could be extact match, could be approximate.
+ * Is exact if the length of the keyword is the
+ * same as the str.
+ */
+ if (*((cl->keyword) + clen) == '\0') {
+ *cmd = cl;
+ return 1;
+ }
+ nmatch++;
+ nearmatch = cl;
+ }
+ }
+
+ /*
+ * See if there is more to do. If so, go again. Sorry about the
+ * goto, too much looking at BSD sources...
+ */
+ if (clist == clist1 && clist2 != 0) {
+ clist = clist2;
+ goto again;
+ }
+
+ /*
+ * If we got extactly 1 near match, use it, else return number
+ * of matches.
+ */
+ if (nmatch == 1) {
+ *cmd = nearmatch;
+ return 1;
+ }
+ return nmatch;
+}
+
+
+/*
+ * getarg - interpret an argument token
+ *
+ * return: 0 - failure
+ * 1 - success
+ * -1 - skip to next token
+ */
+static int
+getarg(
+ char *str,
+ int code,
+ arg_v *argp
+ )
+{
+ int isneg;
+ char *cp, *np;
+ static const char *digits = "0123456789";
+
+ switch (code & ~OPT) {
+ case NTP_STR:
+ argp->string = str;
+ break;
+ case ADD:
+ if (!strcmp("-6", str)) {
+ ai_fam_templ = AF_INET6;
+ return -1;
+ } else if (!strcmp("-4", str)) {
+ ai_fam_templ = AF_INET;
+ return -1;
+ }
+ if (!getnetnum(str, &(argp->netnum), (char *)0, 0)) {
+ return 0;
+ }
+ break;
+ case INT:
+ case UINT:
+ isneg = 0;
+ np = str;
+ if (*np == '-') {
+ np++;
+ isneg = 1;
+ }
+
+ argp->uval = 0;
+ do {
+ cp = strchr(digits, *np);
+ if (cp == NULL) {
+ (void) fprintf(stderr,
+ "***Illegal integer value %s\n", str);
+ return 0;
+ }
+ argp->uval *= 10;
+ argp->uval += (cp - digits);
+ } while (*(++np) != '\0');
+
+ if (isneg) {
+ if ((code & ~OPT) == UINT) {
+ (void) fprintf(stderr,
+ "***Value %s should be unsigned\n", str);
+ return 0;
+ }
+ argp->ival = -argp->ival;
+ }
+ break;
+ case IP_VERSION:
+ if (!strcmp("-6", str))
+ argp->ival = 6 ;
+ else if (!strcmp("-4", str))
+ argp->ival = 4 ;
+ else {
+ (void) fprintf(stderr,
+ "***Version must be either 4 or 6\n");
+ return 0;
+ }
+ break;
+ }
+
+ return 1;
+}
+
+
+/*
+ * getnetnum - given a host name, return its net number
+ * and (optional) full name
+ */
+static int
+getnetnum(
+ const char *hname,
+ struct sockaddr_storage *num,
+ char *fullhost,
+ int af
+ )
+{
+ int err;
+ int sockaddr_len;
+ struct addrinfo hints, *ai = NULL;
+
+ sockaddr_len = (af == AF_INET)
+ ? sizeof(struct sockaddr_in)
+ : sizeof(struct sockaddr_in6);
+ memset((char *)&hints, 0, sizeof(struct addrinfo));
+ hints.ai_flags = AI_CANONNAME;
+#ifdef AI_ADDRCONFIG
+ hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+
+ /* decodenetnum only works with addresses */
+ if (decodenetnum(hname, num)) {
+ if (fullhost != 0) {
+ getnameinfo((struct sockaddr *)num, sockaddr_len,
+ fullhost, sizeof(fullhost), NULL, 0,
+ NI_NUMERICHOST);
+ }
+ return 1;
+ } else if ((err = getaddrinfo(hname, "ntp", &hints, &ai)) == 0) {
+ memmove((char *)num, ai->ai_addr, ai->ai_addrlen);
+ if (fullhost != 0)
+ (void) strcpy(fullhost, ai->ai_canonname);
+ return 1;
+ } else {
+ (void) fprintf(stderr, "***Can't find host %s\n", hname);
+ return 0;
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * nntohost - convert network number to host name. This routine enforces
+ * the showhostnames setting.
+ */
+char *
+nntohost(
+ struct sockaddr_storage *netnum
+ )
+{
+ if (!showhostnames)
+ return stoa(netnum);
+
+ if ((netnum->ss_family == AF_INET) && ISREFCLOCKADR(netnum))
+ return refnumtoa(netnum);
+ return socktohost(netnum);
+}
+
+
+/*
+ * Finally, the built in command handlers
+ */
+
+/*
+ * help - tell about commands, or details of a particular command
+ */
+static void
+help(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ int i;
+ int n;
+ struct xcmd *xcp;
+ char *cmd;
+ const char *cmdsort[100];
+ int length[100];
+ int maxlength;
+ int numperline;
+ static const char *spaces = " "; /* 20 spaces */
+
+ if (pcmd->nargs == 0) {
+ n = 0;
+ for (xcp = builtins; xcp->keyword != 0; xcp++) {
+ if (*(xcp->keyword) != '?')
+ cmdsort[n++] = xcp->keyword;
+ }
+ for (xcp = opcmds; xcp->keyword != 0; xcp++)
+ cmdsort[n++] = xcp->keyword;
+
+#ifdef QSORT_USES_VOID_P
+ qsort(cmdsort, (size_t)n, sizeof(char *), helpsort);
+#else
+ qsort((char *)cmdsort, (size_t)n, sizeof(char *), helpsort);
+#endif
+
+ maxlength = 0;
+ for (i = 0; i < n; i++) {
+ length[i] = strlen(cmdsort[i]);
+ if (length[i] > maxlength)
+ maxlength = length[i];
+ }
+ maxlength++;
+ numperline = 76 / maxlength;
+
+ (void) fprintf(fp, "Commands available:\n");
+ for (i = 0; i < n; i++) {
+ if ((i % numperline) == (numperline-1)
+ || i == (n-1))
+ (void) fprintf(fp, "%s\n", cmdsort[i]);
+ else
+ (void) fprintf(fp, "%s%s", cmdsort[i],
+ spaces+20-maxlength+length[i]);
+ }
+ } else {
+ cmd = pcmd->argval[0].string;
+ n = findcmd(cmd, builtins, opcmds, &xcp);
+ if (n == 0) {
+ (void) fprintf(stderr,
+ "Command `%s' is unknown\n", cmd);
+ return;
+ } else if (n >= 2) {
+ (void) fprintf(stderr,
+ "Command `%s' is ambiguous\n", cmd);
+ return;
+ }
+ (void) fprintf(fp, "function: %s\n", xcp->comment);
+ printusage(xcp, fp);
+ }
+}
+
+
+/*
+ * helpsort - do hostname qsort comparisons
+ */
+#ifdef QSORT_USES_VOID_P
+static int
+helpsort(
+ const void *t1,
+ const void *t2
+ )
+{
+ char const * const * name1 = (char const * const *)t1;
+ char const * const * name2 = (char const * const *)t2;
+
+ return strcmp(*name1, *name2);
+}
+#else
+static int
+helpsort(
+ char **name1,
+ char **name2
+ )
+{
+ return strcmp(*name1, *name2);
+}
+#endif
+
+
+/*
+ * printusage - print usage information for a command
+ */
+static void
+printusage(
+ struct xcmd *xcp,
+ FILE *fp
+ )
+{
+ int i, opt46;
+
+ opt46 = 0;
+ (void) fprintf(fp, "usage: %s", xcp->keyword);
+ for (i = 0; i < MAXARGS && xcp->arg[i] != NO; i++) {
+ if (opt46 == 0 && (xcp->arg[i] & ~OPT) == ADD) {
+ (void) fprintf(fp, " [ -4|-6 ]");
+ opt46 = 1;
+ }
+ if (xcp->arg[i] & OPT)
+ (void) fprintf(fp, " [ %s ]", xcp->desc[i]);
+ else
+ (void) fprintf(fp, " %s", xcp->desc[i]);
+ }
+ (void) fprintf(fp, "\n");
+}
+
+
+/*
+ * timeout - set time out time
+ */
+static void
+timeout(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ int val;
+
+ if (pcmd->nargs == 0) {
+ val = tvout.tv_sec * 1000 + tvout.tv_usec / 1000;
+ (void) fprintf(fp, "primary timeout %d ms\n", val);
+ } else {
+ tvout.tv_sec = pcmd->argval[0].uval / 1000;
+ tvout.tv_usec = (pcmd->argval[0].uval - (tvout.tv_sec * 1000))
+ * 1000;
+ }
+}
+
+
+/*
+ * my_delay - set delay for auth requests
+ */
+static void
+my_delay(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ int isneg;
+ u_long val;
+
+ if (pcmd->nargs == 0) {
+ val = delay_time.l_ui * 1000 + delay_time.l_uf / 4294967;
+ (void) fprintf(fp, "delay %lu ms\n", val);
+ } else {
+ if (pcmd->argval[0].ival < 0) {
+ isneg = 1;
+ val = (u_long)(-pcmd->argval[0].ival);
+ } else {
+ isneg = 0;
+ val = (u_long)pcmd->argval[0].ival;
+ }
+
+ delay_time.l_ui = val / 1000;
+ val %= 1000;
+ delay_time.l_uf = val * 4294967; /* 2**32/1000 */
+
+ if (isneg)
+ L_NEG(&delay_time);
+ }
+}
+
+
+/*
+ * host - set the host we are dealing with.
+ */
+static void
+host(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ int i;
+
+ if (pcmd->nargs == 0) {
+ if (havehost)
+ (void) fprintf(fp, "current host is %s\n", currenthost);
+ else
+ (void) fprintf(fp, "no current host\n");
+ return;
+ }
+
+ i = 0;
+ if (pcmd->nargs == 2) {
+ if (!strcmp("-4", pcmd->argval[i].string))
+ ai_fam_templ = AF_INET;
+ else if (!strcmp("-6", pcmd->argval[i].string))
+ ai_fam_templ = AF_INET6;
+ else {
+ if (havehost)
+ (void) fprintf(fp,
+ "current host remains %s\n", currenthost);
+ else
+ (void) fprintf(fp, "still no current host\n");
+ return;
+ }
+ i = 1;
+ }
+ if (openhost(pcmd->argval[i].string)) {
+ (void) fprintf(fp, "current host set to %s\n", currenthost);
+ } else {
+ if (havehost)
+ (void) fprintf(fp,
+ "current host remains %s\n", currenthost);
+ else
+ (void) fprintf(fp, "still no current host\n");
+ }
+}
+
+
+/*
+ * keyid - get a keyid to use for authenticating requests
+ */
+static void
+keyid(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ if (pcmd->nargs == 0) {
+ if (info_auth_keyid == 0)
+ (void) fprintf(fp, "no keyid defined\n");
+ else
+ (void) fprintf(fp, "keyid is %lu\n", (u_long)info_auth_keyid);
+ } else {
+ info_auth_keyid = pcmd->argval[0].uval;
+ }
+}
+
+
+/*
+ * keytype - get type of key to use for authenticating requests
+ */
+static void
+keytype(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ if (pcmd->nargs == 0)
+ fprintf(fp, "keytype is %s\n",
+ (info_auth_keytype == KEY_TYPE_MD5) ? "MD5" : "???");
+ else
+ switch (*(pcmd->argval[0].string)) {
+ case 'm':
+ case 'M':
+ info_auth_keytype = KEY_TYPE_MD5;
+ break;
+
+ default:
+ fprintf(fp, "keytype must be 'md5'\n");
+ }
+}
+
+
+
+/*
+ * passwd - get an authentication key
+ */
+/*ARGSUSED*/
+static void
+passwd(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ char *pass;
+
+ if (info_auth_keyid == 0) {
+ info_auth_keyid = getkeyid("Keyid: ");
+ if (info_auth_keyid == 0) {
+ (void)fprintf(fp, "Keyid must be defined\n");
+ return;
+ }
+ }
+ if (!interactive) {
+ authusekey(info_auth_keyid, info_auth_keytype,
+ (u_char *)pcmd->argval[0].string);
+ authtrust(info_auth_keyid, 1);
+ } else {
+ pass = getpass("MD5 Password: ");
+ if (*pass == '\0')
+ (void) fprintf(fp, "Password unchanged\n");
+ else {
+ authusekey(info_auth_keyid, info_auth_keytype,
+ (u_char *)pass);
+ authtrust(info_auth_keyid, 1);
+ }
+ }
+}
+
+
+/*
+ * hostnames - set the showhostnames flag
+ */
+static void
+hostnames(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ if (pcmd->nargs == 0) {
+ if (showhostnames)
+ (void) fprintf(fp, "hostnames being shown\n");
+ else
+ (void) fprintf(fp, "hostnames not being shown\n");
+ } else {
+ if (STREQ(pcmd->argval[0].string, "yes"))
+ showhostnames = 1;
+ else if (STREQ(pcmd->argval[0].string, "no"))
+ showhostnames = 0;
+ else
+ (void)fprintf(stderr, "What?\n");
+ }
+}
+
+
+/*
+ * setdebug - set/change debugging level
+ */
+static void
+setdebug(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ if (pcmd->nargs == 0) {
+ (void) fprintf(fp, "debug level is %d\n", debug);
+ return;
+ } else if (STREQ(pcmd->argval[0].string, "no")) {
+ debug = 0;
+ } else if (STREQ(pcmd->argval[0].string, "more")) {
+ debug++;
+ } else if (STREQ(pcmd->argval[0].string, "less")) {
+ debug--;
+ } else {
+ (void) fprintf(fp, "What?\n");
+ return;
+ }
+ (void) fprintf(fp, "debug level set to %d\n", debug);
+}
+
+
+/*
+ * quit - stop this nonsense
+ */
+/*ARGSUSED*/
+static void
+quit(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ if (havehost)
+ closesocket(sockfd);
+ exit(0);
+}
+
+
+/*
+ * version - print the current version number
+ */
+/*ARGSUSED*/
+static void
+version(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+
+ (void) fprintf(fp, "%s\n", Version);
+ return;
+}
+
+
+/*
+ * warning - print a warning message
+ */
+static void
+warning(
+ const char *fmt,
+ const char *st1,
+ const char *st2
+ )
+{
+ (void) fprintf(stderr, "%s: ", progname);
+ (void) fprintf(stderr, fmt, st1, st2);
+ (void) fprintf(stderr, ": ");
+ perror("");
+}
+
+
+/*
+ * error - print a message and exit
+ */
+static void
+error(
+ const char *fmt,
+ const char *st1,
+ const char *st2
+ )
+{
+ warning(fmt, st1, st2);
+ exit(1);
+}
+
+/*
+ * getkeyid - prompt the user for a keyid to use
+ */
+static u_long
+getkeyid(
+ const char *keyprompt
+ )
+{
+ register char *p;
+ register int c;
+ FILE *fi;
+ char pbuf[20];
+
+#ifndef SYS_WINNT
+ if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
+#else
+ if ((fi = _fdopen((int)GetStdHandle(STD_INPUT_HANDLE), "r")) == NULL)
+#endif /* SYS_WINNT */
+ fi = stdin;
+ else
+ setbuf(fi, (char *)NULL);
+ fprintf(stderr, "%s", keyprompt); fflush(stderr);
+ for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
+ if (p < &pbuf[18])
+ *p++ = (char) c;
+ }
+ *p = '\0';
+ if (fi != stdin)
+ fclose(fi);
+ return (u_int32)atoi(pbuf);
+}
diff --git a/ntpdc/ntpdc.h b/ntpdc/ntpdc.h
new file mode 100644
index 0000000000000..589529fb1c1d9
--- /dev/null
+++ b/ntpdc/ntpdc.h
@@ -0,0 +1,64 @@
+/*
+ * ntpdc.h - definitions of interest to ntpdc
+ */
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "ntp_request.h"
+#include "ntp_string.h"
+#include "ntp_malloc.h"
+
+/*
+ * Maximum number of arguments
+ */
+#define MAXARGS 4
+
+/*
+ * Flags for forming descriptors.
+ */
+#define OPT 0x80 /* this argument is optional, or'd with type */
+
+#define NO 0x0
+#define NTP_STR 0x1 /* string argument */
+#define UINT 0x2 /* unsigned integer */
+#define INT 0x3 /* signed integer */
+#define ADD 0x4 /* IP network address */
+#define IP_VERSION 0x5 /* IP version */
+
+/*
+ * Arguments are returned in a union
+ */
+typedef union {
+ char *string;
+ long ival;
+ u_long uval;
+ struct sockaddr_storage netnum;
+} arg_v;
+
+/*
+ * Structure for passing parsed command line
+ */
+struct parse {
+ char *keyword;
+ arg_v argval[MAXARGS];
+ int nargs;
+};
+
+/*
+ * ntpdc includes a command parser which could charitably be called
+ * crude. The following structure is used to define the command
+ * syntax.
+ */
+struct xcmd {
+ const char *keyword; /* command key word */
+ void (*handler) P((struct parse *, FILE *)); /* command handler */
+ u_char arg[MAXARGS]; /* descriptors for arguments */
+ const char *desc[MAXARGS]; /* descriptions for arguments */
+ const char *comment;
+};
+
+extern int impl_ver;
+extern int showhostnames;
+extern int s_port;
+
+extern int doquery P((int, int, int, int, int, char *, int *, int *, char **, int, int));
+extern char * nntohost P((struct sockaddr_storage *));
diff --git a/ntpdc/ntpdc_ops.c b/ntpdc/ntpdc_ops.c
new file mode 100644
index 0000000000000..9fa3bd738aadc
--- /dev/null
+++ b/ntpdc/ntpdc_ops.c
@@ -0,0 +1,3012 @@
+/*
+ * ntpdc_ops.c - subroutines which are called to perform operations by xntpdc
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+
+#include "ntpdc.h"
+#include "ntp_control.h"
+#include "ntp_refclock.h"
+#include "ntp_stdlib.h"
+
+#include <ctype.h>
+#ifdef HAVE_SYS_TIMEX_H
+# include <sys/timex.h>
+#endif
+#include <netdb.h>
+#if !defined(__bsdi__) && !defined(apollo)
+#include <netinet/in.h>
+#endif
+
+#include <arpa/inet.h>
+
+/*
+ * Declarations for command handlers in here
+ */
+static int checkitems P((int, FILE *));
+static int checkitemsize P((int, int));
+static int check1item P((int, FILE *));
+static void peerlist P((struct parse *, FILE *));
+static void peers P((struct parse *, FILE *));
+static void doconfig P((struct parse *pcmd, FILE *fp, int mode, int refc));
+static void dmpeers P((struct parse *, FILE *));
+static void dopeers P((struct parse *, FILE *, int));
+static void printpeer P((struct info_peer *, FILE *));
+static void showpeer P((struct parse *, FILE *));
+static void peerstats P((struct parse *, FILE *));
+static void loopinfo P((struct parse *, FILE *));
+static void sysinfo P((struct parse *, FILE *));
+static void sysstats P((struct parse *, FILE *));
+static void iostats P((struct parse *, FILE *));
+static void memstats P((struct parse *, FILE *));
+static void timerstats P((struct parse *, FILE *));
+static void addpeer P((struct parse *, FILE *));
+static void addserver P((struct parse *, FILE *));
+static void addrefclock P((struct parse *, FILE *));
+static void broadcast P((struct parse *, FILE *));
+static void doconfig P((struct parse *, FILE *, int, int));
+static void unconfig P((struct parse *, FILE *));
+static void set P((struct parse *, FILE *));
+static void sys_clear P((struct parse *, FILE *));
+static void doset P((struct parse *, FILE *, int));
+static void reslist P((struct parse *, FILE *));
+static void new_restrict P((struct parse *, FILE *));
+static void unrestrict P((struct parse *, FILE *));
+static void delrestrict P((struct parse *, FILE *));
+static void do_restrict P((struct parse *, FILE *, int));
+static void monlist P((struct parse *, FILE *));
+static void reset P((struct parse *, FILE *));
+static void preset P((struct parse *, FILE *));
+static void readkeys P((struct parse *, FILE *));
+static void trustkey P((struct parse *, FILE *));
+static void untrustkey P((struct parse *, FILE *));
+static void do_trustkey P((struct parse *, FILE *, int));
+static void authinfo P((struct parse *, FILE *));
+static void traps P((struct parse *, FILE *));
+static void addtrap P((struct parse *, FILE *));
+static void clrtrap P((struct parse *, FILE *));
+static void do_addclr_trap P((struct parse *, FILE *, int));
+static void requestkey P((struct parse *, FILE *));
+static void controlkey P((struct parse *, FILE *));
+static void do_changekey P((struct parse *, FILE *, int));
+static void ctlstats P((struct parse *, FILE *));
+static void clockstat P((struct parse *, FILE *));
+static void fudge P((struct parse *, FILE *));
+static void clkbug P((struct parse *, FILE *));
+static void kerninfo P((struct parse *, FILE *));
+
+/*
+ * Commands we understand. Ntpdc imports this.
+ */
+struct xcmd opcmds[] = {
+ { "listpeers", peerlist, { OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display list of peers the server knows about [IP Version]" },
+ { "peers", peers, { OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display peer summary information [IP Version]" },
+ { "dmpeers", dmpeers, { OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display peer summary info the way Dave Mills likes it (IP Version)" },
+ { "showpeer", showpeer, { ADD, OPT|ADD, OPT|ADD, OPT|ADD},
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "display detailed information for one or more peers" },
+ { "pstats", peerstats, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "display statistical information for one or more peers" },
+ { "loopinfo", loopinfo, { OPT|NTP_STR, NO, NO, NO },
+ { "oneline|multiline", "", "", "" },
+ "display loop filter information" },
+ { "sysinfo", sysinfo, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display local server information" },
+ { "sysstats", sysstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display local server statistics" },
+ { "memstats", memstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display peer memory usage statistics" },
+ { "iostats", iostats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display I/O subsystem statistics" },
+ { "timerstats", timerstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display event timer subsystem statistics" },
+ { "addpeer", addpeer, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR },
+ { "addr", "keyid", "version", "minpoll|prefer" },
+ "configure a new peer association" },
+ { "addserver", addserver, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR },
+ { "addr", "keyid", "version", "minpoll|prefer" },
+ "configure a new server" },
+ { "addrefclock",addrefclock, { ADD, OPT|UINT, OPT|NTP_STR, OPT|NTP_STR },
+ { "addr", "mode", "minpoll|prefer", "minpoll|prefer" },
+ "configure a new server" },
+ { "broadcast", broadcast, { ADD, OPT|UINT, OPT|UINT, OPT|NTP_STR },
+ { "addr", "keyid", "version", "minpoll" },
+ "configure broadcasting time service" },
+ { "unconfig", unconfig, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "unconfigure existing peer assocations" },
+ { "enable", set, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." },
+ "set a system flag (auth, bclient, monitor, pll, kernel, stats)" },
+ { "disable", sys_clear, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." },
+ "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" },
+ { "reslist", reslist, {OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display the server's restrict list" },
+ { "restrict", new_restrict, { ADD, ADD, NTP_STR, OPT|NTP_STR },
+ { "address", "mask",
+ "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod",
+ "..." },
+ "create restrict entry/add flags to entry" },
+ { "unrestrict", unrestrict, { ADD, ADD, NTP_STR, OPT|NTP_STR },
+ { "address", "mask",
+ "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod",
+ "..." },
+ "remove flags from a restrict entry" },
+ { "delrestrict", delrestrict, { ADD, ADD, OPT|NTP_STR, NO },
+ { "address", "mask", "ntpport", "" },
+ "delete a restrict entry" },
+ { "monlist", monlist, { OPT|INT, NO, NO, NO },
+ { "version", "", "", "" },
+ "display data the server's monitor routines have collected" },
+ { "reset", reset, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "io|sys|mem|timer|auth|allpeers", "...", "...", "..." },
+ "reset various subsystem statistics counters" },
+ { "preset", preset, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "reset stat counters associated with particular peer(s)" },
+ { "readkeys", readkeys, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "request a reread of the keys file and re-init of system keys" },
+ { "trustedkey", trustkey, { UINT, OPT|UINT, OPT|UINT, OPT|UINT },
+ { "keyid", "keyid", "keyid", "keyid" },
+ "add one or more key ID's to the trusted list" },
+ { "untrustedkey", untrustkey, { UINT, OPT|UINT, OPT|UINT, OPT|UINT },
+ { "keyid", "keyid", "keyid", "keyid" },
+ "remove one or more key ID's from the trusted list" },
+ { "authinfo", authinfo, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display the state of the authentication code" },
+ { "traps", traps, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display the traps set in the server" },
+ { "addtrap", addtrap, { ADD, OPT|UINT, OPT|ADD, NO },
+ { "address", "port", "interface", "" },
+ "configure a trap in the server" },
+ { "clrtrap", clrtrap, { ADD, OPT|UINT, OPT|ADD, NO },
+ { "address", "port", "interface", "" },
+ "remove a trap (configured or otherwise) from the server" },
+ { "requestkey", requestkey, { UINT, NO, NO, NO },
+ { "keyid", "", "", "" },
+ "change the keyid the server uses to authenticate requests" },
+ { "controlkey", controlkey, { UINT, NO, NO, NO },
+ { "keyid", "", "", "" },
+ "change the keyid the server uses to authenticate control messages" },
+ { "ctlstats", ctlstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display packet count statistics from the control module" },
+ { "clockstat", clockstat, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
+ { "address", "address", "address", "address" },
+ "display clock status information" },
+ { "fudge", fudge, { ADD, NTP_STR, NTP_STR, NO },
+ { "address", "time1|time2|val1|val2|flags", "value", "" },
+ "set/change one of a clock's fudge factors" },
+ { "clkbug", clkbug, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
+ { "address", "address", "address", "address" },
+ "display clock debugging information" },
+ { "kerninfo", kerninfo, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display the kernel pll/pps variables" },
+
+ { 0, 0, { NO, NO, NO, NO },
+ { "", "", "", "" }, "" }
+};
+
+/*
+ * For quick string comparisons
+ */
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+
+/*
+ * checkitems - utility to print a message if no items were returned
+ */
+static int
+checkitems(
+ int items,
+ FILE *fp
+ )
+{
+ if (items == 0) {
+ (void) fprintf(fp, "No data returned in response to query\n");
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * checkitemsize - utility to print a message if the item size is wrong
+ */
+static int
+checkitemsize(
+ int itemsize,
+ int expected
+ )
+{
+ if (itemsize != expected) {
+ (void) fprintf(stderr,
+ "***Incorrect item size returned by remote host (%d should be %d)\n",
+ itemsize, expected);
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * check1item - check to make sure we have exactly one item
+ */
+static int
+check1item(
+ int items,
+ FILE *fp
+ )
+{
+ if (items == 0) {
+ (void) fprintf(fp, "No data returned in response to query\n");
+ return 0;
+ }
+ if (items > 1) {
+ (void) fprintf(fp, "Expected one item in response, got %d\n",
+ items);
+ return 0;
+ }
+ return 1;
+}
+
+
+
+/*
+ * peerlist - get a short list of peers
+ */
+/*ARGSUSED*/
+static void
+peerlist(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_peer_list *plist;
+ struct sockaddr_storage paddr;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items,
+ &itemsize, (void *)&plist, 0,
+ sizeof(struct info_peer_list));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer_list)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer_list)))
+ return;
+
+ while (items > 0) {
+ memset((char *)&paddr, 0, sizeof(paddr));
+ if (plist->v6_flag != 0) {
+ GET_INADDR6(paddr) = plist->addr6;
+ paddr.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(paddr) = plist->addr;
+ paddr.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ paddr.ss_len = SOCKLEN(&paddr);
+#endif
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (plist->v6_flag == 0)))
+ (void) fprintf(fp, "%-9s %s\n",
+ modetoa(plist->hmode),
+ nntohost(&paddr));
+ plist++;
+ items--;
+ }
+}
+
+
+/*
+ * peers - show peer summary
+ */
+static void
+peers(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ dopeers(pcmd, fp, 0);
+}
+
+/*
+ * dmpeers - show peer summary, Dave Mills style
+ */
+static void
+dmpeers(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ dopeers(pcmd, fp, 1);
+}
+
+
+/*
+ * peers - show peer summary
+ */
+/*ARGSUSED*/
+static void
+dopeers(
+ struct parse *pcmd,
+ FILE *fp,
+ int dmstyle
+ )
+{
+ struct info_peer_summary *plist;
+ struct sockaddr_storage dstadr;
+ struct sockaddr_storage srcadr;
+ int items;
+ int itemsize;
+ int ntp_poll;
+ int res;
+ int c;
+ l_fp tempts;
+
+again:
+ res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&plist, 0,
+ sizeof(struct info_peer_summary));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer_summary)))
+ return;
+
+ (void) fprintf(fp,
+ " remote local st poll reach delay offset disp\n");
+ (void) fprintf(fp,
+ "=======================================================================\n");
+ while (items > 0) {
+ if (!dmstyle) {
+ if (plist->flags & INFO_FLAG_SYSPEER)
+ c = '*';
+ else if (plist->hmode == MODE_ACTIVE)
+ c = '+';
+ else if (plist->hmode == MODE_PASSIVE)
+ c = '-';
+ else if (plist->hmode == MODE_CLIENT)
+ c = '=';
+ else if (plist->hmode == MODE_BROADCAST)
+ c = '^';
+ else if (plist->hmode == MODE_BCLIENT)
+ c = '~';
+ else
+ c = ' ';
+ } else {
+ if (plist->flags & INFO_FLAG_SYSPEER)
+ c = '*';
+ else if (plist->flags & INFO_FLAG_SHORTLIST)
+ c = '+';
+ else if (plist->flags & INFO_FLAG_SEL_CANDIDATE)
+ c = '.';
+ else
+ c = ' ';
+ }
+ NTOHL_FP(&(plist->offset), &tempts);
+ ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL),
+ NTP_MINPOLL);
+ memset((char *)&dstadr, 0, sizeof(dstadr));
+ memset((char *)&srcadr, 0, sizeof(srcadr));
+ if (plist->v6_flag != 0) {
+ GET_INADDR6(dstadr) = plist->dstadr6;
+ GET_INADDR6(srcadr) = plist->srcadr6;
+ srcadr.ss_family = AF_INET6;
+ dstadr.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(dstadr) = plist->dstadr;
+ GET_INADDR(srcadr) = plist->srcadr;
+ srcadr.ss_family = AF_INET;
+ dstadr.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ srcadr.ss_len = SOCKLEN(&srcadr);
+ dstadr.ss_len = SOCKLEN(&dstadr);
+#endif
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (plist->v6_flag == 0)))
+ (void) fprintf(fp,
+ "%c%-15.15s %-15.15s %2d %4d %3o %7.7s %9.9s %7.7s\n",
+ c, nntohost(&srcadr), stoa(&dstadr),
+ plist->stratum, ntp_poll, plist->reach,
+ fptoa(NTOHS_FP(plist->delay), 5),
+ lfptoa(&tempts, 6),
+ ufptoa(NTOHS_FP(plist->dispersion), 5));
+ plist++;
+ items--;
+ }
+}
+
+/* Convert a refid & stratum (in host order) to a string */
+static char*
+refid_string(
+ u_int32 refid,
+ int stratum
+ )
+{
+ if (stratum <= 1) {
+ static char junk[5];
+ junk[4] = 0;
+ memmove(junk, (char *)&refid, 4);
+ return junk;
+ }
+
+ return numtoa(refid);
+}
+
+/*
+ * printpeer - print detail information for a peer
+ */
+static void
+printpeer(
+ register struct info_peer *pp,
+ FILE *fp
+ )
+{
+ register int i;
+ const char *str;
+ l_fp tempts;
+ struct sockaddr_storage srcadr, dstadr;
+
+ memset((char *)&srcadr, 0, sizeof(srcadr));
+ memset((char *)&dstadr, 0, sizeof(dstadr));
+ if (pp->v6_flag != 0) {
+ srcadr.ss_family = AF_INET6;
+ dstadr.ss_family = AF_INET6;
+ GET_INADDR6(srcadr) = pp->srcadr6;
+ GET_INADDR6(dstadr) = pp->dstadr6;
+ } else {
+ srcadr.ss_family = AF_INET;
+ dstadr.ss_family = AF_INET;
+ GET_INADDR(srcadr) = pp->srcadr;
+ GET_INADDR(dstadr) = pp->dstadr;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ srcadr.ss_len = SOCKLEN(&srcadr);
+ dstadr.ss_len = SOCKLEN(&dstadr);
+#endif
+ (void) fprintf(fp, "remote %s, local %s\n",
+ stoa(&srcadr), stoa(&dstadr));
+ (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n",
+ modetoa(pp->hmode), modetoa(pp->pmode),
+ pp->stratum, pp->precision);
+
+ (void) fprintf(fp,
+ "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n",
+ pp->leap & 0x2 ? '1' : '0',
+ pp->leap & 0x1 ? '1' : '0',
+ refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5),
+ ufptoa(NTOHS_FP(pp->rootdispersion), 5));
+
+ (void) fprintf(fp,
+ "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n",
+ pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd));
+
+ (void) fprintf(fp,
+ "reach %03o, unreach %d, flash 0x%04x, ",
+ pp->reach, pp->unreach, pp->flash2);
+
+ (void) fprintf(fp, "boffset %s, ttl/mode %d\n",
+ fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl);
+
+ (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer));
+ if (pp->flags == 0) {
+ (void) fprintf(fp, " none\n");
+ } else {
+ str = "";
+ if (pp->flags & INFO_FLAG_SYSPEER) {
+ (void) fprintf(fp, " system_peer");
+ str = ",";
+ }
+ if (pp->flags & INFO_FLAG_CONFIG) {
+ (void) fprintf(fp, "%s config", str);
+ str = ",";
+ }
+ if (pp->flags & INFO_FLAG_REFCLOCK) {
+ (void) fprintf(fp, "%s refclock", str);
+ str = ",";
+ }
+ if (pp->flags & INFO_FLAG_AUTHENABLE) {
+ (void) fprintf(fp, "%s auth", str);
+ str = ",";
+ }
+ if (pp->flags & INFO_FLAG_BCLIENT) {
+ (void) fprintf(fp, "%s bclient", str);
+ str = ",";
+ }
+ if (pp->flags & INFO_FLAG_PREFER) {
+ (void) fprintf(fp, "%s prefer", str);
+ str = ",";
+ }
+ if (pp->flags & INFO_FLAG_BURST) {
+ (void) fprintf(fp, "%s burst", str);
+ }
+ (void) fprintf(fp, "\n");
+ }
+
+ NTOHL_FP(&pp->reftime, &tempts);
+ (void) fprintf(fp, "reference time: %s\n",
+ prettydate(&tempts));
+ NTOHL_FP(&pp->org, &tempts);
+ (void) fprintf(fp, "originate timestamp: %s\n",
+ prettydate(&tempts));
+ NTOHL_FP(&pp->rec, &tempts);
+ (void) fprintf(fp, "receive timestamp: %s\n",
+ prettydate(&tempts));
+ NTOHL_FP(&pp->xmt, &tempts);
+ (void) fprintf(fp, "transmit timestamp: %s\n",
+ prettydate(&tempts));
+
+ (void) fprintf(fp, "filter delay: ");
+ for (i = 0; i < NTP_SHIFT; i++) {
+ (void) fprintf(fp, " %-8.8s",
+ fptoa(NTOHS_FP(pp->filtdelay[i]), 5));
+ if (i == (NTP_SHIFT>>1)-1)
+ (void) fprintf(fp, "\n ");
+ }
+ (void) fprintf(fp, "\n");
+
+ (void) fprintf(fp, "filter offset:");
+ for (i = 0; i < NTP_SHIFT; i++) {
+ NTOHL_FP(&pp->filtoffset[i], &tempts);
+ (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6));
+ if (i == (NTP_SHIFT>>1)-1)
+ (void) fprintf(fp, "\n ");
+ }
+ (void) fprintf(fp, "\n");
+
+ (void) fprintf(fp, "filter order: ");
+ for (i = 0; i < NTP_SHIFT; i++) {
+ (void) fprintf(fp, " %-8d", pp->order[i]);
+ if (i == (NTP_SHIFT>>1)-1)
+ (void) fprintf(fp, "\n ");
+ }
+ (void) fprintf(fp, "\n");
+
+
+ NTOHL_FP(&pp->offset, &tempts);
+ (void) fprintf(fp,
+ "offset %s, delay %s, error bound %s, filter error %s\n",
+ lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5),
+ ufptoa(NTOHS_FP(pp->dispersion), 5),
+ ufptoa(NTOHS_FP(pp->selectdisp), 5));
+}
+
+
+/*
+ * showpeer - show detailed information for a peer
+ */
+static void
+showpeer(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_peer *pp;
+ /* 4 is the maximum number of peers which will fit in a packet */
+ struct info_peer_list *pl, plist[min(MAXARGS, 4)];
+ int qitems;
+ int items;
+ int itemsize;
+ int res;
+ int sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct info_peer_list);
+ else
+ sendsize = v4sizeof(struct info_peer_list);
+
+ for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 4); qitems++) {
+ if (pcmd->argval[qitems].netnum.ss_family == AF_INET) {
+ pl->addr = GET_INADDR(pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->addr6 = GET_INADDR6(pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl->port = (u_short)s_port;
+ pl->hmode = pl->flags = 0;
+ pl = (struct info_peer_list *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, (void *)&pp, 0, sizeof(struct info_peer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer)))
+ return;
+
+ while (items-- > 0) {
+ printpeer(pp, fp);
+ if (items > 0)
+ (void) fprintf(fp, "\n");
+ pp++;
+ }
+}
+
+
+/*
+ * peerstats - return statistics for a peer
+ */
+static void
+peerstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_peer_stats *pp;
+ /* 4 is the maximum number of peers which will fit in a packet */
+ struct info_peer_list *pl, plist[min(MAXARGS, 4)];
+ struct sockaddr_storage src, dst;
+ int qitems;
+ int items;
+ int itemsize;
+ int res;
+ int sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct info_peer_list);
+ else
+ sendsize = v4sizeof(struct info_peer_list);
+
+ memset((char *)plist, 0, sizeof(struct info_peer_list) * min(MAXARGS, 4));
+ for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 4); qitems++) {
+ if (pcmd->argval[qitems].netnum.ss_family == AF_INET) {
+ pl->addr = GET_INADDR(pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->addr6 = GET_INADDR6(pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl->port = (u_short)s_port;
+ pl->hmode = plist[qitems].flags = 0;
+ pl = (struct info_peer_list *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, (void *)&pp, 0,
+ sizeof(struct info_peer_stats));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer_stats)))
+ return;
+
+ while (items-- > 0) {
+ memset((char *)&src, 0, sizeof(src));
+ memset((char *)&dst, 0, sizeof(dst));
+ if (pp->v6_flag != 0) {
+ GET_INADDR6(src) = pp->srcadr6;
+ GET_INADDR6(dst) = pp->dstadr6;
+ src.ss_family = AF_INET6;
+ dst.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(src) = pp->srcadr;
+ GET_INADDR(dst) = pp->dstadr;
+ src.ss_family = AF_INET;
+ dst.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ src.ss_len = SOCKLEN(&src);
+ dst.ss_len = SOCKLEN(&dst);
+#endif
+ (void) fprintf(fp, "remote host: %s\n",
+ nntohost(&src));
+ (void) fprintf(fp, "local interface: %s\n",
+ stoa(&dst));
+ (void) fprintf(fp, "time last received: %lds\n",
+ (long)ntohl(pp->timereceived));
+ (void) fprintf(fp, "time until next send: %lds\n",
+ (long)ntohl(pp->timetosend));
+ (void) fprintf(fp, "reachability change: %lds\n",
+ (long)ntohl(pp->timereachable));
+ (void) fprintf(fp, "packets sent: %ld\n",
+ (long)ntohl(pp->sent));
+ (void) fprintf(fp, "packets received: %ld\n",
+ (long)ntohl(pp->processed));
+ (void) fprintf(fp, "bad authentication: %ld\n",
+ (long)ntohl(pp->badauth));
+ (void) fprintf(fp, "bogus origin: %ld\n",
+ (long)ntohl(pp->bogusorg));
+ (void) fprintf(fp, "duplicate: %ld\n",
+ (long)ntohl(pp->oldpkt));
+ (void) fprintf(fp, "bad dispersion: %ld\n",
+ (long)ntohl(pp->seldisp));
+ (void) fprintf(fp, "bad reference time: %ld\n",
+ (long)ntohl(pp->selbroken));
+ (void) fprintf(fp, "candidate order: %d\n",
+ (int)pp->candidate);
+ if (items > 0)
+ (void) fprintf(fp, "\n");
+ pp++;
+ }
+}
+
+
+/*
+ * loopinfo - show loop filter information
+ */
+static void
+loopinfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_loop *il;
+ int items;
+ int itemsize;
+ int oneline = 0;
+ int res;
+ l_fp tempts;
+
+ if (pcmd->nargs > 0) {
+ if (STREQ(pcmd->argval[0].string, "oneline"))
+ oneline = 1;
+ else if (STREQ(pcmd->argval[0].string, "multiline"))
+ oneline = 0;
+ else {
+ (void) fprintf(stderr, "How many lines?\n");
+ return;
+ }
+ }
+
+again:
+ res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&il, 0,
+ sizeof(struct info_loop));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_loop)))
+ return;
+
+ if (oneline) {
+ l_fp temp2ts;
+
+ NTOHL_FP(&il->last_offset, &tempts);
+ NTOHL_FP(&il->drift_comp, &temp2ts);
+
+ (void) fprintf(fp,
+ "offset %s, frequency %s, time_const %ld, watchdog %ld\n",
+ lfptoa(&tempts, 6),
+ lfptoa(&temp2ts, 3),
+ (u_long)ntohl(il->compliance),
+ (u_long)ntohl(il->watchdog_timer));
+ } else {
+ NTOHL_FP(&il->last_offset, &tempts);
+ (void) fprintf(fp, "offset: %s s\n",
+ lfptoa(&tempts, 6));
+ NTOHL_FP(&il->drift_comp, &tempts);
+ (void) fprintf(fp, "frequency: %s ppm\n",
+ lfptoa(&tempts, 3));
+ (void) fprintf(fp, "poll adjust: %ld\n",
+ (u_long)ntohl(il->compliance));
+ (void) fprintf(fp, "watchdog timer: %ld s\n",
+ (u_long)ntohl(il->watchdog_timer));
+ }
+}
+
+
+/*
+ * sysinfo - show current system state
+ */
+/*ARGSUSED*/
+static void
+sysinfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_sys *is;
+ struct sockaddr_storage peeraddr;
+ int items;
+ int itemsize;
+ int res;
+ l_fp tempts;
+
+again:
+ res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&is, 0,
+ sizeof(struct info_sys));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_sys)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_sys)))
+ return;
+
+ memset((char *)&peeraddr, 0, sizeof(peeraddr));
+ if (is->v6_flag != 0) {
+ GET_INADDR6(peeraddr) = is->peer6;
+ peeraddr.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(peeraddr) = is->peer;
+ peeraddr.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ peeraddr.ss_len = SOCKLEN(&peeraddr);
+#endif
+ (void) fprintf(fp, "system peer: %s\n", nntohost(&peeraddr));
+ (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode));
+ (void) fprintf(fp, "leap indicator: %c%c\n",
+ is->leap & 0x2 ? '1' : '0',
+ is->leap & 0x1 ? '1' : '0');
+ (void) fprintf(fp, "stratum: %d\n", (int)is->stratum);
+ (void) fprintf(fp, "precision: %d\n", (int)is->precision);
+ (void) fprintf(fp, "root distance: %s s\n",
+ fptoa(NTOHS_FP(is->rootdelay), 5));
+ (void) fprintf(fp, "root dispersion: %s s\n",
+ ufptoa(NTOHS_FP(is->rootdispersion), 5));
+ (void) fprintf(fp, "reference ID: [%s]\n",
+ refid_string(is->refid, is->stratum));
+ NTOHL_FP(&is->reftime, &tempts);
+ (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts));
+
+ (void) fprintf(fp, "system flags: ");
+ if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE |
+ INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL |
+ INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) {
+ (void) fprintf(fp, "none\n");
+ } else {
+ if (is->flags & INFO_FLAG_BCLIENT)
+ (void) fprintf(fp, "bclient ");
+ if (is->flags & INFO_FLAG_AUTHENTICATE)
+ (void) fprintf(fp, "auth ");
+ if (is->flags & INFO_FLAG_MONITOR)
+ (void) fprintf(fp, "monitor ");
+ if (is->flags & INFO_FLAG_NTP)
+ (void) fprintf(fp, "ntp ");
+ if (is->flags & INFO_FLAG_KERNEL)
+ (void) fprintf(fp, "kernel ");
+ if (is->flags & INFO_FLAG_FILEGEN)
+ (void) fprintf(fp, "stats ");
+ if (is->flags & INFO_FLAG_CAL)
+ (void) fprintf(fp, "calibrate ");
+ if (is->flags & INFO_FLAG_PPS_SYNC)
+ (void) fprintf(fp, "pps ");
+ (void) fprintf(fp, "\n");
+ }
+ (void) fprintf(fp, "jitter: %s s\n",
+ fptoa(ntohl(is->frequency), 6));
+ (void) fprintf(fp, "stability: %s ppm\n",
+ ufptoa(ntohl(is->stability), 3));
+ (void) fprintf(fp, "broadcastdelay: %s s\n",
+ fptoa(NTOHS_FP(is->bdelay), 6));
+ NTOHL_FP(&is->authdelay, &tempts);
+ (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6));
+}
+
+
+/*
+ * sysstats - print system statistics
+ */
+/*ARGSUSED*/
+static void
+sysstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_sys_stats *ss;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&ss, 0,
+ sizeof(struct info_sys_stats));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (itemsize != sizeof(struct info_sys_stats) &&
+ itemsize != sizeof(struct old_info_sys_stats)) {
+ /* issue warning according to new structure size */
+ checkitemsize(itemsize, sizeof(struct info_sys_stats));
+ return;
+ }
+ fprintf(fp, "time since restart: %ld\n",
+ (u_long)ntohl(ss->timeup));
+ fprintf(fp, "time since reset: %ld\n",
+ (u_long)ntohl(ss->timereset));
+ fprintf(fp, "packets received: %ld\n",
+ (u_long)ntohl(ss->received));
+ fprintf(fp, "packets processed: %ld\n",
+ (u_long)ntohl(ss->processed));
+ fprintf(fp, "current version: %ld\n",
+ (u_long)ntohl(ss->newversionpkt));
+ fprintf(fp, "previous version: %ld\n",
+ (u_long)ntohl(ss->oldversionpkt));
+ fprintf(fp, "bad version: %ld\n",
+ (u_long)ntohl(ss->unknownversion));
+ fprintf(fp, "access denied: %ld\n",
+ (u_long)ntohl(ss->denied));
+ fprintf(fp, "bad length or format: %ld\n",
+ (u_long)ntohl(ss->badlength));
+ fprintf(fp, "bad authentication: %ld\n",
+ (u_long)ntohl(ss->badauth));
+ if (itemsize != sizeof(struct info_sys_stats))
+ return;
+
+ fprintf(fp, "rate exceeded: %ld\n",
+ (u_long)ntohl(ss->limitrejected));
+}
+
+
+
+/*
+ * iostats - print I/O statistics
+ */
+/*ARGSUSED*/
+static void
+iostats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_io_stats *io;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&io, 0,
+ sizeof(struct info_io_stats));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_io_stats)))
+ return;
+
+ (void) fprintf(fp, "time since reset: %ld\n",
+ (u_long)ntohl(io->timereset));
+ (void) fprintf(fp, "receive buffers: %d\n",
+ ntohs(io->totalrecvbufs));
+ (void) fprintf(fp, "free receive buffers: %d\n",
+ ntohs(io->freerecvbufs));
+ (void) fprintf(fp, "used receive buffers: %d\n",
+ ntohs(io->fullrecvbufs));
+ (void) fprintf(fp, "low water refills: %d\n",
+ ntohs(io->lowwater));
+ (void) fprintf(fp, "dropped packets: %ld\n",
+ (u_long)ntohl(io->dropped));
+ (void) fprintf(fp, "ignored packets: %ld\n",
+ (u_long)ntohl(io->ignored));
+ (void) fprintf(fp, "received packets: %ld\n",
+ (u_long)ntohl(io->received));
+ (void) fprintf(fp, "packets sent: %ld\n",
+ (u_long)ntohl(io->sent));
+ (void) fprintf(fp, "packets not sent: %ld\n",
+ (u_long)ntohl(io->notsent));
+ (void) fprintf(fp, "interrupts handled: %ld\n",
+ (u_long)ntohl(io->interrupts));
+ (void) fprintf(fp, "received by int: %ld\n",
+ (u_long)ntohl(io->int_received));
+}
+
+
+/*
+ * memstats - print peer memory statistics
+ */
+/*ARGSUSED*/
+static void
+memstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_mem_stats *mem;
+ int i;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&mem, 0,
+ sizeof(struct info_mem_stats));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_mem_stats)))
+ return;
+
+ (void) fprintf(fp, "time since reset: %ld\n",
+ (u_long)ntohl(mem->timereset));
+ (void) fprintf(fp, "total peer memory: %d\n",
+ ntohs(mem->totalpeermem));
+ (void) fprintf(fp, "free peer memory: %d\n",
+ ntohs(mem->freepeermem));
+ (void) fprintf(fp, "calls to findpeer: %ld\n",
+ (u_long)ntohl(mem->findpeer_calls));
+ (void) fprintf(fp, "new peer allocations: %ld\n",
+ (u_long)ntohl(mem->allocations));
+ (void) fprintf(fp, "peer demobilizations: %ld\n",
+ (u_long)ntohl(mem->demobilizations));
+
+ (void) fprintf(fp, "hash table counts: ");
+ for (i = 0; i < HASH_SIZE; i++) {
+ (void) fprintf(fp, "%4d", (int)mem->hashcount[i]);
+ if ((i % 8) == 7 && i != (HASH_SIZE-1)) {
+ (void) fprintf(fp, "\n ");
+ }
+ }
+ (void) fprintf(fp, "\n");
+}
+
+
+
+/*
+ * timerstats - print timer statistics
+ */
+/*ARGSUSED*/
+static void
+timerstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_timer_stats *tim;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&tim, 0,
+ sizeof(struct info_timer_stats));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_timer_stats)))
+ return;
+
+ (void) fprintf(fp, "time since reset: %ld\n",
+ (u_long)ntohl(tim->timereset));
+ (void) fprintf(fp, "alarms handled: %ld\n",
+ (u_long)ntohl(tim->alarms));
+ (void) fprintf(fp, "alarm overruns: %ld\n",
+ (u_long)ntohl(tim->overflows));
+ (void) fprintf(fp, "calls to transmit: %ld\n",
+ (u_long)ntohl(tim->xmtcalls));
+}
+
+
+/*
+ * addpeer - configure an active mode association
+ */
+static void
+addpeer(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_ACTIVE, 0);
+}
+
+
+/*
+ * addserver - configure a client mode association
+ */
+static void
+addserver(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_CLIENT, 0);
+}
+
+/*
+ * addrefclock - configure a reference clock association
+ */
+static void
+addrefclock(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_CLIENT, 1);
+}
+
+/*
+ * broadcast - configure a broadcast mode association
+ */
+static void
+broadcast(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_BROADCAST, 0);
+}
+
+
+/*
+ * config - configure a new peer association
+ */
+static void
+doconfig(
+ struct parse *pcmd,
+ FILE *fp,
+ int mode,
+ int refc
+ )
+{
+ struct conf_peer cpeer;
+ int items;
+ int itemsize;
+ char *dummy;
+ u_long keyid;
+ u_int version;
+ u_char minpoll;
+ u_int flags;
+ u_char cmode;
+ int res;
+ int sendsize;
+
+again:
+ keyid = 0;
+ version = NTP_OLDVERSION + 1;
+ flags = 0;
+ res = 0;
+ cmode = 0;
+ minpoll = NTP_MINDPOLL;
+
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_peer);
+ else
+ sendsize = v4sizeof(struct conf_peer);
+
+ items = pcmd->nargs;
+
+ if (refc) {
+ if (pcmd->nargs > 1) {
+ cmode = (u_char) pcmd->argval[1].uval;
+ items = 2;
+ }
+ } else {
+ if (pcmd->nargs > 1) {
+ keyid = pcmd->argval[1].uval;
+ if (keyid > 0) {
+ flags |= CONF_FLAG_AUTHENABLE;
+ }
+ if (pcmd->nargs > 2) {
+ version = (u_int)pcmd->argval[2].uval;
+ if (version > NTP_VERSION ||
+ version < NTP_OLDVERSION) {
+ (void)fprintf(fp,
+ "invalid version number %u\n",
+ version);
+ res++;
+ }
+ items = 3;
+ }
+ }
+ }
+
+ while (pcmd->nargs > items) {
+ if (STREQ(pcmd->argval[items].string, "prefer"))
+ flags |= CONF_FLAG_PREFER;
+ else if (STREQ(pcmd->argval[items].string, "burst"))
+ flags |= CONF_FLAG_BURST;
+ else {
+ long val;
+ if (!atoint(pcmd->argval[items].string, &val)) {
+ (void) fprintf(fp,
+ "%s not understood\n",
+ pcmd->argval[items].string);
+ res++;
+ break;
+ } else {
+ if (val >= NTP_MINPOLL && val <= NTP_MAXPOLL) {
+ minpoll = (u_char)val;
+ } else {
+ (void) fprintf(fp,
+ "minpol must be within %d..%d\n",
+ NTP_MINPOLL, NTP_MAXPOLL);
+ res++;
+ break;
+ }
+ }
+ }
+ items++;
+ }
+
+ if (res)
+ return;
+
+ memset((void *)&cpeer, 0, sizeof(cpeer));
+
+ if (pcmd->argval[0].netnum.ss_family == AF_INET) {
+ cpeer.peeraddr = GET_INADDR(pcmd->argval[0].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ cpeer.v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ cpeer.peeraddr6 = GET_INADDR6(pcmd->argval[0].netnum);
+ cpeer.v6_flag = 1;
+ }
+ cpeer.hmode = (u_char) mode;
+ cpeer.keyid = keyid;
+ cpeer.version = (u_char) version;
+ cpeer.minpoll = minpoll;
+ cpeer.maxpoll = NTP_MAXDPOLL;
+ cpeer.flags = (u_char)flags;
+ cpeer.ttl = cmode;
+
+ res = doquery(impl_ver, REQ_CONFIG, 1, 1,
+ sendsize, (char *)&cpeer, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_peer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == INFO_ERR_FMT) {
+ (void) fprintf(fp,
+ "***Retrying command with old conf_peer size\n");
+ res = doquery(impl_ver, REQ_CONFIG, 1, 1,
+ sizeof(struct old_conf_peer), (char *)&cpeer,
+ &items, &itemsize, &dummy, 0,
+ sizeof(struct conf_peer));
+ }
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+/*
+ * unconfig - unconfigure some associations
+ */
+static void
+unconfig(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ /* 8 is the maximum number of peers which will fit in a packet */
+ struct conf_unpeer *pl, plist[min(MAXARGS, 8)];
+ int qitems;
+ int items;
+ int itemsize;
+ char *dummy;
+ int res;
+ int sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_unpeer);
+ else
+ sendsize = v4sizeof(struct conf_unpeer);
+
+ for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 8); qitems++) {
+ if (pcmd->argval[0].netnum.ss_family == AF_INET) {
+ pl->peeraddr = GET_INADDR(pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->peeraddr6 =
+ GET_INADDR6(pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl = (struct conf_unpeer *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_unpeer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+}
+
+
+/*
+ * set - set some system flags
+ */
+static void
+set(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doset(pcmd, fp, REQ_SET_SYS_FLAG);
+}
+
+
+/*
+ * clear - clear some system flags
+ */
+static void
+sys_clear(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doset(pcmd, fp, REQ_CLR_SYS_FLAG);
+}
+
+
+/*
+ * doset - set/clear system flags
+ */
+static void
+doset(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ /* 8 is the maximum number of peers which will fit in a packet */
+ struct conf_sys_flags sys;
+ int items;
+ int itemsize;
+ char *dummy;
+ int res;
+
+ sys.flags = 0;
+ res = 0;
+ for (items = 0; items < pcmd->nargs; items++) {
+ if (STREQ(pcmd->argval[items].string, "auth"))
+ sys.flags |= SYS_FLAG_AUTH;
+ else if (STREQ(pcmd->argval[items].string, "bclient"))
+ sys.flags |= SYS_FLAG_BCLIENT;
+ else if (STREQ(pcmd->argval[items].string, "calibrate"))
+ sys.flags |= SYS_FLAG_CAL;
+ else if (STREQ(pcmd->argval[items].string, "kernel"))
+ sys.flags |= SYS_FLAG_KERNEL;
+ else if (STREQ(pcmd->argval[items].string, "monitor"))
+ sys.flags |= SYS_FLAG_MONITOR;
+ else if (STREQ(pcmd->argval[items].string, "ntp"))
+ sys.flags |= SYS_FLAG_NTP;
+ else if (STREQ(pcmd->argval[items].string, "pps"))
+ sys.flags |= SYS_FLAG_PPS;
+ else if (STREQ(pcmd->argval[items].string, "stats"))
+ sys.flags |= SYS_FLAG_FILEGEN;
+ else {
+ (void) fprintf(fp, "Unknown flag %s\n",
+ pcmd->argval[items].string);
+ res = 1;
+ }
+ }
+
+ if (res || sys.flags == 0)
+ return;
+
+again:
+ res = doquery(impl_ver, req, 1, 1,
+ sizeof(struct conf_sys_flags), (char *)&sys, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_sys_flags));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+}
+
+
+/*
+ * data for printing/interrpreting the restrict flags
+ */
+struct resflags {
+ const char *str;
+ int bit;
+};
+
+static struct resflags resflags[] = {
+ { "ignore", RES_IGNORE },
+ { "noserve", RES_DONTSERVE },
+ { "notrust", RES_DONTTRUST },
+ { "noquery", RES_NOQUERY },
+ { "nomodify", RES_NOMODIFY },
+ { "nopeer", RES_NOPEER },
+ { "notrap", RES_NOTRAP },
+ { "lptrap", RES_LPTRAP },
+ { "limited", RES_LIMITED },
+ { "version", RES_VERSION },
+ { "kod", RES_DEMOBILIZE },
+ { "timeout", RES_TIMEOUT },
+
+ { "", 0 }
+};
+
+static struct resflags resmflags[] = {
+ { "ntpport", RESM_NTPONLY },
+ { "interface", RESM_INTERFACE },
+ { "", 0 }
+};
+
+
+/*
+ * reslist - obtain and print the server's restrict list
+ */
+/*ARGSUSED*/
+static void
+reslist(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_restrict *rl;
+ struct sockaddr_storage resaddr;
+ struct sockaddr_storage maskaddr;
+ int items;
+ int itemsize;
+ int res;
+ int skip;
+ char *addr;
+ char *mask;
+ struct resflags *rf;
+ u_int32 count;
+ u_short flags;
+ u_short mflags;
+ char flagstr[300];
+ static const char *comma = ", ";
+
+again:
+ res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&rl, 0,
+ sizeof(struct info_restrict));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_restrict)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_restrict)))
+ return;
+
+ (void) fprintf(fp,
+ " address mask count flags\n");
+ (void) fprintf(fp,
+ "=====================================================================\n");
+
+ while (items > 0) {
+ memset((char *)&resaddr, 0, sizeof(resaddr));
+ memset((char *)&maskaddr, 0, sizeof(maskaddr));
+ if (rl->v6_flag != 0) {
+ GET_INADDR6(resaddr) = rl->addr6;
+ GET_INADDR6(maskaddr) = rl->mask6;
+ resaddr.ss_family = AF_INET6;
+ maskaddr.ss_family = AF_INET6;
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ resaddr.ss_len = SOCKLEN(&resaddr);
+#endif
+ addr = nntohost(&resaddr);
+ } else {
+ GET_INADDR(resaddr) = rl->addr;
+ GET_INADDR(maskaddr) = rl->mask;
+ resaddr.ss_family = AF_INET;
+ maskaddr.ss_family = AF_INET;
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ resaddr.ss_len = SOCKLEN(&resaddr);
+#endif
+ if ((rl->mask == (u_int32)0xffffffff))
+ addr = nntohost(&resaddr);
+ else
+ addr = stoa(&resaddr);
+ }
+ mask = stoa(&maskaddr);
+ skip = 1;
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (rl->v6_flag == 0)))
+ skip = 0;
+ count = ntohl(rl->count);
+ flags = ntohs(rl->flags);
+ mflags = ntohs(rl->mflags);
+ flagstr[0] = '\0';
+
+ res = 1;
+ rf = &resmflags[0];
+ while (rf->bit != 0) {
+ if (mflags & rf->bit) {
+ if (!res)
+ (void) strcat(flagstr, comma);
+ res = 0;
+ (void) strcat(flagstr, rf->str);
+ }
+ rf++;
+ }
+
+ rf = &resflags[0];
+ while (rf->bit != 0) {
+ if (flags & rf->bit) {
+ if (!res)
+ (void) strcat(flagstr, comma);
+ res = 0;
+ (void) strcat(flagstr, rf->str);
+ }
+ rf++;
+ }
+
+ if (flagstr[0] == '\0')
+ (void) strcpy(flagstr, "none");
+
+ if (!skip)
+ (void) fprintf(fp, "%-15.15s %-15.15s %9ld %s\n",
+ addr, mask, (u_long)count, flagstr);
+ rl++;
+ items--;
+ }
+}
+
+
+
+/*
+ * new_restrict - create/add a set of restrictions
+ */
+static void
+new_restrict(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_restrict(pcmd, fp, REQ_RESADDFLAGS);
+}
+
+
+/*
+ * unrestrict - remove restriction flags from existing entry
+ */
+static void
+unrestrict(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_restrict(pcmd, fp, REQ_RESSUBFLAGS);
+}
+
+
+/*
+ * delrestrict - delete an existing restriction
+ */
+static void
+delrestrict(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_restrict(pcmd, fp, REQ_UNRESTRICT);
+}
+
+
+/*
+ * do_restrict - decode commandline restrictions and make the request
+ */
+static void
+do_restrict(
+ struct parse *pcmd,
+ FILE *fp,
+ int req_code
+ )
+{
+ struct conf_restrict cres;
+ int items;
+ int itemsize;
+ char *dummy;
+ u_int32 num;
+ u_long bit;
+ int i;
+ int res;
+ int err;
+ int sendsize;
+
+ /* Initialize cres */
+ cres.addr = 0;
+ cres.mask = 0;
+ cres.flags = 0;
+ cres.mflags = 0;
+ cres.v6_flag = 0;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_restrict);
+ else
+ sendsize = v4sizeof(struct conf_restrict);
+
+ if (pcmd->argval[0].netnum.ss_family == AF_INET) {
+ cres.addr = GET_INADDR(pcmd->argval[0].netnum);
+ cres.mask = GET_INADDR(pcmd->argval[1].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ cres.v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ cres.addr6 = GET_INADDR6(pcmd->argval[0].netnum);
+ cres.v6_flag = 1;
+ }
+ cres.flags = 0;
+ cres.mflags = 0;
+ err = 0;
+ for (res = 2; res < pcmd->nargs; res++) {
+ if (STREQ(pcmd->argval[res].string, "ntpport")) {
+ cres.mflags |= RESM_NTPONLY;
+ } else {
+ for (i = 0; resflags[i].bit != 0; i++) {
+ if (STREQ(pcmd->argval[res].string,
+ resflags[i].str))
+ break;
+ }
+ if (resflags[i].bit != 0) {
+ cres.flags |= resflags[i].bit;
+ if (req_code == REQ_UNRESTRICT) {
+ (void) fprintf(fp,
+ "Flag %s inappropriate\n",
+ resflags[i].str);
+ err++;
+ }
+ } else {
+ (void) fprintf(fp, "Unknown flag %s\n",
+ pcmd->argval[res].string);
+ err++;
+ }
+ }
+ }
+
+ /*
+ * Make sure mask for default address is zero. Otherwise,
+ * make sure mask bits are contiguous.
+ */
+ if (pcmd->argval[0].netnum.ss_family == AF_INET) {
+ if (cres.addr == 0) {
+ cres.mask = 0;
+ } else {
+ num = ntohl(cres.mask);
+ for (bit = 0x80000000; bit != 0; bit >>= 1)
+ if ((num & bit) == 0)
+ break;
+ for ( ; bit != 0; bit >>= 1)
+ if ((num & bit) != 0)
+ break;
+ if (bit != 0) {
+ (void) fprintf(fp, "Invalid mask %s\n",
+ numtoa(cres.mask));
+ err++;
+ }
+ }
+ } else {
+ /* XXX IPv6 sanity checking stuff */
+ }
+
+ if (err)
+ return;
+
+ res = doquery(impl_ver, req_code, 1, 1,
+ sendsize, (char *)&cres, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_restrict));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+/*
+ * monlist - obtain and print the server's monitor data
+ */
+/*ARGSUSED*/
+static void
+monlist(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ char *struct_star;
+ struct sockaddr_storage addr;
+ struct sockaddr_storage dstadr;
+ int items;
+ int itemsize;
+ int res;
+ int version = -1;
+
+ if (pcmd->nargs > 0) {
+ version = pcmd->argval[0].ival;
+ }
+
+again:
+ res = doquery(impl_ver,
+ (version == 1 || version == -1) ? REQ_MON_GETLIST_1 :
+ REQ_MON_GETLIST, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, &struct_star,
+ (version < 0) ? (1 << INFO_ERR_REQ) : 0,
+ sizeof(struct info_monitor_1));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == INFO_ERR_REQ && version < 0)
+ res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, &struct_star, 0,
+ sizeof(struct info_monitor));
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (itemsize == sizeof(struct info_monitor_1) ||
+ itemsize == v4sizeof(struct info_monitor_1)) {
+ struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star;
+
+ (void) fprintf(fp,
+ "remote address port local address count m ver code avgint lstint\n");
+ (void) fprintf(fp,
+ "===============================================================================\n");
+ while (items > 0) {
+ memset((char *)&addr, 0, sizeof(addr));
+ memset((char *)&dstadr, 0, sizeof(dstadr));
+ if (ml->v6_flag != 0) {
+ GET_INADDR6(addr) = ml->addr6;
+ addr.ss_family = AF_INET6;
+ GET_INADDR6(dstadr) = ml->daddr6;
+ dstadr.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(addr) = ml->addr;
+ addr.ss_family = AF_INET;
+ GET_INADDR(dstadr) = ml->daddr;
+ dstadr.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ addr.ss_len = SOCKLEN(&addr);
+ dstadr.ss_len = SOCKLEN(&dstadr);
+#endif
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (ml->v6_flag == 0)))
+ (void) fprintf(fp,
+ "%-22.22s %5d %-15s %8ld %1d %1d %6lx %6lu %7lu\n",
+ nntohost(&addr),
+ ntohs(ml->port),
+ stoa(&dstadr),
+ (u_long)ntohl(ml->count),
+ ml->mode,
+ ml->version,
+ (u_long)ntohl(ml->lastdrop),
+ (u_long)ntohl(ml->lasttime),
+ (u_long)ntohl(ml->firsttime));
+ ml++;
+ items--;
+ }
+ } else if (itemsize == sizeof(struct info_monitor) ||
+ itemsize == v4sizeof(struct info_monitor)) {
+ struct info_monitor *ml = (struct info_monitor *) struct_star;
+
+ (void) fprintf(fp,
+ " address port count mode ver code avgint lstint\n");
+ (void) fprintf(fp,
+ "===============================================================================\n");
+ while (items > 0) {
+ memset((char *)&dstadr, 0, sizeof(dstadr));
+ if (ml->v6_flag != 0) {
+ GET_INADDR6(dstadr) = ml->addr6;
+ dstadr.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(dstadr) = ml->addr;
+ dstadr.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ dstadr.ss_len = SOCKLEN(&dstadr);
+#endif
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (ml->v6_flag == 0)))
+ (void) fprintf(fp,
+ "%-25.25s %5d %9ld %4d %2d %9lx %9lu %9lu\n",
+ nntohost(&dstadr),
+ ntohs(ml->port),
+ (u_long)ntohl(ml->count),
+ ml->mode,
+ ml->version,
+ (u_long)ntohl(ml->lastdrop),
+ (u_long)ntohl(ml->lasttime),
+ (u_long)ntohl(ml->firsttime));
+ ml++;
+ items--;
+ }
+ } else if (itemsize == sizeof(struct old_info_monitor)) {
+ struct old_info_monitor *oml = (struct old_info_monitor *)struct_star;
+ (void) fprintf(fp,
+ " address port count mode version lasttime firsttime\n");
+ (void) fprintf(fp,
+ "======================================================================\n");
+ while (items > 0) {
+ memset((char *)&dstadr, 0, sizeof(dstadr));
+ if (oml->v6_flag != 0) {
+ GET_INADDR6(dstadr) = oml->addr6;
+ dstadr.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(dstadr) = oml->addr;
+ dstadr.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ dstadr.ss_len = SOCKLEN(&dstadr);
+#endif
+ (void) fprintf(fp, "%-20.20s %5d %9ld %4d %3d %9lu %9lu\n",
+ nntohost(&dstadr),
+ ntohs(oml->port),
+ (u_long)ntohl(oml->count),
+ oml->mode,
+ oml->version,
+ (u_long)ntohl(oml->lasttime),
+ (u_long)ntohl(oml->firsttime));
+ oml++;
+ items--;
+ }
+ } else {
+ /* issue warning according to new info_monitor size */
+ checkitemsize(itemsize, sizeof(struct info_monitor));
+ }
+}
+
+
+/*
+ * Mapping between command line strings and stat reset flags
+ */
+struct statreset {
+ const char *str;
+ int flag;
+} sreset[] = {
+ { "io", RESET_FLAG_IO },
+ { "sys", RESET_FLAG_SYS },
+ { "mem", RESET_FLAG_MEM },
+ { "timer", RESET_FLAG_TIMER },
+ { "auth", RESET_FLAG_AUTH },
+ { "allpeers", RESET_FLAG_ALLPEERS },
+ { "", 0 }
+};
+
+/*
+ * reset - reset statistic counters
+ */
+static void
+reset(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct reset_flags rflags;
+ int items;
+ int itemsize;
+ char *dummy;
+ int i;
+ int res;
+ int err;
+
+ err = 0;
+ rflags.flags = 0;
+ for (res = 0; res < pcmd->nargs; res++) {
+ for (i = 0; sreset[i].flag != 0; i++) {
+ if (STREQ(pcmd->argval[res].string, sreset[i].str))
+ break;
+ }
+ if (sreset[i].flag == 0) {
+ (void) fprintf(fp, "Flag %s unknown\n",
+ pcmd->argval[res].string);
+ err++;
+ } else {
+ rflags.flags |= sreset[i].flag;
+ }
+ }
+
+ if (err) {
+ (void) fprintf(fp, "Not done due to errors\n");
+ return;
+ }
+
+again:
+ res = doquery(impl_ver, REQ_RESET_STATS, 1, 1,
+ sizeof(struct reset_flags), (char *)&rflags, &items,
+ &itemsize, &dummy, 0, sizeof(struct reset_flags));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * preset - reset stat counters for particular peers
+ */
+static void
+preset(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ /* 8 is the maximum number of peers which will fit in a packet */
+ struct conf_unpeer *pl, plist[min(MAXARGS, 8)];
+ int qitems;
+ int items;
+ int itemsize;
+ char *dummy;
+ int res;
+ int sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_unpeer);
+ else
+ sendsize = v4sizeof(struct conf_unpeer);
+
+ for (qitems = 0, pl = plist; qitems < min(pcmd->nargs, 8); qitems++) {
+ if (pcmd->argval[qitems].netnum.ss_family == AF_INET) {
+ pl->peeraddr = GET_INADDR(pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->peeraddr6 =
+ GET_INADDR6(pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl = (struct conf_unpeer *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_unpeer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+}
+
+
+/*
+ * readkeys - request the server to reread the keys file
+ */
+/*ARGSUSED*/
+static void
+readkeys(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ int items;
+ int itemsize;
+ char *dummy;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0,
+ &items, &itemsize, &dummy, 0, sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+/*
+ * trustkey - add some keys to the trusted key list
+ */
+static void
+trustkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_trustkey(pcmd, fp, REQ_TRUSTKEY);
+}
+
+
+/*
+ * untrustkey - remove some keys from the trusted key list
+ */
+static void
+untrustkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_trustkey(pcmd, fp, REQ_UNTRUSTKEY);
+}
+
+
+/*
+ * do_trustkey - do grunge work of adding/deleting keys
+ */
+static void
+do_trustkey(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ u_long keyids[MAXARGS];
+ int i;
+ int items;
+ int itemsize;
+ char *dummy;
+ int ritems;
+ int res;
+
+ ritems = 0;
+ for (i = 0; i < pcmd->nargs; i++) {
+ keyids[ritems++] = pcmd->argval[i].uval;
+ }
+
+again:
+ res = doquery(impl_ver, req, 1, ritems, sizeof(u_long),
+ (char *)keyids, &items, &itemsize, &dummy, 0,
+ sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * authinfo - obtain and print info about authentication
+ */
+/*ARGSUSED*/
+static void
+authinfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_auth *ia;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&ia, 0,
+ sizeof(struct info_auth));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_auth)))
+ return;
+
+ (void) fprintf(fp, "time since reset: %ld\n",
+ (u_long)ntohl(ia->timereset));
+ (void) fprintf(fp, "stored keys: %ld\n",
+ (u_long)ntohl(ia->numkeys));
+ (void) fprintf(fp, "free keys: %ld\n",
+ (u_long)ntohl(ia->numfreekeys));
+ (void) fprintf(fp, "key lookups: %ld\n",
+ (u_long)ntohl(ia->keylookups));
+ (void) fprintf(fp, "keys not found: %ld\n",
+ (u_long)ntohl(ia->keynotfound));
+ (void) fprintf(fp, "uncached keys: %ld\n",
+ (u_long)ntohl(ia->keyuncached));
+ (void) fprintf(fp, "encryptions: %ld\n",
+ (u_long)ntohl(ia->encryptions));
+ (void) fprintf(fp, "decryptions: %ld\n",
+ (u_long)ntohl(ia->decryptions));
+ (void) fprintf(fp, "expired keys: %ld\n",
+ (u_long)ntohl(ia->expired));
+}
+
+
+
+/*
+ * traps - obtain and print a list of traps
+ */
+/*ARGSUSED*/
+static void
+traps(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ int i;
+ struct info_trap *it;
+ struct sockaddr_storage trap_addr, local_addr;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&it, 0,
+ sizeof(struct info_trap));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_trap)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_trap)))
+ return;
+
+ for (i = 0; i < items; i++ ) {
+ if (i != 0)
+ (void) fprintf(fp, "\n");
+ memset((char *)&trap_addr, 0, sizeof(trap_addr));
+ memset((char *)&local_addr, 0, sizeof(local_addr));
+ if (it->v6_flag != 0) {
+ GET_INADDR6(trap_addr) = it->trap_address6;
+ GET_INADDR6(local_addr) = it->local_address6;
+ trap_addr.ss_family = AF_INET6;
+ local_addr.ss_family = AF_INET6;
+ } else {
+ GET_INADDR(trap_addr) = it->trap_address;
+ GET_INADDR(local_addr) = it->local_address;
+ trap_addr.ss_family = AF_INET;
+ local_addr.ss_family = AF_INET;
+ }
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ trap_addr.ss_len = SOCKLEN(&trap_addr);
+ local_addr.ss_len = SOCKLEN(&local_addr);
+#endif
+ (void) fprintf(fp, "address %s, port %d\n",
+ stoa(&trap_addr),
+ ntohs(it->trap_port));
+ (void) fprintf(fp, "interface: %s, ",
+ (it->local_address == 0)
+ ? "wildcard"
+ : stoa(&local_addr));
+ if (ntohl(it->flags) & TRAP_CONFIGURED)
+ (void) fprintf(fp, "configured\n");
+ else if (ntohl(it->flags) & TRAP_NONPRIO)
+ (void) fprintf(fp, "low priority\n");
+ else
+ (void) fprintf(fp, "normal priority\n");
+
+ (void) fprintf(fp, "set for %ld secs, last set %ld secs ago\n",
+ (long)ntohl(it->origtime),
+ (long)ntohl(it->settime));
+ (void) fprintf(fp, "sequence %d, number of resets %ld\n",
+ ntohs(it->sequence),
+ (long)ntohl(it->resets));
+ }
+}
+
+
+/*
+ * addtrap - configure a trap
+ */
+static void
+addtrap(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_addclr_trap(pcmd, fp, REQ_ADD_TRAP);
+}
+
+
+/*
+ * clrtrap - clear a trap from the server
+ */
+static void
+clrtrap(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_addclr_trap(pcmd, fp, REQ_CLR_TRAP);
+}
+
+
+/*
+ * do_addclr_trap - do grunge work of adding/deleting traps
+ */
+static void
+do_addclr_trap(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ struct conf_trap ctrap;
+ int items;
+ int itemsize;
+ char *dummy;
+ int res;
+ int sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_trap);
+ else
+ sendsize = v4sizeof(struct conf_trap);
+
+ if (pcmd->argval[0].netnum.ss_family == AF_INET) {
+ ctrap.trap_address = GET_INADDR(pcmd->argval[0].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ ctrap.v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ ctrap.trap_address6 = GET_INADDR6(pcmd->argval[0].netnum);
+ ctrap.v6_flag = 1;
+ }
+ ctrap.local_address = 0;
+ ctrap.trap_port = htons(TRAPPORT);
+ ctrap.unused = 0;
+
+ if (pcmd->nargs > 1) {
+ ctrap.trap_port
+ = htons((u_short)(pcmd->argval[1].uval & 0xffff));
+ if (pcmd->nargs > 2) {
+ if (pcmd->argval[2].netnum.ss_family !=
+ pcmd->argval[0].netnum.ss_family) {
+ fprintf(stderr,
+ "***Cannot mix IPv4 and IPv6 addresses\n");
+ return;
+ }
+ if (pcmd->argval[2].netnum.ss_family == AF_INET)
+ ctrap.local_address = GET_INADDR(pcmd->argval[2].netnum);
+ else
+ ctrap.local_address6 = GET_INADDR6(pcmd->argval[2].netnum);
+ }
+ }
+
+ res = doquery(impl_ver, req, 1, 1, sendsize,
+ (char *)&ctrap, &items, &itemsize, &dummy, 0,
+ sizeof(struct conf_trap));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * requestkey - change the server's request key (a dangerous request)
+ */
+static void
+requestkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_changekey(pcmd, fp, REQ_REQUEST_KEY);
+}
+
+
+/*
+ * controlkey - change the server's control key
+ */
+static void
+controlkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_changekey(pcmd, fp, REQ_CONTROL_KEY);
+}
+
+
+
+/*
+ * do_changekey - do grunge work of changing keys
+ */
+static void
+do_changekey(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ u_long key;
+ int items;
+ int itemsize;
+ char *dummy;
+ int res;
+
+
+ key = htonl((u_int32)pcmd->argval[0].uval);
+
+again:
+ res = doquery(impl_ver, req, 1, 1, sizeof(u_int32),
+ (char *)&key, &items, &itemsize, &dummy, 0,
+ sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * ctlstats - obtain and print info about authentication
+ */
+/*ARGSUSED*/
+static void
+ctlstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_control *ic;
+ int items;
+ int itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&ic, 0,
+ sizeof(struct info_control));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_control)))
+ return;
+
+ (void) fprintf(fp, "time since reset: %ld\n",
+ (u_long)ntohl(ic->ctltimereset));
+ (void) fprintf(fp, "requests received: %ld\n",
+ (u_long)ntohl(ic->numctlreq));
+ (void) fprintf(fp, "responses sent: %ld\n",
+ (u_long)ntohl(ic->numctlresponses));
+ (void) fprintf(fp, "fragments sent: %ld\n",
+ (u_long)ntohl(ic->numctlfrags));
+ (void) fprintf(fp, "async messages sent: %ld\n",
+ (u_long)ntohl(ic->numasyncmsgs));
+ (void) fprintf(fp, "error msgs sent: %ld\n",
+ (u_long)ntohl(ic->numctlerrors));
+ (void) fprintf(fp, "total bad pkts: %ld\n",
+ (u_long)ntohl(ic->numctlbadpkts));
+ (void) fprintf(fp, "packet too short: %ld\n",
+ (u_long)ntohl(ic->numctltooshort));
+ (void) fprintf(fp, "response on input: %ld\n",
+ (u_long)ntohl(ic->numctlinputresp));
+ (void) fprintf(fp, "fragment on input: %ld\n",
+ (u_long)ntohl(ic->numctlinputfrag));
+ (void) fprintf(fp, "error set on input: %ld\n",
+ (u_long)ntohl(ic->numctlinputerr));
+ (void) fprintf(fp, "bad offset on input: %ld\n",
+ (u_long)ntohl(ic->numctlbadoffset));
+ (void) fprintf(fp, "bad version packets: %ld\n",
+ (u_long)ntohl(ic->numctlbadversion));
+ (void) fprintf(fp, "data in pkt too short: %ld\n",
+ (u_long)ntohl(ic->numctldatatooshort));
+ (void) fprintf(fp, "unknown op codes: %ld\n",
+ (u_long)ntohl(ic->numctlbadop));
+}
+
+
+/*
+ * clockstat - get and print clock status information
+ */
+static void
+clockstat(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_clock *cl;
+ /* 8 is the maximum number of clocks which will fit in a packet */
+ u_long clist[min(MAXARGS, 8)];
+ int qitems;
+ int items;
+ int itemsize;
+ int res;
+ l_fp ts;
+ struct clktype *clk;
+ u_long ltemp;
+
+ for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++)
+ clist[qitems] = GET_INADDR(pcmd->argval[qitems].netnum);
+
+again:
+ res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems,
+ sizeof(u_int32), (char *)clist, &items,
+ &itemsize, (void *)&cl, 0, sizeof(struct info_clock));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_clock)))
+ return;
+
+ while (items-- > 0) {
+ (void) fprintf(fp, "clock address: %s\n",
+ numtoa(cl->clockadr));
+ for (clk = clktypes; clk->code >= 0; clk++)
+ if (clk->code == cl->type)
+ break;
+ if (clk->code >= 0)
+ (void) fprintf(fp, "clock type: %s\n",
+ clk->clocktype);
+ else
+ (void) fprintf(fp, "clock type: unknown type (%d)\n",
+ cl->type);
+ (void) fprintf(fp, "last event: %d\n",
+ cl->lastevent);
+ (void) fprintf(fp, "current status: %d\n",
+ cl->currentstatus);
+ (void) fprintf(fp, "number of polls: %lu\n",
+ (u_long)ntohl(cl->polls));
+ (void) fprintf(fp, "no response to poll: %lu\n",
+ (u_long)ntohl(cl->noresponse));
+ (void) fprintf(fp, "bad format responses: %lu\n",
+ (u_long)ntohl(cl->badformat));
+ (void) fprintf(fp, "bad data responses: %lu\n",
+ (u_long)ntohl(cl->baddata));
+ (void) fprintf(fp, "running time: %lu\n",
+ (u_long)ntohl(cl->timestarted));
+ NTOHL_FP(&cl->fudgetime1, &ts);
+ (void) fprintf(fp, "fudge time 1: %s\n",
+ lfptoa(&ts, 6));
+ NTOHL_FP(&cl->fudgetime2, &ts);
+ (void) fprintf(fp, "fudge time 2: %s\n",
+ lfptoa(&ts, 6));
+ (void) fprintf(fp, "stratum: %ld\n",
+ (u_long)ntohl(cl->fudgeval1));
+ ltemp = ntohl(cl->fudgeval2);
+ (void) fprintf(fp, "reference ID: %s\n",
+ (char *)&ltemp);
+ (void) fprintf(fp, "fudge flags: 0x%x\n",
+ cl->flags);
+
+ if (items > 0)
+ (void) fprintf(fp, "\n");
+ cl++;
+ }
+}
+
+
+/*
+ * fudge - set clock fudge factors
+ */
+static void
+fudge(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct conf_fudge fudgedata;
+ int items;
+ int itemsize;
+ char *dummy;
+ l_fp ts;
+ int res;
+ long val;
+ u_long u_val;
+ int err;
+
+
+ err = 0;
+ memset((char *)&fudgedata, 0, sizeof fudgedata);
+ fudgedata.clockadr = GET_INADDR(pcmd->argval[0].netnum);
+
+ if (STREQ(pcmd->argval[1].string, "time1")) {
+ fudgedata.which = htonl(FUDGE_TIME1);
+ if (!atolfp(pcmd->argval[2].string, &ts))
+ err = 1;
+ else
+ NTOHL_FP(&ts, &fudgedata.fudgetime);
+ } else if (STREQ(pcmd->argval[1].string, "time2")) {
+ fudgedata.which = htonl(FUDGE_TIME2);
+ if (!atolfp(pcmd->argval[2].string, &ts))
+ err = 1;
+ else
+ NTOHL_FP(&ts, &fudgedata.fudgetime);
+ } else if (STREQ(pcmd->argval[1].string, "val1")) {
+ fudgedata.which = htonl(FUDGE_VAL1);
+ if (!atoint(pcmd->argval[2].string, &val))
+ err = 1;
+ else
+ fudgedata.fudgeval_flags = htonl(val);
+ } else if (STREQ(pcmd->argval[1].string, "val2")) {
+ fudgedata.which = htonl(FUDGE_VAL2);
+ if (!atoint(pcmd->argval[2].string, &val))
+ err = 1;
+ else
+ fudgedata.fudgeval_flags = htonl((u_int32)val);
+ } else if (STREQ(pcmd->argval[1].string, "flags")) {
+ fudgedata.which = htonl(FUDGE_FLAGS);
+ if (!hextoint(pcmd->argval[2].string, &u_val))
+ err = 1;
+ else
+ fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf));
+ } else {
+ (void) fprintf(stderr, "What fudge is %s?\n",
+ pcmd->argval[1].string);
+ return;
+ }
+
+ if (err) {
+ (void) fprintf(stderr, "Unknown fudge parameter %s\n",
+ pcmd->argval[2].string);
+ return;
+ }
+
+again:
+ res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1,
+ sizeof(struct conf_fudge), (char *)&fudgedata, &items,
+ &itemsize, &dummy, 0, sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+/*
+ * clkbug - get and print clock debugging information
+ */
+static void
+clkbug(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ register int i;
+ register int n;
+ register u_int32 s;
+ struct info_clkbug *cl;
+ /* 8 is the maximum number of clocks which will fit in a packet */
+ u_long clist[min(MAXARGS, 8)];
+ u_int32 ltemp;
+ int qitems;
+ int items;
+ int itemsize;
+ int res;
+ int needsp;
+ l_fp ts;
+
+ for (qitems = 0; qitems < min(pcmd->nargs, 8); qitems++)
+ clist[qitems] = GET_INADDR(pcmd->argval[qitems].netnum);
+
+again:
+ res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems,
+ sizeof(u_int32), (char *)clist, &items,
+ &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_clkbug)))
+ return;
+
+ while (items-- > 0) {
+ (void) fprintf(fp, "clock address: %s\n",
+ numtoa(cl->clockadr));
+ n = (int)cl->nvalues;
+ (void) fprintf(fp, "values: %d", n);
+ s = ntohs(cl->svalues);
+ if (n > NUMCBUGVALUES)
+ n = NUMCBUGVALUES;
+ for (i = 0; i < n; i++) {
+ ltemp = ntohl(cl->values[i]);
+ ltemp &= 0xffffffff; /* HMS: This does nothing now */
+ if ((i & 0x3) == 0)
+ (void) fprintf(fp, "\n");
+ if (s & (1 << i))
+ (void) fprintf(fp, "%12ld", (u_long)ltemp);
+ else
+ (void) fprintf(fp, "%12lu", (u_long)ltemp);
+ }
+ (void) fprintf(fp, "\n");
+
+ n = (int)cl->ntimes;
+ (void) fprintf(fp, "times: %d", n);
+ s = ntohl(cl->stimes);
+ if (n > NUMCBUGTIMES)
+ n = NUMCBUGTIMES;
+ needsp = 0;
+ for (i = 0; i < n; i++) {
+ if ((i & 0x1) == 0) {
+ (void) fprintf(fp, "\n");
+ } else {
+ for (;needsp > 0; needsp--)
+ putc(' ', fp);
+ }
+ NTOHL_FP(&cl->times[i], &ts);
+ if (s & (1 << i)) {
+ (void) fprintf(fp, "%17s",
+ lfptoa(&ts, 6));
+ needsp = 22;
+ } else {
+ (void) fprintf(fp, "%37s",
+ uglydate(&ts));
+ needsp = 2;
+ }
+ }
+ (void) fprintf(fp, "\n");
+ if (items > 0) {
+ cl++;
+ (void) fprintf(fp, "\n");
+ }
+ }
+}
+
+
+/*
+ * kerninfo - display the kernel pll/pps variables
+ */
+static void
+kerninfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_kernel *ik;
+ int items;
+ int itemsize;
+ int res;
+ unsigned status;
+ double tscale = 1e-6;
+
+again:
+ res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&ik, 0,
+ sizeof(struct info_kernel));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0 && items == 0)
+ return;
+ if (!check1item(items, fp))
+ return;
+ if (!checkitemsize(itemsize, sizeof(struct info_kernel)))
+ return;
+
+ status = ntohs(ik->status) & 0xffff;
+ /*
+ * pll variables. We know more than we should about the NANO bit.
+ */
+#ifdef STA_NANO
+ if (status & STA_NANO)
+ tscale = 1e-9;
+#endif
+ (void)fprintf(fp, "pll offset: %g s\n",
+ (long)ntohl(ik->offset) * tscale);
+ (void)fprintf(fp, "pll frequency: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->freq), 3));
+ (void)fprintf(fp, "maximum error: %g s\n",
+ (u_long)ntohl(ik->maxerror) * 1e-6);
+ (void)fprintf(fp, "estimated error: %g s\n",
+ (u_long)ntohl(ik->esterror) * 1e-6);
+ (void)fprintf(fp, "status: %04x ", status);
+#ifdef STA_PLL
+ if (status & STA_PLL) (void)fprintf(fp, " pll");
+#endif
+#ifdef STA_PPSFREQ
+ if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq");
+#endif
+#ifdef STA_PPSTIME
+ if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime");
+#endif
+#ifdef STA_FLL
+ if (status & STA_FLL) (void)fprintf(fp, " fll");
+#endif
+#ifdef STA_INS
+ if (status & STA_INS) (void)fprintf(fp, " ins");
+#endif
+#ifdef STA_DEL
+ if (status & STA_DEL) (void)fprintf(fp, " del");
+#endif
+#ifdef STA_UNSYNC
+ if (status & STA_UNSYNC) (void)fprintf(fp, " unsync");
+#endif
+#ifdef STA_FREQHOLD
+ if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold");
+#endif
+#ifdef STA_PPSSIGNAL
+ if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal");
+#endif
+#ifdef STA_PPSJITTER
+ if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter");
+#endif
+#ifdef STA_PPSWANDER
+ if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander");
+#endif
+#ifdef STA_PPSERROR
+ if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror");
+#endif
+#ifdef STA_CLOCKERR
+ if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr");
+#endif
+#ifdef STA_NANO
+ if (status & STA_NANO) (void)fprintf(fp, " nano");
+#endif
+#ifdef STA_MODE
+ if (status & STA_MODE) (void)fprintf(fp, " mode=fll");
+#endif
+#ifdef STA_CLK
+ if (status & STA_CLK) (void)fprintf(fp, " src=B");
+#endif
+ (void)fprintf(fp, "\n");
+ (void)fprintf(fp, "pll time constant: %ld\n",
+ (u_long)ntohl(ik->constant));
+ (void)fprintf(fp, "precision: %g s\n",
+ (u_long)ntohl(ik->precision) * tscale);
+ (void)fprintf(fp, "frequency tolerance: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->tolerance), 0));
+
+ /*
+ * For backwards compatibility (ugh), we find the pps variables
+ * only if the shift member is nonzero.
+ */
+ if (!ik->shift)
+ return;
+
+ /*
+ * pps variables
+ */
+ (void)fprintf(fp, "pps frequency: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->ppsfreq), 3));
+ (void)fprintf(fp, "pps stability: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->stabil), 3));
+ (void)fprintf(fp, "pps jitter: %g s\n",
+ (u_long)ntohl(ik->jitter) * tscale);
+ (void)fprintf(fp, "calibration interval: %d s\n",
+ 1 << ntohs(ik->shift));
+ (void)fprintf(fp, "calibration cycles: %ld\n",
+ (u_long)ntohl(ik->calcnt));
+ (void)fprintf(fp, "jitter exceeded: %ld\n",
+ (u_long)ntohl(ik->jitcnt));
+ (void)fprintf(fp, "stability exceeded: %ld\n",
+ (u_long)ntohl(ik->stbcnt));
+ (void)fprintf(fp, "calibration errors: %ld\n",
+ (u_long)ntohl(ik->errcnt));
+}