]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Many files:
authorHarlan Stenn <stenn@ntp.org>
Tue, 14 Mar 2000 03:41:14 +0000 (03:41 -0000)
committerHarlan Stenn <stenn@ntp.org>
Tue, 14 Mar 2000 03:41:14 +0000 (03:41 -0000)
  Crypto code update

bk: 38cdb4daeEsO7vdrLKTVcn21iHA_Jg

51 files changed:
COPYRIGHT
Makefile.in
adjtimed/Makefile.in
clockstuff/Makefile.in
config.h.in
configure
configure.in
include/Makefile.am
include/Makefile.in
include/ntp.h
include/ntp_control.h
include/ntp_crypto.h [new file with mode: 0644]
include/ntp_request.h
include/ntp_stdlib.h
include/ntp_types.h
include/ntpd.h
kernel/Makefile.in
kernel/sys/Makefile.in
libntp/Makefile.in
libntp/a_md5encrypt.c
libntp/authencrypt.c
libntp/authkeys.c
libntp/authusekey.c
libntp/systime.c
libparse/Makefile.in
librsaref/Makefile.in
ntpd/Makefile.am
ntpd/Makefile.in
ntpd/ntp_config.c
ntpd/ntp_control.c
ntpd/ntp_crypto.c [new file with mode: 0644]
ntpd/ntp_intres.c
ntpd/ntp_loopfilter.c
ntpd/ntp_peer.c
ntpd/ntp_proto.c
ntpd/ntp_request.c
ntpd/ntp_resolver.c [new file with mode: 0644]
ntpd/ntp_timer.c
ntpd/ntp_util.c
ntpd/ntpd.c
ntpdate/Makefile.in
ntpdate/ntpdate.c
ntpdate/ntptimeset.c
ntpdc/Makefile.in
ntpq/Makefile.in
ntptrace/Makefile.in
parseutil/Makefile.in
scripts/Makefile.in
util/Makefile.am
util/Makefile.in
util/ntp_genkeys.c [new file with mode: 0644]

index 44ee155bae65ebc23636628ef4b6cfab71c62529..5a2de4821d3cc4dabb264139cec83a57ce921bda 100644 (file)
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -163,5 +163,5 @@ References
   47. mailto:tsuruoka@nc.fukuoka-u.ac.jp
   48. mailto:vixie@vix.com
   49. mailto:Ulrich.Windl@rz.uni-regensburg.de
-  50. file://localhost/backroom/ntp4/html/index.htm
+  50. file://localhost/backroom/ntp4+/html/index.htm
   51. mailto:mills@udel.edu
index d754804b6bb21513b7c7a2adb18b00c3711c2cce..596be05eb32dbb2a813cb47cacec7ce3c9dca824 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index be13d2aa18bc7717f6a6a6b6c4712ed6ae45af44..3e42ddcc830d39e4c5d265cbe08ced138b92c9b1 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 29713aeeb870ddf47c30566fe124c7d35c3b78d3..07ac40bdc6925905a9cfa14bfe31ab4134de9269 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 34a469fdf581d76091a94729df782c10661ff942..a25caa4cf2160c474f239342c67a73d9b4c5cc42 100644 (file)
 /* toupper()? */
 #undef DECL_TOUPPER_0
 
+/* Autokey? */
+#undef AUTOKEY
+
 /* Define if you have the <arpa/nameser.h> header file. */
 #undef HAVE_ARPA_NAMESER_H
 
 /* Define if you have the `getuid' function. */
 #undef HAVE_GETUID
 
+/* Define if you have the <ieeefp.h> header file. */
+#undef HAVE_IEEEFP_H
+
 /* Define if you have the `kvm_open' function. */
 #undef HAVE_KVM_OPEN
 
 /* Define if compiler has function prototypes */
 #undef PROTOTYPES
 
+/* Public key? */
+#undef PUBKEY
+
 /* Define as the return type of signal handlers (`int' or `void'). */
 #undef RETSIGTYPE
 
index 9f0d309cb11667638c1273877008be49b26b3d4f..de7bf8f4793f92295b484d2e4081f375bf9a1d73 100755 (executable)
--- a/configure
+++ b/configure
@@ -144,6 +144,8 @@ ac_arg_enable_help="$ac_arg_enable_help
   --enable-WHARTON        s WHARTON 400A Series clock"
 ac_arg_enable_help="$ac_arg_enable_help
   --enable-VARITEXT       s VARITEXT clock"
+ac_arg_with_help="$ac_arg_with_help
+  --with-rsaref           + Use rsaref if possible"
 ac_arg_enable_help="$ac_arg_enable_help
   --enable-kmem           s read /dev/kmem for tick and/or tickadj"
 ac_arg_enable_help="$ac_arg_enable_help
@@ -727,7 +729,7 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub"
 ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
 
 echo $ac_n "checking host system type... $ac_c" 1>&6
-echo "configure:731: checking host system type" 1>&5
+echo "configure:733: checking host system type" 1>&5
 if test "x$ac_cv_host" = "x" || (test "x$host" != "xNONE" && test "x$host" != "x$ac_cv_host_alias"); then
 
   # Make sure we can run config.sub.
@@ -763,7 +765,7 @@ host_vendor=$ac_cv_host_vendor
 host_os=$ac_cv_host_os
 
 echo $ac_n "checking target system type... $ac_c" 1>&6
-echo "configure:767: checking target system type" 1>&5
+echo "configure:769: checking target system type" 1>&5
 if test "x$ac_cv_target" = "x" || (test "x$target" != "xNONE" && test "x$target" != "x$ac_cv_target_alias"); then
 
   # Make sure we can run config.sub.
@@ -798,7 +800,7 @@ target_vendor=$ac_cv_target_vendor
 target_os=$ac_cv_target_os
 
 echo $ac_n "checking build system type... $ac_c" 1>&6
-echo "configure:802: checking build system type" 1>&5
+echo "configure:804: checking build system type" 1>&5
 if test "x$ac_cv_build" = "x" || (test "x$build" != "xNONE" && test "x$build" != "x$ac_cv_build_alias"); then
 
   # Make sure we can run config.sub.
@@ -892,7 +894,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install... $ac_c" 1>&6
-echo "configure:896: checking for a BSD compatible install" 1>&5
+echo "configure:898: checking for a BSD compatible install" 1>&5
 if test -z "$INSTALL"; then
 if test "${ac_cv_path_install+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -949,7 +951,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether build environment is sane... $ac_c" 1>&6
-echo "configure:953: checking whether build environment is sane" 1>&5
+echo "configure:955: checking whether build environment is sane" 1>&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -1001,7 +1003,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1005: checking for $ac_word" 1>&5
+echo "configure:1007: checking for $ac_word" 1>&5
 if test "${ac_cv_prog_AWK+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1031,7 +1033,7 @@ test -n "$AWK" && break
 done
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}... $ac_c" 1>&6
-echo "configure:1035: checking whether ${MAKE-make} sets \${MAKE}" 1>&5
+echo "configure:1037: checking whether ${MAKE-make} sets \${MAKE}" 1>&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1137,7 +1139,7 @@ esac
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1141: checking for $ac_word" 1>&5
+echo "configure:1143: checking for $ac_word" 1>&5
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1167,7 +1169,7 @@ fi
     # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1171: checking for $ac_word" 1>&5
+echo "configure:1173: checking for $ac_word" 1>&5
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1218,7 +1220,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1222: checking for $ac_word" 1>&5
+echo "configure:1224: checking for $ac_word" 1>&5
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1253,7 +1255,7 @@ done
 test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works... $ac_c" 1>&6
-echo "configure:1257: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" 1>&5
+echo "configure:1259: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) works" 1>&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1264,12 +1266,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat >conftest.$ac_ext <<EOF
 
-#line 1268 "configure"
+#line 1270 "configure"
 #include "confdefs.h"
 
 int main(){return(0);}
 EOF
-if { (eval echo configure:1273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1295,12 +1297,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 77; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler... $ac_c" 1>&6
-echo "configure:1299: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" 1>&5
+echo "configure:1301: checking whether the C compiler ($CC $CFLAGS $CPPFLAGS $LDFLAGS) is a cross-compiler" 1>&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
-echo "configure:1304: checking whether we are using GNU C" 1>&5
+echo "configure:1306: checking whether we are using GNU C" 1>&5
 if test "${ac_cv_prog_gcc+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1309,7 +1311,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1313: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1315: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1327,7 +1329,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g... $ac_c" 1>&6
-echo "configure:1331: checking whether ${CC-cc} accepts -g" 1>&5
+echo "configure:1333: checking whether ${CC-cc} accepts -g" 1>&5
 if test "${ac_cv_prog_cc_g+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1358,7 +1360,7 @@ else
 fi
 
 echo $ac_n "checking how to run the C preprocessor... $ac_c" 1>&6
-echo "configure:1362: checking how to run the C preprocessor" 1>&5
+echo "configure:1364: checking how to run the C preprocessor" 1>&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1373,13 +1375,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat >conftest.$ac_ext <<EOF
-#line 1377 "configure"
+#line 1379 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1385: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1390,13 +1392,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat >conftest.$ac_ext <<EOF
-#line 1394 "configure"
+#line 1396 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1400: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1402: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1407,13 +1409,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat >conftest.$ac_ext <<EOF
-#line 1411 "configure"
+#line 1413 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1417: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1419: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1440,7 +1442,7 @@ echo "$ac_t""$CPP" 1>&6
 depcc="$CC"
 depcpp="$CPP"
 echo $ac_n "checking dependency style of $depcc... $ac_c" 1>&6
-echo "configure:1444: checking dependency style of $depcc" 1>&5
+echo "configure:1446: checking dependency style of $depcc" 1>&5
 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1484,7 +1486,7 @@ echo "$ac_t""$am_cv_CC_dependencies_compiler_type" 1>&6
 CCDEPMODE="depmode=$am_cv_CC_dependencies_compiler_type"
 
 echo $ac_n "checking how to run the C preprocessor... $ac_c" 1>&6
-echo "configure:1488: checking how to run the C preprocessor" 1>&5
+echo "configure:1490: checking how to run the C preprocessor" 1>&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1499,13 +1501,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat >conftest.$ac_ext <<EOF
-#line 1503 "configure"
+#line 1505 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1509: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1511: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1516,13 +1518,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat >conftest.$ac_ext <<EOF
-#line 1520 "configure"
+#line 1522 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1526: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1528: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1533,13 +1535,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat >conftest.$ac_ext <<EOF
-#line 1537 "configure"
+#line 1539 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1543: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1545: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1604,7 +1606,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1608: checking for $ac_word" 1>&5
+echo "configure:1610: checking for $ac_word" 1>&5
 if test "${ac_cv_prog_AWK+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1634,7 +1636,7 @@ test -n "$AWK" && break
 done
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}... $ac_c" 1>&6
-echo "configure:1638: checking whether ${MAKE-make} sets \${MAKE}" 1>&5
+echo "configure:1640: checking whether ${MAKE-make} sets \${MAKE}" 1>&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1675,7 +1677,7 @@ case "$GCC" in
     CFLAGS="$CFLAGS -Wstrict-prototypes"
 
     echo $ac_n "checking whether ${CC-cc} -pipe works... $ac_c" 1>&6
-echo "configure:1679: checking whether ${CC-cc} -pipe works" 1>&5
+echo "configure:1681: checking whether ${CC-cc} -pipe works" 1>&5
 if test "${ac_cv_prog_cc_pipe+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1743,7 +1745,7 @@ case "$ac_busted_vpath_in_make$srcdir" in
 esac
 
 echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
-echo "configure:1747: checking whether ln -s works" 1>&5
+echo "configure:1749: checking whether ln -s works" 1>&5
 if test "${ac_cv_prog_LN_S+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1765,13 +1767,13 @@ fi
 
 if test $ac_cv_prog_gcc = yes; then
     echo $ac_n "checking whether ${CC-cc} needs -traditional... $ac_c" 1>&6
-echo "configure:1769: checking whether ${CC-cc} needs -traditional" 1>&5
+echo "configure:1771: checking whether ${CC-cc} needs -traditional" 1>&5
 if test "${ac_cv_prog_gcc_traditional+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     ac_pattern="Autoconf.*'x'"
   cat >conftest.$ac_ext <<EOF
-#line 1775 "configure"
+#line 1777 "configure"
 #include "confdefs.h"
 #include <sgtty.h>
 Autoconf TIOCGETP
@@ -1788,7 +1790,7 @@ rm -f conftest*
 
   if test $ac_cv_prog_gcc_traditional = no; then
     cat >conftest.$ac_ext <<EOF
-#line 1792 "configure"
+#line 1794 "configure"
 #include "confdefs.h"
 #include <termio.h>
 Autoconf TCGETA
@@ -1809,9 +1811,9 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
 fi
 
 echo $ac_n "checking for AIX... $ac_c" 1>&6
-echo "configure:1813: checking for AIX" 1>&5
+echo "configure:1815: checking for AIX" 1>&5
 cat >conftest.$ac_ext <<EOF
-#line 1815 "configure"
+#line 1817 "configure"
 #include "confdefs.h"
 #ifdef _AIX
   yes
@@ -1833,18 +1835,18 @@ fi
 rm -f conftest*
 
 echo $ac_n "checking for minix/config.h... $ac_c" 1>&6
-echo "configure:1837: checking for minix/config.h" 1>&5
+echo "configure:1839: checking for minix/config.h" 1>&5
 if test "${ac_cv_header_minix_config_h+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 1842 "configure"
+#line 1844 "configure"
 #include "confdefs.h"
 #include <minix/config.h>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1850: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1881,7 +1883,7 @@ EOF
 fi
 
 echo $ac_n "checking for POSIXized ISC... $ac_c" 1>&6
-echo "configure:1885: checking for POSIXized ISC" 1>&5
+echo "configure:1887: checking for POSIXized ISC" 1>&5
 if test -d /etc/conf/kconfig.d &&
    grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
 then
@@ -1904,7 +1906,7 @@ fi
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1908: checking for $ac_word" 1>&5
+echo "configure:1910: checking for $ac_word" 1>&5
 if test "${ac_cv_prog_RANLIB+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1934,7 +1936,7 @@ fi
 # Extract the first word of "sh", so it can be a program name with args.
 set dummy sh; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1938: checking for $ac_word" 1>&5
+echo "configure:1940: checking for $ac_word" 1>&5
 if test "${ac_cv_path_PATH_SH+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1966,7 +1968,7 @@ fi
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word... $ac_c" 1>&6
-echo "configure:1970: checking for $ac_word" 1>&5
+echo "configure:1972: checking for $ac_word" 1>&5
 if test "${ac_cv_path_PATH_PERL+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2013,7 +2015,7 @@ esac
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install... $ac_c" 1>&6
-echo "configure:2017: checking for a BSD compatible install" 1>&5
+echo "configure:2019: checking for a BSD compatible install" 1>&5
 if test -z "$INSTALL"; then
 if test "${ac_cv_path_install+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2072,14 +2074,14 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 case "$target" in
  *-pc-cygwin*)
     echo $ac_n "checking for main in -ladvapi32... $ac_c" 1>&6
-echo "configure:2076: checking for main in -ladvapi32" 1>&5
+echo "configure:2078: checking for main in -ladvapi32" 1>&5
 if test "${ac_cv_lib_advapi32_main+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-ladvapi32  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2083 "configure"
+#line 2085 "configure"
 #include "confdefs.h"
 
 int
@@ -2090,7 +2092,7 @@ main()
   return 0;
 }
 EOF
-if { (eval echo configure:2094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_advapi32_main=yes
 else
@@ -2116,14 +2118,14 @@ fi
     ;;
 esac
 echo $ac_n "checking for nlist in -lelf... $ac_c" 1>&6
-echo "configure:2120: checking for nlist in -lelf" 1>&5
+echo "configure:2122: checking for nlist in -lelf" 1>&5
 if test "${ac_cv_lib_elf_nlist+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lelf  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2127 "configure"
+#line 2129 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2138,7 +2140,7 @@ nlist()
   return 0;
 }
 EOF
-if { (eval echo configure:2142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_elf_nlist=yes
 else
@@ -2162,14 +2164,14 @@ EOF
 fi
 
 echo $ac_n "checking for main in -lkvm... $ac_c" 1>&6
-echo "configure:2166: checking for main in -lkvm" 1>&5
+echo "configure:2168: checking for main in -lkvm" 1>&5
 if test "${ac_cv_lib_kvm_main+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lkvm  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2173 "configure"
+#line 2175 "configure"
 #include "confdefs.h"
 
 int
@@ -2180,7 +2182,7 @@ main()
   return 0;
 }
 EOF
-if { (eval echo configure:2184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_kvm_main=yes
 else
@@ -2203,14 +2205,14 @@ EOF
 
 fi
                echo $ac_n "checking for nlist in -lld... $ac_c" 1>&6
-echo "configure:2207: checking for nlist in -lld" 1>&5
+echo "configure:2209: checking for nlist in -lld" 1>&5
 if test "${ac_cv_lib_ld_nlist+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lld  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2214 "configure"
+#line 2216 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2225,7 +2227,7 @@ nlist()
   return 0;
 }
 EOF
-if { (eval echo configure:2229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_ld_nlist=yes
 else
@@ -2249,14 +2251,14 @@ EOF
 fi
 
 echo $ac_n "checking for nlist in -lmld... $ac_c" 1>&6
-echo "configure:2253: checking for nlist in -lmld" 1>&5
+echo "configure:2255: checking for nlist in -lmld" 1>&5
 if test "${ac_cv_lib_mld_nlist+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lmld  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2260 "configure"
+#line 2262 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2271,7 +2273,7 @@ nlist()
   return 0;
 }
 EOF
-if { (eval echo configure:2275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_mld_nlist=yes
 else
@@ -2295,12 +2297,12 @@ EOF
 fi
 
 echo $ac_n "checking for gethostent... $ac_c" 1>&6
-echo "configure:2299: checking for gethostent" 1>&5
+echo "configure:2301: checking for gethostent" 1>&5
 if test "${ac_cv_func_gethostent+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2304 "configure"
+#line 2306 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostent(); below.  */
@@ -2328,7 +2330,7 @@ f = gethostent;
   return 0;
 }
 EOF
-if { (eval echo configure:2332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_gethostent=yes
 else
@@ -2345,14 +2347,14 @@ if test $ac_cv_func_gethostent = yes; then
   :
 else
   echo $ac_n "checking for gethostent in -lnsl... $ac_c" 1>&6
-echo "configure:2349: checking for gethostent in -lnsl" 1>&5
+echo "configure:2351: checking for gethostent in -lnsl" 1>&5
 if test "${ac_cv_lib_nsl_gethostent+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl -lsocket $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2356 "configure"
+#line 2358 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2367,7 +2369,7 @@ gethostent()
   return 0;
 }
 EOF
-if { (eval echo configure:2371: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_nsl_gethostent=yes
 else
@@ -2393,12 +2395,12 @@ fi
 fi
 
 echo $ac_n "checking for openlog... $ac_c" 1>&6
-echo "configure:2397: checking for openlog" 1>&5
+echo "configure:2399: checking for openlog" 1>&5
 if test "${ac_cv_func_openlog+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2402 "configure"
+#line 2404 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char openlog(); below.  */
@@ -2426,7 +2428,7 @@ f = openlog;
   return 0;
 }
 EOF
-if { (eval echo configure:2430: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2432: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_openlog=yes
 else
@@ -2443,14 +2445,14 @@ if test $ac_cv_func_openlog = yes; then
   :
 else
   echo $ac_n "checking for openlog in -lgen... $ac_c" 1>&6
-echo "configure:2447: checking for openlog in -lgen" 1>&5
+echo "configure:2449: checking for openlog in -lgen" 1>&5
 if test "${ac_cv_lib_gen_openlog+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lgen  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2454 "configure"
+#line 2456 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2465,7 +2467,7 @@ openlog()
   return 0;
 }
 EOF
-if { (eval echo configure:2469: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_gen_openlog=yes
 else
@@ -2491,14 +2493,14 @@ fi
 fi
 
 echo $ac_n "checking for sched_setscheduler in -lrt... $ac_c" 1>&6
-echo "configure:2495: checking for sched_setscheduler in -lrt" 1>&5
+echo "configure:2497: checking for sched_setscheduler in -lrt" 1>&5
 if test "${ac_cv_lib_rt_sched_setscheduler+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lrt  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2502 "configure"
+#line 2504 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2513,7 +2515,7 @@ sched_setscheduler()
   return 0;
 }
 EOF
-if { (eval echo configure:2517: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2519: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_rt_sched_setscheduler=yes
 else
@@ -2536,14 +2538,14 @@ EOF
 
 else
   echo $ac_n "checking for sched_setscheduler in -lposix4... $ac_c" 1>&6
-echo "configure:2540: checking for sched_setscheduler in -lposix4" 1>&5
+echo "configure:2542: checking for sched_setscheduler in -lposix4" 1>&5
 if test "${ac_cv_lib_posix4_sched_setscheduler+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lposix4  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2547 "configure"
+#line 2549 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2558,7 +2560,7 @@ sched_setscheduler()
   return 0;
 }
 EOF
-if { (eval echo configure:2562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_posix4_sched_setscheduler=yes
 else
@@ -2584,12 +2586,12 @@ fi
 fi
 
 echo $ac_n "checking for setsockopt... $ac_c" 1>&6
-echo "configure:2588: checking for setsockopt" 1>&5
+echo "configure:2590: checking for setsockopt" 1>&5
 if test "${ac_cv_func_setsockopt+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2593 "configure"
+#line 2595 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char setsockopt(); below.  */
@@ -2617,7 +2619,7 @@ f = setsockopt;
   return 0;
 }
 EOF
-if { (eval echo configure:2621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2623: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_setsockopt=yes
 else
@@ -2634,14 +2636,14 @@ if test $ac_cv_func_setsockopt = yes; then
   :
 else
   echo $ac_n "checking for setsockopt in -lsocket... $ac_c" 1>&6
-echo "configure:2638: checking for setsockopt in -lsocket" 1>&5
+echo "configure:2640: checking for setsockopt in -lsocket" 1>&5
 if test "${ac_cv_lib_socket_setsockopt+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat >conftest.$ac_ext <<EOF
-#line 2645 "configure"
+#line 2647 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2656,7 +2658,7 @@ setsockopt()
   return 0;
 }
 EOF
-if { (eval echo configure:2660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_lib_socket_setsockopt=yes
 else
@@ -2682,12 +2684,12 @@ fi
 fi
 
 echo $ac_n "checking for ANSI C header files... $ac_c" 1>&6
-echo "configure:2686: checking for ANSI C header files" 1>&5
+echo "configure:2688: checking for ANSI C header files" 1>&5
 if test "${ac_cv_header_stdc+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2691 "configure"
+#line 2693 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2696,7 +2698,7 @@ else
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2700: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2713,7 +2715,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat >conftest.$ac_ext <<EOF
-#line 2717 "configure"
+#line 2719 "configure"
 #include "confdefs.h"
 #include <string.h>
 
@@ -2732,7 +2734,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat >conftest.$ac_ext <<EOF
-#line 2736 "configure"
+#line 2738 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 
@@ -2754,7 +2756,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat >conftest.$ac_ext <<EOF
-#line 2758 "configure"
+#line 2760 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #if ((' ' & 0x0FF) == 0x020)
@@ -2779,7 +2781,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:2783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2802,22 +2804,22 @@ EOF
 
 fi
 
-for ac_header in bstring.h errno.h fcntl.h memory.h netdb.h poll.h resolv.h
+for ac_header in bstring.h errno.h fcntl.h ieeefp.h memory.h netdb.h poll.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:2810: checking for $ac_header" 1>&5
+echo "configure:2812: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2815 "configure"
+#line 2817 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2821: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2823: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2840,22 +2842,22 @@ EOF
 fi
 done
 
-for ac_header in sched.h sgtty.h stdlib.h string.h termio.h termios.h
+for ac_header in resolv.h sched.h sgtty.h stdlib.h string.h termio.h termios.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:2848: checking for $ac_header" 1>&5
+echo "configure:2850: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2853 "configure"
+#line 2855 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2859: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2861: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2882,18 +2884,18 @@ for ac_header in timepps.h timex.h unistd.h utmp.h utmpx.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:2886: checking for $ac_header" 1>&5
+echo "configure:2888: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2891 "configure"
+#line 2893 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2897: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2899: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2920,18 +2922,18 @@ for ac_header in arpa/nameser.h net/if.h netinet/in_systm.h netinet/in.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:2924: checking for $ac_header" 1>&5
+echo "configure:2926: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2929 "configure"
+#line 2931 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2935: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2937: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2958,18 +2960,18 @@ for ac_header in netinfo/ni.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:2962: checking for $ac_header" 1>&5
+echo "configure:2964: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 2967 "configure"
+#line 2969 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2973: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2999,18 +3001,18 @@ for ac_header in sun/audioio.h sys/audioio.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3003: checking for $ac_header" 1>&5
+echo "configure:3005: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3008 "configure"
+#line 3010 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3014: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3016: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3037,18 +3039,18 @@ for ac_header in sys/clkdefs.h sys/file.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3041: checking for $ac_header" 1>&5
+echo "configure:3043: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3046 "configure"
+#line 3048 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3052: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3054: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3077,18 +3079,18 @@ case "$target" in
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3081: checking for $ac_header" 1>&5
+echo "configure:3083: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3086 "configure"
+#line 3088 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3092: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3094: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3117,18 +3119,18 @@ for ac_header in sys/lock.h sys/mman.h sys/modem.h sys/param.h sys/ppsclock.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3121: checking for $ac_header" 1>&5
+echo "configure:3123: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3126 "configure"
+#line 3128 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3132: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3134: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3155,18 +3157,18 @@ for ac_header in sys/ppstime.h sys/proc.h sys/resource.h sys/sched.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3159: checking for $ac_header" 1>&5
+echo "configure:3161: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3164 "configure"
+#line 3166 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3170: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3195,18 +3197,18 @@ case "$target" in
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3199: checking for $ac_header" 1>&5
+echo "configure:3201: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3204 "configure"
+#line 3206 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3210: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3212: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3235,18 +3237,18 @@ for ac_header in sys/select.h sys/sockio.h sys/stat.h sys/stream.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3239: checking for $ac_header" 1>&5
+echo "configure:3241: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3244 "configure"
+#line 3246 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3250: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3252: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3273,18 +3275,18 @@ for ac_header in sys/stropts.h sys/sysctl.h sys/syssgi.h sys/termios.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3277: checking for $ac_header" 1>&5
+echo "configure:3279: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3282 "configure"
+#line 3284 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3288: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3290: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3311,18 +3313,18 @@ for ac_header in sys/time.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3315: checking for $ac_header" 1>&5
+echo "configure:3317: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3320 "configure"
+#line 3322 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3326: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3328: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3346,7 +3348,7 @@ fi
 done
 
 cat >conftest.$ac_ext <<EOF
-#line 3350 "configure"
+#line 3352 "configure"
 #include "confdefs.h"
 #include <sys/timepps.h>
 #ifdef PPS_API_VERS_1
@@ -3361,18 +3363,18 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3365: checking for $ac_header" 1>&5
+echo "configure:3367: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3370 "configure"
+#line 3372 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3376: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3378: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3402,18 +3404,18 @@ for ac_header in sys/timers.h sys/timex.h sys/tpro.h sys/types.h sys/wait.h
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3406: checking for $ac_header" 1>&5
+echo "configure:3408: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3411 "configure"
+#line 3413 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3417: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3419: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3437,12 +3439,12 @@ fi
 done
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included... $ac_c" 1>&6
-echo "configure:3441: checking whether time.h and sys/time.h may both be included" 1>&5
+echo "configure:3443: checking whether time.h and sys/time.h may both be included" 1>&5
 if test "${ac_cv_header_time+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3446 "configure"
+#line 3448 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -3456,7 +3458,7 @@ struct tm *tp;
   return 0;
 }
 EOF
-if { (eval echo configure:3460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3462: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -3481,18 +3483,18 @@ case "$target" in
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3485: checking for $ac_header" 1>&5
+echo "configure:3487: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3490 "configure"
+#line 3492 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3496: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3521,18 +3523,18 @@ done
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3525: checking for $ac_header" 1>&5
+echo "configure:3527: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3530 "configure"
+#line 3532 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3536: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3538: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3559,18 +3561,18 @@ done
 esac
 
 echo $ac_n "checking for nlist.h... $ac_c" 1>&6
-echo "configure:3563: checking for nlist.h" 1>&5
+echo "configure:3565: checking for nlist.h" 1>&5
 if test "${ac_cv_header_nlist_h+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3568 "configure"
+#line 3570 "configure"
 #include "confdefs.h"
 #include <nlist.h>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3574: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3576: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3591,12 +3593,12 @@ if test $ac_cv_header_nlist_h = yes; then
 EOF
 
 echo $ac_n "checking for n_un in struct nlist... $ac_c" 1>&6
-echo "configure:3595: checking for n_un in struct nlist" 1>&5
+echo "configure:3597: checking for n_un in struct nlist" 1>&5
 if test "${ac_cv_struct_nlist_n_un+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3600 "configure"
+#line 3602 "configure"
 #include "confdefs.h"
 #include <nlist.h>
 int
@@ -3607,7 +3609,7 @@ struct nlist n; n.n_un.n_name = 0;
   return 0;
 }
 EOF
-if { (eval echo configure:3611: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3613: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_nlist_n_un=yes
 else
@@ -3629,12 +3631,12 @@ fi
 fi
 
 echo $ac_n "checking for basic volatile support... $ac_c" 1>&6
-echo "configure:3633: checking for basic volatile support" 1>&5
+echo "configure:3635: checking for basic volatile support" 1>&5
 if test "${ac_cv_c_volatile+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3638 "configure"
+#line 3640 "configure"
 #include "confdefs.h"
 
 int
@@ -3646,7 +3648,7 @@ volatile int x;
   return 0;
 }
 EOF
-if { (eval echo configure:3650: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3652: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_volatile=yes
 else
@@ -3677,7 +3679,7 @@ case "$target" in
     
 
 echo $ac_n "checking for ${CC-cc} option to accept ANSI C... $ac_c" 1>&6
-echo "configure:3681: checking for ${CC-cc} option to accept ANSI C" 1>&5
+echo "configure:3683: checking for ${CC-cc} option to accept ANSI C" 1>&5
 if test "${am_cv_prog_cc_stdc+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3694,7 +3696,7 @@ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIO
 do
   CC="$ac_save_CC $ac_arg"
   cat >conftest.$ac_ext <<EOF
-#line 3698 "configure"
+#line 3700 "configure"
 #include "confdefs.h"
 #include <stdarg.h>
 #include <stdio.h>
@@ -3735,7 +3737,7 @@ return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
   return 0;
 }
 EOF
-if { (eval echo configure:3739: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   am_cv_prog_cc_stdc="$ac_arg"; break
 else
@@ -3759,7 +3761,7 @@ case "x$am_cv_prog_cc_stdc" in
 esac
 
 echo $ac_n "checking for function prototypes... $ac_c" 1>&6
-echo "configure:3763: checking for function prototypes" 1>&5
+echo "configure:3765: checking for function prototypes" 1>&5
 if test "$am_cv_prog_cc_stdc" != no; then
   echo "$ac_t""yes" 1>&6
   cat >>confdefs.h <<\EOF
@@ -3772,12 +3774,12 @@ else
   U=_ ANSI2KNR=./ansi2knr
   # Ensure some checks needed by ansi2knr itself.
   echo $ac_n "checking for ANSI C header files... $ac_c" 1>&6
-echo "configure:3776: checking for ANSI C header files" 1>&5
+echo "configure:3778: checking for ANSI C header files" 1>&5
 if test "${ac_cv_header_stdc+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3781 "configure"
+#line 3783 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -3786,7 +3788,7 @@ else
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3790: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3792: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3803,7 +3805,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat >conftest.$ac_ext <<EOF
-#line 3807 "configure"
+#line 3809 "configure"
 #include "confdefs.h"
 #include <string.h>
 
@@ -3822,7 +3824,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat >conftest.$ac_ext <<EOF
-#line 3826 "configure"
+#line 3828 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 
@@ -3844,7 +3846,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat >conftest.$ac_ext <<EOF
-#line 3848 "configure"
+#line 3850 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #if ((' ' & 0x0FF) == 0x020)
@@ -3869,7 +3871,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:3873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3875: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -3896,18 +3898,18 @@ fi
 do
 ac_ac_Header=`echo "ac_cv_header_$ac_header" | $ac_tr_sh`
 echo $ac_n "checking for $ac_header... $ac_c" 1>&6
-echo "configure:3900: checking for $ac_header" 1>&5
+echo "configure:3902: checking for $ac_header" 1>&5
 if eval "test \"\${$ac_ac_Header+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3905 "configure"
+#line 3907 "configure"
 #include "confdefs.h"
 #include <$ac_header>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3911: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3935,12 +3937,12 @@ fi
     ;;
 esac
 echo $ac_n "checking if C compiler permits function prototypes... $ac_c" 1>&6
-echo "configure:3939: checking if C compiler permits function prototypes" 1>&5
+echo "configure:3941: checking if C compiler permits function prototypes" 1>&5
 if test "${ac_cv_have_prototypes+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 3944 "configure"
+#line 3946 "configure"
 #include "confdefs.h"
 
 extern int foo (short);
@@ -3954,7 +3956,7 @@ int i;
   return 0;
 }
 EOF
-if { (eval echo configure:3958: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3960: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_prototypes=yes
 else
@@ -3975,7 +3977,7 @@ EOF
 fi
 
 echo $ac_n "checking for ${CC-cc} option to accept ANSI C... $ac_c" 1>&6
-echo "configure:3979: checking for ${CC-cc} option to accept ANSI C" 1>&5
+echo "configure:3981: checking for ${CC-cc} option to accept ANSI C" 1>&5
 if test "${ac_cv_prog_cc_stdc+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3992,7 +3994,7 @@ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIO
 do
   CC="$ac_save_CC $ac_arg"
   cat >conftest.$ac_ext <<EOF
-#line 3996 "configure"
+#line 3998 "configure"
 #include "confdefs.h"
 #include <stdarg.h>
 #include <stdio.h>
@@ -4030,7 +4032,7 @@ return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
   return 0;
 }
 EOF
-if { (eval echo configure:4034: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_prog_cc_stdc="$ac_arg"; break
 else
@@ -4052,12 +4054,12 @@ case "x$ac_cv_prog_cc_stdc" in
 esac
 
 echo $ac_n "checking for an ANSI C conforming const... $ac_c" 1>&6
-echo "configure:4056: checking for an ANSI C conforming const" 1>&5
+echo "configure:4058: checking for an ANSI C conforming const" 1>&5
 if test "${ac_cv_c_const+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4061 "configure"
+#line 4063 "configure"
 #include "confdefs.h"
 
 int
@@ -4114,7 +4116,7 @@ main ()
   return 0;
 }
 EOF
-if { (eval echo configure:4118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4120: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -4136,14 +4138,14 @@ fi
 case "$host" in
  $target)
     echo $ac_n "checking whether byte ordering is bigendian... $ac_c" 1>&6
-echo "configure:4140: checking whether byte ordering is bigendian" 1>&5
+echo "configure:4142: checking whether byte ordering is bigendian" 1>&5
 if test "${ac_cv_c_bigendian+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat >conftest.$ac_ext <<EOF
-#line 4147 "configure"
+#line 4149 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4159,11 +4161,11 @@ main ()
   return 0;
 }
 EOF
-if { (eval echo configure:4163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4165: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat >conftest.$ac_ext <<EOF
-#line 4167 "configure"
+#line 4169 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4179,7 +4181,7 @@ main ()
   return 0;
 }
 EOF
-if { (eval echo configure:4183: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -4199,7 +4201,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; }
 else
   cat >conftest.$ac_ext <<EOF
-#line 4203 "configure"
+#line 4205 "configure"
 #include "confdefs.h"
 int
 main ()
@@ -4214,7 +4216,7 @@ main ()
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:4218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -4254,12 +4256,12 @@ EOF
     ;;
 esac
 echo $ac_n "checking return type of signal handlers... $ac_c" 1>&6
-echo "configure:4258: checking return type of signal handlers" 1>&5
+echo "configure:4260: checking return type of signal handlers" 1>&5
 if test "${ac_cv_type_signal+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4263 "configure"
+#line 4265 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -4280,7 +4282,7 @@ int i;
   return 0;
 }
 EOF
-if { (eval echo configure:4284: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4286: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -4297,12 +4299,12 @@ cat >>confdefs.h <<EOF
 EOF
 
 echo $ac_n "checking for off_t... $ac_c" 1>&6
-echo "configure:4301: checking for off_t" 1>&5
+echo "configure:4303: checking for off_t" 1>&5
 if test "${ac_cv_type_off_t+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4306 "configure"
+#line 4308 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -4316,7 +4318,7 @@ if (sizeof (off_t))
   return 0;
 }
 EOF
-if { (eval echo configure:4320: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4322: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_off_t=yes
 else
@@ -4338,12 +4340,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t... $ac_c" 1>&6
-echo "configure:4342: checking for size_t" 1>&5
+echo "configure:4344: checking for size_t" 1>&5
 if test "${ac_cv_type_size_t+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4347 "configure"
+#line 4349 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -4357,7 +4359,7 @@ if (sizeof (size_t))
   return 0;
 }
 EOF
-if { (eval echo configure:4361: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4363: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_size_t=yes
 else
@@ -4379,12 +4381,12 @@ EOF
 fi
 
 echo $ac_n "checking for time_t... $ac_c" 1>&6
-echo "configure:4383: checking for time_t" 1>&5
+echo "configure:4385: checking for time_t" 1>&5
 if test "${ac_cv_type_time_t+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4388 "configure"
+#line 4390 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -4398,7 +4400,7 @@ if (sizeof (time_t))
   return 0;
 }
 EOF
-if { (eval echo configure:4402: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4404: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_time_t=yes
 else
@@ -4420,12 +4422,12 @@ EOF
 fi
 
 echo $ac_n "checking whether struct tm is in sys/time.h or time.h... $ac_c" 1>&6
-echo "configure:4424: checking whether struct tm is in sys/time.h or time.h" 1>&5
+echo "configure:4426: checking whether struct tm is in sys/time.h or time.h" 1>&5
 if test "${ac_cv_struct_tm+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4429 "configure"
+#line 4431 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <time.h>
@@ -4438,7 +4440,7 @@ struct tm *tp; tp->tm_sec;
   return 0;
 }
 EOF
-if { (eval echo configure:4442: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4444: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_tm=time.h
 else
@@ -4458,7 +4460,7 @@ EOF
 fi
 
 echo $ac_n "checking for a fallback value for HZ... $ac_c" 1>&6
-echo "configure:4462: checking for a fallback value for HZ" 1>&5
+echo "configure:4464: checking for a fallback value for HZ" 1>&5
 if test "${ac_cv_var_default_hz+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4478,7 +4480,7 @@ cat >>confdefs.h <<EOF
 EOF
 
 echo $ac_n "checking if we need to override the system's value for HZ... $ac_c" 1>&6
-echo "configure:4482: checking if we need to override the system's value for HZ" 1>&5
+echo "configure:4484: checking if we need to override the system's value for HZ" 1>&5
 if test "${ac_cv_var_override_hz+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4509,13 +4511,13 @@ EOF
 esac
 
 echo $ac_n "checking struct sigaction for sa_sigaction... $ac_c" 1>&6
-echo "configure:4513: checking struct sigaction for sa_sigaction" 1>&5
+echo "configure:4515: checking struct sigaction for sa_sigaction" 1>&5
 if test "${ac_cv_struct_sigaction_has_sa_sigaction+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat >conftest.$ac_ext <<EOF
-#line 4519 "configure"
+#line 4521 "configure"
 #include "confdefs.h"
 #include <signal.h>
 int
@@ -4526,7 +4528,7 @@ struct sigaction act; act.sa_sigaction = 0;
   return 0;
 }
 EOF
-if { (eval echo configure:4530: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4532: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_sigaction_has_sa_sigaction=yes
 else
@@ -4549,12 +4551,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct ppsclockev... $ac_c" 1>&6
-echo "configure:4553: checking for struct ppsclockev" 1>&5
+echo "configure:4555: checking for struct ppsclockev" 1>&5
 if test "${ac_cv_struct_ppsclockev+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4558 "configure"
+#line 4560 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -4577,7 +4579,7 @@ return pce->serial;
   return 0;
 }
 EOF
-if { (eval echo configure:4581: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4583: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_ppsclockev=yes
 else
@@ -4598,12 +4600,12 @@ EOF
 fi
 
 echo $ac_n "checking struct sockaddr for sa_len... $ac_c" 1>&6
-echo "configure:4602: checking struct sockaddr for sa_len" 1>&5
+echo "configure:4604: checking struct sockaddr for sa_len" 1>&5
 if test "${ac_cv_struct_sockaddr_has_sa_len+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4607 "configure"
+#line 4609 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -4618,7 +4620,7 @@ return ps->sa_len;
   return 0;
 }
 EOF
-if { (eval echo configure:4622: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4624: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_sockaddr_has_sa_len=yes
 else
@@ -4639,12 +4641,12 @@ EOF
 fi
 
 echo $ac_n "checking struct clockinfo for hz... $ac_c" 1>&6
-echo "configure:4643: checking struct clockinfo for hz" 1>&5
+echo "configure:4645: checking struct clockinfo for hz" 1>&5
 if test "${ac_cv_struct_clockinfo_has_hz+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4648 "configure"
+#line 4650 "configure"
 #include "confdefs.h"
 
 #include <sys/time.h>
@@ -4658,7 +4660,7 @@ return pc->hz;
   return 0;
 }
 EOF
-if { (eval echo configure:4662: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4664: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_clockinfo_has_hz=yes
 else
@@ -4679,12 +4681,12 @@ EOF
 fi
 
 echo $ac_n "checking struct clockinfo for tickadj... $ac_c" 1>&6
-echo "configure:4683: checking struct clockinfo for tickadj" 1>&5
+echo "configure:4685: checking struct clockinfo for tickadj" 1>&5
 if test "${ac_cv_struct_clockinfo_has_tickadj+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4688 "configure"
+#line 4690 "configure"
 #include "confdefs.h"
 
 #include <sys/time.h>
@@ -4698,7 +4700,7 @@ return pc->tickadj;
   return 0;
 }
 EOF
-if { (eval echo configure:4702: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4704: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_clockinfo_has_tickadj=yes
 else
@@ -4719,12 +4721,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct ntptimeval... $ac_c" 1>&6
-echo "configure:4723: checking for struct ntptimeval" 1>&5
+echo "configure:4725: checking for struct ntptimeval" 1>&5
 if test "${ac_cv_struct_ntptimeval+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4728 "configure"
+#line 4730 "configure"
 #include "confdefs.h"
 
 #include <sys/time.h>
@@ -4737,7 +4739,7 @@ struct ntptimeval n;
   return 0;
 }
 EOF
-if { (eval echo configure:4741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4743: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_ntptimeval=yes
 else
@@ -4757,12 +4759,12 @@ EOF
 fi
 
 echo $ac_n "checking struct ntptimeval for time.tv_nsec... $ac_c" 1>&6
-echo "configure:4761: checking struct ntptimeval for time.tv_nsec" 1>&5
+echo "configure:4763: checking struct ntptimeval for time.tv_nsec" 1>&5
 if test "${ac_cv_struct_ntptimeval_tv_nsec+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4766 "configure"
+#line 4768 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_SYS_TIME_H
@@ -4789,7 +4791,7 @@ return ntv->time.tv_nsec;
   return 0;
 }
 EOF
-if { (eval echo configure:4793: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_ntptimeval_tv_nsec=yes
 else
@@ -4810,12 +4812,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct timespec in struct ntptimeval... $ac_c" 1>&6
-echo "configure:4814: checking for struct timespec in struct ntptimeval" 1>&5
+echo "configure:4816: checking for struct timespec in struct ntptimeval" 1>&5
 if test "${ac_cv_struct_ntptimeval_timespec+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 4819 "configure"
+#line 4821 "configure"
 #include "confdefs.h"
 #include <sys/time.h>
 #include <sys/timex.h>
@@ -4827,7 +4829,7 @@ struct ntptimeval n; n.time.tv_nsec = 0;
   return 0;
 }
 EOF
-if { (eval echo configure:4831: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4833: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_ntptimeval_timespec=yes
 else
@@ -4847,14 +4849,14 @@ EOF
 fi
 
 echo $ac_n "checking for inline... $ac_c" 1>&6
-echo "configure:4851: checking for inline" 1>&5
+echo "configure:4853: checking for inline" 1>&5
 if test "${ac_cv_c_inline+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat >conftest.$ac_ext <<EOF
-#line 4858 "configure"
+#line 4860 "configure"
 #include "confdefs.h"
 
 int
@@ -4868,7 +4870,7 @@ main ()
   return 0;
 }
 EOF
-if { (eval echo configure:4872: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4874: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -4893,14 +4895,14 @@ EOF
 esac
 
 echo $ac_n "checking whether char is unsigned... $ac_c" 1>&6
-echo "configure:4897: checking whether char is unsigned" 1>&5
+echo "configure:4899: checking whether char is unsigned" 1>&5
 if test "${ac_cv_c_char_unsigned+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$GCC" = yes; then
   # GCC predefines this symbol on systems where it applies.
 cat >conftest.$ac_ext <<EOF
-#line 4904 "configure"
+#line 4906 "configure"
 #include "confdefs.h"
 #ifdef __CHAR_UNSIGNED__
   yes
@@ -4922,7 +4924,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; }
 else
   cat >conftest.$ac_ext <<EOF
-#line 4926 "configure"
+#line 4928 "configure"
 #include "confdefs.h"
 /* volatile prevents gcc2 from optimizing the test away on sparcs.  */
 #if !defined(__STDC__) || __STDC__ != 1
@@ -4935,7 +4937,7 @@ main()
   exit(c < 0);
 }
 EOF
-if { (eval echo configure:4939: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_char_unsigned=yes
 else
@@ -4960,7 +4962,7 @@ fi
                case "$host" in
  $target)
     echo $ac_n "checking size of signed char... $ac_c" 1>&6
-echo "configure:4964: checking size of signed char" 1>&5
+echo "configure:4966: checking size of signed char" 1>&5
 if test "${ac_cv_sizeof_signed_char+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4968,7 +4970,7 @@ else
     { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; }
 else
   cat >conftest.$ac_ext <<EOF
-#line 4972 "configure"
+#line 4974 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -4981,7 +4983,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:4985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_signed_char=`cat conftestval`
 else
@@ -5004,7 +5006,7 @@ EOF
  *) case "$target" in
      *-*-vxworks*)
        echo $ac_n "checking size of signed char... $ac_c" 1>&6
-echo "configure:5008: checking size of signed char" 1>&5
+echo "configure:5010: checking size of signed char" 1>&5
 if test "${ac_cv_sizeof_signed_char+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5012,7 +5014,7 @@ else
   ac_cv_sizeof_signed_char=1
 else
   cat >conftest.$ac_ext <<EOF
-#line 5016 "configure"
+#line 5018 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -5025,7 +5027,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:5029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_signed_char=`cat conftestval`
 else
@@ -5054,7 +5056,7 @@ esac
 case "$host" in
  $target)
     echo $ac_n "checking size of int... $ac_c" 1>&6
-echo "configure:5058: checking size of int" 1>&5
+echo "configure:5060: checking size of int" 1>&5
 if test "${ac_cv_sizeof_int+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5062,7 +5064,7 @@ else
     { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; }
 else
   cat >conftest.$ac_ext <<EOF
-#line 5066 "configure"
+#line 5068 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -5075,7 +5077,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:5079: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5081: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int=`cat conftestval`
 else
@@ -5098,7 +5100,7 @@ EOF
  *) case "$target" in
      *-*-vxworks*)
        echo $ac_n "checking size of int... $ac_c" 1>&6
-echo "configure:5102: checking size of int" 1>&5
+echo "configure:5104: checking size of int" 1>&5
 if test "${ac_cv_sizeof_int+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5106,7 +5108,7 @@ else
   ac_cv_sizeof_int=4
 else
   cat >conftest.$ac_ext <<EOF
-#line 5110 "configure"
+#line 5112 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -5119,7 +5121,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:5123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5125: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int=`cat conftestval`
 else
@@ -5148,7 +5150,7 @@ esac
 case "$host" in
  $target)
     echo $ac_n "checking size of long... $ac_c" 1>&6
-echo "configure:5152: checking size of long" 1>&5
+echo "configure:5154: checking size of long" 1>&5
 if test "${ac_cv_sizeof_long+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5156,7 +5158,7 @@ else
     { echo "configure: error: cannot run test program while cross compiling" 1>&2; exit 1; }
 else
   cat >conftest.$ac_ext <<EOF
-#line 5160 "configure"
+#line 5162 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -5169,7 +5171,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:5173: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long=`cat conftestval`
 else
@@ -5192,7 +5194,7 @@ EOF
  *) case "$target" in
      *-*-vxworks*)
        echo $ac_n "checking size of long... $ac_c" 1>&6
-echo "configure:5196: checking size of long" 1>&5
+echo "configure:5198: checking size of long" 1>&5
 if test "${ac_cv_sizeof_long+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5200,7 +5202,7 @@ else
   ac_cv_sizeof_long=4
 else
   cat >conftest.$ac_ext <<EOF
-#line 5204 "configure"
+#line 5206 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -5213,7 +5215,7 @@ main ()
   exit (0);
 }
 EOF
-if { (eval echo configure:5217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long=`cat conftestval`
 else
@@ -5240,12 +5242,12 @@ EOF
 esac
 
 echo $ac_n "checking for s_char... $ac_c" 1>&6
-echo "configure:5244: checking for s_char" 1>&5
+echo "configure:5246: checking for s_char" 1>&5
 if test "${ac_cv_type_s_char+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5249 "configure"
+#line 5251 "configure"
 #include "confdefs.h"
 $ac_includes_default
 int
@@ -5259,7 +5261,7 @@ if (sizeof (s_char))
   return 0;
 }
 EOF
-if { (eval echo configure:5263: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5265: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_s_char=yes
 else
@@ -5309,12 +5311,12 @@ EOF
     ;;
 esac
 echo $ac_n "checking for uid_t in sys/types.h... $ac_c" 1>&6
-echo "configure:5313: checking for uid_t in sys/types.h" 1>&5
+echo "configure:5315: checking for uid_t in sys/types.h" 1>&5
 if test "${ac_cv_type_uid_t+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5318 "configure"
+#line 5320 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 
@@ -5348,12 +5350,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5352: checking for $ac_func" 1>&5
+echo "configure:5354: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5357 "configure"
+#line 5359 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5381,7 +5383,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5385: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5416,12 +5418,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5420: checking for $ac_func" 1>&5
+echo "configure:5422: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5425 "configure"
+#line 5427 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5449,7 +5451,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5476,12 +5478,12 @@ for ac_func in daemon getbootfile getdtablesize getrusage
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5480: checking for $ac_func" 1>&5
+echo "configure:5482: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5485 "configure"
+#line 5487 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5509,7 +5511,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5534,12 +5536,12 @@ for ac_func in gettimeofday
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5538: checking for $ac_func" 1>&5
+echo "configure:5540: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5543 "configure"
+#line 5545 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5567,7 +5569,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5595,12 +5597,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5599: checking for $ac_func" 1>&5
+echo "configure:5601: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5604 "configure"
+#line 5606 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5628,7 +5630,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5632: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5634: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5655,12 +5657,12 @@ for ac_func in K_open kvm_open memcpy memmove memset
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5659: checking for $ac_func" 1>&5
+echo "configure:5661: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5664 "configure"
+#line 5666 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5688,7 +5690,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5717,12 +5719,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5721: checking for $ac_func" 1>&5
+echo "configure:5723: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5726 "configure"
+#line 5728 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5750,7 +5752,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5754: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5756: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5777,12 +5779,12 @@ for ac_func in mktime
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5781: checking for $ac_func" 1>&5
+echo "configure:5783: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5786 "configure"
+#line 5788 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5810,7 +5812,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5816: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5850,12 +5852,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5854: checking for $ac_func" 1>&5
+echo "configure:5856: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5859 "configure"
+#line 5861 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5883,7 +5885,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5908,12 +5910,12 @@ done
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5912: checking for $ac_func" 1>&5
+echo "configure:5914: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5917 "configure"
+#line 5919 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5941,7 +5943,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:5945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -5967,12 +5969,12 @@ done
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:5971: checking for $ac_func" 1>&5
+echo "configure:5973: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 5976 "configure"
+#line 5978 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6000,7 +6002,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6006: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6027,12 +6029,12 @@ for ac_func in mrand48 srand48 nice nlist
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6031: checking for $ac_func" 1>&5
+echo "configure:6033: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6036 "configure"
+#line 6038 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6060,7 +6062,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6089,12 +6091,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6093: checking for $ac_func" 1>&5
+echo "configure:6095: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6098 "configure"
+#line 6100 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6122,7 +6124,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6149,12 +6151,12 @@ for ac_func in plock pututline pututxline rtprio
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6153: checking for $ac_func" 1>&5
+echo "configure:6155: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6158 "configure"
+#line 6160 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6182,7 +6184,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6209,12 +6211,12 @@ case "$ac_cv_func_mrand48" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6213: checking for $ac_func" 1>&5
+echo "configure:6215: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6218 "configure"
+#line 6220 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6242,7 +6244,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6248: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6278,12 +6280,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6282: checking for $ac_func" 1>&5
+echo "configure:6284: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6287 "configure"
+#line 6289 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6311,7 +6313,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6338,12 +6340,12 @@ for ac_func in setlinebuf
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6342: checking for $ac_func" 1>&5
+echo "configure:6344: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6347 "configure"
+#line 6349 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6371,7 +6373,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6396,12 +6398,12 @@ for ac_func in setpgid setpriority setsid settimeofday setvbuf sigaction
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6400: checking for $ac_func" 1>&5
+echo "configure:6402: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6405 "configure"
+#line 6407 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6429,7 +6431,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6435: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6454,12 +6456,12 @@ for ac_func in sigvec sigset sigsuspend stime strchr sysconf sysctl
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6458: checking for $ac_func" 1>&5
+echo "configure:6460: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6463 "configure"
+#line 6465 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6487,7 +6489,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6512,12 +6514,12 @@ for ac_func in strerror
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6516: checking for $ac_func" 1>&5
+echo "configure:6518: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6521 "configure"
+#line 6523 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6545,7 +6547,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6582,12 +6584,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6586: checking for $ac_func" 1>&5
+echo "configure:6588: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6591 "configure"
+#line 6593 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6615,7 +6617,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6646,12 +6648,12 @@ case "$target" in
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6650: checking for $ac_func" 1>&5
+echo "configure:6652: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6655 "configure"
+#line 6657 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6679,7 +6681,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6706,12 +6708,12 @@ for ac_func in uname updwtmp updwtmpx vsprintf
 do
 ac_ac_var=`echo "ac_cv_func_$ac_func" | $ac_tr_sh`
 echo $ac_n "checking for $ac_func... $ac_c" 1>&6
-echo "configure:6710: checking for $ac_func" 1>&5
+echo "configure:6712: checking for $ac_func" 1>&5
 if eval "test \"\${$ac_ac_var+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6715 "configure"
+#line 6717 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6739,7 +6741,7 @@ f = $ac_func;
   return 0;
 }
 EOF
-if { (eval echo configure:6743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "$ac_ac_var=yes"
 else
@@ -6761,12 +6763,12 @@ fi
 done
 
 echo $ac_n "checking number of arguments to gettimeofday()... $ac_c" 1>&6
-echo "configure:6765: checking number of arguments to gettimeofday()" 1>&5
+echo "configure:6767: checking number of arguments to gettimeofday()" 1>&5
 if test "${ac_cv_func_Xettimeofday_nargs+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6770 "configure"
+#line 6772 "configure"
 #include "confdefs.h"
 #include <sys/time.h>
 int
@@ -6780,7 +6782,7 @@ settimeofday((struct timeval*)0,(struct timezone*)0);
   return 0;
 }
 EOF
-if { (eval echo configure:6784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_func_Xettimeofday_nargs=2
 else
@@ -6801,12 +6803,12 @@ EOF
 fi
 
 echo $ac_n "checking number of arguments taken by setpgrp()... $ac_c" 1>&6
-echo "configure:6805: checking number of arguments taken by setpgrp()" 1>&5
+echo "configure:6807: checking number of arguments taken by setpgrp()" 1>&5
 if test "${ac_cv_func_setpgrp_nargs+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6810 "configure"
+#line 6812 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_SYS_TYPES_H
@@ -6824,7 +6826,7 @@ setpgrp(0,0);
   return 0;
 }
 EOF
-if { (eval echo configure:6828: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_func_setpgrp_nargs=2
 else
@@ -6848,12 +6850,12 @@ save_CFLAGS=$CFLAGS
 CFLAGS="$CFLAGS -I$srcdir/include"
 
 echo $ac_n "checking argument pointer type of qsort()'s compare function and base... $ac_c" 1>&6
-echo "configure:6852: checking argument pointer type of qsort()'s compare function and base" 1>&5
+echo "configure:6854: checking argument pointer type of qsort()'s compare function and base" 1>&5
 if test "${ac_cv_func_qsort_argtype+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6857 "configure"
+#line 6859 "configure"
 #include "confdefs.h"
 
 #include "l_stdlib.h"
@@ -6880,7 +6882,7 @@ qsort(base, 2, sizeof(char *), sortfunc);
   return 0;
 }
 EOF
-if { (eval echo configure:6884: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_func_qsort_argtype=void
 else
@@ -6905,12 +6907,12 @@ esac
 CFLAGS=$save_CFLAGS
 
 echo $ac_n "checking if we need to declare 'errno'... $ac_c" 1>&6
-echo "configure:6909: checking if we need to declare 'errno'" 1>&5
+echo "configure:6911: checking if we need to declare 'errno'" 1>&5
 if test "${ac_cv_decl_errno+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6914 "configure"
+#line 6916 "configure"
 #include "confdefs.h"
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -6923,7 +6925,7 @@ errno = 0;
   return 0;
 }
 EOF
-if { (eval echo configure:6927: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6929: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_decl_errno=no
 else
@@ -6943,12 +6945,12 @@ EOF
 esac
 
 echo $ac_n "checking if we may declare 'h_errno'... $ac_c" 1>&6
-echo "configure:6947: checking if we may declare 'h_errno'" 1>&5
+echo "configure:6949: checking if we may declare 'h_errno'" 1>&5
 if test "${ac_cv_decl_h_errno+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 6952 "configure"
+#line 6954 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #ifdef HAVE_NETINET_IN_H
@@ -6971,7 +6973,7 @@ extern int h_errno;
   return 0;
 }
 EOF
-if { (eval echo configure:6975: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_decl_h_errno=yes
 else
@@ -6991,12 +6993,12 @@ EOF
 esac
 
 echo $ac_n "checking if declaring 'char *sys_errlist[]' is ok... $ac_c" 1>&6
-echo "configure:6995: checking [if declaring 'char *sys_errlist[]' is ok]" 1>&5
+echo "configure:6997: checking [if declaring 'char *sys_errlist[]' is ok]" 1>&5
 if test "${ac_cv_decl_sys_errlist+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 7000 "configure"
+#line 7002 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #ifdef HAVE_ERRNO_H
@@ -7011,7 +7013,7 @@ extern char *sys_errlist[];
   return 0;
 }
 EOF
-if { (eval echo configure:7015: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7017: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_decl_sys_errlist=yes
 else
@@ -7031,12 +7033,12 @@ EOF
 esac
 
 echo $ac_n "checking if declaring 'syscall()' is ok... $ac_c" 1>&6
-echo "configure:7035: checking if declaring 'syscall()' is ok" 1>&5
+echo "configure:7037: checking if declaring 'syscall()' is ok" 1>&5
 if test "${ac_cv_decl_syscall+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 7040 "configure"
+#line 7042 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_SYS_TYPES_H
@@ -7059,7 +7061,7 @@ extern int syscall P((int, ...));
   return 0;
 }
 EOF
-if { (eval echo configure:7063: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7065: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_decl_syscall=yes
 else
@@ -7345,7 +7347,7 @@ EOF
 esac
 
 echo $ac_n "checking if we should use a streams device for ifconfig... $ac_c" 1>&6
-echo "configure:7349: checking if we should use a streams device for ifconfig" 1>&5
+echo "configure:7351: checking if we should use a streams device for ifconfig" 1>&5
 if test "${ac_cv_var_use_streams_device_for_ifconfig+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7354,7 +7356,7 @@ fi
 echo "$ac_t""$ac_cv_var_use_streams_device_for_ifconfig" 1>&6
 
 echo $ac_n "checking if we need extra room for SO_RCVBUF... $ac_c" 1>&6
-echo "configure:7358: checking if we need extra room for SO_RCVBUF" 1>&5
+echo "configure:7360: checking if we need extra room for SO_RCVBUF" 1>&5
 if test "${ac_cv_var_rcvbuf_slop+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7375,7 +7377,7 @@ EOF
 esac
 
 echo $ac_n "checking if we will open the broadcast socket... $ac_c" 1>&6
-echo "configure:7379: checking if we will open the broadcast socket" 1>&5
+echo "configure:7381: checking if we will open the broadcast socket" 1>&5
 if test "${ac_cv_var_open_bcast_socket+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7399,7 +7401,7 @@ EOF
 esac
 
 echo $ac_n "checking if we want the HPUX version of FindConfig()... $ac_c" 1>&6
-echo "configure:7403: checking if we want the HPUX version of FindConfig()" 1>&5
+echo "configure:7405: checking if we want the HPUX version of FindConfig()" 1>&5
 if test "${ac_cv_var_hpux_findconfig+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7420,7 +7422,7 @@ EOF
 esac
 
 echo $ac_n "checking if process groups are set with -pid... $ac_c" 1>&6
-echo "configure:7424: checking if process groups are set with -pid" 1>&5
+echo "configure:7426: checking if process groups are set with -pid" 1>&5
 if test "${ac_cv_arg_setpgrp_negpid+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7455,7 +7457,7 @@ EOF
 esac
 
 echo $ac_n "checking if we need a ctty for F_SETOWN... $ac_c" 1>&6
-echo "configure:7459: checking if we need a ctty for F_SETOWN" 1>&5
+echo "configure:7461: checking if we need a ctty for F_SETOWN" 1>&5
 if test "${ac_cv_func_ctty_for_f_setown+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7490,7 +7492,7 @@ esac
 
 ntp_warning='GRONK'
 echo $ac_n "checking if we'll use clock_settime or settimeofday or stime... $ac_c" 1>&6
-echo "configure:7494: checking if we'll use clock_settime or settimeofday or stime" 1>&5
+echo "configure:7496: checking if we'll use clock_settime or settimeofday or stime" 1>&5
 case "$ac_cv_func_clock_settime$ac_cv_func_settimeofday$ac_cv_func_stime" in
  yes*)
     ntp_warning=''
@@ -7519,7 +7521,7 @@ case "$ntp_warning" in
 esac
 
 echo $ac_n "checking if we have a losing syscall()... $ac_c" 1>&6
-echo "configure:7523: checking if we have a losing syscall()" 1>&5
+echo "configure:7525: checking if we have a losing syscall()" 1>&5
 if test "${ac_cv_var_syscall_bug+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7541,7 +7543,7 @@ EOF
 esac
 
 echo $ac_n "checking for Streams/TLI... $ac_c" 1>&6
-echo "configure:7545: checking for Streams/TLI" 1>&5
+echo "configure:7547: checking for Streams/TLI" 1>&5
 if test "${ac_cv_var_streams_tli+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7569,12 +7571,12 @@ EOF
 esac
 
 echo $ac_n "checking for SIGIO... $ac_c" 1>&6
-echo "configure:7573: checking for SIGIO" 1>&5
+echo "configure:7575: checking for SIGIO" 1>&5
 if test "${ac_cv_hdr_def_sigio+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 7578 "configure"
+#line 7580 "configure"
 #include "confdefs.h"
 #include <signal.h>
 #ifdef SIGIO
@@ -7596,7 +7598,7 @@ fi
 echo "$ac_t""$ac_cv_hdr_def_sigio" 1>&6
 
 echo $ac_n "checking if we want to use signalled IO... $ac_c" 1>&6
-echo "configure:7600: checking if we want to use signalled IO" 1>&5
+echo "configure:7602: checking if we want to use signalled IO" 1>&5
 if test "${ac_cv_var_signalled_io+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7646,12 +7648,12 @@ EOF
 esac
 
 echo $ac_n "checking for SIGPOLL... $ac_c" 1>&6
-echo "configure:7650: checking for SIGPOLL" 1>&5
+echo "configure:7652: checking for SIGPOLL" 1>&5
 if test "${ac_cv_hdr_def_sigpoll+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 7655 "configure"
+#line 7657 "configure"
 #include "confdefs.h"
 #include <signal.h>
 #ifdef SIGPOLL
@@ -7673,12 +7675,12 @@ fi
 echo "$ac_t""$ac_cv_hdr_def_sigpoll" 1>&6
 
 echo $ac_n "checking for SIGSYS... $ac_c" 1>&6
-echo "configure:7677: checking for SIGSYS" 1>&5
+echo "configure:7679: checking for SIGSYS" 1>&5
 if test "${ac_cv_hdr_def_sigsys+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 7682 "configure"
+#line 7684 "configure"
 #include "confdefs.h"
 #include <signal.h>
 #ifdef SIGSYS
@@ -7700,7 +7702,7 @@ fi
 echo "$ac_t""$ac_cv_hdr_def_sigsys" 1>&6
 
 echo $ac_n "checking if we can use SIGPOLL for UDP I/O... $ac_c" 1>&6
-echo "configure:7704: checking if we can use SIGPOLL for UDP I/O" 1>&5
+echo "configure:7706: checking if we can use SIGPOLL for UDP I/O" 1>&5
 if test "${ac_cv_var_use_udp_sigpoll+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7754,7 +7756,7 @@ EOF
 esac
 
 echo $ac_n "checking if we can use SIGPOLL for TTY I/O... $ac_c" 1>&6
-echo "configure:7758: checking if we can use SIGPOLL for TTY I/O" 1>&5
+echo "configure:7760: checking if we can use SIGPOLL for TTY I/O" 1>&5
 if test "${ac_cv_var_use_tty_sigpoll+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7810,12 +7812,12 @@ esac
 case "$ac_cv_header_sys_sio_h" in
  yes)
     echo $ac_n "checking sys/sio.h for TIOCDCDTIMESTAMP... $ac_c" 1>&6
-echo "configure:7814: checking sys/sio.h for TIOCDCDTIMESTAMP" 1>&5
+echo "configure:7816: checking sys/sio.h for TIOCDCDTIMESTAMP" 1>&5
 if test "${ac_cv_hdr_def_tiocdcdtimestamp+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 7819 "configure"
+#line 7821 "configure"
 #include "confdefs.h"
 #include <sys/sio.h>
 #ifdef TIOCDCDTIMESTAMP
@@ -7845,7 +7847,7 @@ case "$ac_cv_hdr_def_tiocdcdtimestamp" in
 esac
 
 echo $ac_n "checking if nlist() values might require extra indirection... $ac_c" 1>&6
-echo "configure:7849: checking if nlist() values might require extra indirection" 1>&5
+echo "configure:7851: checking if nlist() values might require extra indirection" 1>&5
 if test "${ac_cv_var_nlist_extra_indirection+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7866,7 +7868,7 @@ EOF
 esac
 
 echo $ac_n "checking for a minimum recommended value of tickadj... $ac_c" 1>&6
-echo "configure:7870: checking for a minimum recommended value of tickadj" 1>&5
+echo "configure:7872: checking for a minimum recommended value of tickadj" 1>&5
 if test "${ac_cv_var_min_rec_tickadj+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7888,7 +7890,7 @@ EOF
 esac
 
 echo $ac_n "checking if the TTY code permits PARENB and IGNPAR... $ac_c" 1>&6
-echo "configure:7892: checking if the TTY code permits PARENB and IGNPAR" 1>&5
+echo "configure:7894: checking if the TTY code permits PARENB and IGNPAR" 1>&5
 if test "${ac_cv_var_no_parenb_ignpar+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7912,7 +7914,7 @@ EOF
 esac
 
 echo $ac_n "checking if we're including debugging code... $ac_c" 1>&6
-echo "configure:7916: checking if we're including debugging code" 1>&5
+echo "configure:7918: checking if we're including debugging code" 1>&5
 # Check whether --enable-debugging or --disable-debugging was given.
 if test "${enable_debugging+set}" = set; then
   enableval="$enable_debugging"
@@ -7930,7 +7932,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking for a the number of minutes in a DST adjustment... $ac_c" 1>&6
-echo "configure:7934: checking for a the number of minutes in a DST adjustment" 1>&5
+echo "configure:7936: checking for a the number of minutes in a DST adjustment" 1>&5
 # Check whether --enable-dst_minutes or --disable-dst_minutes was given.
 if test "${enable_dst_minutes+set}" = set; then
   enableval="$enable_dst_minutes"
@@ -7946,7 +7948,7 @@ EOF
 echo "$ac_t""$ans" 1>&6
 
 echo $ac_n "checking if we have the tty_clk line discipline/streams module... $ac_c" 1>&6
-echo "configure:7950: checking if we have the tty_clk line discipline/streams module" 1>&5
+echo "configure:7952: checking if we have the tty_clk line discipline/streams module" 1>&5
 if test "${ac_cv_var_tty_clk+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7963,7 +7965,7 @@ EOF
 esac
 
 echo $ac_n "checking for the ppsclock streams module... $ac_c" 1>&6
-echo "configure:7967: checking for the ppsclock streams module" 1>&5
+echo "configure:7969: checking for the ppsclock streams module" 1>&5
 if test "${ac_cv_var_ppsclock+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7978,7 +7980,7 @@ EOF
 esac
 
 echo $ac_n "checking for kernel multicast support... $ac_c" 1>&6
-echo "configure:7982: checking for kernel multicast support" 1>&5
+echo "configure:7984: checking for kernel multicast support" 1>&5
 if test "${ac_cv_var_mcast+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7986,7 +7988,7 @@ else
   case "$target" in
    i386-sequent-sysv4) ;;
    *) cat >conftest.$ac_ext <<EOF
-#line 7990 "configure"
+#line 7992 "configure"
 #include "confdefs.h"
 #include <netinet/in.h>
 #ifdef IP_ADD_MEMBERSHIP
@@ -8012,7 +8014,7 @@ EOF
 esac
 
 echo $ac_n "checking availability of ntp_{adj,get}time()... $ac_c" 1>&6
-echo "configure:8016: checking [availability of ntp_{adj,get}time()]" 1>&5
+echo "configure:8018: checking [availability of ntp_{adj,get}time()]" 1>&5
 if test "${ac_cv_var_ntp_syscalls+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8026,7 +8028,7 @@ else
         ac_cv_var_ntp_syscalls=libc
         ;;
       *) cat >conftest.$ac_ext <<EOF
-#line 8030 "configure"
+#line 8032 "configure"
 #include "confdefs.h"
 #include <sys/syscall.h>
 #if defined(SYS_ntp_gettime) && defined(SYS_ntp_adjtime)
@@ -8065,12 +8067,12 @@ EOF
 esac
 
 echo $ac_n "checking if sys/timex.h has STA_FLL... $ac_c" 1>&6
-echo "configure:8069: checking if sys/timex.h has STA_FLL" 1>&5
+echo "configure:8071: checking if sys/timex.h has STA_FLL" 1>&5
 if test "${ac_cv_var_sta_fll+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8074 "configure"
+#line 8076 "configure"
 #include "confdefs.h"
 #include <sys/timex.h>
 #ifdef STA_FLL
@@ -8092,7 +8094,7 @@ fi
 echo "$ac_t""$ac_cv_var_sta_fll" 1>&6
 
 echo $ac_n "checking if we have kernel PLL support... $ac_c" 1>&6
-echo "configure:8096: checking if we have kernel PLL support" 1>&5
+echo "configure:8098: checking if we have kernel PLL support" 1>&5
 if test "${ac_cv_var_kernel_pll+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8115,7 +8117,7 @@ EOF
 esac
 
 echo $ac_n "checking if SIOCGIFCONF returns buffer size in the buffer... $ac_c" 1>&6
-echo "configure:8119: checking if SIOCGIFCONF returns buffer size in the buffer" 1>&5
+echo "configure:8121: checking if SIOCGIFCONF returns buffer size in the buffer" 1>&5
 if test "${ac_cv_var_size_returned_in_buffer+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8142,7 +8144,7 @@ EOF
 esac
 
 echo $ac_n "checking if we want to use MD5 authentication... $ac_c" 1>&6
-echo "configure:8146: checking if we want to use MD5 authentication" 1>&5
+echo "configure:8148: checking if we want to use MD5 authentication" 1>&5
 if test "${ac_cv_var_use_md5+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8158,18 +8160,24 @@ ac_cv_var_use_md5=$ans
 fi
 echo "$ac_t""$ac_cv_var_use_md5" 1>&6
 case "$ac_cv_var_use_md5" in
- yes) cat >>confdefs.h <<\EOF
+ yes)
+     cat >>confdefs.h <<\EOF
+#define AUTOKEY 
+EOF
+
+     cat >>confdefs.h <<\EOF
 #define MD5 1
 EOF
- ;;
+
+     ;;
 esac
 
 # Check for ioctls TIOCGPPSEV
 echo $ac_n "checking ioctl TIOCGPPSEV... $ac_c" 1>&6
-echo "configure:8170: checking ioctl TIOCGPPSEV" 1>&5
+echo "configure:8178: checking ioctl TIOCGPPSEV" 1>&5
 if test "$ac_cv_header_termios_h" = "yes"; then
     cat >conftest.$ac_ext <<EOF
-#line 8173 "configure"
+#line 8181 "configure"
 #include "confdefs.h"
 #include <termios.h>
 #ifdef TIOCGPPSEV
@@ -8201,10 +8209,10 @@ echo "$ac_t""$ntp_ok" 1>&6
 
 # Check for ioctls TIOCSPPS
 echo $ac_n "checking ioctl TIOCSPPS... $ac_c" 1>&6
-echo "configure:8205: checking ioctl TIOCSPPS" 1>&5
+echo "configure:8213: checking ioctl TIOCSPPS" 1>&5
 if test "$ac_cv_header_termios_h" = "yes"; then
     cat >conftest.$ac_ext <<EOF
-#line 8208 "configure"
+#line 8216 "configure"
 #include "confdefs.h"
 #include <termios.h>
 #ifdef TIOCSPPS
@@ -8236,10 +8244,10 @@ echo "$ac_t""$ntp_ok" 1>&6
 
 # Check for ioctls CIOGETEV
 echo $ac_n "checking ioctl CIOGETEV... $ac_c" 1>&6
-echo "configure:8240: checking ioctl CIOGETEV" 1>&5
+echo "configure:8248: checking ioctl CIOGETEV" 1>&5
 if test "$ac_cv_header_sys_ppsclock_h" = "yes"; then
     cat >conftest.$ac_ext <<EOF
-#line 8243 "configure"
+#line 8251 "configure"
 #include "confdefs.h"
 #include <sys/ppsclock.h>
 #ifdef CIOGETEV
@@ -8289,18 +8297,18 @@ esac
 
 # Check for ioctls TIOCGSERIAL, TIOCSSERIAL, ASYNC_PPS_CD_POS, ASYNC_PPS_CD_NEG
 echo $ac_n "checking for linux/serial.h... $ac_c" 1>&6
-echo "configure:8293: checking for linux/serial.h" 1>&5
+echo "configure:8301: checking for linux/serial.h" 1>&5
 if test "${ac_cv_header_linux_serial_h+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8298 "configure"
+#line 8306 "configure"
 #include "confdefs.h"
 #include <linux/serial.h>
 
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8304: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8312: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -8317,11 +8325,11 @@ fi
 echo "$ac_t""$ac_cv_header_linux_serial_h" 1>&6
 
 echo $ac_n "checking ioctl TIOCGSERIAL... $ac_c" 1>&6
-echo "configure:8321: checking ioctl TIOCGSERIAL" 1>&5
+echo "configure:8329: checking ioctl TIOCGSERIAL" 1>&5
 case "$ac_cv_header_sys_ppsclock_h$ac_cv_header_linux_serial_h" in
   yesyes)
     cat >conftest.$ac_ext <<EOF
-#line 8325 "configure"
+#line 8333 "configure"
 #include "confdefs.h"
 #include <sys/time.h>
 typedef int u_int;
@@ -8364,7 +8372,7 @@ echo "$ac_t""$ntp_ok" 1>&6
 
 # Check for SHMEM_STATUS support
 echo $ac_n "checking SHMEM_STATUS support... $ac_c" 1>&6
-echo "configure:8368: checking SHMEM_STATUS support" 1>&5
+echo "configure:8376: checking SHMEM_STATUS support" 1>&5
 case "$ac_cv_header_sys_mman_h" in
  yes) ntp_ok=yes ;;
  *)   ntp_ok=no  ;;
@@ -8381,7 +8389,7 @@ ntp_refclock=no
 
 # HPUX only, and by explicit request
 echo $ac_n "checking Datum/Bancomm bc635/VME interface... $ac_c" 1>&6
-echo "configure:8385: checking Datum/Bancomm bc635/VME interface" 1>&5
+echo "configure:8393: checking Datum/Bancomm bc635/VME interface" 1>&5
 # Check whether --enable-BANCOMM or --disable-BANCOMM was given.
 if test "${enable_BANCOMM+set}" = set; then
   enableval="$enable_BANCOMM"
@@ -8405,7 +8413,7 @@ esac
 
 #HPUX only, and only by explicit request
 echo $ac_n "checking TrueTime GPS receiver/VME interface... $ac_c" 1>&6
-echo "configure:8409: checking TrueTime GPS receiver/VME interface" 1>&5
+echo "configure:8417: checking TrueTime GPS receiver/VME interface" 1>&5
 # Check whether --enable-GPSVME or --disable-GPSVME was given.
 if test "${enable_GPSVME+set}" = set; then
   enableval="$enable_GPSVME"
@@ -8428,7 +8436,7 @@ case "$ntp_ok$target" in
 esac
 
 echo $ac_n "checking for PCL720 clock support... $ac_c" 1>&6
-echo "configure:8432: checking for PCL720 clock support" 1>&5
+echo "configure:8440: checking for PCL720 clock support" 1>&5
 case "$ac_cv_header_machine_inline_h$ac_cv_header_sys_pcl720_h$ac_cv_header_sys_i8253_h" in
  yesyesyes)
     cat >>confdefs.h <<\EOF
@@ -8444,7 +8452,7 @@ esac
 echo "$ac_t""$ans" 1>&6
 
 echo $ac_n "checking for SHM clock attached thru shared memory... $ac_c" 1>&6
-echo "configure:8448: checking for SHM clock attached thru shared memory" 1>&5
+echo "configure:8456: checking for SHM clock attached thru shared memory" 1>&5
 # Check whether --enable-SHM or --disable-SHM was given.
 if test "${enable_SHM+set}" = set; then
   enableval="$enable_SHM"
@@ -8463,7 +8471,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking for default inclusion of all suitable non-PARSE clocks... $ac_c" 1>&6
-echo "configure:8467: checking for default inclusion of all suitable non-PARSE clocks" 1>&5
+echo "configure:8475: checking for default inclusion of all suitable non-PARSE clocks" 1>&5
 # Check whether --enable-all-clocks or --disable-all-clocks was given.
 if test "${enable_all_clocks+set}" = set; then
   enableval="$enable_all_clocks"
@@ -8475,7 +8483,7 @@ fi
 echo "$ac_t""$ntp_eac" 1>&6
 
 echo $ac_n "checking if we have support for PARSE clocks... $ac_c" 1>&6
-echo "configure:8479: checking if we have support for PARSE clocks" 1>&5
+echo "configure:8487: checking if we have support for PARSE clocks" 1>&5
 case "$ac_cv_header_termio_h$ac_cv_header_termios_h" in
  *yes*)
     ntp_canparse=yes
@@ -8486,7 +8494,7 @@ esac
 echo "$ac_t""$ntp_canparse" 1>&6
 
 echo $ac_n "checking if we have support for audio clocks... $ac_c" 1>&6
-echo "configure:8490: checking if we have support for audio clocks" 1>&5
+echo "configure:8498: checking if we have support for audio clocks" 1>&5
 case "$ac_cv_header_sun_audioio_h$ac_cv_header_sys_audioio_h" in
  *yes*)        ntp_canaudio=yes ;;
  *)    ntp_canaudio=no  ;;
@@ -8494,12 +8502,12 @@ esac
 echo "$ac_t""$ntp_canaudio" 1>&6
 
 echo $ac_n "checking for struct audio_info.monitor_gain... $ac_c" 1>&6
-echo "configure:8498: checking for struct audio_info.monitor_gain" 1>&5
+echo "configure:8506: checking for struct audio_info.monitor_gain" 1>&5
 if test "${ac_cv_member_struct_audio_info_monitor_gain+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8503 "configure"
+#line 8511 "configure"
 #include "confdefs.h"
 #ifdef HAVE_SUN_AUDIO_H
 #include <sun/audio.h>
@@ -8517,7 +8525,7 @@ foo.monitor_gain;
   return 0;
 }
 EOF
-if { (eval echo configure:8521: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8529: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_member_struct_audio_info_monitor_gain=yes
 else
@@ -8537,12 +8545,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct audio_info.output_muted... $ac_c" 1>&6
-echo "configure:8541: checking for struct audio_info.output_muted" 1>&5
+echo "configure:8549: checking for struct audio_info.output_muted" 1>&5
 if test "${ac_cv_member_struct_audio_info_output_muted+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8546 "configure"
+#line 8554 "configure"
 #include "confdefs.h"
 #ifdef HAVE_SUN_AUDIO_H
 #include <sun/audio.h>
@@ -8560,7 +8568,7 @@ foo.output_muted;
   return 0;
 }
 EOF
-if { (eval echo configure:8564: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8572: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_member_struct_audio_info_output_muted=yes
 else
@@ -8580,12 +8588,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct audio_info.blocksize... $ac_c" 1>&6
-echo "configure:8584: checking for struct audio_info.blocksize" 1>&5
+echo "configure:8592: checking for struct audio_info.blocksize" 1>&5
 if test "${ac_cv_member_struct_audio_info_blocksize+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8589 "configure"
+#line 8597 "configure"
 #include "confdefs.h"
 #ifdef HAVE_SUN_AUDIO_H
 #include <sun/audio.h>
@@ -8603,7 +8611,7 @@ foo.blocksize;
   return 0;
 }
 EOF
-if { (eval echo configure:8607: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_member_struct_audio_info_blocksize=yes
 else
@@ -8623,12 +8631,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct audio_info.hiwat... $ac_c" 1>&6
-echo "configure:8627: checking for struct audio_info.hiwat" 1>&5
+echo "configure:8635: checking for struct audio_info.hiwat" 1>&5
 if test "${ac_cv_member_struct_audio_info_hiwat+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8632 "configure"
+#line 8640 "configure"
 #include "confdefs.h"
 #ifdef HAVE_SUN_AUDIO_H
 #include <sun/audio.h>
@@ -8646,7 +8654,7 @@ foo.hiwat;
   return 0;
 }
 EOF
-if { (eval echo configure:8650: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8658: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_member_struct_audio_info_hiwat=yes
 else
@@ -8666,12 +8674,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct audio_info.lowat... $ac_c" 1>&6
-echo "configure:8670: checking for struct audio_info.lowat" 1>&5
+echo "configure:8678: checking for struct audio_info.lowat" 1>&5
 if test "${ac_cv_member_struct_audio_info_lowat+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8675 "configure"
+#line 8683 "configure"
 #include "confdefs.h"
 #ifdef HAVE_SUN_AUDIO_H
 #include <sun/audio.h>
@@ -8689,7 +8697,7 @@ foo.lowat;
   return 0;
 }
 EOF
-if { (eval echo configure:8693: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8701: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_member_struct_audio_info_lowat=yes
 else
@@ -8709,12 +8717,12 @@ EOF
 fi
 
 echo $ac_n "checking for struct audio_info.mode... $ac_c" 1>&6
-echo "configure:8713: checking for struct audio_info.mode" 1>&5
+echo "configure:8721: checking for struct audio_info.mode" 1>&5
 if test "${ac_cv_member_struct_audio_info_mode+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat >conftest.$ac_ext <<EOF
-#line 8718 "configure"
+#line 8726 "configure"
 #include "confdefs.h"
 #ifdef HAVE_SUN_AUDIO_H
 #include <sun/audio.h>
@@ -8732,7 +8740,7 @@ foo.mode;
   return 0;
 }
 EOF
-if { (eval echo configure:8736: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8744: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_member_struct_audio_info_mode=yes
 else
@@ -8753,14 +8761,14 @@ fi
 
 # Requires modem control
 echo $ac_n "checking ACTS modem service... $ac_c" 1>&6
-echo "configure:8757: checking ACTS modem service" 1>&5
+echo "configure:8765: checking ACTS modem service" 1>&5
 # Check whether --enable-ACTS or --disable-ACTS was given.
 if test "${enable_ACTS+set}" = set; then
   enableval="$enable_ACTS"
   ntp_ok=$enableval
 else
   cat >conftest.$ac_ext <<EOF
-#line 8764 "configure"
+#line 8772 "configure"
 #include "confdefs.h"
 #include <termios.h>
 #ifdef HAVE_SYS_IOCTL_H
@@ -8793,7 +8801,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Arbiter 1088A/B GPS receiver... $ac_c" 1>&6
-echo "configure:8797: checking Arbiter 1088A/B GPS receiver" 1>&5
+echo "configure:8805: checking Arbiter 1088A/B GPS receiver" 1>&5
 # Check whether --enable-ARBITER or --disable-ARBITER was given.
 if test "${enable_ARBITER+set}" = set; then
   enableval="$enable_ARBITER"
@@ -8812,7 +8820,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Arcron MSF receiver... $ac_c" 1>&6
-echo "configure:8816: checking Arcron MSF receiver" 1>&5
+echo "configure:8824: checking Arcron MSF receiver" 1>&5
 # Check whether --enable-ARCRON_MSF or --disable-ARCRON_MSF was given.
 if test "${enable_ARCRON_MSF+set}" = set; then
   enableval="$enable_ARCRON_MSF"
@@ -8831,7 +8839,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Austron 2200A/2201A GPS receiver... $ac_c" 1>&6
-echo "configure:8835: checking Austron 2200A/2201A GPS receiver" 1>&5
+echo "configure:8843: checking Austron 2200A/2201A GPS receiver" 1>&5
 # Check whether --enable-AS2201 or --disable-AS2201 was given.
 if test "${enable_AS2201+set}" = set; then
   enableval="$enable_AS2201"
@@ -8850,7 +8858,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking PPS interface... $ac_c" 1>&6
-echo "configure:8854: checking PPS interface" 1>&5
+echo "configure:8862: checking PPS interface" 1>&5
 # Check whether --enable-ATOM or --disable-ATOM was given.
 if test "${enable_ATOM+set}" = set; then
   enableval="$enable_ATOM"
@@ -8869,7 +8877,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking CHU modem/decoder... $ac_c" 1>&6
-echo "configure:8873: checking CHU modem/decoder" 1>&5
+echo "configure:8881: checking CHU modem/decoder" 1>&5
 # Check whether --enable-CHU or --disable-CHU was given.
 if test "${enable_CHU+set}" = set; then
   enableval="$enable_CHU"
@@ -8889,7 +8897,7 @@ echo "$ac_t""$ntp_ok" 1>&6
 ac_refclock_chu=$ntp_ok
 
 echo $ac_n "checking CHU audio/decoder... $ac_c" 1>&6
-echo "configure:8893: checking CHU audio/decoder" 1>&5
+echo "configure:8901: checking CHU audio/decoder" 1>&5
 # Check whether --enable-AUDIO-CHU or --disable-AUDIO-CHU was given.
 if test "${enable_AUDIO_CHU+set}" = set; then
   enableval="$enable_AUDIO_CHU"
@@ -8915,7 +8923,7 @@ esac
 
 # Not under HP-UX
 echo $ac_n "checking Datum Programmable Time System... $ac_c" 1>&6
-echo "configure:8919: checking Datum Programmable Time System" 1>&5
+echo "configure:8927: checking Datum Programmable Time System" 1>&5
 # Check whether --enable-DATUM or --disable-DATUM was given.
 if test "${enable_DATUM+set}" = set; then
   enableval="$enable_DATUM"
@@ -8940,7 +8948,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Forum Graphic GPS... $ac_c" 1>&6
-echo "configure:8944: checking Forum Graphic GPS" 1>&5
+echo "configure:8952: checking Forum Graphic GPS" 1>&5
 # Check whether --enable-FG or --disable-FG was given.
 if test "${enable_FG+set}" = set; then
   enableval="$enable_FG"
@@ -8960,14 +8968,14 @@ echo "$ac_t""$ntp_ok" 1>&6
 
 # Requires modem control
 echo $ac_n "checking Heath GC-1000 WWV/WWVH receiver... $ac_c" 1>&6
-echo "configure:8964: checking Heath GC-1000 WWV/WWVH receiver" 1>&5
+echo "configure:8972: checking Heath GC-1000 WWV/WWVH receiver" 1>&5
 # Check whether --enable-HEATH or --disable-HEATH was given.
 if test "${enable_HEATH+set}" = set; then
   enableval="$enable_HEATH"
   ntp_ok=$enableval
 else
   cat >conftest.$ac_ext <<EOF
-#line 8971 "configure"
+#line 8979 "configure"
 #include "confdefs.h"
 #include <termios.h>
 #ifdef HAVE_SYS_IOCTL_H
@@ -9000,7 +9008,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking HP 58503A GPS receiver... $ac_c" 1>&6
-echo "configure:9004: checking HP 58503A GPS receiver" 1>&5
+echo "configure:9012: checking HP 58503A GPS receiver" 1>&5
 # Check whether --enable-HPGPS or --disable-HPGPS was given.
 if test "${enable_HPGPS+set}" = set; then
   enableval="$enable_HPGPS"
@@ -9019,7 +9027,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Sun IRIG audio decoder... $ac_c" 1>&6
-echo "configure:9023: checking Sun IRIG audio decoder" 1>&5
+echo "configure:9031: checking Sun IRIG audio decoder" 1>&5
 # Check whether --enable-IRIG or --disable-IRIG was given.
 if test "${enable_IRIG+set}" = set; then
   enableval="$enable_IRIG"
@@ -9044,7 +9052,7 @@ case "$ntp_ok$ntp_canaudio" in
 esac
 
 echo $ac_n "checking Leitch CSD 5300 Master Clock System Driver... $ac_c" 1>&6
-echo "configure:9048: checking Leitch CSD 5300 Master Clock System Driver" 1>&5
+echo "configure:9056: checking Leitch CSD 5300 Master Clock System Driver" 1>&5
 # Check whether --enable-LEITCH or --disable-LEITCH was given.
 if test "${enable_LEITCH+set}" = set; then
   enableval="$enable_LEITCH"
@@ -9063,7 +9071,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking local clock reference... $ac_c" 1>&6
-echo "configure:9067: checking local clock reference" 1>&5
+echo "configure:9075: checking local clock reference" 1>&5
 # Check whether --enable-LOCAL-CLOCK or --disable-LOCAL-CLOCK was given.
 if test "${enable_LOCAL_CLOCK+set}" = set; then
   enableval="$enable_LOCAL_CLOCK"
@@ -9082,7 +9090,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking EES M201 MSF receiver... $ac_c" 1>&6
-echo "configure:9086: checking EES M201 MSF receiver" 1>&5
+echo "configure:9094: checking EES M201 MSF receiver" 1>&5
 # Check whether --enable-MSFEES or --disable-MSFEES was given.
 if test "${enable_MSFEES+set}" = set; then
   enableval="$enable_MSFEES"
@@ -9102,7 +9110,7 @@ echo "$ac_t""$ntp_ok" 1>&6
 
 # Not Ultrix
 echo $ac_n "checking Magnavox MX4200 GPS receiver... $ac_c" 1>&6
-echo "configure:9106: checking Magnavox MX4200 GPS receiver" 1>&5
+echo "configure:9114: checking Magnavox MX4200 GPS receiver" 1>&5
 # Check whether --enable-MX4200 or --disable-MX4200 was given.
 if test "${enable_MX4200+set}" = set; then
   enableval="$enable_MX4200"
@@ -9129,7 +9137,7 @@ case "$ntp_ok$target" in
 esac
 
 echo $ac_n "checking NMEA GPS receiver... $ac_c" 1>&6
-echo "configure:9133: checking NMEA GPS receiver" 1>&5
+echo "configure:9141: checking NMEA GPS receiver" 1>&5
 # Check whether --enable-NMEA or --disable-NMEA was given.
 if test "${enable_NMEA+set}" = set; then
   enableval="$enable_NMEA"
@@ -9148,7 +9156,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking for ONCORE Motorola VP/UT Oncore GPS... $ac_c" 1>&6
-echo "configure:9152: checking for ONCORE Motorola VP/UT Oncore GPS" 1>&5
+echo "configure:9160: checking for ONCORE Motorola VP/UT Oncore GPS" 1>&5
 # Check whether --enable-ONCORE or --disable-ONCORE was given.
 if test "${enable_ONCORE+set}" = set; then
   enableval="$enable_ONCORE"
@@ -9170,7 +9178,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking for Palisade clock... $ac_c" 1>&6
-echo "configure:9174: checking for Palisade clock" 1>&5
+echo "configure:9182: checking for Palisade clock" 1>&5
 # Check whether --enable-PALISADE or --disable-PALISADE was given.
 if test "${enable_PALISADE+set}" = set; then
   enableval="$enable_PALISADE"
@@ -9195,7 +9203,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking PST/Traconex 1020 WWV/WWVH receiver... $ac_c" 1>&6
-echo "configure:9199: checking PST/Traconex 1020 WWV/WWVH receiver" 1>&5
+echo "configure:9207: checking PST/Traconex 1020 WWV/WWVH receiver" 1>&5
 # Check whether --enable-PST or --disable-PST was given.
 if test "${enable_PST+set}" = set; then
   enableval="$enable_PST"
@@ -9215,7 +9223,7 @@ echo "$ac_t""$ntp_ok" 1>&6
 
 # Not Ultrix
 echo $ac_n "checking Rockwell Jupiter GPS receiver... $ac_c" 1>&6
-echo "configure:9219: checking Rockwell Jupiter GPS receiver" 1>&5
+echo "configure:9227: checking Rockwell Jupiter GPS receiver" 1>&5
 # Check whether --enable-JUPITER or --disable-JUPITER was given.
 if test "${enable_JUPITER+set}" = set; then
   enableval="$enable_JUPITER"
@@ -9243,14 +9251,14 @@ esac
 
 # Requires modem control
 echo $ac_n "checking PTB modem service... $ac_c" 1>&6
-echo "configure:9247: checking PTB modem service" 1>&5
+echo "configure:9255: checking PTB modem service" 1>&5
 # Check whether --enable-PTBACTS or --disable-PTBACTS was given.
 if test "${enable_PTBACTS+set}" = set; then
   enableval="$enable_PTBACTS"
   ntp_ok=$enableval
 else
   cat >conftest.$ac_ext <<EOF
-#line 9254 "configure"
+#line 9262 "configure"
 #include "confdefs.h"
 #include <termios.h>
 #ifdef HAVE_SYS_IOCTL_H
@@ -9283,7 +9291,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking KSI/Odetics TPRO/S GPS receiver/IRIG interface... $ac_c" 1>&6
-echo "configure:9287: checking KSI/Odetics TPRO/S GPS receiver/IRIG interface" 1>&5
+echo "configure:9295: checking KSI/Odetics TPRO/S GPS receiver/IRIG interface" 1>&5
 # Check whether --enable-TPRO or --disable-TPRO was given.
 if test "${enable_TPRO+set}" = set; then
   enableval="$enable_TPRO"
@@ -9311,7 +9319,7 @@ case "$ntp_ok$ac_cv_header_sys_tpro" in
 esac
 
 echo $ac_n "checking TRAK 8810 GPS receiver... $ac_c" 1>&6
-echo "configure:9315: checking TRAK 8810 GPS receiver" 1>&5
+echo "configure:9323: checking TRAK 8810 GPS receiver" 1>&5
 # Check whether --enable-TRAK or --disable-TRAK was given.
 if test "${enable_TRAK+set}" = set; then
   enableval="$enable_TRAK"
@@ -9330,7 +9338,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Chrono-log K-series WWVB receiver... $ac_c" 1>&6
-echo "configure:9334: checking Chrono-log K-series WWVB receiver" 1>&5
+echo "configure:9342: checking Chrono-log K-series WWVB receiver" 1>&5
 # Check whether --enable-CHRONOLOG or --disable-CHRONOLOG was given.
 if test "${enable_CHRONOLOG+set}" = set; then
   enableval="$enable_CHRONOLOG"
@@ -9349,7 +9357,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Dumb generic hh:mm:ss local clock... $ac_c" 1>&6
-echo "configure:9353: checking Dumb generic hh:mm:ss local clock" 1>&5
+echo "configure:9361: checking Dumb generic hh:mm:ss local clock" 1>&5
 # Check whether --enable-DUMBCLOCK or --disable-DUMBCLOCK was given.
 if test "${enable_DUMBCLOCK+set}" = set; then
   enableval="$enable_DUMBCLOCK"
@@ -9368,7 +9376,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Conrad parallel port radio clock... $ac_c" 1>&6
-echo "configure:9372: checking Conrad parallel port radio clock" 1>&5
+echo "configure:9380: checking Conrad parallel port radio clock" 1>&5
 # Check whether --enable-PCF or --disable-PCF was given.
 if test "${enable_PCF+set}" = set; then
   enableval="$enable_PCF"
@@ -9387,7 +9395,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking Spectracom 8170/Netclock/2 WWVB receiver... $ac_c" 1>&6
-echo "configure:9391: checking Spectracom 8170/Netclock/2 WWVB receiver" 1>&5
+echo "configure:9399: checking Spectracom 8170/Netclock/2 WWVB receiver" 1>&5
 # Check whether --enable-SPECTRACOM or --disable-SPECTRACOM was given.
 if test "${enable_SPECTRACOM+set}" = set; then
   enableval="$enable_SPECTRACOM"
@@ -9407,7 +9415,7 @@ echo "$ac_t""$ntp_ok" 1>&6
 
 # Not on a vax-dec-bsd
 echo $ac_n "checking Kinemetrics/TrueTime receivers... $ac_c" 1>&6
-echo "configure:9411: checking Kinemetrics/TrueTime receivers" 1>&5
+echo "configure:9419: checking Kinemetrics/TrueTime receivers" 1>&5
 # Check whether --enable-TRUETIME or --disable-TRUETIME was given.
 if test "${enable_TRUETIME+set}" = set; then
   enableval="$enable_TRUETIME"
@@ -9436,7 +9444,7 @@ case "$ntp_ok$target" in
 esac
 
 echo $ac_n "checking Ultralink M320 WWVB receiver... $ac_c" 1>&6
-echo "configure:9440: checking Ultralink M320 WWVB receiver" 1>&5
+echo "configure:9448: checking Ultralink M320 WWVB receiver" 1>&5
 # Check whether --enable-ULINK or --disable-ULINK was given.
 if test "${enable_ULINK+set}" = set; then
   enableval="$enable_ULINK"
@@ -9455,7 +9463,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking WWV receiver... $ac_c" 1>&6
-echo "configure:9459: checking WWV receiver" 1>&5
+echo "configure:9467: checking WWV receiver" 1>&5
 # Check whether --enable-WWV or --disable-WWV was given.
 if test "${enable_WWV+set}" = set; then
   enableval="$enable_WWV"
@@ -9481,14 +9489,14 @@ esac
 
 # Requires modem control
 echo $ac_n "checking USNO modem service... $ac_c" 1>&6
-echo "configure:9485: checking USNO modem service" 1>&5
+echo "configure:9493: checking USNO modem service" 1>&5
 # Check whether --enable-USNO or --disable-USNO was given.
 if test "${enable_USNO+set}" = set; then
   enableval="$enable_USNO"
   ntp_ok=$enableval
 else
   cat >conftest.$ac_ext <<EOF
-#line 9492 "configure"
+#line 9500 "configure"
 #include "confdefs.h"
 #include <termios.h>
 #ifdef HAVE_SYS_IOCTL_H
@@ -9521,7 +9529,7 @@ fi
 echo "$ac_t""$ntp_ok" 1>&6
 
 echo $ac_n "checking for default inclusion of all suitable PARSE clocks... $ac_c" 1>&6
-echo "configure:9525: checking for default inclusion of all suitable PARSE clocks" 1>&5
+echo "configure:9533: checking for default inclusion of all suitable PARSE clocks" 1>&5
 # Check whether --enable-parse-clocks or --disable-parse-clocks was given.
 if test "${enable_parse_clocks+set}" = set; then
   enableval="$enable_parse_clocks"
@@ -9551,7 +9559,7 @@ ntp_parseutil=no
 ntp_rawdcf=no
 
 echo $ac_n "checking Diem Computime Radio Clock... $ac_c" 1>&6
-echo "configure:9555: checking Diem Computime Radio Clock" 1>&5
+echo "configure:9563: checking Diem Computime Radio Clock" 1>&5
 # Check whether --enable-COMPUTIME or --disable-COMPUTIME was given.
 if test "${enable_COMPUTIME+set}" = set; then
   enableval="$enable_COMPUTIME"
@@ -9576,7 +9584,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking ELV/DCF7000 clock... $ac_c" 1>&6
-echo "configure:9580: checking ELV/DCF7000 clock" 1>&5
+echo "configure:9588: checking ELV/DCF7000 clock" 1>&5
 # Check whether --enable-DCF7000 or --disable-DCF7000 was given.
 if test "${enable_DCF7000+set}" = set; then
   enableval="$enable_DCF7000"
@@ -9601,7 +9609,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking HOPF 6021 clock... $ac_c" 1>&6
-echo "configure:9605: checking HOPF 6021 clock" 1>&5
+echo "configure:9613: checking HOPF 6021 clock" 1>&5
 # Check whether --enable-HOPF6021 or --disable-HOPF6021 was given.
 if test "${enable_HOPF6021+set}" = set; then
   enableval="$enable_HOPF6021"
@@ -9626,7 +9634,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking Meinberg clocks... $ac_c" 1>&6
-echo "configure:9630: checking Meinberg clocks" 1>&5
+echo "configure:9638: checking Meinberg clocks" 1>&5
 # Check whether --enable-MEINBERG or --disable-MEINBERG was given.
 if test "${enable_MEINBERG+set}" = set; then
   enableval="$enable_MEINBERG"
@@ -9651,7 +9659,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking DCF77 raw time code... $ac_c" 1>&6
-echo "configure:9655: checking DCF77 raw time code" 1>&5
+echo "configure:9663: checking DCF77 raw time code" 1>&5
 # Check whether --enable-RAWDCF or --disable-RAWDCF was given.
 if test "${enable_RAWDCF+set}" = set; then
   enableval="$enable_RAWDCF"
@@ -9680,7 +9688,7 @@ esac
 case "$ntp_rawdcf" in
  yes)
     echo $ac_n "checking if we must enable parity for RAWDCF... $ac_c" 1>&6
-echo "configure:9684: checking if we must enable parity for RAWDCF" 1>&5
+echo "configure:9692: checking if we must enable parity for RAWDCF" 1>&5
 if test "${ac_cv_var_rawdcf_parity+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9707,7 +9715,7 @@ EOF
 esac
 
 echo $ac_n "checking RCC 8000 clock... $ac_c" 1>&6
-echo "configure:9711: checking RCC 8000 clock" 1>&5
+echo "configure:9719: checking RCC 8000 clock" 1>&5
 # Check whether --enable-RCC8000 or --disable-RCC8000 was given.
 if test "${enable_RCC8000+set}" = set; then
   enableval="$enable_RCC8000"
@@ -9732,7 +9740,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking Schmid DCF77 clock... $ac_c" 1>&6
-echo "configure:9736: checking Schmid DCF77 clock" 1>&5
+echo "configure:9744: checking Schmid DCF77 clock" 1>&5
 # Check whether --enable-SCHMID or --disable-SCHMID was given.
 if test "${enable_SCHMID+set}" = set; then
   enableval="$enable_SCHMID"
@@ -9757,7 +9765,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking Trimble GPS receiver/TAIP protocol... $ac_c" 1>&6
-echo "configure:9761: checking Trimble GPS receiver/TAIP protocol" 1>&5
+echo "configure:9769: checking Trimble GPS receiver/TAIP protocol" 1>&5
 # Check whether --enable-TRIMTAIP or --disable-TRIMTAIP was given.
 if test "${enable_TRIMTAIP+set}" = set; then
   enableval="$enable_TRIMTAIP"
@@ -9782,7 +9790,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking Trimble GPS receiver/TSIP protocol... $ac_c" 1>&6
-echo "configure:9786: checking Trimble GPS receiver/TSIP protocol" 1>&5
+echo "configure:9794: checking Trimble GPS receiver/TSIP protocol" 1>&5
 # Check whether --enable-TRIMTSIP or --disable-TRIMTSIP was given.
 if test "${enable_TRIMTSIP+set}" = set; then
   enableval="$enable_TRIMTSIP"
@@ -9807,7 +9815,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking WHARTON 400A Series clock... $ac_c" 1>&6
-echo "configure:9811: checking WHARTON 400A Series clock" 1>&5
+echo "configure:9819: checking WHARTON 400A Series clock" 1>&5
 # Check whether --enable-WHARTON or --disable-WHARTON was given.
 if test "${enable_WHARTON+set}" = set; then
   enableval="$enable_WHARTON"
@@ -9832,7 +9840,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking VARITEXT clock... $ac_c" 1>&6
-echo "configure:9836: checking VARITEXT clock" 1>&5
+echo "configure:9844: checking VARITEXT clock" 1>&5
 # Check whether --enable-VARITEXT or --disable-VARITEXT was given.
 if test "${enable_VARITEXT+set}" = set; then
   enableval="$enable_VARITEXT"
@@ -9857,7 +9865,7 @@ case "$ntp_ok$ntp_canparse" in
 esac
 
 echo $ac_n "checking if we need to make and use the parse libraries... $ac_c" 1>&6
-echo "configure:9861: checking if we need to make and use the parse libraries" 1>&5
+echo "configure:9869: checking if we need to make and use the parse libraries" 1>&5
 ans=no
 case "$ntp_libparse" in
  yes)
@@ -9882,22 +9890,42 @@ esac
 echo "$ac_t""$ans" 1>&6
 
 echo $ac_n "checking if we need to make and use the RSAREF library... $ac_c" 1>&6
-echo "configure:9886: checking if we need to make and use the RSAREF library" 1>&5
-ans=no
-if test -f $srcdir/rsaref2/source/rsa.c
-then
-    ans=yes
-    LIBRSAREF=../librsaref/librsaref.a
-    MAKE_LIBRSAREF=librsaref.a
-    cat >>confdefs.h <<\EOF
+echo "configure:9894: checking if we need to make and use the RSAREF library" 1>&5
+# Check whether --with-rsaref or --without-rsaref was given.
+if test "${with_rsaref+set}" = set; then
+  withval="$with_rsaref"
+  ans=yes
+case "$withval" in
+ no) ans=no ;;
+esac
+else
+  ans=yes
+fi
+
+case "$ans" in
+ yes)
+    ans=no
+    if test -f $srcdir/rsaref2/source/rsa.c
+    then
+       ans=yes
+       LIBRSAREF=../librsaref/librsaref.a
+       MAKE_LIBRSAREF=librsaref.a
+       MAKE_NTP_GENKEYS=ntp_genkeys
+       cat >>confdefs.h <<\EOF
 #define DES 1
 EOF
 
-fi
+       cat >>confdefs.h <<\EOF
+#define PUBKEY 
+EOF
+
+    fi
+    ;;
+esac
 echo "$ac_t""$ans" 1>&6
 
 echo $ac_n "checking if we can make dcf parse utilities... $ac_c" 1>&6
-echo "configure:9901: checking if we can make dcf parse utilities" 1>&5
+echo "configure:9929: checking if we can make dcf parse utilities" 1>&5
 ans=no
 if test "$ntp_parseutil" = "yes"; then
     case "$target" in
@@ -9911,7 +9939,7 @@ fi
 echo "$ac_t""$ans" 1>&6
 
 echo $ac_n "checking if we can build kernel streams modules for parse... $ac_c" 1>&6
-echo "configure:9915: checking if we can build kernel streams modules for parse" 1>&5
+echo "configure:9943: checking if we can build kernel streams modules for parse" 1>&5
 ans=no
 case "$ntp_parseutil$ac_cv_header_sys_stropts_h" in
  yesyes)
@@ -9938,7 +9966,7 @@ esac
 echo "$ac_t""$ans" 1>&6
 
 echo $ac_n "checking if we need basic refclock support... $ac_c" 1>&6
-echo "configure:9942: checking if we need basic refclock support" 1>&5
+echo "configure:9970: checking if we need basic refclock support" 1>&5
 if test "$ntp_refclock" = "yes"; then
     cat >>confdefs.h <<\EOF
 #define REFCLOCK 1
@@ -9950,7 +9978,7 @@ echo "$ac_t""$ntp_refclock" 1>&6
                        
 
 echo $ac_n "checking if we want HP-UX adjtimed support... $ac_c" 1>&6
-echo "configure:9954: checking if we want HP-UX adjtimed support" 1>&5
+echo "configure:9982: checking if we want HP-UX adjtimed support" 1>&5
 case "$target" in
  *-*-hpux[56789]*)
     ans=yes
@@ -9968,7 +9996,7 @@ fi
 echo "$ac_t""$ans" 1>&6
 
 echo $ac_n "checking if we can read kmem... $ac_c" 1>&6
-echo "configure:9972: checking if we can read kmem" 1>&5
+echo "configure:10000: checking if we can read kmem" 1>&5
 if test "${ac_cv_var_can_kmem+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10020,7 +10048,7 @@ EOF
 esac
 
 echo $ac_n "checking if adjtime is accurate... $ac_c" 1>&6
-echo "configure:10024: checking if adjtime is accurate" 1>&5
+echo "configure:10052: checking if adjtime is accurate" 1>&5
 if test "${ac_cv_var_adjtime_is_accurate+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10071,7 +10099,7 @@ EOF
 esac
 
 echo $ac_n "checking the name of 'tick' in the kernel... $ac_c" 1>&6
-echo "configure:10075: checking the name of 'tick' in the kernel" 1>&5
+echo "configure:10103: checking the name of 'tick' in the kernel" 1>&5
 if test "${ac_cv_var_nlist_tick+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10114,7 +10142,7 @@ EOF
 esac
 #
 echo $ac_n "checking for the units of 'tick'... $ac_c" 1>&6
-echo "configure:10118: checking for the units of 'tick'" 1>&5
+echo "configure:10146: checking for the units of 'tick'" 1>&5
 if test "${ac_cv_var_tick_nano+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10137,7 +10165,7 @@ EOF
 esac
 #
 echo $ac_n "checking the name of 'tickadj' in the kernel... $ac_c" 1>&6
-echo "configure:10141: checking the name of 'tickadj' in the kernel" 1>&5
+echo "configure:10169: checking the name of 'tickadj' in the kernel" 1>&5
 if test "${ac_cv_var_nlist_tickadj+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10189,7 +10217,7 @@ EOF
 esac
 #
 echo $ac_n "checking for the units of 'tickadj'... $ac_c" 1>&6
-echo "configure:10193: checking for the units of 'tickadj'" 1>&5
+echo "configure:10221: checking for the units of 'tickadj'" 1>&5
 if test "${ac_cv_var_tickadj_nano+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10212,7 +10240,7 @@ EOF
 esac
 #
 echo $ac_n "checking half-heartedly for 'dosynctodr' in the kernel... $ac_c" 1>&6
-echo "configure:10216: checking half-heartedly for 'dosynctodr' in the kernel" 1>&5
+echo "configure:10244: checking half-heartedly for 'dosynctodr' in the kernel" 1>&5
 if test "${ac_cv_var_nlist_dosynctodr+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10264,7 +10292,7 @@ EOF
 esac
 #
 echo $ac_n "checking half-heartedly for 'noprintf' in the kernel... $ac_c" 1>&6
-echo "configure:10268: checking half-heartedly for 'noprintf' in the kernel" 1>&5
+echo "configure:10296: checking half-heartedly for 'noprintf' in the kernel" 1>&5
 if test "${ac_cv_var_nlist_noprintf+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10310,7 +10338,7 @@ EOF
 esac
 
 echo $ac_n "checking for a default value for 'tick'... $ac_c" 1>&6
-echo "configure:10314: checking for a default value for 'tick'" 1>&5
+echo "configure:10342: checking for a default value for 'tick'" 1>&5
 if test "${ac_cv_var_tick+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10353,7 +10381,7 @@ EOF
 esac
 
 echo $ac_n "checking for a default value for 'tickadj'... $ac_c" 1>&6
-echo "configure:10357: checking for a default value for 'tickadj'" 1>&5
+echo "configure:10385: checking for a default value for 'tickadj'" 1>&5
 if test "${ac_cv_var_tickadj+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10484,7 +10512,7 @@ case "$target" in
 esac
 
 echo $ac_n "checking if we want and can make the tickadj utility... $ac_c" 1>&6
-echo "configure:10488: checking if we want and can make the tickadj utility" 1>&5
+echo "configure:10516: checking if we want and can make the tickadj utility" 1>&5
 if test "${ac_cv_make_tickadj+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10498,7 +10526,7 @@ case "$ac_cv_make_tickadj" in
 esac
 
 echo $ac_n "checking if we want and can make the ntptime utility... $ac_c" 1>&6
-echo "configure:10502: checking if we want and can make the ntptime utility" 1>&5
+echo "configure:10530: checking if we want and can make the ntptime utility" 1>&5
 if test "${ac_cv_make_ntptime+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10523,7 +10551,7 @@ case "$ac_cv_make_ntptime" in
 esac
 
 echo $ac_n "checking if we want UDP wildcard delivery... $ac_c" 1>&6
-echo "configure:10527: checking if we want UDP wildcard delivery" 1>&5
+echo "configure:10555: checking if we want UDP wildcard delivery" 1>&5
 if test "${ac_cv_var_udp_wildcard_delivery+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10601,7 +10629,7 @@ case "$host" in
 esac
 
 echo $ac_n "checking if we should always slew the time... $ac_c" 1>&6
-echo "configure:10605: checking if we should always slew the time" 1>&5
+echo "configure:10633: checking if we should always slew the time" 1>&5
 if test "${ac_cv_var_slew_always+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10640,7 +10668,7 @@ EOF
 esac
 
 echo $ac_n "checking if we should step and slew the time... $ac_c" 1>&6
-echo "configure:10644: checking if we should step and slew the time" 1>&5
+echo "configure:10672: checking if we should step and slew the time" 1>&5
 if test "${ac_cv_var_step_slew+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10682,7 +10710,7 @@ EOF
 esac
 
 echo $ac_n "checking if ntpdate should step the time... $ac_c" 1>&6
-echo "configure:10686: checking if ntpdate should step the time" 1>&5
+echo "configure:10714: checking if ntpdate should step the time" 1>&5
 if test "${ac_cv_var_ntpdate_step+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10712,7 +10740,7 @@ EOF
 esac
 
 echo $ac_n "checking if we should sync TODR clock every hour... $ac_c" 1>&6
-echo "configure:10716: checking if we should sync TODR clock every hour" 1>&5
+echo "configure:10744: checking if we should sync TODR clock every hour" 1>&5
 if test "${ac_cv_var_sync_todr+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -10744,7 +10772,7 @@ EOF
 esac
 
 echo $ac_n "checking if we should avoid kernel FLL bug... $ac_c" 1>&6
-echo "configure:10748: checking if we should avoid kernel FLL bug" 1>&5
+echo "configure:10776: checking if we should avoid kernel FLL bug" 1>&5
 if test "${ac_cv_var_kernel_fll_bug+set}" = set; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -11121,6 +11149,7 @@ s%@MAKE_CHECK_Y2K@%$MAKE_CHECK_Y2K%;t t
 s%@RSAREF@%$RSAREF%;t t
 s%@LIBRSAREF@%$LIBRSAREF%;t t
 s%@MAKE_LIBRSAREF@%$MAKE_LIBRSAREF%;t t
+s%@MAKE_NTP_GENKEYS@%$MAKE_NTP_GENKEYS%;t t
 s%@TESTDCF@%$TESTDCF%;t t
 s%@DCFD@%$DCFD%;t t
 s%@MAKE_PARSEKMODULE@%$MAKE_PARSEKMODULE%;t t
index 09653053362a6b07ee552538932d4daeace1aa36..e9aa84bd985bb89fe545d202c46fd9b63bf8c807 100644 (file)
@@ -187,8 +187,8 @@ AC_CHECK_LIB(rt, sched_setscheduler, ,
 AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
 
 AC_HEADER_STDC
-AC_CHECK_HEADERS(bstring.h errno.h fcntl.h memory.h netdb.h poll.h resolv.h)
-AC_CHECK_HEADERS(sched.h sgtty.h stdlib.h string.h termio.h termios.h)
+AC_CHECK_HEADERS(bstring.h errno.h fcntl.h ieeefp.h memory.h netdb.h poll.h)
+AC_CHECK_HEADERS(resolv.h sched.h sgtty.h stdlib.h string.h termio.h termios.h)
 AC_CHECK_HEADERS(timepps.h timex.h unistd.h utmp.h utmpx.h)
 AC_CHECK_HEADERS(arpa/nameser.h net/if.h netinet/in_systm.h netinet/in.h)
 AC_CHECK_HEADERS(netinfo/ni.h, [AC_DEFINE(HAVE_NETINFO)])
@@ -1352,7 +1352,10 @@ AC_CACHE_CHECK(if we want to use MD5 authentication, ac_cv_var_use_md5,
     [ans=$enableval], [ans=yes])
 ac_cv_var_use_md5=$ans])
 case "$ac_cv_var_use_md5" in
- yes) AC_DEFINE(MD5) ;;
+ yes)
+     AC_DEFINE(AUTOKEY, , [Autokey?])
+     AC_DEFINE(MD5)
+     ;;
 esac
 
 # Check for ioctls TIOCGPPSEV
@@ -2229,15 +2232,27 @@ AC_MSG_RESULT($ans)
 AC_SUBST(RSAREF)
 AC_SUBST(LIBRSAREF)
 AC_SUBST(MAKE_LIBRSAREF)
+AC_SUBST(MAKE_NTP_GENKEYS)
 AC_MSG_CHECKING(if we need to make and use the RSAREF library)
-ans=no
-if test -f $srcdir/rsaref2/source/rsa.c
-then
-    ans=yes
-    LIBRSAREF=../librsaref/librsaref.a
-    MAKE_LIBRSAREF=librsaref.a
-    AC_DEFINE(DES)
-fi
+AC_ARG_WITH(rsaref,    [  --with-rsaref           + Use rsaref if possible],
+[ans=yes
+case "$withval" in
+ no) ans=no ;;
+esac], [ans=yes])
+case "$ans" in
+ yes)
+    ans=no
+    if test -f $srcdir/rsaref2/source/rsa.c
+    then
+       ans=yes
+       LIBRSAREF=../librsaref/librsaref.a
+       MAKE_LIBRSAREF=librsaref.a
+       MAKE_NTP_GENKEYS=ntp_genkeys
+       AC_DEFINE(DES)
+       AC_DEFINE(PUBKEY, , [Public key?])
+    fi
+    ;;
+esac
 AC_MSG_RESULT($ans)
 
 AC_SUBST(TESTDCF)
index d7f28f6155abdc50641f3dc93a358c5e76897937..46c22d34bf74ba8d46294b1473f3a54571ba3f6c 100644 (file)
@@ -5,6 +5,7 @@ ETAGS_ARGS = $(srcdir)/Makefile.am
 
 noinst_HEADERS = \
        adjtime.h \
+       audio.h \
        ascii.h \
        audio.h \
        binio.h \
@@ -21,6 +22,7 @@ noinst_HEADERS = \
        ntp.h \
        ntp_calendar.h \
        ntp_control.h \
+       ntp_crypto.h \
        ntp_datum.h \
        ntp_filegen.h \
        ntp_fp.h \
index b48a2b714da6e720a37e74d2fbbc5d426592f31a..96ac009e8b0d6b57578c09e60f65dcfba15b2445 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
@@ -108,6 +109,7 @@ ETAGS_ARGS = $(srcdir)/Makefile.am
 
 noinst_HEADERS = \
        adjtime.h \
+       audio.h \
        ascii.h \
        audio.h \
        binio.h \
@@ -124,6 +126,7 @@ noinst_HEADERS = \
        ntp.h \
        ntp_calendar.h \
        ntp_control.h \
+       ntp_crypto.h \
        ntp_datum.h \
        ntp_filegen.h \
        ntp_fp.h \
index e07870cf8f222d26116ba3b81ce88b63cbc30131..81d73f98ea73fe730f48abf99eb9bc01d66f8bc8 100644 (file)
@@ -8,58 +8,64 @@
 #include "ntp_types.h"
 #include <math.h>
 
-       /* common definitions for Y2K repairs                   [ Y2KFixes */
-
-               /* (this might better be put in ntp_calendar.h) */
-#define YEAR_BREAK 500         /* assume years < this are tm_year values: */
-                                   /*    Break < AnyFourDigitYear
-                                      && Break > Anytm_yearYear */
-#define YEAR_PIVOT 98          /* 97/98: assume years < this are year 2000+ */
-       /* FYI: official UNIX pivot year is 68/69 */
-
-  /* Number of Days since (mythical) 1.BC Gregorian to 1 January of given year*/
-#define julian0(year) \
-       (       \
-         ( (year) * 365 ) + ( (year) > 0       \
-               ? ( ((year)+3) / 4 - ((year-1) / 100) + ((year-1) / 400) )  \
-               : 0 ) \
-       )
-
-  /* Number of days since start of NTP time to 1 January of given year */
-#define ntp0(year)  ( julian0(year) - julian0(1900) )
-
-  /* Number of days since start of UNIX time to 1 January of given year */
-#define unix0(year)  ( julian0(year) - julian0(1970) )
-
-  /* LEAP YEAR test for full 4-digit years (e.g, 1999, 2010) */
-#define isleap_4(y)     /* a TRUE and PROPER leap year test */ \
-                  ((y)%4 == 0 && !((y)%100 == 0 && !(y%400 == 0)))
-           /* NOTE: year 2000 TRULY IS A LEAP YEAR!!! */
-
-  /* LEAP YEAR test for tm_year (struct tm) years (e.g, 99, 110) */
-#define isleap_tm(y)     /* a TRUE and PROPER leap year test */ \
-                  ((y)%4 == 0 && !((y)%100 == 0 && !(((y)+1900)%400 == 0)))
-
-  /* to convert simple two-digit years to tm_year style years:
-       if ( year < YEAR_PIVOT ) year += 100;
-
-   * to convert either two-digit OR tm_year years to four-digit years:
-       if ( year < YEAR_PIVOT ) year += 100;
-       if ( year < YEAR_BREAK ) year += 1900;
-
- CALL TO STANDARD:
-   * As the Internet is an INTERNATIONAL network, it makes SENSE to use
-     the international standard ISO 8601 to format dates and times.
-     Basically this is yyyy-mm-dd for years and hh:mm:ss for times
-     (joining the two togeather in computer readable media calls for
-     yyyy-mm-ddThh:mm:ss, though yyyy-mm-dd hh:mm:ss is often used
-     for human readable forms even though it is not not strictly
-     valid ISO 8601). Standard time-zone offsets ([+-]hh:mm) are allowed.
-                                       ghealton                 ] Y2KFixes */
+/*
+ * Calendar arithmetic - contributed by G. Healton
+ */
+#define YEAR_BREAK 500         /* years < this are tm_year values:
+                                * Break < AnyFourDigitYear && Break >
+                                * Anytm_yearYear */
+
+#define YEAR_PIVOT 98          /* 97/98: years < this are year 2000+
+                                * FYI: official UNIX pivot year is
+                                * 68/69 */
+
+/*
+ * Number of Days since 1 BC Gregorian to 1 January of given year
+ */
+#define julian0(year)  (((year) * 365 ) + ((year) > 0 ? (((year) + 3) \
+                           / 4 - ((year - 1) / 100) + ((year - 1) / \
+                           400)) : 0))
+
+/*
+ * Number of days since start of NTP time to 1 January of given year
+ */
+#define ntp0(year)     (julian0(year) - julian0(1900))
+
+/*
+ * Number of days since start of UNIX time to 1 January of given year
+ */
+#define unix0(year)    (julian0(year) - julian0(1970))
+
+/*
+ * LEAP YEAR test for full 4-digit years (e.g, 1999, 2010)
+ */
+#define isleap_4(y)    ((y) % 4 == 0 && !((y) % 100 == 0 && !(y % \
+                           400 == 0)))
+
+/*
+ * LEAP YEAR test for tm_year (struct tm) years (e.g, 99, 110)
+ */
+#define isleap_tm(y)   ((y) % 4 == 0 && !((y) % 100 == 0 && !(((y) \
+                           + 1900) % 400 == 0)))
+
+/*
+ * to convert simple two-digit years to tm_year style years:
+ *
+ *     if (year < YEAR_PIVOT)
+ *             year += 100;
+ *
+ * to convert either two-digit OR tm_year years to four-digit years:
+ *
+ *     if (year < YEAR_PIVOT)
+ *             year += 100;
+ *
+ *     if (year < YEAR_BREAK)
+ *             year += 1900;
+ */
 
 /*
  * How to get signed characters.  On machines where signed char works,
- * use it.  On machines where signed char doesn't work, char had better
+ * use it. On machines where signed char doesn't work, char had better
  * be signed.
  */
 #ifdef NEED_S_CHAR_TYPEDEF
@@ -90,6 +96,7 @@ typedef char s_char;
 #define        NTP_MAXSTRATUM  ((u_char)15) /* max stratum, infinity a la Bellman-Ford */
 #define        NTP_MAXAGE      86400   /* one day in seconds */
 #define NTP_UNREACH    16      /* poll interval backoff count */
+#define NTP_TAILMAX    4       /* tailgate poll counter max */
 #define NTP_MINDPOLL   6       /* log2 default min poll interval (64 s) */
 #define NTP_MAXDPOLL   10      /* log2 default max poll interval (~17 m) */
 #define        NTP_MINPOLL     4       /* log2 min poll interval (16 s) */
@@ -100,7 +107,8 @@ typedef char s_char;
 #define        NTP_WINDOW      8       /* reachability register size */
 #define        NTP_SHIFT       8       /* 8 suitable for crystal time base */
 #define        NTP_MAXKEY      65535   /* maximum authentication key number */
-#define NTP_MAXSESSION 100     /* maximum entries on session key list */
+#define NTP_MINSESSION 10      /* minimum session key list entries */
+#define NTP_MAXSESSION 100     /* maximum session key list entries */
 #define NTP_AUTOMAX    12      /* log2 default max session key lifetime */
 #define KEY_REVOKE     16      /* log2 default key revoke timeout */
 #define NTP_FWEIGHT    .5      /* clock filter weight */
@@ -111,13 +119,14 @@ typedef char s_char;
  
 /*
  * Operations for jitter (variance) calculations (these use doubles).
- * Note that we carefully separate the jitter component from the dispersion
- * component (frequency error plus precision). The frequency error
- * component is computed as CLOCK_PHI times the difference between the epoch
- * of the time measurement and the reference time. The precision componen
- * is computed as the square root of the mean of the squares of a zero-
- * mean, uniform distribution of unit maximum amplitude. Whether this
- * makes statistical sense may be arguable.
+ *
+ * Note that we carefully separate the jitter component from the
+ * dispersion component (frequency error plus precision). The frequency
+ * error component is computed as CLOCK_PHI times the difference between
+ * the epoch of the time measurement and the reference time. The
+ * precision componen is computed as the square root of the mean of the
+ * squares of a zero-mean, uniform distribution of unit maximum
+ * amplitude. Whether this makes statistical sense may be arguable.
  */
 #define SQUARE(x) ((x) * (x))
 #define SQRT(x) (sqrt(x))
@@ -139,7 +148,7 @@ typedef char s_char;
  */
 #define CLOCK_PHI      15e-6   /* max frequency wander */
 
-#define        EVENT_TIMEOUT 0         /* one second, that is */
+#define        EVENT_TIMEOUT   0       /* one second, that is */
 
 /*
  * The interface structure is used to hold the addresses and socket
@@ -149,8 +158,8 @@ struct interface {
        int fd;                 /* socket this is opened on */
        int bfd;                /* socket for receiving broadcasts */
        struct sockaddr_in sin; /* interface address */
-       struct sockaddr_in bcast;       /* broadcast address */
-       struct sockaddr_in mask;        /* interface mask */
+       struct sockaddr_in bcast; /* broadcast address */
+       struct sockaddr_in mask; /* interface mask */
        char name[8];           /* name of interface */
        int flags;              /* interface flags */
        int last_ttl;           /* last TTL specified */
@@ -168,7 +177,7 @@ struct interface {
 #define INT_MULTICAST  8       /* multicasting enabled */
 
 /*
- * Define flasher bits (tests 1 through 8 in packet procedure)
+ * Define flasher bits (tests 1 through 11 in packet procedure)
  * These reveal the state at the last grumble from the peer and are
  * most handy for diagnosing problems, even if not strictly a state
  * variable in the spec. These are recorded in the peer structure.
@@ -181,97 +190,145 @@ struct interface {
 #define TEST6          0x0020  /* peer clock unsynchronized */
 #define TEST7          0x0040  /* peer stratum out of bounds */
 #define TEST8          0x0080  /* root delay/dispersion bounds check */
-#define TEST9          0x0100  /* peer not authenticated */
-#define TEST10         0x0200  /* access denied */
+#define TEST9          0x0100  /* access denied */
+#define TEST10         0x0200  /* autokey not authentic */
+#define TEST11         0x0400  /* autokey not confirmed */
 
 /*
- * The peer structure.  Holds state information relating to the guys
- * we are peering with.  Most of this stuff is from section 3.2 of the
+ * The peer structure. Holds state information relating to the guys
+ * we are peering with. Most of this stuff is from section 3.2 of the
  * spec.
  */
 struct peer {
-       struct peer *next;
-       struct peer *ass_next;          /* link pointer in associd hash */
-       struct sockaddr_in srcadr;      /* address of remote host */
-       struct interface *dstadr;       /* pointer to address on local host */
-       struct refclockproc *procptr;   /* pointer to reference clock stuff */
-       u_char leap;                    /* leap indicator */
-       u_char hmode;                   /* association mode with this peer */
-       u_char pmode;                   /* peer's association mode */
-       u_char stratum;                 /* stratum of remote peer */
-       s_char precision;               /* peer's clock precision */
-       u_char ppoll;                   /* peer poll interval */
-       u_char hpoll;                   /* local host poll interval */
-       u_char minpoll;                 /* min local host poll interval */
-       u_char maxpoll;                 /* max local host poll interval */
-       u_char burst;                   /* packets remaining in burst */
-       u_char version;                 /* version number */
-       u_int flags;                    /* peer flags */
-       u_char cast_flags;              /* flags MDF_?CAST */
-       u_int flash;                    /* protocol error tally bits */
-       u_char refclktype;              /* reference clock type */
-       u_char refclkunit;              /* reference clock unit number */
-       u_char sstclktype;              /* clock type for system status word */
-       u_int32 refid;                  /* peer reference ID */
-       l_fp reftime;                   /* update epoch */
-       u_long keyid;                   /* current key ID */
-       u_long pkeyid;                  /* previous key ID (autokey) */
-       u_long *keylist;                /* session key identifier list */
-       int keynumber;                  /* session key identifier number */
-       u_short associd;                /* association ID, a unique integer */
-       u_char ttl;                     /* time to live (multicast) */
-
-/* **Start of clear-to-zero area.*** */
-/* Everything that is cleared to zero goes below here */
-       u_char valid;                   /* valid counter */
-#define        clear_to_zero valid
-       double estbdelay;               /* broadcast offset */
-       u_char status;                  /* peer status */
-       u_char pollsw;                  /* what it says */
-       u_char reach;                   /* reachability, NTP_WINDOW bits */
-       u_char unreach;                 /* unreachable count */
-       u_short filter_nextpt;          /* index into filter shift register */
-       double filter_delay[NTP_SHIFT]; /* delay part of shift register */
-       double filter_offset[NTP_SHIFT]; /* offset part of shift register */
-       double filter_disp[NTP_SHIFT];  /* dispersion part of shift register */
-       u_long filter_epoch[NTP_SHIFT]; /* epoch part of shift register */
-       u_char filter_order[NTP_SHIFT]; /* we keep the filter sorted here */
-       l_fp org;                       /* originate time stamp */
-       l_fp rec;                       /* receive time stamp */
-       l_fp xmt;                       /* transmit time stamp */
-       double offset;                  /* peer clock offset */
-       double delay;                   /* peer roundtrip delay */
-       double variance;                /* peer variance (jitter) */
-       double disp;                    /* peer dispersion */
-       double rootdelay;               /* roundtrip delay to primary clock */
-       double rootdispersion;          /* dispersion to primary clock */
-       u_long epoch;                   /* reference epoch */
-
-/* ***End of clear-to-zero area.*** */
-/* Everything that is cleared to zero goes above here */
-       u_long update;                  /* receive epoch */
+       struct peer *next;      /* pointer to next association */
+       struct peer *ass_next;  /* link pointer in associd hash */
+       struct sockaddr_in srcadr; /* address of remote host */
+       struct interface *dstadr; /* pointer to address on local host */
+       u_short associd;        /* association ID, a unique integer */
+       u_char  version;        /* version number */
+       u_char  hmode;          /* local association mode */
+       u_char  hpoll;          /* local poll interval */
+       u_char  minpoll;        /* min poll interval */
+       u_char  maxpoll;        /* max poll interval */
+       u_char  burst;          /* packets remaining in burst */
+       u_int   flags;          /* peer association flags */
+       u_char  cast_flags;     /* additional flags */
+       u_int   flash;          /* protocol error test tally bits */
+       u_char  last_event;     /* last peer error code */
+       u_char  num_events;     /* number of error events */
+       u_char  ttl;            /* m'cast time to live/refclock mode */
+
+       /*
+        * Variables used by reference clock support
+        */
+       struct refclockproc *procptr; /* refclock structure pointer */
+       u_char  refclktype;     /* reference clock type */
+       u_char  refclkunit;     /* reference clock unit number */
+       u_char  sstclktype;     /* clock type for system status word */
+
+       /*
+        * Variables set by received packet
+        */
+       u_char  leap;           /* local leap indicator */
+       u_char  pmode;          /* remote association mode */
+       u_char  stratum;        /* remote stratum */
+       s_char  precision;      /* remote clock precision */
+       u_char  ppoll;          /* remote poll interval */
+       u_int32 refid;          /* remote reference ID */
+       l_fp    reftime;        /* update epoch */
+
+       /*
+        * Variables used by authenticated client
+        */
+       keyid_t keyid;          /* current key ID */
+       u_char  *keystr;        /* public key file name */
+#ifdef PUBKEY
+       u_char  *pubkey;        /* public key */
+#endif /* PUBKEY */
+#ifdef AUTOKEY
+       keyid_t pkeyid;         /* previous key ID */
+#define clear_to_zero pkeyid
+       keyid_t hcookie;        /* host cookie */
+       keyid_t pcookie;        /* peer cookie */
+       int     recseq;         /* session key number */
+       keyid_t finlkey;        /* initial key ID */
+       int     finlseq;        /* initial key number */
+       u_int32 cmmd;           /* peer command */
+       u_short assoc;          /* association ID of peer */
+       u_char  *dh_public;     /* Diffie-Hellman public value */
+       u_char  *dh_key;        /* Diffie-Hellman agreed key */
+
+       /*
+        * Variables used by authenticated server
+        */
+       keyid_t *keylist;       /* session key ID list */
+       int     keynumber;      /* current key number */
+       keyid_t lastkey;        /* initial key ID */
+       int     lastseq;        /* initial key number */
+#ifdef PUBKEY
+       u_char  *sign;          /* signature of keylist values */
+       u_int   signlen;        /* length of signature */
+#endif /* PUBKEY */
+#endif /* AUTOKEY */
+
+       /*
+        * Ephemeral state variables
+        */
+       u_int   valid;          /* valid update counter */
+       u_int   tailcnt;        /* tailgate poll counter */
+#ifndef AUTOKEY
+#define clear_to_zero valid
+#endif /* AUTOKEY */
+       u_char  status;         /* peer status */
+       u_char  pollsw;         /* what it says */
+       u_char  reach;          /* reachability register */
+       u_char  unreach;        /* unreachable count */
+       u_long  epoch;          /* reference epoch */
+       u_short filter_nextpt;  /* index into filter shift register */
+       double  filter_delay[NTP_SHIFT]; /* delay shift register */
+       double  filter_offset[NTP_SHIFT]; /* offset shift register */
+       double  filter_disp[NTP_SHIFT]; /* dispersion shift register */
+       u_long  filter_epoch[NTP_SHIFT]; /* epoch shift register */
+       u_char  filter_order[NTP_SHIFT]; /* filter sort index */
+       l_fp    org;            /* originate time stamp */
+       l_fp    rec;            /* receive time stamp */
+       l_fp    xmt;            /* transmit time stamp */
+       double  offset;         /* peer clock offset */
+       double  delay;          /* peer roundtrip delay */
+       double  variance;       /* peer variance (jitter) */
+       double  disp;           /* peer dispersion */
+       double  estbdelay;      /* clock offset to broadcast server */
+
+       /*
+        * Variables set by received packet
+        */
+       double  rootdelay;      /* roundtrip delay to primary clock */
+       double  rootdispersion; /* dispersion to primary clock */
+
+       /*
+        * End of clear-to-zero area
+        */
+       u_long  update;         /* receive epoch */
 #define end_clear_to_zero update
-       u_long outdate;                 /* send time last packet */
-       u_long nextdate;                /* send time next packet */
-        u_long nextaction;             /* peer local activity timeout (refclocks mainly) */
-        void   (*action) P((struct peer *));/* action timeout function */
+       u_long  outdate;        /* send time last packet */
+       u_long  nextdate;       /* send time next packet */
+        u_long nextaction;     /* peer local activity timeout (refclocks mainly) */
+        void (*action) P((struct peer *)); /* action timeout function */
        /*
-        * statistic counters
+        * Statistic counters
         */
-       u_long timereset;               /* time stat counters were reset */
-       u_long sent;                    /* number of updates sent */
-       u_long received;                /* number of frames received */
-       u_long timereceived;            /* last time a frame received */
-       u_long timereachable;           /* last reachable/unreachable event */
-       u_long processed;               /* processed by the protocol */
-       u_long badauth;                 /* bad credentials detected */
-       u_long bogusorg;                /* rejected due to bogus origin */
-       u_long oldpkt;                  /* rejected as duplicate packet */
-       u_long seldisptoolarge;         /* too much dispersion for selection */
-       u_long selbroken;               /* broken NTP detected in selection */
-       u_long seltooold;               /* too long since sync in selection */
-       u_char last_event;              /* set to code for last peer error */
-       u_char num_events;              /* num. of events which have occurred */
+       u_long  timereset;      /* time stat counters were reset */
+       u_long  timereceived;   /* last packet received time */
+       u_long  timereachable;  /* last reachable/unreachable time */
+
+       u_long  sent;           /* packets sent */
+       u_long  received;       /* packets received */
+       u_long  processed;      /* packets processed by the protocol */
+       u_long  badauth;        /* packets cryptosum failed */
+       u_long  bogusorg;       /* packets bogus origin */
+       u_long  oldpkt;         /* packets duplicate packet */
+       u_long  seldisptoolarge; /* packets dispersion to large*/
+       u_long  selbroken;      /* not used */
 };
 
 /*
@@ -310,17 +367,18 @@ struct peer {
 /*
  * Values for peer.flags
  */
-#define        FLAG_CONFIG             0x1     /* association was configured */
-#define        FLAG_AUTHENABLE         0x2     /* this guy needs authentication */
-#define        FLAG_MCAST1             0x4     /* multicast client/server mode */
-#define        FLAG_MCAST2             0x8     /* multicast client mode */
-#define        FLAG_AUTHENTIC          0x10    /* last message was authentic */
-#define        FLAG_REFCLOCK           0x20    /* this is actually a reference clock */
-#define        FLAG_SYSPEER            0x40    /* this is one of the selected peers */
-#define FLAG_PREFER            0x80    /* this is the preferred peer */
-#define FLAG_BURST             0x100   /* burst mode */
-#define FLAG_SKEY              0x200   /* autokey authentication */
-#define FLAG_NOSELECT          0x400   /* this is a "noselect" peer */
+#define        FLAG_CONFIG     0x0001  /* association was configured */
+#define        FLAG_AUTHENABLE 0x0002  /* authentication required */
+#define        FLAG_MCAST1     0x0004  /* multicast client/server mode */
+#define        FLAG_MCAST2     0x0008  /* multicast client mode */
+#define        FLAG_AUTHENTIC  0x0010  /* last message was authentic */
+#define        FLAG_REFCLOCK   0x0020  /* this is actually a reference clock */
+#define        FLAG_SYSPEER    0x0040  /* this is one of the selected peers */
+#define FLAG_PREFER    0x0080  /* this is the preferred peer */
+#define FLAG_BURST     0x0100  /* burst mode */
+#define FLAG_SKEY      0x0200  /* autokey authentication */
+#define FLAG_NOSELECT  0x0400  /* this is a "noselect" peer */
+#define FLAG_AUTOKEY   0x0800  /* autokey confirmed */
 
 /*
  * Definitions for the clear() routine.  We use memset() to clear
@@ -420,9 +478,9 @@ struct peer {
  * and must be converted (except the mac, which isn't, really).
  */
 struct pkt {
-       u_char li_vn_mode;      /* contains leap indicator, version and mode */
-       u_char stratum;         /* peer's stratum */
-       u_char ppoll;           /* the peer polling interval */
+       u_char li_vn_mode;      /* leap indicator, version and mode */
+       u_char stratum;         /* peer stratum */
+       u_char ppoll;           /* peer poll interval */
        s_char precision;       /* peer clock precision */
        u_fp rootdelay;         /* distance to primary clock */
        u_fp rootdispersion;    /* clock dispersion */
@@ -432,32 +490,27 @@ struct pkt {
        l_fp rec;               /* receive time stamp */
        l_fp xmt;               /* transmit time stamp */
 
-#define MIN_MAC_LEN    (sizeof(u_int32) + 8)           /* DES */
-#define MAX_MAC_LEN    (sizeof(u_int32) + 16)          /* MD5 */
+#define        LEN_PKT_NOMAC   12 * sizeof(u_int32) /* min header length */
+#define        LEN_PKT_MAC     LEN_PKT_NOMAC +  sizeof(u_int32)
+#define MIN_MAC_LEN    3 * sizeof(u_int32)     /* DES */
+#define MAX_MAC_LEN    5 * sizeof(u_int32)     /* MD5 */
+#define        MAX_EXT_LEN     264                     /* RSA public key */
 
        /*
         * The length of the packet less MAC must be a multiple of 64
-        * bits. For normal private-key cryptography, the cryptosum
-        * covers only the raw NTP header. For autokey cryptography,
-        * the heade is incresed by 64 bits to contain the field length
-        * and private value.
+        * bits. The maximum length of an extension data field is 272
+        * octets. The next longest is 80 octets. There can only be
+        * two extension fields in a message, so the maximum lenth
+        * is 352 octets or 88 words, so we cheat and call it 100.
         */
-       u_int32 keyid1;         /* key identifier 1 */
-       u_int32 keyid2;         /* key identifier 2 */
-       u_int32 keyid3;         /* key identifier 3 */
+#ifdef AUTOKEY
+       u_int32 exten[100];     /* extension field */
+#else
+       u_int32 exten[1];       /* misused */
+#endif /* AUTOKEY */
        u_char mac[MAX_MAC_LEN]; /* mac */
 };
 
-/*
- * Packets can come in two flavours, one with a mac and one without.
- */
-#define LEN_PKT_NOMAC  (sizeof(struct pkt) - MAX_MAC_LEN - 3 * sizeof(u_int32))
-
-/*
- * Minimum size of packet with a MAC: has to include at least a key number.
- */
-#define LEN_PKT_MAC    (LEN_PKT_NOMAC + sizeof(u_int32))
-
 /*
  * Stuff for extracting things from li_vn_mode
  */
@@ -482,37 +535,42 @@ struct pkt {
 #define        STRATUM_TO_PKT(s)       ((u_char)(((s) == (STRATUM_UNSPEC)) ?\
                                (STRATUM_PKT_UNSPEC) : (s)))
 
-
 /*
- * Event codes.  Used for reporting errors/events to the control module
+ * Event codes. Used for reporting errors/events to the control module
  */
-#define        PEER_EVENT      0x80            /* this is a peer event */
+#define        PEER_EVENT      0x80    /* this is a peer event */
 
-#define        EVNT_UNSPEC     0
-#define        EVNT_SYSRESTART 1
-#define        EVNT_SYSFAULT   2
-#define        EVNT_SYNCCHG    3
-#define        EVNT_PEERSTCHG  4
-#define        EVNT_CLOCKRESET 5
-#define        EVNT_BADDATETIM 6
-#define        EVNT_CLOCKEXCPT 7
+/*
+ * System event codes
+ */
+#define        EVNT_UNSPEC     0       /* unspecified */
+#define        EVNT_SYSRESTART 1       /* system restart */
+#define        EVNT_SYSFAULT   2       /* wsystem or hardware fault */
+#define        EVNT_SYNCCHG    3       /* new leap or synch change */
+#define        EVNT_PEERSTCHG  4       /* new source or stratum */
+#define        EVNT_CLOCKRESET 5       /* clock reset */
+#define        EVNT_BADDATETIM 6       /* invalid time or date */
+#define        EVNT_CLOCKEXCPT 7       /* reference clock exception */
 
-#define        EVNT_PEERIPERR  (1|PEER_EVENT)
-#define        EVNT_PEERAUTH   (2|PEER_EVENT)
-#define        EVNT_UNREACH    (3|PEER_EVENT)
-#define        EVNT_REACH      (4|PEER_EVENT)
-#define        EVNT_PEERCLOCK  (5|PEER_EVENT)
+/*
+ * Peer event codes
+ */
+#define        EVNT_PEERIPERR  (1 | PEER_EVENT) /* IP error */
+#define        EVNT_PEERAUTH   (2 | PEER_EVENT) /* authentication failure */
+#define        EVNT_UNREACH    (3 | PEER_EVENT) /* change to unreachable */
+#define        EVNT_REACH      (4 | PEER_EVENT) /* change to reachable */
+#define        EVNT_PEERCLOCK  (5 | PEER_EVENT) /* clock exception */
 
 /*
  * Clock event codes
  */
-#define        CEVNT_NOMINAL   0
-#define        CEVNT_TIMEOUT   1
-#define        CEVNT_BADREPLY  2
-#define        CEVNT_FAULT     3
-#define        CEVNT_PROP      4
-#define        CEVNT_BADDATE   5
-#define        CEVNT_BADTIME   6
+#define        CEVNT_NOMINAL   0       /* unspecified */
+#define        CEVNT_TIMEOUT   1       /* poll timeout */
+#define        CEVNT_BADREPLY  2       /* bad reply format */
+#define        CEVNT_FAULT     3       /* hardware or software fault */
+#define        CEVNT_PROP      4       /* propagation failure */
+#define        CEVNT_BADDATE   5       /* bad date format or value */
+#define        CEVNT_BADTIME   6       /* bad time format or value */
 #define CEVNT_MAX      CEVNT_BADTIME
 
 /*
@@ -522,8 +580,8 @@ struct pkt {
 
 
 /*
- * To speed lookups, peers are hashed by the low order bits of the remote
- * IP address.  These definitions relate to that.
+ * To speed lookups, peers are hashed by the low order bits of the
+ * remote IP address. These definitions relate to that.
  */
 #define        HASH_SIZE       32
 #define        HASH_MASK       (HASH_SIZE-1)
index dbcc2c659ff38bf00db9b326f2afc9da9f3a00f2..7181d7a024e98287b45a1cd910ae8f82b96e5870 100644 (file)
@@ -163,8 +163,14 @@ struct ntp_control {
 #define        CS_SYSTEM       16
 #define        CS_STABIL       17
 #define CS_VARLIST     18
-
+#ifdef PUBKEY
+#define        CS_PRIVATE      19
+#define CS_PUBLIC      20
+#define CS_DHPARAMS    21
+#define        CS_MAXCODE      CS_DHPARAMS
+#else
 #define        CS_MAXCODE      CS_VARLIST
+#endif /* PUBKEY */
 
 /*
  * Peer variables we understand
@@ -206,8 +212,17 @@ struct ntp_control {
 #define        CP_FLASH        35
 #define CP_DISP                36
 #define CP_VARLIST     37
-
+#ifdef PUBKEY
+#define CP_PUBLIC      38
+#define        CP_SESKEY       39
+#define        CP_SASKEY       40
+#define        CP_AUTOSEQ      41
+#define        CP_INITKEY      42
+#define        CP_INITSEQ      43
+#define        CP_MAXCODE      CP_INITSEQ
+#else
 #define        CP_MAXCODE      CP_VARLIST
+#endif /* PUBKEY */
 
 /*
  * Clock variables we understand
diff --git a/include/ntp_crypto.h b/include/ntp_crypto.h
new file mode 100644 (file)
index 0000000..f85097d
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * ntp_crypto.h - definitions for cryptographic operations
+ */
+#ifdef AUTOKEY
+#include "global.h"
+#include "md5.h"
+#ifdef PUBKEY
+#include "rsaref.h"
+#include "rsa.h"
+#endif /* PUBKEY */
+
+/*
+ * Extension field definitions
+ */
+#define CRYPTO_NULL    0       /* no operation */
+#define CRYPTO_PUBL    1       /* public key */
+#define CRYPTO_ASSOC   2       /* association ID */
+#define CRYPTO_AUTO    3       /* autokey values */
+#define CRYPTO_PRIV    4       /* cookie value (client/server) */
+#define CRYPTO_DH      5       /* Diffie-Hellman value (symmetric) */
+#define CRYPTO_RESP    0x80    /* response */
+#define CRYPTO_ERROR   0x40    /* error */
+
+/*
+ * Cryptoflags
+ */
+#define CRYPTO_FLAG_NONE  0x00 /* nothing happening */
+#define CRYPTO_FLAG_PUBL  0x01 /* read peer public key from file */
+
+#ifdef PUBKEY
+/*
+ * Configuration codes
+ */
+#define CRYPTO_CONF_NONE  0    /* nothing doing */
+#define CRYPTO_CONF_FLAGS 1    /* initialize flags */
+#define CRYPTO_CONF_PRIV  2    /* load private key from file */
+#define CRYPTO_CONF_PUBL  3    /* load public key from file */
+#define CRYPTO_CONF_DH    4    /* load Diffie_Hellman pars from file */
+#define CRYPTO_CONF_KEYS  5    /* set keys directory path */
+#endif /* PUBKEY */
+
+/*
+ * Function prototypes
+ */
+extern  void    crypto_recv     P((struct peer *, struct recvbuf *));
+extern  int     crypto_xmit     P((u_int32 *, int, u_int, keyid_t,
+                                   int));
+extern keyid_t session_key     P((struct sockaddr_in *, struct
+                                   sockaddr_in *, keyid_t, keyid_t,
+                                   u_long));
+extern void    make_keylist    P((struct peer *));
+extern void    key_expire      P((struct peer *));
+#ifdef PUBKEY
+extern void    crypto_init     P((void));
+extern void    crypto_config   P((int, char *));
+extern void    crypto_setup    P((void));
+extern void    crypto_public   P((struct peer *, u_char *));
+extern void    crypto_agree    P((void));
+
+/*
+ * Cryptographic values
+ */
+extern int                     crypto_enable;
+extern char *                  private_key_file;
+extern char *                  public_key_file;
+extern char *                  dh_public_file;
+#endif /* PUBKEY */
+#endif /* AUTOKEY */
index 87dba881543341aec7f2f0eab358dd9b4aec8900..5246163d88920304479988f19035e4f63ee5eda4 100644 (file)
 /*
  * A request packet.  These are almost a fixed length.
  */
+#define MAXFILENAME    128             /* max key file name length */
+
 struct req_pkt {
        u_char rm_vn_mode;              /* response, more, version, mode */
        u_char auth_seq;                /* key, sequence number */
@@ -118,9 +120,9 @@ struct req_pkt {
        u_char request;                 /* request number */
        u_short err_nitems;             /* error code/number of data items */
        u_short mbz_itemsize;           /* item size */
-       char data[32];                  /* data area */
+       char data[144];                 /* data area */
        l_fp tstamp;                    /* time stamp, for authentication */
-       u_int32 keyid;                  /* encryption key */
+       keyid_t keyid;                  /* encryption key */
        char mac[MAX_MAC_LEN-sizeof(u_int32)]; /* (optional) 8 byte auth code */
 };
 
@@ -257,7 +259,8 @@ struct resp_pkt {
 #define REQ_GET_KERNEL         38      /* get kernel pll/pps information */
 #define        REQ_GET_CLKBUGINFO      39      /* get clock debugging info */
 #define        REQ_SET_PRECISION       41      /* (not used) */
-#define        REQ_MON_GETLIST_1       42      /* return data collected by monitor v1 */
+#define        REQ_MON_GETLIST_1       42      /* return collected v1 monitor data */
+#define        REQ_HOSTNAME_ASSOCID    43      /* Here is a hostname + assoc_id */
 
 /*
  * Flags in the peer information returns
@@ -286,6 +289,7 @@ struct resp_pkt {
 /*
  * Peer list structure.  Used to return raw lists of peers.  It goes
  * without saying that everything returned is in network byte order.
+ * Well, it *would* have gone without saying, but somebody said it.
  */
 struct info_peer_list {
        u_int32 address;        /* address of peer */
@@ -337,7 +341,7 @@ struct info_peer {
        u_char ttl;             /* peer.ttl */
        u_short flash2;         /* new peer.flash */
        u_short associd;        /* association ID */
-       u_int32 keyid;          /* peer.keyid */
+       keyid_t keyid;          /* peer.keyid */
        u_int32 pkeyid;         /* unused */
        u_int32 refid;          /* peer.refid */
        u_int32 timer;          /* peer.timer */
@@ -524,7 +528,8 @@ struct conf_peer {
        u_char flags;           /* flags for this request */
        u_char ttl;             /* time to live (multicast) or refclock mode */
        u_short unused;         /* unused */
-       u_int32 keyid;          /* key to use for this association */
+       keyid_t keyid;          /* key to use for this association */
+       char keystr[MAXFILENAME]; /* public key file name*/
 };
 
 #define        CONF_FLAG_AUTHENABLE    0x1
@@ -788,3 +793,13 @@ struct info_kernel {
        int32 errcnt;
        int32 stbcnt;
 };
+
+/*
+ * Info returned with IP -> hostname lookup
+ */
+#define NTP_MAXHOSTNAME (144 - sizeof(u_int32) - sizeof(u_short))
+struct info_dns_assoc {
+       u_int32 peeraddr;       /* peer address (HMS: being careful...) */
+       u_short associd;        /* association ID */
+       char hostname[NTP_MAXHOSTNAME]; /* hostname */
+};
index 6a2a85221267b81e3e77651965819fe6d8b2e347..30423204cffcd0675c0bb341affa55d0eccf72d9 100644 (file)
@@ -32,25 +32,15 @@ extern      void    msyslog         P((int, const char *, ...))
 extern void msyslog            P(());
 #endif
 
-#if 0                          /* HMS: These seem to be unused now */
-extern void    auth_des        P((u_long *, u_char *));
 extern void    auth_delkeys    P((void));
-extern int     auth_parity     P((u_long *));
-extern void    auth_setkey     P((u_long, u_long *));
-extern void    auth_subkeys    P((u_long *, u_char *, u_char *));
-#endif
-
-extern void    auth1crypt      P((u_long, u_int32 *, int));
-extern int     auth2crypt      P((u_long, u_int32 *, int));
-extern void    auth_delkeys    P((void));
-extern int     auth_havekey    P((u_long));
-extern int     authdecrypt     P((u_long, u_int32 *, int, int));
-extern int     authencrypt     P((u_long, u_int32 *, int));
-extern int     authhavekey     P((u_long));
-extern int     authistrusted   P((u_long));
+extern int     auth_havekey    P((keyid_t));
+extern int     authdecrypt     P((keyid_t, u_int32 *, int, int));
+extern int     authencrypt     P((keyid_t, u_int32 *, int));
+extern int     authhavekey     P((keyid_t));
+extern int     authistrusted   P((keyid_t));
 extern int     authreadkeys    P((const char *));
-extern void    authtrust       P((u_long, int));
-extern int     authusekey      P((u_long, int, const u_char *));
+extern void    authtrust       P((keyid_t, u_long));
+extern int     authusekey      P((keyid_t, int, const u_char *));
 
 extern u_long  calleapwhen     P((u_long));
 extern u_long  calyearstart    P((u_long));
@@ -66,14 +56,14 @@ extern      int     ntp_getopt      P((int, char **, const char *));
 extern void    init_auth       P((void));
 extern void    init_lib        P((void));
 extern void    init_random     P((void));
-extern struct savekey *auth_findkey P((u_long));
+extern struct savekey *auth_findkey P((keyid_t));
 extern int     auth_moremem    P((void));
 extern int     ymd2yd          P((int, int, int));
 
 #ifdef DES
 extern int     DESauthdecrypt  P((u_char *, u_int32 *, int, int));
 extern int     DESauthencrypt  P((u_char *, u_int32 *, int));
-extern void    DESauth_setkey  P((u_long, const u_int32 *));
+extern void    DESauth_setkey  P((keyid_t, const u_int32 *));
 extern void    DESauth_subkeys P((const u_int32 *, u_char *, u_char *));
 extern void    DESauth_des     P((u_int32 *, u_char *));
 extern int     DESauth_parity  P((u_int32 *));
@@ -82,8 +72,7 @@ extern        int     DESauth_parity  P((u_int32 *));
 #ifdef MD5
 extern int     MD5authdecrypt  P((u_char *, u_int32 *, int, int));
 extern int     MD5authencrypt  P((u_char *, u_int32 *, int));
-extern void    MD5auth_setkey  P((u_long, const u_char *, const int));
-extern u_long  session_key     P((u_int32, u_int32, u_long, u_long));
+extern void    MD5auth_setkey  P((keyid_t, const u_char *, const int));
 #endif /* MD5 */
 
 extern int     atoint          P((const char *, long *));
@@ -143,7 +132,7 @@ extern int  authnumfreekeys;
 /*
  * The key cache. We cache the last key we looked at here.
  */
-extern u_long  cache_keyid;            /* key identifier */
+extern keyid_t cache_keyid;            /* key identifier */
 extern u_char *        cache_key;              /* key pointer */
 extern u_int   cache_keylen;           /* key length */
 
index 820c72aeedd18c07ae032c7d58c02cca835926bb..25a5a8d73f83eaa6adfbb839956f735a7492a9a3 100644 (file)
@@ -65,5 +65,7 @@ typedef unsigned int u_int;
 # include "Bletch: what's 32 bits on this machine?"
 #endif /* not sizeof(int) == 4 */
 
+typedef u_int32 keyid_t;
+
 #endif /* _NTP_TYPES_ */
 
index 1a83d6eb0a6c00478519c80604fba60e7fa6f47c..fcb480b56014de67ea3cf50d0d1e4d8547c3a617 100644 (file)
@@ -11,6 +11,7 @@
 #include "recvbuff.h"
 
 #define MAXINTERFACES  512
+#define MAXFILENAME    128     /* maximum length of a file name */
 
 #ifdef SYS_WINNT
 #define exit service_exit
@@ -71,6 +72,8 @@ extern  void    set_var P((struct ctl_var **, const char *, unsigned long, int))
 extern  void    set_sys_var P((char *, unsigned long, int));
 
 /* ntp_intres.c */
+extern void    ntp_res_send    P((void *, char *, u_int32, u_short));
+extern void    ntp_res_recv    P((void));
 extern void    ntp_intres      P((void));
 
 /* ntp_io.c */
@@ -125,7 +128,7 @@ extern      struct peer *findpeerbyassoc P((int));
 extern struct peer *newpeer    P((struct sockaddr_in *, struct interface *, int, int, int, int, int, u_long));
 extern void    peer_all_reset  P((void));
 extern void    peer_clr_stats  P((void));
-extern struct peer *peer_config P((struct sockaddr_in *, struct interface *, int, int, int, int, int, int, u_long));
+extern struct peer *peer_config P((struct sockaddr_in *, struct interface *, int, int, int, int, int, int, keyid_t, u_char *));
 extern void    peer_reset      P((struct peer *));
 extern int     peer_unconfig   P((struct sockaddr_in *, struct interface *, int));
 extern void    unpeer          P((struct peer *));
@@ -137,7 +140,7 @@ extern      void    peer_config_manycast    P((struct peer *, struct peer *));
 extern void    transmit        P((struct peer *));
 extern void    receive         P((struct recvbuf *));
 extern void    peer_clear      P((struct peer *));
-extern int     process_packet  P((struct peer *, struct pkt *, l_fp *));
+extern void    process_packet  P((struct peer *, struct pkt *, l_fp *));
 extern void    clock_select    P((void));
 
 /*
@@ -203,7 +206,7 @@ extern int  config_priority;
 struct ctl_trap;
 extern struct ctl_trap ctl_trap[];
 extern int     num_ctl_traps;
-extern u_long  ctl_auth_keyid;         /* keyid used for authenticating write requests */
+extern keyid_t ctl_auth_keyid;         /* keyid used for authenticating write requests */
 
 /*
  * Statistic counters to keep track of requests and responses.
@@ -225,7 +228,7 @@ extern u_long       numctlbadop;            /* bad op code found in packet */
 extern u_long  numasyncmsgs;           /* number of async messages we've sent */
 
 /* ntp_intres.c */
-extern u_long  req_keyid;              /* request keyid */
+extern keyid_t req_keyid;              /* request keyid */
 extern char *  req_file;               /* name of the file with configuration info */
 
 /*
@@ -326,7 +329,7 @@ extern int  sys_bclient;            /* we set our time to broadcasts */
 extern double  sys_bdelay;             /* broadcast client default delay */
 extern int     sys_authenticate;       /* requre authentication for config */
 extern l_fp    sys_authdelay;          /* authentication delay */
-extern u_long  sys_private;            /* private value for session seed */
+extern keyid_t sys_private;            /* private value for session seed */
 extern int     sys_manycastserver;     /* 1 => respond to manycast client pkts */
 
 /*
@@ -350,7 +353,7 @@ extern int  fdpps;                  /* pps file descriptor */
 #endif
 
 /* ntp_request.c */
-extern u_long  info_auth_keyid;        /* keyid used to authenticate requests */
+extern keyid_t info_auth_keyid;        /* keyid used to authenticate requests */
 
 /* ntp_restrict.c */
 extern struct restrictlist *restrictlist; /* the restriction list */
index b79370efa906f2392f9bc6a1b7d5d5a07701844c..e657e98e5f82405ea29ecb7b77ab7a4a7fba3e02 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 25d8ad189d2695374e1d69fe238789d95c5296d0..430bf57bc7e8310c90c2dffa358cd2d31661068a 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 005e5890c8501da11f7bccd6a8beec9081eb6281..c69becec61386979545318c9cfebcf0fbefa1376 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 76f9c4fadd2adf263ca34147a870b3aaf5e5422c..8271ae55b59e0c2f9718d9fdb92c93e55d590f13 100644 (file)
 #include <stdio.h>
 
 #include "ntp_types.h"
-#include "ntp_fp.h"
 #include "ntp_string.h"
 #include "global.h"
 #include "md5.h"
 #include "ntp_stdlib.h"
 
 #define BLOCK_OCTETS   16      /* message digest size */
-#define NTP_MAXKEY     65535   /* max identifier from ntp.h */
 
 
 /*
@@ -85,48 +83,4 @@ MD5authdecrypt(
        return (!memcmp((char *)digest, (char *)pkt + length + 4,
                BLOCK_OCTETS));
 }
-
-
-/*
- * session_key - generate session key from supplied plaintext.
- *
- * Returns hashed session key for validation.
- */
-u_long
-session_key(
-       u_int32 srcadr,         /* source address */
-       u_int32 dstadr,         /* destination address */
-       u_long keyno,           /* key identifier */
-       u_long lifetime         /* key lifetime */
-       )
-{
-       MD5_CTX ctx;
-       u_int32 header[3];
-       u_long keyid;
-       u_char digest[BLOCK_OCTETS];
-
-       /*
-        * Generate the session key and retrieve the hash for later. If
-        * the lifetime is greater than zero, call the key trusted.
-        */
-       header[0] = htonl(srcadr);
-       header[1] = htonl(dstadr);
-       header[2] = htonl(keyno);
-       MD5Init(&ctx);
-       MD5Update(&ctx, (u_char *)header, sizeof(header));
-       MD5Final(digest, &ctx);
-       memcpy(&keyid, digest, 4);
-       if (lifetime != 0) {
-               MD5auth_setkey(keyno, digest, BLOCK_OCTETS);
-               authtrust(keyno, (int)lifetime);
-       }
-#ifdef DEBUG
-       if (debug > 1)
-               printf(
-                       "session_key: from %s to %s keyid %08lx hash %08lx life %ld\n",
-                       numtoa(htonl(srcadr)), numtoa(htonl(dstadr)), keyno,
-                       keyid, lifetime);
-#endif
-       return (keyid);
-}
 #endif /* MD5 */
index 22f910c36691c32d48f60f8abbd324d2d5375835..075afe09b749ce23fe73069d78ebee8492c569c0 100644 (file)
@@ -67,7 +67,7 @@ int
 DESauthdecrypt(
        u_char *key,            /* key pointer */
        u_int32 *pkt,           /* packet pointer */
-       int length,     /* packet length */
+       int length,             /* packet length */
        int size                /* size of MAC field */
        )
 {
index 578688bdf27ca0325e613192a338fdab4218d47b..670e8d0b65c28706c712c3cf70d55beec74497b4 100644 (file)
@@ -30,7 +30,7 @@ struct savekey {
                u_char MD5_key[32];     /* MD5 key */
 #endif
        } k;
-       u_long keyid;           /* key identifier */
+       keyid_t keyid;          /* key identifier */
        u_short flags;          /* flags that wave */
        u_long lifetime;        /* remaining lifetime */
 #ifdef MD5
@@ -73,7 +73,7 @@ int authnumfreekeys;
 /*
  * The key cache. We cache the last key we looked at here.
  */
-u_long cache_keyid;            /* key identifier */
+keyid_t        cache_keyid;            /* key identifier */
 u_char *cache_key;             /* key pointer */
 u_int  cache_keylen;           /* key length */
 u_short cache_flags;           /* flags that wave */
@@ -97,7 +97,7 @@ init_auth(void)
  */
 struct savekey *
 auth_findkey(
-       u_long keyno
+       keyid_t keyno
        )
 {
        struct savekey *sk;
@@ -118,7 +118,7 @@ auth_findkey(
  */
 int
 auth_havekey(
-       u_long keyno
+       keyid_t keyno
        )
 {
        struct savekey *sk;
@@ -142,7 +142,7 @@ auth_havekey(
  */
 int
 authhavekey(
-       u_long keyno
+       keyid_t keyno
        )
 {
        struct savekey *sk;
@@ -211,15 +211,15 @@ auth_moremem(void)
  */
 void
 authtrust(
-       u_long keyno,
-       int trust
+       keyid_t keyno,
+       u_long trust
        )
 {
        struct savekey *sk;
 
 #ifdef DEBUG
-       if (debug > 1)
-               printf("authtrust: keyid %08lx life %d\n", (u_long)keyno, trust);
+       if (debug > 2)
+               printf("authtrust: keyid %08x life %lu\n", keyno, trust);
 #endif
        sk = key_hash[KEYHASH(keyno)];
        while (sk != 0) {
@@ -288,7 +288,7 @@ authtrust(
  */
 int
 authistrusted(
-       u_long keyno
+       keyid_t keyno
        )
 {
        struct savekey *sk;
@@ -321,7 +321,7 @@ authistrusted(
  */
 void
 DESauth_setkey(
-       u_long keyno,
+       keyid_t keyno,
        const u_int32 *key
        )
 {
@@ -371,7 +371,7 @@ DESauth_setkey(
 #ifdef MD5
 void
 MD5auth_setkey(
-       u_long keyno,
+       keyid_t keyno,
        const u_char *key,
        const int len
        )
@@ -503,7 +503,7 @@ auth_agekeys(void)
  */
 int
 authencrypt(
-       u_long keyno,
+       keyid_t keyno,
        u_int32 *pkt,
        int length
        )
@@ -515,7 +515,7 @@ authencrypt(
         * consists of a single word with value zero.
         */
        authencryptions++;
-       pkt[length / 4] = (u_long)htonl(keyno);
+       pkt[length / 4] = htonl(keyno);
        if (keyno == 0) {
                return (4);
        }
@@ -541,7 +541,7 @@ authencrypt(
  */
 int
 authdecrypt(
-       u_long keyno,
+       keyid_t keyno,
        u_int32 *pkt,
        int length,
        int size
@@ -555,7 +555,7 @@ authdecrypt(
         */
        authdecryptions++;
        if (keyno == 0)
-               return (1);
+               return (0);
 
        if (!authhavekey(keyno) || size < 4)
                return (0);
index a399a48a13a0bc0b6c63d0fe2dd24ad0424dd01e..b944d7dc43af7d847c93533b9c4b89adb1725a8f 100644 (file)
@@ -30,7 +30,7 @@
 
 int
 authusekey(
-       u_long keyno,
+       keyid_t keyno,
        int keytype,
        const u_char *str
        )
index 2ef6ef9da7caffaa438dd4743d576948aa45ac08..3664870104704cb28cf256fd2eecf495c1c88ec8 100644 (file)
@@ -159,7 +159,8 @@ adj_systime(
        /* casey - we need a posix type thang here */
        if (adjtime(&adjtv, &oadjtv) < 0)
        {
-               msyslog(LOG_ERR, "Can't adjust time: %m");
+               msyslog(LOG_ERR, "Can't adjust time (%d sec, %d usec): %m",
+                       adjtv.tv_sec, adjtv.tv_usec);
                return 0;
        } 
        else {
index 8331a908d985e60bc5886f860cf9db489a18030c..e4cab217a648b0365da91c04ee0bec6cddda8935 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index fe2a22bc692a45a9c1036ebfe1b5ebdc6c159447..b8d8a3e2e0d8a07cda713dc11fbe046767a82b0b 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 8c53a23cd5bf6fd3773ddcd2b74b1f7d331af61e..2b30f69d14c9a4ec74888f5c34b975f2cef76463 100644 (file)
@@ -15,9 +15,11 @@ EXTRA_PROGRAMS = check_y2k
 check-local: @MAKE_CHECK_Y2K@
        [ -z "@MAKE_CHECK_Y2K@" ] || ./@MAKE_CHECK_Y2K@
 
-ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_filegen.c \
+ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_crypto.c \
+       ntp_filegen.c \
        ntp_intres.c ntp_io.c ntp_loopfilter.c ntp_monitor.c ntp_peer.c \
-       ntp_proto.c ntp_refclock.c ntp_request.c ntp_restrict.c ntp_timer.c \
+       ntp_proto.c ntp_refclock.c ntp_request.c ntp_resolver.c \
+       ntp_restrict.c ntp_timer.c \
        ntp_util.c ntpd.c refclock_acts.c refclock_arbiter.c refclock_arc.c \
        refclock_as2201.c refclock_atom.c refclock_bancomm.c \
        refclock_chronolog.c refclock_chu.c refclock_conf.c refclock_datum.c \
index f26b375a8ededc804f47d8e28d33155004d58f8c..87319fa818486ef63681e9ebb75470ab4a54eb28 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
@@ -115,9 +116,11 @@ ETAGS_ARGS = Makefile.am
 check_PROGRAMS = @MAKE_CHECK_Y2K@
 EXTRA_PROGRAMS = check_y2k
 
-ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_filegen.c \
+ntpd_SOURCES = jupiter.h map_vme.c ntp_config.c ntp_control.c ntp_crypto.c \
+       ntp_filegen.c \
        ntp_intres.c ntp_io.c ntp_loopfilter.c ntp_monitor.c ntp_peer.c \
-       ntp_proto.c ntp_refclock.c ntp_request.c ntp_restrict.c ntp_timer.c \
+       ntp_proto.c ntp_refclock.c ntp_request.c ntp_resolver.c \
+       ntp_restrict.c ntp_timer.c \
        ntp_util.c ntpd.c refclock_acts.c refclock_arbiter.c refclock_arc.c \
        refclock_as2201.c refclock_atom.c refclock_bancomm.c \
        refclock_chronolog.c refclock_chu.c refclock_conf.c refclock_datum.c \
@@ -146,21 +149,21 @@ check_y2k_LDADD = $(LDADD)
 check_y2k_DEPENDENCIES =  version.o ../libntp/libntp.a
 check_y2k_LDFLAGS = 
 am_ntpd_OBJECTS =  map_vme$U.o ntp_config$U.o ntp_control$U.o \
-ntp_filegen$U.o ntp_intres$U.o ntp_io$U.o ntp_loopfilter$U.o \
-ntp_monitor$U.o ntp_peer$U.o ntp_proto$U.o ntp_refclock$U.o \
-ntp_request$U.o ntp_restrict$U.o ntp_timer$U.o ntp_util$U.o ntpd$U.o \
-refclock_acts$U.o refclock_arbiter$U.o refclock_arc$U.o \
-refclock_as2201$U.o refclock_atom$U.o refclock_bancomm$U.o \
-refclock_chronolog$U.o refclock_chu$U.o refclock_conf$U.o \
-refclock_datum$U.o refclock_dumbclock$U.o refclock_fg$U.o \
-refclock_gpsvme$U.o refclock_heath$U.o refclock_hpgps$U.o \
-refclock_irig$U.o refclock_jupiter$U.o refclock_leitch$U.o \
-refclock_local$U.o refclock_msfees$U.o refclock_mx4200$U.o \
-refclock_nmea$U.o refclock_oncore$U.o refclock_palisade$U.o \
-refclock_parse$U.o refclock_pcf$U.o refclock_pst$U.o \
-refclock_ptbacts$U.o refclock_shm$U.o refclock_tpro$U.o \
-refclock_trak$U.o refclock_true$U.o refclock_ulink$U.o \
-refclock_usno$U.o refclock_wwv$U.o refclock_wwvb$U.o
+ntp_crypto$U.o ntp_filegen$U.o ntp_intres$U.o ntp_io$U.o \
+ntp_loopfilter$U.o ntp_monitor$U.o ntp_peer$U.o ntp_proto$U.o \
+ntp_refclock$U.o ntp_request$U.o ntp_resolver$U.o ntp_restrict$U.o \
+ntp_timer$U.o ntp_util$U.o ntpd$U.o refclock_acts$U.o \
+refclock_arbiter$U.o refclock_arc$U.o refclock_as2201$U.o \
+refclock_atom$U.o refclock_bancomm$U.o refclock_chronolog$U.o \
+refclock_chu$U.o refclock_conf$U.o refclock_datum$U.o \
+refclock_dumbclock$U.o refclock_fg$U.o refclock_gpsvme$U.o \
+refclock_heath$U.o refclock_hpgps$U.o refclock_irig$U.o \
+refclock_jupiter$U.o refclock_leitch$U.o refclock_local$U.o \
+refclock_msfees$U.o refclock_mx4200$U.o refclock_nmea$U.o \
+refclock_oncore$U.o refclock_palisade$U.o refclock_parse$U.o \
+refclock_pcf$U.o refclock_pst$U.o refclock_ptbacts$U.o refclock_shm$U.o \
+refclock_tpro$U.o refclock_trak$U.o refclock_true$U.o \
+refclock_ulink$U.o refclock_usno$U.o refclock_wwv$U.o refclock_wwvb$U.o
 ntpd_OBJECTS =  $(am_ntpd_OBJECTS)
 ntpd_DEPENDENCIES =  version.o ../libntp/libntp.a
 ntpd_LDFLAGS = 
@@ -177,11 +180,12 @@ GZIP_ENV = --best
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 DEP_FILES =  @AMDEP@ $(DEPDIR)/check_y2k$U.Po $(DEPDIR)/map_vme$U.Po \
 $(DEPDIR)/ntp_config$U.Po $(DEPDIR)/ntp_control$U.Po \
-$(DEPDIR)/ntp_filegen$U.Po $(DEPDIR)/ntp_intres$U.Po \
-$(DEPDIR)/ntp_io$U.Po $(DEPDIR)/ntp_loopfilter$U.Po \
-$(DEPDIR)/ntp_monitor$U.Po $(DEPDIR)/ntp_peer$U.Po \
-$(DEPDIR)/ntp_proto$U.Po $(DEPDIR)/ntp_refclock$U.Po \
-$(DEPDIR)/ntp_request$U.Po $(DEPDIR)/ntp_restrict$U.Po \
+$(DEPDIR)/ntp_crypto$U.Po $(DEPDIR)/ntp_filegen$U.Po \
+$(DEPDIR)/ntp_intres$U.Po $(DEPDIR)/ntp_io$U.Po \
+$(DEPDIR)/ntp_loopfilter$U.Po $(DEPDIR)/ntp_monitor$U.Po \
+$(DEPDIR)/ntp_peer$U.Po $(DEPDIR)/ntp_proto$U.Po \
+$(DEPDIR)/ntp_refclock$U.Po $(DEPDIR)/ntp_request$U.Po \
+$(DEPDIR)/ntp_resolver$U.Po $(DEPDIR)/ntp_restrict$U.Po \
 $(DEPDIR)/ntp_timer$U.Po $(DEPDIR)/ntp_util$U.Po $(DEPDIR)/ntpd$U.Po \
 $(DEPDIR)/refclock_acts$U.Po $(DEPDIR)/refclock_arbiter$U.Po \
 $(DEPDIR)/refclock_arc$U.Po $(DEPDIR)/refclock_as2201$U.Po \
@@ -292,6 +296,8 @@ ntp_config_.c: ntp_config.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_config.c; then echo $(srcdir)/ntp_config.c; else echo ntp_config.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_config_.c
 ntp_control_.c: ntp_control.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_control.c; then echo $(srcdir)/ntp_control.c; else echo ntp_control.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_control_.c
+ntp_crypto_.c: ntp_crypto.c $(ANSI2KNR)
+       $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_crypto.c; then echo $(srcdir)/ntp_crypto.c; else echo ntp_crypto.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_crypto_.c
 ntp_filegen_.c: ntp_filegen.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_filegen.c; then echo $(srcdir)/ntp_filegen.c; else echo ntp_filegen.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_filegen_.c
 ntp_intres_.c: ntp_intres.c $(ANSI2KNR)
@@ -310,6 +316,8 @@ ntp_refclock_.c: ntp_refclock.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_refclock.c; then echo $(srcdir)/ntp_refclock.c; else echo ntp_refclock.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_refclock_.c
 ntp_request_.c: ntp_request.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_request.c; then echo $(srcdir)/ntp_request.c; else echo ntp_request.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_request_.c
+ntp_resolver_.c: ntp_resolver.c $(ANSI2KNR)
+       $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_resolver.c; then echo $(srcdir)/ntp_resolver.c; else echo ntp_resolver.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_resolver_.c
 ntp_restrict_.c: ntp_restrict.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_restrict.c; then echo $(srcdir)/ntp_restrict.c; else echo ntp_restrict.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_restrict_.c
 ntp_timer_.c: ntp_timer.c $(ANSI2KNR)
@@ -390,13 +398,13 @@ refclock_wwv_.c: refclock_wwv.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/refclock_wwv.c; then echo $(srcdir)/refclock_wwv.c; else echo refclock_wwv.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > refclock_wwv_.c
 refclock_wwvb_.c: refclock_wwvb.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/refclock_wwvb.c; then echo $(srcdir)/refclock_wwvb.c; else echo refclock_wwvb.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > refclock_wwvb_.c
-check_y2k_.o map_vme_.o ntp_config_.o ntp_control_.o ntp_filegen_.o \
-ntp_intres_.o ntp_io_.o ntp_loopfilter_.o ntp_monitor_.o ntp_peer_.o \
-ntp_proto_.o ntp_refclock_.o ntp_request_.o ntp_restrict_.o \
-ntp_timer_.o ntp_util_.o ntpd_.o refclock_acts_.o refclock_arbiter_.o \
-refclock_arc_.o refclock_as2201_.o refclock_atom_.o refclock_bancomm_.o \
-refclock_chronolog_.o refclock_chu_.o refclock_conf_.o \
-refclock_datum_.o refclock_dumbclock_.o refclock_fg_.o \
+check_y2k_.o map_vme_.o ntp_config_.o ntp_control_.o ntp_crypto_.o \
+ntp_filegen_.o ntp_intres_.o ntp_io_.o ntp_loopfilter_.o ntp_monitor_.o \
+ntp_peer_.o ntp_proto_.o ntp_refclock_.o ntp_request_.o ntp_resolver_.o \
+ntp_restrict_.o ntp_timer_.o ntp_util_.o ntpd_.o refclock_acts_.o \
+refclock_arbiter_.o refclock_arc_.o refclock_as2201_.o refclock_atom_.o \
+refclock_bancomm_.o refclock_chronolog_.o refclock_chu_.o \
+refclock_conf_.o refclock_datum_.o refclock_dumbclock_.o refclock_fg_.o \
 refclock_gpsvme_.o refclock_heath_.o refclock_hpgps_.o refclock_irig_.o \
 refclock_jupiter_.o refclock_leitch_.o refclock_local_.o \
 refclock_msfees_.o refclock_mx4200_.o refclock_nmea_.o \
@@ -456,6 +464,7 @@ distdir: $(DISTFILES)
 @AMDEP@include $(DEPDIR)/map_vme$U.Po
 @AMDEP@include $(DEPDIR)/ntp_config$U.Po
 @AMDEP@include $(DEPDIR)/ntp_control$U.Po
+@AMDEP@include $(DEPDIR)/ntp_crypto$U.Po
 @AMDEP@include $(DEPDIR)/ntp_filegen$U.Po
 @AMDEP@include $(DEPDIR)/ntp_intres$U.Po
 @AMDEP@include $(DEPDIR)/ntp_io$U.Po
@@ -465,6 +474,7 @@ distdir: $(DISTFILES)
 @AMDEP@include $(DEPDIR)/ntp_proto$U.Po
 @AMDEP@include $(DEPDIR)/ntp_refclock$U.Po
 @AMDEP@include $(DEPDIR)/ntp_request$U.Po
+@AMDEP@include $(DEPDIR)/ntp_resolver$U.Po
 @AMDEP@include $(DEPDIR)/ntp_restrict$U.Po
 @AMDEP@include $(DEPDIR)/ntp_timer$U.Po
 @AMDEP@include $(DEPDIR)/ntp_util$U.Po
index 60c9283d416c03565e823a77e1ffa085bf6e1e10..d71e051ef866d8dc24d7f217de955f6a5ce69488 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * ntp_config.c - read and apply configuration information
  */
-
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
 #include "ntp_filegen.h"
 #include "ntp_stdlib.h"
 
+#ifdef PUBKEY
+#include "ntp_crypto.h"
+#endif /* PUBKEY */
+
 #ifdef SYS_WINNT
 #include <io.h>
 extern HANDLE ResolverThreadHandle;
@@ -71,6 +74,8 @@ extern HANDLE ResolverThreadHandle;
  * restrict [ addr ] [ mask 255.255.255.0 ] ignore|noserve|notrust|noquery
  * driftfile file_name
  * keys file_name
+ * publickey file_name
+ * privatekey file_name
  * statsdir /var/NTP/
  * filegen peerstats [ file peerstats ] [ type day ] [ link ]
  * clientlimit [ n ]
@@ -95,6 +100,9 @@ extern HANDLE ResolverThreadHandle;
  */
 #define CONFIG_UNKNOWN         0
 
+/*
+ * Command keywords
+ */
 #define CONFIG_PEER            1
 #define CONFIG_SERVER          2
 #define CONFIG_AUTOMAX         3
@@ -112,7 +120,9 @@ extern HANDLE ResolverThreadHandle;
 #define CONFIG_CONTROLKEY      15
 #define CONFIG_TRAP            16
 #define CONFIG_FUDGE           17
-#define CONFIG_18              18 /* unused */
+#ifdef PUBKEY
+#define CONFIG_KEYSDIR         18
+#endif /* PUBKEY */
 #define CONFIG_STATSDIR                19
 #define CONFIG_FILEGEN         20
 #define CONFIG_STATISTICS      21
@@ -128,7 +138,13 @@ extern HANDLE ResolverThreadHandle;
 #define CONFIG_LOGCONFIG       31
 #define CONFIG_MANYCASTCLIENT  32
 #define CONFIG_MANYCASTSERVER  33
+#ifdef PUBKEY
+#define CONFIG_CRYPTO          34
+#endif /* PUBKEY */
 
+/*
+ * "peer", "server", "broadcast" modifier keywords
+ */
 #define CONF_MOD_VERSION       1
 #define CONF_MOD_KEY           2
 #define CONF_MOD_MINPOLL       3
@@ -139,7 +155,13 @@ extern HANDLE ResolverThreadHandle;
 #define CONF_MOD_TTL           8
 #define CONF_MOD_MODE          9
 #define CONF_MOD_NOSELECT      10
+#ifdef PUBKEY
+#define CONF_MOD_PUBLICKEY     11
+#endif /* PUBKEY */
 
+/*
+ * "restrict" modifier keywords
+ */
 #define CONF_RES_MASK          1
 #define CONF_RES_IGNORE                2
 #define CONF_RES_NOSERVE       3
@@ -152,9 +174,15 @@ extern HANDLE ResolverThreadHandle;
 #define CONF_RES_NTPPORT       10
 #define CONF_RES_LIMITED       11
 
+/*
+ * "trap" modifier keywords
+ */
 #define CONF_TRAP_PORT         1
 #define CONF_TRAP_INTERFACE    2
 
+/*
+ * "fudge" modifier keywords
+ */
 #define CONF_FDG_TIME1         1
 #define CONF_FDG_TIME2         2
 #define CONF_FDG_STRATUM       3
@@ -164,6 +192,9 @@ extern HANDLE ResolverThreadHandle;
 #define CONF_FDG_FLAG3         7
 #define CONF_FDG_FLAG4         8
 
+/*
+ * "filegen" modifier keywords
+ */
 #define CONF_FGEN_FILE         1
 #define CONF_FGEN_TYPE         2
 #define CONF_FGEN_FLAG_LINK    3
@@ -171,10 +202,23 @@ extern HANDLE ResolverThreadHandle;
 #define CONF_FGEN_FLAG_ENABLE  5
 #define CONF_FGEN_FLAG_DISABLE 6
 
+/*
+ * "pps" modifier keywords
+ */
 #define CONF_PPS_ASSERT                1
 #define CONF_PPS_CLEAR         2
 #define CONF_PPS_HARDPPS       3
 
+#ifdef PUBKEY
+/*
+ * "crypto" modifier keywords
+ */
+#define CONF_CRYPTO_DH         1
+#define        CONF_CRYPTO_PRIVATEKEY  2
+#define        CONF_CRYPTO_PUBLICKEY   3
+#define CONF_CRYPTO_FLAGS      4
+#endif /* PUBKEY */
+
 /*
  * Translation table - keywords to function index
  */
@@ -187,38 +231,44 @@ struct keyword {
  * Command keywords
  */
 static struct keyword keywords[] = {
-       { "peer",               CONFIG_PEER },
-       { "server",             CONFIG_SERVER },
-       { "driftfile",          CONFIG_DRIFTFILE },
-       { "broadcast",          CONFIG_BROADCAST },
-       { "broadcastclient",    CONFIG_BROADCASTCLIENT },
-       { "multicastclient",    CONFIG_MULTICASTCLIENT },
-       { "manycastclient",     CONFIG_MANYCASTCLIENT },
-       { "manycastserver",     CONFIG_MANYCASTSERVER },
        { "authenticate",       CONFIG_AUTHENTICATE },
-       { "keys",               CONFIG_KEYS },
-       { "revoke",             CONFIG_REVOKE },
-       { "pps",                CONFIG_PPS },
        { "automax",            CONFIG_AUTOMAX },
-       { "restrict",           CONFIG_RESTRICT },
+       { "broadcast",          CONFIG_BROADCAST },
+       { "broadcastclient",    CONFIG_BROADCASTCLIENT },
        { "broadcastdelay",     CONFIG_BDELAY },
-       { "trustedkey",         CONFIG_TRUSTEDKEY },
-       { "requestkey",         CONFIG_REQUESTKEY },
-       { "controlkey",         CONFIG_CONTROLKEY },
-       { "trap",               CONFIG_TRAP },
-       { "fudge",              CONFIG_FUDGE },
-       { "statsdir",           CONFIG_STATSDIR },
-       { "filegen",            CONFIG_FILEGEN },
-       { "statistics",         CONFIG_STATISTICS },
-       { "pidfile",            CONFIG_PIDFILE },
-       { "setvar",             CONFIG_SETVAR },
        { "clientlimit",        CONFIG_CLIENTLIMIT },
        { "clientperiod",       CONFIG_CLIENTPERIOD },
-       { "enable",             CONFIG_ENABLE },
+#ifdef PUBKEY
+       { "crypto",             CONFIG_CRYPTO },
+#endif /* PUBKEY */
+       { "controlkey",         CONFIG_CONTROLKEY },
        { "disable",            CONFIG_DISABLE },
-       { "phone",              CONFIG_PHONE },
-       { "logfile",            CONFIG_LOGFILE },
+       { "driftfile",          CONFIG_DRIFTFILE },
+       { "enable",             CONFIG_ENABLE },
+       { "filegen",            CONFIG_FILEGEN },
+       { "fudge",              CONFIG_FUDGE },
+       { "keys",               CONFIG_KEYS },
+#ifdef PUBKEY
+       { "keysdir",            CONFIG_KEYSDIR },
+#endif /* PUBKEY */
        { "logconfig",          CONFIG_LOGCONFIG },
+       { "logfile",            CONFIG_LOGFILE },
+       { "manycastclient",     CONFIG_MANYCASTCLIENT },
+       { "manycastserver",     CONFIG_MANYCASTSERVER },
+       { "multicastclient",    CONFIG_MULTICASTCLIENT },
+       { "peer",               CONFIG_PEER },
+       { "phone",              CONFIG_PHONE },
+       { "pidfile",            CONFIG_PIDFILE },
+       { "pps",                CONFIG_PPS },
+       { "requestkey",         CONFIG_REQUESTKEY },
+       { "restrict",           CONFIG_RESTRICT },
+       { "revoke",             CONFIG_REVOKE },
+       { "server",             CONFIG_SERVER },
+       { "setvar",             CONFIG_SETVAR },
+       { "statistics",         CONFIG_STATISTICS },
+       { "statsdir",           CONFIG_STATSDIR },
+       { "trap",               CONFIG_TRAP },
+       { "trustedkey",         CONFIG_TRUSTEDKEY },
        { "",                   CONFIG_UNKNOWN }
 };
 
@@ -226,16 +276,19 @@ static    struct keyword keywords[] = {
  * "peer", "server", "broadcast" modifier keywords
  */
 static struct keyword mod_keywords[] = {
-       { "version",            CONF_MOD_VERSION },
+       { "autokey",            CONF_MOD_SKEY },
+       { "burst",              CONF_MOD_BURST },
        { "key",                CONF_MOD_KEY },
-       { "minpoll",            CONF_MOD_MINPOLL },
        { "maxpoll",            CONF_MOD_MAXPOLL },
-       { "prefer",             CONF_MOD_PREFER },
+       { "minpoll",            CONF_MOD_MINPOLL },
+       { "mode",               CONF_MOD_MODE },    /* refclocks */
        { "noselect",           CONF_MOD_NOSELECT },
-       { "burst",              CONF_MOD_BURST },
-       { "autokey",            CONF_MOD_SKEY },
-       { "mode",               CONF_MOD_MODE },    /* reference clocks */
+       { "prefer",             CONF_MOD_PREFER },
+#ifdef PUBKEY
+       { "publickey",          CONF_MOD_PUBLICKEY },
+#endif /* PUBKEY */
        { "ttl",                CONF_MOD_TTL },     /* NTP peers */
+       { "version",            CONF_MOD_VERSION },
        { "",                   CONFIG_UNKNOWN }
 };
 
@@ -243,17 +296,17 @@ static    struct keyword mod_keywords[] = {
  * "restrict" modifier keywords
  */
 static struct keyword res_keywords[] = {
-       { "mask",               CONF_RES_MASK },
        { "ignore",             CONF_RES_IGNORE },
-       { "noserve",            CONF_RES_NOSERVE },
-       { "notrust",            CONF_RES_NOTRUST },
-       { "noquery",            CONF_RES_NOQUERY },
+       { "limited",            CONF_RES_LIMITED },
+       { "lowpriotrap",        CONF_RES_LPTRAP },
+       { "mask",               CONF_RES_MASK },
        { "nomodify",           CONF_RES_NOMODIFY },
        { "nopeer",             CONF_RES_NOPEER },
+       { "noquery",            CONF_RES_NOQUERY },
+       { "noserve",            CONF_RES_NOSERVE },
        { "notrap",             CONF_RES_NOTRAP },
-       { "lowpriotrap",        CONF_RES_LPTRAP },
+       { "notrust",            CONF_RES_NOTRUST },
        { "ntpport",            CONF_RES_NTPPORT },
-       { "limited",            CONF_RES_LIMITED },
        { "",                   CONFIG_UNKNOWN }
 };
 
@@ -266,19 +319,18 @@ static    struct keyword trap_keywords[] = {
        { "",                   CONFIG_UNKNOWN }
 };
 
-
 /*
  * "fudge" modifier keywords
  */
 static struct keyword fudge_keywords[] = {
-       { "time1",              CONF_FDG_TIME1 },
-       { "time2",              CONF_FDG_TIME2 },
-       { "stratum",            CONF_FDG_STRATUM },
-       { "refid",              CONF_FDG_REFID },
        { "flag1",              CONF_FDG_FLAG1 },
        { "flag2",              CONF_FDG_FLAG2 },
        { "flag3",              CONF_FDG_FLAG3 },
        { "flag4",              CONF_FDG_FLAG4 },
+       { "refid",              CONF_FDG_REFID },
+       { "stratum",            CONF_FDG_STRATUM },
+       { "time1",              CONF_FDG_TIME1 },
+       { "time2",              CONF_FDG_TIME2 },
        { "",                   CONFIG_UNKNOWN }
 };
 
@@ -287,12 +339,12 @@ static    struct keyword fudge_keywords[] = {
  * "filegen" modifier keywords
  */
 static struct keyword filegen_keywords[] = {
+       { "disable",            CONF_FGEN_FLAG_DISABLE },
+       { "enable",             CONF_FGEN_FLAG_ENABLE },
        { "file",               CONF_FGEN_FILE },
-       { "type",               CONF_FGEN_TYPE },
        { "link",               CONF_FGEN_FLAG_LINK },
        { "nolink",             CONF_FGEN_FLAG_NOLINK },
-       { "enable",             CONF_FGEN_FLAG_ENABLE },
-       { "disable",            CONF_FGEN_FLAG_DISABLE },
+       { "type",               CONF_FGEN_TYPE },
        { "",                   CONFIG_UNKNOWN }
 };
 
@@ -300,13 +352,13 @@ static    struct keyword filegen_keywords[] = {
  * "type" modifier keywords
  */
 static struct keyword fgen_types[] = {
+       { "age",                FILEGEN_AGE   },
+       { "day",                FILEGEN_DAY   },
+       { "month",              FILEGEN_MONTH },
        { "none",               FILEGEN_NONE  },
        { "pid",                FILEGEN_PID   },
-       { "day",                FILEGEN_DAY   },
        { "week",               FILEGEN_WEEK  },
-       { "month",              FILEGEN_MONTH },
        { "year",               FILEGEN_YEAR  },
-       { "age",                FILEGEN_AGE   },
        { "",                   CONFIG_UNKNOWN}
 };
 
@@ -316,15 +368,15 @@ static    struct keyword fgen_types[] = {
 static struct keyword flags_keywords[] = {
        { "auth",               PROTO_AUTHENTICATE },
        { "bclient",            PROTO_BROADCLIENT },
-       { "ntp",                PROTO_NTP },
        { "kernel",             PROTO_KERNEL },
        { "monitor",            PROTO_MONITOR },
+       { "ntp",                PROTO_NTP },
        { "stats",              PROTO_FILEGEN },
        { "",                   CONFIG_UNKNOWN }
 };
 
 /*
- * pps modifier keywords
+ * "pps" modifier keywords
  */
 static struct keyword pps_keywords[] = {
        { "assert",             CONF_PPS_ASSERT },
@@ -333,6 +385,19 @@ static struct keyword pps_keywords[] = {
        { "",                   CONFIG_UNKNOWN }
 };
 
+#ifdef PUBKEY
+/*
+ * "crypto" modifier keywords
+ */
+static struct keyword crypto_keywords[] = {
+       { "dh",                 CONF_CRYPTO_DH },
+       { "flags",              CONF_CRYPTO_FLAGS },
+       { "privatekey",         CONF_CRYPTO_PRIVATEKEY },
+       { "publickey",          CONF_CRYPTO_PUBLICKEY },
+       { "",                   CONFIG_UNKNOWN }
+};
+#endif /* PUBKEY */
+
 /*
  * "logconfig" building blocks
  */
@@ -342,10 +407,10 @@ struct masks {
 };
 
 static struct masks logcfg_class[] = {
-       { "sys",                NLOG_OSYS },
-       { "peer",               NLOG_OPEER },
        { "clock",              NLOG_OCLOCK },
+       { "peer",               NLOG_OPEER },
        { "sync",               NLOG_OSYNC },
+       { "sys",                NLOG_OSYS },
        { (char *)0,    0 }
 };
 
@@ -373,8 +438,6 @@ static struct masks logcfg_item[] = {
 #define MAXLINE                1024    /* maximum length of line */
 #define MAXPHONE       5       /* maximum number of phone strings */
 #define MAXPPS         20      /* maximum length of PPS device string */
-#define MAXFILENAME    128     /* maximum length of a file name (alloca()?) */
-
 
 /*
  * Miscellaneous macros
@@ -439,7 +502,8 @@ static      int gettokens_netinfo P((struct netinfo_config_state *, char **, int *));
 static int gettokens P((FILE *, char *, char **, int *));
 static int matchkey P((char *, struct keyword *));
 static int getnetnum P((const char *, struct sockaddr_in *, int));
-static void save_resolve P((char *, int, int, int, int, int, int, u_long));
+static void save_resolve P((char *, int, int, int, int, int, int,
+    keyid_t, u_char *));
 static void do_resolve_internal P((void));
 static void abort_resolve P((void));
 #if !defined(VMS)
@@ -640,8 +704,9 @@ getconfig(
        int minpoll;
        int maxpoll;
        int ttl;
-       u_long peerkey;
-       u_long lpeerkey;
+       keyid_t peerkey;
+       char *peerkeystr;
+       keyid_t lpeerkey;
        int peerflags;
        int hmode;
        struct sockaddr_in peeraddr;
@@ -954,6 +1019,7 @@ getconfig(
                        minpoll = NTP_MINDPOLL;
                        maxpoll = NTP_MAXDPOLL;
                        peerkey = 0;
+                       peerkeystr = "*";
                        peerflags = 0;
                        ttl = 0;
                        for (i = 2; i < ntokens; i++)
@@ -1022,11 +1088,27 @@ getconfig(
                                case CONF_MOD_BURST:
                                    peerflags |= FLAG_BURST;
                                    break;
-
+#ifdef AUTOKEY
                                case CONF_MOD_SKEY:
-                                   peerflags |= FLAG_SKEY | FLAG_AUTHENABLE;
+                                   peerflags |= FLAG_SKEY |
+                                       FLAG_AUTHENABLE;
                                    break;
 
+#ifdef PUBKEY
+                               case CONF_MOD_PUBLICKEY:
+                                   if (i >= ntokens - 1) {
+                                       msyslog(LOG_ERR,
+                                           "Public key file name required");
+                                       errflg = 1;
+                                       break;
+                                   }
+                                   peerflags |= FLAG_SKEY |
+                                       FLAG_AUTHENABLE;
+                                   peerkeystr = tokens[++i];
+                                   break;
+#endif /* PUBKEY */
+#endif /* AUTOKEY */
+
                                case CONF_MOD_TTL:
                                    if (i >= ntokens-1) {
                                            msyslog(LOG_ERR,
@@ -1056,19 +1138,20 @@ getconfig(
                                errflg = 1;
                        }
                        if (errflg == 0) {
-                               if (peer_config(&peeraddr,
-                                               (struct interface *)0, hmode,
-                                               peerversion, minpoll, maxpoll,
-                                               peerflags, ttl, peerkey)
-                                   == 0) {
+                           if (peer_config(&peeraddr,
+                                   (struct interface *)0, hmode,
+                                   peerversion, minpoll, maxpoll, peerflags,
+                                   ttl, peerkey, peerkeystr) == 0) {
                                        msyslog(LOG_ERR,
                                                "configuration of %s failed",
                                                ntoa(&peeraddr));
-                               }
+                           }
+       
                        } else if (errflg == -1) {
-                               save_resolve(tokens[1], hmode, peerversion,
-                                            minpoll, maxpoll, peerflags, ttl,
-                                            peerkey);
+                               save_resolve(tokens[1], hmode,
+                                   peerversion, minpoll, maxpoll,
+                                   peerflags, ttl, peerkey,
+                                   peerkeystr);
                        }
                        break;
 
@@ -1089,6 +1172,7 @@ getconfig(
                    case CONFIG_LOGFILE:
                        if (ntokens >= 2) {
                                FILE *new_file;
+
                                new_file = fopen(tokens[1], "a");
                                if (new_file != NULL) {
                                        NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
@@ -1199,18 +1283,57 @@ getconfig(
                        }
                        break;
 
+#ifdef AUTOKEY
                    case CONFIG_REVOKE:
-                       if (ntokens >= 2) {
-                               sys_revoke = 1 << max(atoi(tokens[1]), 10);
-                       }
+                       if (ntokens >= 2)
+                           sys_revoke = 1 << max(atoi(tokens[1]), 10);
                        break;
 
                    case CONFIG_AUTOMAX:
-                       if (ntokens >= 2) {
-                               sys_automax = 1 << max(atoi(tokens[1]), 10);
+                       if (ntokens >= 2)
+                           sys_automax = 1 << max(atoi(tokens[1]), 10);
+                       break;
+
+#ifdef PUBKEY
+                   case CONFIG_KEYSDIR:
+                       if (ntokens < 2) {
+                           msyslog(LOG_ERR,
+                               "Keys directory name required");
+                           break;
                        }
+                       crypto_config(CRYPTO_CONF_KEYS, tokens[1]);
                        break;
 
+                   case CONFIG_CRYPTO:
+                       crypto_enable = 1;
+                       for (i = 2; i < ntokens; i++) {
+                           switch (matchkey(tokens[i],
+                               crypto_keywords)) {
+
+                           case CONF_CRYPTO_FLAGS:
+                                   crypto_config(CRYPTO_CONF_FLAGS,
+                                       tokens[i++]);
+
+                           case CONF_CRYPTO_DH:
+                                   crypto_config(CRYPTO_CONF_DH,
+                                       tokens[i++]);
+                                   break;
+
+                           case CONF_CRYPTO_PRIVATEKEY:
+                                   crypto_config(CRYPTO_CONF_PRIV,
+                                       tokens[i++]);
+                                   break;
+
+                           case CONF_CRYPTO_PUBLICKEY:
+                                   crypto_config(CRYPTO_CONF_PUBL,
+                                       tokens[i++]);
+                                   break;
+                           }
+                       }
+                       break;
+#endif /* PUBKEY */
+#endif /* AUTOKEY */
+
                    case CONFIG_RESTRICT:
                        if (ntokens < 2) {
                                msyslog(LOG_ERR, "restrict requires an address");
@@ -1310,7 +1433,7 @@ getconfig(
 
                    case CONFIG_TRUSTEDKEY:
                        for (i = 1; i < ntokens; i++) {
-                               u_long tkey;
+                               keyid_t tkey;
 
                                tkey = atol(tokens[i]);
                                if (tkey == 0) {
@@ -1325,7 +1448,7 @@ getconfig(
 
                    case CONFIG_REQUESTKEY:
                        if (ntokens >= 2) {
-                               u_long rkey;
+                               keyid_t rkey;
 
                                if (!atouint(tokens[1], &rkey)) {
                                        msyslog(LOG_ERR,
@@ -1339,7 +1462,7 @@ getconfig(
 #ifdef DEBUG
                                        if (debug > 3)
                                            printf(
-                                                   "set info_auth_key to %lu\n", rkey);
+                                                   "set info_auth_key to %08x\n", rkey);
 #endif
                                        info_auth_keyid = rkey;
                                }
@@ -1348,7 +1471,7 @@ getconfig(
 
                    case CONFIG_CONTROLKEY:
                        if (ntokens >= 2) {
-                               u_long ckey;
+                               keyid_t ckey;
 
                                ckey = atol(tokens[1]);
                                if (ckey == 0) {
@@ -1558,15 +1681,14 @@ getconfig(
                         */
                        if (!errflg) {
                                refclock_control(&peeraddr, &clock_stat,
-                                                (struct refclockstat *)0);
+                                   (struct refclockstat *)0);
                        }
 #endif
                        break;
 
                    case CONFIG_STATSDIR:
-                       if (ntokens >= 2) {
+                       if (ntokens >= 2)
                                stats_config(STATS_STATSDIR,tokens[1]);
-                       }
                        break;
 
                    case CONFIG_STATISTICS:
@@ -1808,6 +1930,7 @@ getconfig(
                 */
                do_resolve_internal();
        }
+       ntp_res_send(0, 0, inet_addr("127.0.0.1"), 0);  /* HMS: Testing... */
 }
 
 
@@ -2167,7 +2290,8 @@ save_resolve(
        int maxpoll,
        int flags,
        int ttl,
-       u_long keyid
+       keyid_t keyid,
+       u_char *keystr
        )
 {
 #ifndef SYS_VXWORKS
@@ -2208,8 +2332,14 @@ save_resolve(
        }
 #endif
 
-       (void) fprintf(res_fp, "%s %d %d %d %d %d %d %lu\n", name, mode,
-                          version, minpoll, maxpoll, flags, ttl, keyid);
+       (void)fprintf(res_fp, "%s %d %d %d %d %d %d %08x %s\n", name,
+           mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr);
+#ifdef DEBUG
+       if (debug > 1)
+               printf("config: %s %d %d %d %d %d %d %08x %s\n", name, mode,
+                   version, minpoll, maxpoll, flags, ttl, keyid, keystr);
+#endif
+
 #else  /* SYS_VXWORKS */
        /* save resolve info to a struct */
 #endif /* SYS_VXWORKS */
@@ -2326,10 +2456,10 @@ do_resolve_internal(void)
                 * async io information causes it to process requests from
                 * all file decriptor causing a race between the NTP daemon
                 * and the resolver. which then eats data when it wins 8-(.
-                * It is absolutly necessary to kill ane io associations
-                * shared with the NTP daemon. I currently don't want
+                * It is absolutly necessary to kill any IO associations
+                * shared with the NTP daemon.
                 *
-                * we also block SIGIO (currently no portes means to
+                * We also block SIGIO (currently no ports means to
                 * disable the signal handle for IO).
                 *
                 * Thanks to wgstuken@informatik.uni-erlangen.de to notice
index e2fb03995f525f3543cc6d96d15f9230f6853753..908f005d34d0911fe40850ca07c5c0920e4bfc5d 100644 (file)
 #include "ntp_control.h"
 #include "ntp_stdlib.h"
 
+#ifdef PUBKEY
+#include "ntp_crypto.h"
+#endif /* PUBKEY */
+
 /*
  * Structure to hold request procedure information
  */
@@ -26,9 +30,9 @@
 #define NO_REQUEST     (-1)
 
 struct ctl_proc {
-       short control_code;                             /* defined request code */
-       u_short flags;                                  /* flags word */
-       void (*handler) P((struct recvbuf *, int));     /* routine to handle request */
+       short control_code;             /* defined request code */
+       u_short flags;                  /* flags word */
+       void (*handler) P((struct recvbuf *, int)); /* handle request */
 };
 
 /*
@@ -44,9 +48,10 @@ static       void    ctl_error       P((int));
 static u_short ctlclkstatus    P((struct refclockstat *));
 static void    ctl_flushpkt    P((int));
 static void    ctl_putdata     P((const char *, unsigned int, int));
-static void    ctl_putstr      P((const char *, const char *, unsigned int));
+static void    ctl_putstr      P((const char *, const char *,
+                                   unsigned int));
 static void    ctl_putdbl      P((const char *, double));
-static void    ctl_putuint P((const char *, u_long));
+static void    ctl_putuint     P((const char *, u_long));
 static void    ctl_puthex      P((const char *, u_long));
 static void    ctl_putint      P((const char *, long));
 static void    ctl_putts       P((const char *, l_fp *));
@@ -54,21 +59,22 @@ static      void    ctl_putadr      P((const char *, u_int32));
 static void    ctl_putid       P((const char *, char *));
 static void    ctl_putarray    P((const char *, double *, int));
 static void    ctl_putsys      P((int));
-static void    ctl_putpeer P((int, struct peer *));
+static void    ctl_putpeer     P((int, struct peer *));
 #ifdef REFCLOCK
 static void    ctl_putclock    P((int, struct refclockstat *, int));
 #endif /* REFCLOCK */
 static struct ctl_var *ctl_getitem P((struct ctl_var *, char **));
-static u_long count_var P((struct ctl_var *));
+static u_long count_var        P((struct ctl_var *));
 static void    control_unspec  P((struct recvbuf *, int));
-static void    read_status P((struct recvbuf *, int));
+static void    read_status     P((struct recvbuf *, int));
 static void    read_variables  P((struct recvbuf *, int));
 static void    write_variables P((struct recvbuf *, int));
-static void    read_clock_status       P((struct recvbuf *, int));
-static void    write_clock_status      P((struct recvbuf *, int));
+static void    read_clock_status P((struct recvbuf *, int));
+static void    write_clock_status P((struct recvbuf *, int));
 static void    set_trap        P((struct recvbuf *, int));
 static void    unset_trap      P((struct recvbuf *, int));
-static struct ctl_trap *ctlfindtrap    P((struct sockaddr_in *, struct interface *));
+static struct ctl_trap *ctlfindtrap P((struct sockaddr_in *,
+                                   struct interface *));
 
 static struct ctl_proc control_codes[] = {
        { CTL_OP_UNSPEC,        NOAUTH, control_unspec },
@@ -83,10 +89,10 @@ static      struct ctl_proc control_codes[] = {
 };
 
 /*
- * System variable values.     The array can be indexed by
- * the variable index to find the textual name.
+ * System variable values. The array can be indexed by the variable
+ * index to find the textual name.
  */
-static struct ctl_var sys_var[] = {
+static struct ctl_var sys_var[] = {
        { 0,            PADDING, "" },          /* 0 */
        { CS_LEAP,      RW, "leap" },           /* 1 */
        { CS_STRATUM,   RO, "stratum" },        /* 2 */
@@ -106,13 +112,19 @@ static    struct ctl_var sys_var[] = {
        { CS_SYSTEM,    RO, "system" },         /* 16 */
        { CS_STABIL,    RO, "stability" },      /* 17 */
        { CS_VARLIST,   RO, "sys_var_list" },   /* 18 */
+#ifdef PUBKEY
+       { CS_PRIVATE,   RO, "privatekey" },     /* 19 */
+       { CS_PUBLIC,    RO, "publickey" },      /* 20 */
+       { CS_DHPARAMS,  RO, "dhparams" },       /* 21 */
+#endif /* PUBKEY */
        { 0,            EOV,    ""  }
 };
 
-static struct ctl_var *ext_sys_var = (struct ctl_var *)0;
+static struct ctl_var *ext_sys_var = (struct ctl_var *)0;
 
 /*
- * System variables we print by default (in fuzzball order, more-or-less)
+ * System variables we print by default (in fuzzball order,
+ * more-or-less)
  */
 static u_char def_sys_var[] = {
        CS_PROCESSOR,
@@ -132,6 +144,11 @@ static     u_char def_sys_var[] = {
        CS_DRIFT,
        CS_COMPLIANCE,
        CS_STABIL,
+#ifdef PUBKEY
+       CS_PRIVATE,
+       CS_PUBLIC,
+       CS_DHPARAMS,
+#endif /* PUBKEY */
        0
 };
 
@@ -139,7 +156,7 @@ static      u_char def_sys_var[] = {
 /*
  * Peer variable list
  */
-static struct ctl_var peer_var[] = {
+static struct ctl_var peer_var[] = {
        { 0,            PADDING, "" },      /* 0 */
        { CP_CONFIG,    RO, "config" }, /* 1 */
        { CP_AUTHENABLE, RO,    "authenable" }, /* 2 */
@@ -178,6 +195,14 @@ static     struct ctl_var peer_var[] = {
        { CP_FLASH, RO, "flash" },  /* 35 */
        { CP_DISP,      PADDING,"" },       /* 36 */
        { CP_VARLIST,   RO, "peer_var_list" }, /* 37 */
+#ifdef PUBKEY
+       { CP_PUBLIC,    RO, "publickey" },      /* 38 */
+       { CP_SESKEY,    RO, "pcookie" },        /* 39 */
+       { CP_SASKEY,    RO, "hcookie" },        /* 40 */
+       { CP_AUTOSEQ,   RO, "sequence" },       /* 41 */
+       { CP_INITKEY,   RO, "initkey" },        /* 42 */
+       { CP_INITSEQ,   RO, "initsequence" },   /* 43 */
+#endif /* PUBKEY */
        { 0,            EOV,    ""  }
 };
 
@@ -185,7 +210,7 @@ static      struct ctl_var peer_var[] = {
 /*
  * Peer variables we print by default
  */
-static u_char def_peer_var[] = {
+static u_char def_peer_var[] = {
        CP_SRCADR,
        CP_SRCPORT,
        CP_DSTADR,
@@ -215,6 +240,9 @@ static      u_char def_peer_var[] = {
        CP_FILTDELAY,
        CP_FILTOFFSET,
        CP_FILTERROR,
+#ifdef PUBKEY
+       CP_PUBLIC,
+#endif /* PUBKEY */
        0
 };
 
@@ -223,7 +251,7 @@ static      u_char def_peer_var[] = {
 /*
  * Clock variable list
  */
-static struct ctl_var clock_var[] = {
+static struct ctl_var clock_var[] = {
        { 0,            PADDING, "" },      /* 0 */
        { CC_TYPE,      RO, "type" },   /* 1 */
        { CC_TIMECODE,  RO, "timecode" },   /* 2 */
@@ -245,9 +273,9 @@ static      struct ctl_var clock_var[] = {
 /*
  * Clock variables printed by default
  */
-static u_char def_clock_var[] = {
+static u_char def_clock_var[] = {
        CC_DEVICE,
-       CC_TYPE,        /* won't be output if device= known */
+       CC_TYPE,        /* won't be output if device = known */
        CC_TIMECODE,
        CC_POLL,
        CC_NOREPLY,
@@ -264,14 +292,14 @@ static    u_char def_clock_var[] = {
 
 
 /*
- * System and processor definitions.  These will change for the gizmo board.
+ * System and processor definitions.
  */
 #ifndef HAVE_UNAME
 # ifndef STR_SYSTEM
-#  define              STR_SYSTEM              "UNIX"
+#  define              STR_SYSTEM      "UNIX"
 # endif
 # ifndef STR_PROCESSOR
-#      define           STR_PROCESSOR   "unknown"
+#      define          STR_PROCESSOR   "unknown"
 # endif
 
 static char str_system[] = STR_SYSTEM;
@@ -282,10 +310,10 @@ static struct utsname utsnamebuf;
 #endif /* HAVE_UNAME */
 
 /*
- * Trap structures.  We only allow a few of these, and send
- * a copy of each async message to each live one.  Traps time
- * out after an hour, it is up to the trap receipient to
- * keep resetting it to avoid being timed out.
+ * Trap structures. We only allow a few of these, and send a copy of
+ * each async message to each live one. Traps time out after an hour, it
+ * is up to the trap receipient to keep resetting it to avoid being
+ * timed out.
  */
 /* ntp_request.c */
 struct ctl_trap ctl_trap[CTL_MAXTRAPS];
@@ -301,9 +329,9 @@ int num_ctl_traps;
 
 /*
  * List relating reference clock types to control message time sources.
- * Index by the reference clock type.
- * This list will only be used iff the reference clock driver doesn't
- * set peer->sstclktype to something different than CTL_SST_TS_UNSPEC.
+ * Index by the reference clock type. This list will only be used iff
+ * the reference clock driver doesn't set peer->sstclktype to something
+ * different than CTL_SST_TS_UNSPEC.
  */
 static u_char clocktypes[] = {
        CTL_SST_TS_NTP,         /* REFCLK_NONE (0) */
@@ -342,7 +370,7 @@ static u_char clocktypes[] = {
        CTL_SST_TS_LF,          /* REFCLK_DUMBCLOCK (32) */
        CTL_SST_TS_LF,          /* REFCLK_ULINK (33) */
        CTL_SST_TS_LF,          /* REFCLK_PCF (35) */
-       CTL_SST_TS_LF,          /* REFCLK_WWW (36) */
+       CTL_SST_TS_LF,          /* REFCLK_WWV (36) */
        CTL_SST_TS_LF,          /* REFCLK_FG (37) */
 };
 
@@ -350,7 +378,7 @@ static u_char clocktypes[] = {
 /*
  * Keyid used for authenticating write requests.
  */
-u_long ctl_auth_keyid;
+keyid_t ctl_auth_keyid;
 
 /*
  * We keep track of the last error reported by the system internally
@@ -366,7 +394,7 @@ u_long ctltimereset;                /* time stats reset */
 u_long numctlreq;              /* number of requests we've received */
 u_long numctlbadpkts;          /* number of bad control packets */
 u_long numctlresponses;        /* number of resp packets sent with data */
-u_long numctlfrags;    /* number of fragments sent */
+u_long numctlfrags;            /* number of fragments sent */
 u_long numctlerrors;           /* number of error responses sent */
 u_long numctltooshort;         /* number of too short input packets */
 u_long numctlinputresp;        /* number of responses on input */
@@ -375,11 +403,11 @@ u_long numctlinputerr;            /* number of input pkts with err bit set */
 u_long numctlbadoffset;        /* number of input pkts with nonzero offset */
 u_long numctlbadversion;       /* number of input pkts with unknown version */
 u_long numctldatatooshort;     /* data too short for count */
-u_long numctlbadop;    /* bad op code found in packet */
+u_long numctlbadop;            /* bad op code found in packet */
 u_long numasyncmsgs;           /* number of async messages we've sent */
 
 /*
- * Response packet used by these routines.     Also some state information
+ * Response packet used by these routines. Also some state information
  * so that we can handle packet formatting within a common set of
  * subroutines.  Note we try to enter data in place whenever possible,
  * but the need to set the more bit correctly means we occasionally
@@ -399,7 +427,7 @@ static struct interface *lcl_inter;
 
 static u_char  res_authenticate;
 static u_char  res_authokay;
-static u_long  res_keyid;
+static keyid_t res_keyid;
 
 #define MAXDATALINELEN (72)
 
@@ -448,10 +476,11 @@ ctl_error(
                printf("sending control error %d\n", errcode);
 #endif
        /*
-        * fill in the fields.  We assume rpkt.sequence and rpkt.associd
+        * Fill in the fields. We assume rpkt.sequence and rpkt.associd
         * have already been filled in.
         */
-       rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode & CTL_OP_MASK));
+       rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode &
+           CTL_OP_MASK));
        rpkt.status = htons((u_short) ((errcode<<8) & 0xff00));
        rpkt.count = 0;
 
@@ -461,15 +490,15 @@ ctl_error(
        if (res_authenticate && sys_authenticate) {
                int maclen;
 
-               *(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN)
-                       = htonl(res_keyid);
+               *(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN) =
+                   htonl(res_keyid);
                maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
-                       CTL_HEADER_LEN);
+                   CTL_HEADER_LEN);
                sendpkt(rmt_addr, lcl_inter, -2, (struct pkt *)&rpkt,
-                       CTL_HEADER_LEN + maclen);
+                   CTL_HEADER_LEN + maclen);
        } else {
                sendpkt(rmt_addr, lcl_inter, -3, (struct pkt *)&rpkt,
-                       CTL_HEADER_LEN);
+                   CTL_HEADER_LEN);
        }
        numctlerrors++;
 }
@@ -492,7 +521,7 @@ process_control(
        int maclen;
 
 #ifdef DEBUG
-       if (debug > 1)
+       if (debug > 2)
                printf("in process_control()\n");
 #endif
 
@@ -509,8 +538,8 @@ process_control(
         * it is a response or a fragment, ignore this.
         */
        if (rbufp->recv_length < CTL_HEADER_LEN
-               || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR)
-               || pkt->offset != 0) {
+           || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR)
+           || pkt->offset != 0) {
 #ifdef DEBUG
                if (debug)
                        printf("invalid format in control packet\n");
@@ -539,9 +568,11 @@ process_control(
        }
 
        /*
-        * Pull enough data from the packet to make intelligent responses
+        * Pull enough data from the packet to make intelligent
+        * responses
         */
-       rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version, MODE_CONTROL);
+       rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
+           MODE_CONTROL);
        res_opcode = pkt->r_m_e_op;
        rpkt.sequence = pkt->sequence;
        rpkt.associd = pkt->associd;
@@ -559,8 +590,8 @@ process_control(
        dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
 
        /*
-        * We're set up now.  Make sure we've got at least
-        * enough incoming data space to match the count.
+        * We're set up now. Make sure we've got at least enough
+        * incoming data space to match the count.
         */
        req_data = rbufp->recv_length - CTL_HEADER_LEN;
        if (req_data < req_count || rbufp->recv_length & 0x3) {
@@ -571,40 +602,43 @@ process_control(
 
        properlen = req_count + CTL_HEADER_LEN;
 #ifdef DEBUG
-       if (debug >= 2 && (rbufp->recv_length & 0x3) != 0)
-               printf("Packet length %d unrounded\n", rbufp->recv_length);
+       if (debug > 2 && (rbufp->recv_length & 0x3) != 0)
+               printf("Packet length %d unrounded\n",
+                   rbufp->recv_length);
 #endif
        /* round up proper len to a 8 octet boundary */
 
        properlen = (properlen + 7) & ~7;
        maclen = rbufp->recv_length - properlen;
        if ((rbufp->recv_length & (sizeof(u_long) - 1)) == 0 &&
-               maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
-               sys_authenticate) {
+           maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
+           sys_authenticate) {
                res_authenticate = 1;
-               res_keyid = ntohl(*(u_int32 *)((u_char *)pkt + properlen));
+               res_keyid = ntohl(*(u_int32 *)((u_char *)pkt +
+                   properlen));
 
 #ifdef DEBUG
-               if (debug >= 3)
+               if (debug > 2)
                        printf(
-                               "recv_len %d, properlen %d, wants auth with keyid %ld, MAC length=%d\n",
-                               rbufp->recv_length, properlen, res_keyid, maclen);
+                           "recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%d\n",
+                           rbufp->recv_length, properlen, res_keyid, maclen);
 #endif
                if (!authistrusted(res_keyid)) {
 #ifdef DEBUG
-                       if (debug >= 2)
-                               printf("invalid keyid %lu\n", res_keyid);
+                       if (debug > 2)
+                               printf("invalid keyid %08x\n",
+                                   res_keyid);
 #endif
                } else if (authdecrypt(res_keyid, (u_int32 *)pkt,
-                          rbufp->recv_length - maclen, maclen)) {
+                   rbufp->recv_length - maclen, maclen)) {
 #ifdef DEBUG
-                       if (debug >= 3)
+                       if (debug > 2)
                                printf("authenticated okay\n");
 #endif
                        res_authokay = 1;
                } else {
 #ifdef DEBUG
-                       if (debug >= 3)
+                       if (debug > 2)
                                printf("authentication failed\n");
 #endif
                        res_keyid = 0;
@@ -623,12 +657,12 @@ process_control(
        for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
                if (cc->control_code == res_opcode) {
 #ifdef DEBUG
-                       if (debug >= 2)
+                       if (debug > 2)
                                printf("opcode %d, found command handler\n",
-                                  res_opcode);
+                                   res_opcode);
 #endif
-                       if (cc->flags == AUTH && (!res_authokay
-                                                 || res_keyid != ctl_auth_keyid)) {
+                       if (cc->flags == AUTH && (!res_authokay ||
+                           res_keyid != ctl_auth_keyid)) {
                                ctl_error(CERR_PERMISSION);
                                return;
                        }
@@ -666,7 +700,7 @@ ctlpeerstatus(
        if (peer->reach != 0)
                status |= CTL_PST_REACH;
        return (u_short)CTL_PEER_STATUS(status, peer->num_events,
-               peer->last_event);
+           peer->last_event);
 }
 
 
@@ -678,12 +712,11 @@ ctlclkstatus(
        struct refclockstat *this_clock
        )
 {
-       return ((u_short)(this_clock->currentstatus) << 8)
-               | (u_short)(this_clock->lastevent);
+       return ((u_short)(this_clock->currentstatus) << 8) |
+           (u_short)(this_clock->lastevent);
 }
 
 
-
 /*
  * ctlsysstatus - return the system status word
  */
@@ -700,17 +733,17 @@ ctlsysstatus(void)
                                this_clock |= CTL_SST_TS_PPS;
                } else {
                        if (sys_peer->refclktype < sizeof(clocktypes))
-                               this_clock = clocktypes[sys_peer->refclktype];
+                               this_clock =
+                                   clocktypes[sys_peer->refclktype];
                        if (pps_control)
                                this_clock |= CTL_SST_TS_PPS;
                }
        }
        return (u_short)CTL_SYS_STATUS(sys_leap, this_clock,
-               ctl_sys_num_events, ctl_sys_last_event);
+           ctl_sys_num_events, ctl_sys_last_event);
 }
 
 
-
 /*
  * ctl_flushpkt - write out the current packet and prepare
  *               another if necessary.
@@ -744,7 +777,8 @@ ctl_flushpkt(
        /*
         * Fill in the packet with the current info
         */
-       rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode & CTL_OP_MASK));
+       rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode &
+           CTL_OP_MASK));
        rpkt.count = htons((u_short) dlen);
        rpkt.offset = htons( (u_short) res_offset);
        if (res_async) {
@@ -752,12 +786,14 @@ ctl_flushpkt(
 
                for (i = 0; i < CTL_MAXTRAPS; i++) {
                        if (ctl_trap[i].tr_flags & TRAP_INUSE) {
-                               rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
-                                                                ctl_trap[i].tr_version, MODE_CONTROL);
-                               rpkt.sequence = htons(ctl_trap[i].tr_sequence);
+                               rpkt.li_vn_mode =
+                                   PKT_LI_VN_MODE(sys_leap,
+                                   ctl_trap[i].tr_version,
+                                   MODE_CONTROL);
+                               rpkt.sequence =
+                                   htons(ctl_trap[i].tr_sequence);
                                sendpkt(&ctl_trap[i].tr_addr,
-                                       ctl_trap[i].tr_localaddr,
-                                       -4,
+                                       ctl_trap[i].tr_localaddr, -4,
                                        (struct pkt *)&rpkt, sendlen);
                                if (!more)
                                        ctl_trap[i].tr_sequence++;
@@ -768,25 +804,25 @@ ctl_flushpkt(
                if (res_authenticate && sys_authenticate) {
                        int maclen;
                        int totlen = sendlen;
-                       u_long keyid = htonl(res_keyid);
+                       keyid_t keyid = htonl(res_keyid);
 
                        /*
-                        *      If we are going to authenticate, then there is
-                        *      an additional requirement that the MAC begin on
-                        *      a 64 bit boundary.
+                        * If we are going to authenticate, then there
+                        * is an additional requirement that the MAC
+                        * begin on a 64 bit boundary.
                         */
                        while (totlen & 7) {
                                *datapt++ = '\0';
                                totlen++;
                        }
                        memcpy(datapt, &keyid, sizeof keyid);
-                       maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
-                               totlen);
-                       sendpkt(rmt_addr, lcl_inter, -5, (struct pkt *)&rpkt,
-                               totlen + maclen);
+                       maclen = authencrypt(res_keyid,
+                           (u_int32 *)&rpkt, totlen);
+                       sendpkt(rmt_addr, lcl_inter, -5,
+                           (struct pkt *)&rpkt, totlen + maclen);
                } else {
-                       sendpkt(rmt_addr, lcl_inter, -6, (struct pkt *)&rpkt,
-                               sendlen);
+                       sendpkt(rmt_addr, lcl_inter, -6,
+                           (struct pkt *)&rpkt, sendlen);
                }
                if (more)
                        numctlfrags++;
@@ -803,8 +839,8 @@ ctl_flushpkt(
 
 
 /*
- * ctl_putdata - write data into the packet, fragmenting and
- *              starting another if this one is full.
+ * ctl_putdata - write data into the packet, fragmenting and starting
+ * another if this one is full.
  */
 static void
 ctl_putdata(
@@ -822,7 +858,8 @@ ctl_putdata(
                if (datapt != rpkt.data) {
                        *datapt++ = ',';
                        datalinelen++;
-                       if ((dlen + datalinelen + 1) >= MAXDATALINELEN) {
+                       if ((dlen + datalinelen + 1) >= MAXDATALINELEN)
+                           {
                                *datapt++ = '\r';
                                *datapt++ = '\n';
                                datalinelen = 0;
@@ -842,7 +879,6 @@ ctl_putdata(
                 */
                ctl_flushpkt(CTL_MORE);
        }
-
        memmove((char *)datapt, dp, (unsigned)dlen);
        datapt += dlen;
        datalinelen += dlen;
@@ -867,7 +903,6 @@ ctl_putstr(
        cq = tag;
        while (*cq != '\0')
                *cp++ = *cq++;
-
        if (len > 0) {
                *cp++ = '=';
                *cp++ = '"';
@@ -877,7 +912,6 @@ ctl_putstr(
                cp += len;
                *cp++ = '"';
        }
-
        ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
 }
 
@@ -928,7 +962,6 @@ ctl_putuint(
        (void) sprintf(cp, "%lu", uval);
        while (*cp != '\0')
                cp++;
-
        ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
 }
 
@@ -955,7 +988,6 @@ ctl_puthex(
        (void) sprintf(cp, "0x%lx", uval);
        while (*cp != '\0')
                cp++;
-
        ctl_putdata(buffer,(unsigned)( cp - buffer ), 0);
 }
 
@@ -982,7 +1014,6 @@ ctl_putint(
        (void) sprintf(cp, "%ld", ival);
        while (*cp != '\0')
                cp++;
-
        ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
 }
 
@@ -1010,7 +1041,6 @@ ctl_putts(
                           ts->l_uf & 0xffffffffL);
        while (*cp != '\0')
                cp++;
-
        ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
 }
 
@@ -1037,7 +1067,6 @@ ctl_putadr(
        cq = numtoa(addr);
        while (*cq != '\0')
                *cp++ = *cq++;
-
        ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
 }
 
@@ -1064,7 +1093,6 @@ ctl_putid(
        cq = id;
        while (*cq != '\0' && (cq - id) < 4)
                *cp++ = *cq++;
-
        ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
 }
 
@@ -1113,143 +1141,178 @@ ctl_putsys(
 #ifdef HAVE_UNAME
        char str[50];
 #endif
-
        switch (varid) {
-               case CS_LEAP:
+
+       case CS_LEAP:
                ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
                break;
-               case CS_STRATUM:
+
+       case CS_STRATUM:
                ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
                break;
-               case CS_PRECISION:
+
+       case CS_PRECISION:
                ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
                break;
-               case CS_ROOTDELAY:
-               ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay * 1e3);
+
+       case CS_ROOTDELAY:
+               ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
+                   1e3);
                break;
-               case CS_ROOTDISPERSION:
+
+       case CS_ROOTDISPERSION:
                ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
                    sys_rootdispersion * 1e3);
                break;
-               case CS_REFID:
+
+       case CS_REFID:
                if (sys_stratum > 1)
                        ctl_putadr(sys_var[CS_REFID].text, sys_refid);
                else
-                       ctl_putid(sys_var[CS_REFID].text, (char *)&sys_refid);
+                       ctl_putid(sys_var[CS_REFID].text,
+                           (char *)&sys_refid);
                break;
-               case CS_REFTIME:
+
+       case CS_REFTIME:
                ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
                break;
-               case CS_POLL:
+
+       case CS_POLL:
                ctl_putuint(sys_var[CS_POLL].text, sys_poll);
                break;
-               case CS_PEERID:
+
+       case CS_PEERID:
                if (sys_peer == NULL)
                        ctl_putuint(sys_var[CS_PEERID].text, 0);
                else
                        ctl_putuint(sys_var[CS_PEERID].text,
                                sys_peer->associd);
                break;
-               case CS_STATE:
+
+       case CS_STATE:
                ctl_putuint(sys_var[CS_STATE].text, (unsigned)state);
                break;
-               case CS_OFFSET:
+
+       case CS_OFFSET:
                ctl_putdbl(sys_var[CS_OFFSET].text, last_offset * 1e3);
                break;
-               case CS_DRIFT:
+
+       case CS_DRIFT:
                ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
                break;
-               case CS_COMPLIANCE:
-               ctl_putdbl(sys_var[CS_COMPLIANCE].text, sys_error * 1e3);
+
+       case CS_COMPLIANCE:
+               ctl_putdbl(sys_var[CS_COMPLIANCE].text, sys_error *
+                   1e3);
                break;
-               case CS_CLOCK:
+
+       case CS_CLOCK:
                get_systime(&tmp);
                ctl_putts(sys_var[CS_CLOCK].text, &tmp);
                break;
-               case CS_PROCESSOR:
+
+       case CS_PROCESSOR:
 #ifndef HAVE_UNAME
                ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
-                          sizeof(str_processor) - 1);
+                   sizeof(str_processor) - 1);
 #else
-               ctl_putstr(sys_var[CS_PROCESSOR].text, utsnamebuf.machine,
-                          strlen(utsnamebuf.machine));
+               ctl_putstr(sys_var[CS_PROCESSOR].text,
+                   utsnamebuf.machine, strlen(utsnamebuf.machine));
 #endif /* HAVE_UNAME */
                break;
-               case CS_SYSTEM:
+
+       case CS_SYSTEM:
 #ifndef HAVE_UNAME
                ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
-                          sizeof(str_system) - 1);
+                   sizeof(str_system) - 1);
 #else
                (void)strcpy(str, utsnamebuf.sysname);
                (void)strcat(str, utsnamebuf.release);
                ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
 #endif /* HAVE_UNAME */
                break;
-               case CS_STABIL:
-               ctl_putdbl(sys_var[CS_STABIL].text, clock_stability * 1e6);
-               break;
-               case CS_VARLIST:
-                       {
-                               char buf[CTL_MAX_DATA_LEN];
-                               register char *s, *t, *be;
-                               register const char *ss;
-                               register int i;
-                               register struct ctl_var *k;
-
-                               s = buf;
-                               be = buf + sizeof(buf) - strlen(sys_var[CS_VARLIST].text) - 4;
-                               if (s > be)
-                               break;  /* really long var name 8-( - Killer */
-
-                               strcpy(s, sys_var[CS_VARLIST].text);
-                               strcat(s, "=\"");
-                               s += strlen(s);
-                               t = s;
-
-                               for (k = sys_var; !(k->flags &EOV); k++)
-                               {
-                                       if (k->flags & PADDING)
+
+       case CS_STABIL:
+               ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
+                   1e6);
+               break;
+
+       case CS_VARLIST:
+               {
+                       char buf[CTL_MAX_DATA_LEN];
+                       register char *s, *t, *be;
+                       register const char *ss;
+                       register int i;
+                       register struct ctl_var *k;
+
+                       s = buf;
+                       be = buf + sizeof(buf) -
+                           strlen(sys_var[CS_VARLIST].text) - 4;
+                       if (s > be)
+                               break;  /* really long var name */
+
+                       strcpy(s, sys_var[CS_VARLIST].text);
+                       strcat(s, "=\"");
+                       s += strlen(s);
+                       t = s;
+                       for (k = sys_var; !(k->flags &EOV); k++) {
+                               if (k->flags & PADDING)
                                        continue;
+                               i = strlen(k->text);
+                               if (s+i+1 >= be)
+                               break;
 
-                                       i = strlen(k->text);
-                                       if (s+i+1 >= be)
-                                       break;
-                                       if (s != t)
-                                       *s++ = ',';
-                                       strcpy(s, k->text);
-                                       s += i;
-                               }
+                               if (s != t)
+                               *s++ = ',';
+                               strcpy(s, k->text);
+                               s += i;
+                       }
 
-                               for (k = ext_sys_var; k && !(k->flags &EOV); k++)
-                               {
-                                       if (k->flags & PADDING)
+                       for (k = ext_sys_var; k && !(k->flags &EOV);
+                           k++) {
+                               if (k->flags & PADDING)
                                        continue;
 
-                                       ss = k->text;
-                                       if (!ss)
+                               ss = k->text;
+                               if (!ss)
                                        continue;
 
-                                       while (*ss && *ss != '=')
+                               while (*ss && *ss != '=')
                                        ss++;
-
-                                       i = ss - k->text;
-                                       if (s+i+1 >= be)
+                               i = ss - k->text;
+                               if (s + i + 1 >= be)
                                        break;
-                                       if (s != t)
-                                       *s++ = ',';
-                                       strncpy(s, k->text, (unsigned)i);
-                                       s += i;
-                               }
 
-                               if (s+2 >= be)
+                               if (s != t)
+                               *s++ = ',';
+                               strncpy(s, k->text,
+                                   (unsigned)i);
+                               s += i;
+                       }
+                       if (s+2 >= be)
                                break;
 
-                               *s++ = '"';
-                               *s = '\0';
+                       *s++ = '"';
+                       *s = '\0';
 
-                               ctl_putdata(buf, (unsigned)( s - buf ), 0);
-                       }
-                       break;
+                       ctl_putdata(buf, (unsigned)( s - buf ),
+                           0);
+               }
+               break;
+
+#ifdef PUBKEY
+       case CS_PRIVATE:
+               if (private_key_file != NULL)
+                       ctl_putstr(sys_var[CS_PRIVATE].text,
+                           private_key_file, strlen(private_key_file));
+               break;
+
+       case CS_PUBLIC:
+               if (public_key_file != NULL)
+                       ctl_putstr(sys_var[CS_PUBLIC].text,
+                           public_key_file, strlen(public_key_file));
+               break;
+#endif /* PUBKEY */
        }
 }
 
@@ -1263,187 +1326,243 @@ ctl_putpeer(
        struct peer *peer
        )
 {
+#ifdef PUBKEY
+       u_int len;
+#endif /* PUBKEY */
+
        switch (varid) {
-               case CP_CONFIG:
+
+       case CP_CONFIG:
                ctl_putuint(peer_var[CP_CONFIG].text,
-                           (unsigned)((peer->flags & FLAG_CONFIG) != 0));
+                   (unsigned)((peer->flags & FLAG_CONFIG) != 0));
                break;
-               case CP_AUTHENABLE:
+
+       case CP_AUTHENABLE:
                ctl_putuint(peer_var[CP_AUTHENABLE].text,
-                           (unsigned)((peer->flags & FLAG_AUTHENABLE) != 0));
+                   (unsigned)((peer->flags & FLAG_AUTHENABLE) != 0));
                break;
-               case CP_AUTHENTIC:
+
+       case CP_AUTHENTIC:
                ctl_putuint(peer_var[CP_AUTHENTIC].text,
-                           (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0));
+                   (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0));
                break;
-               case CP_SRCADR:
+
+       case CP_SRCADR:
                ctl_putadr(peer_var[CP_SRCADR].text,
-                  peer->srcadr.sin_addr.s_addr);
+                   peer->srcadr.sin_addr.s_addr);
                break;
-               case CP_SRCPORT:
+
+       case CP_SRCPORT:
                ctl_putuint(peer_var[CP_SRCPORT].text,
-                       ntohs(peer->srcadr.sin_port));
-               break;
-               case CP_DSTADR:
-               ctl_putadr(peer_var[CP_DSTADR].text,
-                  peer->processed ?
-                  peer->cast_flags & MDF_BCAST ?
-                  peer->dstadr->bcast.sin_addr.s_addr:
-                  peer->cast_flags ?
-                  peer->dstadr->sin.sin_addr.s_addr ?
-                  peer->dstadr->sin.sin_addr.s_addr:
-                  peer->dstadr->bcast.sin_addr.s_addr:
-                  8 : 12);
-               break;
-               case CP_DSTPORT:
+                   ntohs(peer->srcadr.sin_port));
+               break;
+
+       case CP_DSTADR:
+               ctl_putadr(peer_var[CP_DSTADR].text, peer->processed ?
+                   peer->cast_flags & MDF_BCAST ?
+                   peer->dstadr->bcast.sin_addr.s_addr:
+                   peer->cast_flags ?
+                   peer->dstadr->sin.sin_addr.s_addr ?
+                   peer->dstadr->sin.sin_addr.s_addr:
+                   peer->dstadr->bcast.sin_addr.s_addr: 8 : 12);
+               break;
+
+       case CP_DSTPORT:
                ctl_putuint(peer_var[CP_DSTPORT].text,
-                           (u_long)(peer->dstadr
-                            ? ntohs(peer->dstadr->sin.sin_port)
-                            : 0
-                            )
-                           );
+                   (u_long)(peer->dstadr ?
+                   ntohs(peer->dstadr->sin.sin_port) : 0));
                break;
-               case CP_LEAP:
+
+       case CP_LEAP:
                ctl_putuint(peer_var[CP_LEAP].text, peer->leap);
                break;
-               case CP_HMODE:
+
+       case CP_HMODE:
                ctl_putuint(peer_var[CP_HMODE].text, peer->hmode);
                break;
-               case CP_STRATUM:
+
+       case CP_STRATUM:
                ctl_putuint(peer_var[CP_STRATUM].text, peer->stratum);
                break;
-               case CP_PPOLL:
+
+       case CP_PPOLL:
                ctl_putuint(peer_var[CP_PPOLL].text, peer->ppoll);
                break;
-               case CP_HPOLL:
+
+       case CP_HPOLL:
                ctl_putuint(peer_var[CP_HPOLL].text, peer->hpoll);
                break;
-               case CP_PRECISION:
-               ctl_putint(peer_var[CP_PRECISION].text, peer->precision);
+
+       case CP_PRECISION:
+               ctl_putint(peer_var[CP_PRECISION].text,
+                   peer->precision);
                break;
-               case CP_ROOTDELAY:
-               ctl_putdbl(peer_var[CP_ROOTDELAY].text, peer->rootdelay * 1e3);
+
+       case CP_ROOTDELAY:
+               ctl_putdbl(peer_var[CP_ROOTDELAY].text,
+                   peer->rootdelay * 1e3);
                break;
-               case CP_ROOTDISPERSION:
+
+       case CP_ROOTDISPERSION:
                ctl_putdbl(peer_var[CP_ROOTDISPERSION].text,
-                       peer->rootdispersion * 1e3);
+                   peer->rootdispersion * 1e3);
                break;
-               case CP_REFID:
-               if (peer->stratum > 1)
-                   {
+
+       case CP_REFID:
+               if (peer->stratum > 1) {
                        if (peer->flags & FLAG_REFCLOCK)
                            ctl_putadr(peer_var[CP_REFID].text,
-                                      peer->srcadr.sin_addr.s_addr);
+                               peer->srcadr.sin_addr.s_addr);
                        else
                            ctl_putadr(peer_var[CP_REFID].text,
-                                      peer->refid);
-                   }
-               else
+                               peer->refid);
+               } else {
                        ctl_putid(peer_var[CP_REFID].text,
-                                 (char *)&peer->refid);
+                           (char *)&peer->refid);
+               }
                break;
-               case CP_REFTIME:
+
+       case CP_REFTIME:
                ctl_putts(peer_var[CP_REFTIME].text, &peer->reftime);
                break;
-               case CP_ORG:
+
+       case CP_ORG:
                ctl_putts(peer_var[CP_ORG].text, &peer->org);
                break;
-               case CP_REC:
+
+       case CP_REC:
                ctl_putts(peer_var[CP_REC].text, &peer->rec);
                break;
-               case CP_XMT:
+
+       case CP_XMT:
                ctl_putts(peer_var[CP_XMT].text, &peer->xmt);
                break;
-               case CP_REACH:
+
+       case CP_REACH:
                ctl_puthex(peer_var[CP_REACH].text, peer->reach);
                break;
-               case CP_FLASH:
+
+       case CP_FLASH:
                ctl_puthex(peer_var[CP_FLASH].text, peer->flash);
                break;
-               case CP_VALID:
+
+       case CP_VALID:
                ctl_putuint(peer_var[CP_VALID].text, peer->valid);
                break;
-               case CP_TIMER:
+       case CP_TIMER:
                ctl_putuint(peer_var[CP_TIMER].text,
                    peer->nextdate - current_time);
                break;
-               case CP_DELAY:
+
+       case CP_DELAY:
                ctl_putdbl(peer_var[CP_DELAY].text, peer->delay * 1e3);
                break;
-               case CP_OFFSET:
-               ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset * 1e3);
+
+       case CP_OFFSET:
+               ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset *
+                   1e3);
                break;
-               case CP_JITTER:
+
+       case CP_JITTER:
                ctl_putdbl(peer_var[CP_JITTER].text,
                    SQRT(peer->variance) * 1e3);
                break;
-               case CP_DISPERSION:
-               ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp * 1e3);
+
+       case CP_DISPERSION:
+               ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp *
+                   1e3);
                break;
-               case CP_KEYID:
+
+       case CP_KEYID:
                ctl_putuint(peer_var[CP_KEYID].text, peer->keyid);
                break;
-               case CP_FILTDELAY:
+
+       case CP_FILTDELAY:
                ctl_putarray(peer_var[CP_FILTDELAY].text,
                    peer->filter_delay, (int)peer->filter_nextpt);
                break;
-               case CP_FILTOFFSET:
+
+       case CP_FILTOFFSET:
                ctl_putarray(peer_var[CP_FILTOFFSET].text,
                    peer->filter_offset, (int)peer->filter_nextpt);
                break;
-               case CP_FILTERROR:
+
+       case CP_FILTERROR:
                ctl_putarray(peer_var[CP_FILTERROR].text,
                    peer->filter_disp, (int)peer->filter_nextpt);
                break;
-               case CP_PMODE:
+
+       case CP_PMODE:
                ctl_putuint(peer_var[CP_PMODE].text, peer->pmode);
                break;
-               case CP_RECEIVED:
+
+       case CP_RECEIVED:
                ctl_putuint(peer_var[CP_RECEIVED].text, peer->received);
                break;
-               case CP_SENT:
+
+       case CP_SENT:
                ctl_putuint(peer_var[CP_SENT].text, peer->sent);
                break;
-               case CP_VARLIST:
-                       {
-                               char buf[CTL_MAX_DATA_LEN];
-                               register char *s, *t, *be;
-                               register int i;
-                               register struct ctl_var *k;
-
-                               s = buf;
-                               be = buf + sizeof(buf) - strlen(peer_var[CP_VARLIST].text) - 4;
-                               if (s > be)
-                               break;  /* really long var name 8-( - Killer */
-
-                               strcpy(s, peer_var[CP_VARLIST].text);
-                               strcat(s, "=\"");
-                               s += strlen(s);
-                               t = s;
-
-                               for (k = peer_var; !(k->flags &EOV); k++)
-                               {
-                                       if (k->flags & PADDING)
+
+       case CP_VARLIST:
+               {
+                       char buf[CTL_MAX_DATA_LEN];
+                       register char *s, *t, *be;
+                       register int i;
+                       register struct ctl_var *k;
+
+                       s = buf;
+                       be = buf + sizeof(buf) -
+                           strlen(peer_var[CP_VARLIST].text) - 4;
+                       if (s > be)
+                               break;  /* really long var name */
+
+                       strcpy(s, peer_var[CP_VARLIST].text);
+                       strcat(s, "=\"");
+                       s += strlen(s);
+                       t = s;
+                       for (k = peer_var; !(k->flags &EOV); k++) {
+                               if (k->flags & PADDING)
                                        continue;
 
-                                       i = strlen(k->text);
-                                       if (s+i+1 >= be)
-                                       break;
-                                       if (s != t)
-                                       *s++ = ',';
-                                       strcpy(s, k->text);
-                                       s += i;
-                               }
+                               i = strlen(k->text);
+                               if (s + i + 1 >= be)
+                               break;
 
-                               if (s+2 >= be)
+                               if (s != t)
+                                       *s++ = ',';
+                               strcpy(s, k->text);
+                               s += i;
+                       }
+                       if (s+2 >= be)
                                break;
 
-                               *s++ = '"';
-                               *s = '\0';
+                       *s++ = '"';
+                       *s = '\0';
+                       ctl_putdata(buf, (unsigned)(s - buf), 0);
+               }
+               break;
+#ifdef PUBKEY
+       case CP_PUBLIC:
+               if (peer->keystr == 0)
+                       break;
+               len = strlen(peer->keystr);
+               ctl_putstr(peer_var[CP_PUBLIC].text, peer->keystr, len);
 
-                               ctl_putdata(buf, (unsigned)(s - buf), 0);
-                       }
+       case CP_SESKEY:
+               if (peer->pcookie != 0)
+                       ctl_puthex(peer_var[CP_SESKEY].text, peer->pcookie);
+               if (peer->hcookie != 0)
+                       ctl_puthex(peer_var[CP_SASKEY].text, peer->hcookie);
+               break;
+
+       case CP_AUTOSEQ:
+               if (peer->keynumber == 0)
                        break;
+               ctl_putint(peer_var[CP_AUTOSEQ].text, peer->recseq);
+               ctl_puthex(peer_var[CP_INITKEY].text, peer->finlkey);
+               ctl_putint(peer_var[CP_INITSEQ].text, peer->finlseq);
+#endif /* PUBKEY */
        }
 }
 
@@ -1460,132 +1579,148 @@ ctl_putclock(
        )
 {
        switch(varid) {
-               case CC_TYPE:
+
+       case CC_TYPE:
                if (mustput || clock_stat->clockdesc == NULL
                        || *(clock_stat->clockdesc) == '\0') {
                        ctl_putuint(clock_var[CC_TYPE].text, clock_stat->type);
                }
                break;
-               case CC_TIMECODE:
-               ctl_putstr(clock_var[CC_TIMECODE].text, clock_stat->p_lastcode,
-                          (unsigned)clock_stat->lencode);
+       case CC_TIMECODE:
+               ctl_putstr(clock_var[CC_TIMECODE].text,
+                   clock_stat->p_lastcode,
+                   (unsigned)clock_stat->lencode);
                break;
-               case CC_POLL:
+
+       case CC_POLL:
                ctl_putuint(clock_var[CC_POLL].text, clock_stat->polls);
                break;
-               case CC_NOREPLY:
-               ctl_putuint(clock_var[CC_NOREPLY].text, clock_stat->noresponse);
+
+       case CC_NOREPLY:
+               ctl_putuint(clock_var[CC_NOREPLY].text,
+                   clock_stat->noresponse);
                break;
-               case CC_BADFORMAT:
-               ctl_putuint(clock_var[CC_BADFORMAT].text, clock_stat->badformat);
+
+       case CC_BADFORMAT:
+               ctl_putuint(clock_var[CC_BADFORMAT].text,
+                   clock_stat->badformat);
                break;
-               case CC_BADDATA:
-               ctl_putuint(clock_var[CC_BADDATA].text, clock_stat->baddata);
+
+       case CC_BADDATA:
+               ctl_putuint(clock_var[CC_BADDATA].text,
+                   clock_stat->baddata);
                break;
-               case CC_FUDGETIME1:
-               if (mustput || (clock_stat->haveflags & CLK_HAVETIME1)) {
+
+       case CC_FUDGETIME1:
+               if (mustput || (clock_stat->haveflags & CLK_HAVETIME1))
                        ctl_putdbl(clock_var[CC_FUDGETIME1].text,
-                               clock_stat->fudgetime1 * 1e3);
-               }
+                           clock_stat->fudgetime1 * 1e3);
                break;
-               case CC_FUDGETIME2:
-               if (mustput || (clock_stat->haveflags & CLK_HAVETIME2)) {
-                       ctl_putdbl(clock_var[CC_FUDGETIME2].text,
-                               clock_stat->fudgetime2 * 1e3);
-               }
+
+       case CC_FUDGETIME2:
+               if (mustput || (clock_stat->haveflags & CLK_HAVETIME2))                         ctl_putdbl(clock_var[CC_FUDGETIME2].text,
+                           clock_stat->fudgetime2 * 1e3);
                break;
-               case CC_FUDGEVAL1:
+
+       case CC_FUDGEVAL1:
                if (mustput || (clock_stat->haveflags & CLK_HAVEVAL1))
                        ctl_putint(clock_var[CC_FUDGEVAL1].text,
-                                  clock_stat->fudgeval1);
+                           clock_stat->fudgeval1);
                break;
-               case CC_FUDGEVAL2:
+
+       case CC_FUDGEVAL2:
                if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) {
                        if (clock_stat->fudgeval1 > 1)
-                       ctl_putadr(clock_var[CC_FUDGEVAL2].text,
-                                  (u_int32)clock_stat->fudgeval2);
+                               ctl_putadr(clock_var[CC_FUDGEVAL2].text,
+                                   (u_int32)clock_stat->fudgeval2);
                        else
-                       ctl_putid(clock_var[CC_FUDGEVAL2].text,
-                                 (char *)&clock_stat->fudgeval2);
+                               ctl_putid(clock_var[CC_FUDGEVAL2].text,
+                                   (char *)&clock_stat->fudgeval2);
                }
                break;
-               case CC_FLAGS:
-               if (mustput || (clock_stat->haveflags &
-                               (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4)))
-                       ctl_putuint(clock_var[CC_FLAGS].text, clock_stat->flags);
+
+       case CC_FLAGS:
+               if (mustput || (clock_stat->haveflags & (CLK_HAVEFLAG1 |
+                   CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4)))
+                       ctl_putuint(clock_var[CC_FLAGS].text,
+                           clock_stat->flags);
                break;
-               case CC_DEVICE:
-               if (clock_stat->clockdesc == NULL || *(clock_stat->clockdesc) == '\0') {
+
+       case CC_DEVICE:
+               if (clock_stat->clockdesc == NULL ||
+                   *(clock_stat->clockdesc) == '\0') {
                        if (mustput)
-                               ctl_putstr(clock_var[CC_DEVICE].text, "", 0);
+                               ctl_putstr(clock_var[CC_DEVICE].text,
+                                   "", 0);
                } else {
-                       ctl_putstr(clock_var[CC_DEVICE].text, clock_stat->clockdesc,
-                                  strlen(clock_stat->clockdesc));
+                       ctl_putstr(clock_var[CC_DEVICE].text,
+                           clock_stat->clockdesc,
+                           strlen(clock_stat->clockdesc));
                }
                break;
-               case CC_VARLIST:
-                       {
-                               char buf[CTL_MAX_DATA_LEN];
-                               register char *s, *t, *be;
-                               register const char *ss;
-                               register int i;
-                               register struct ctl_var *k;
-
-                               s = buf;
-                           be = buf + sizeof(buf);
-                           if (s + strlen(clock_var[CC_VARLIST].text) + 4 > be)
-                               break;  /* really long var name 8-( - Killer */
-
-                               strcpy(s, clock_var[CC_VARLIST].text);
-                               strcat(s, "=\"");
-                               s += strlen(s);
-                               t = s;
-
-                               for (k = clock_var; !(k->flags &EOV); k++)
-                               {
-                                       if (k->flags & PADDING)
+
+       case CC_VARLIST:
+               {
+                       char buf[CTL_MAX_DATA_LEN];
+                       register char *s, *t, *be;
+                       register const char *ss;
+                       register int i;
+                       register struct ctl_var *k;
+
+                       s = buf;
+                       be = buf + sizeof(buf);
+                       if (s + strlen(clock_var[CC_VARLIST].text) + 4 >
+                           be)
+                               break;  /* really long var name */
+
+                       strcpy(s, clock_var[CC_VARLIST].text);
+                       strcat(s, "=\"");
+                       s += strlen(s);
+                       t = s;
+
+                       for (k = clock_var; !(k->flags &EOV); k++) {
+                               if (k->flags & PADDING)
                                        continue;
 
-                                       i = strlen(k->text);
-                                       if (s+i+1 >= be)
+                               i = strlen(k->text);
+                               if (s + i + 1 >= be)
                                        break;
-                                       if (s != t)
-                                       *s++ = ',';
-                                       strcpy(s, k->text);
-                                       s += i;
-                               }
 
-                               for (k = clock_stat->kv_list; k && !(k->flags &EOV); k++)
-                               {
-                                       if (k->flags & PADDING)
+                               if (s != t)
+                               *s++ = ',';
+                               strcpy(s, k->text);
+                               s += i;
+                       }
+
+                       for (k = clock_stat->kv_list; k && !(k->flags &
+                           EOV); k++) {
+                               if (k->flags & PADDING)
                                        continue;
 
-                                       ss = k->text;
-                                       if (!ss)
+                               ss = k->text;
+                               if (!ss)
                                        continue;
 
-                                       while (*ss && *ss != '=')
+                               while (*ss && *ss != '=')
                                        ss++;
-
-                                       i = ss - k->text;
-                                       if (s+i+1 >= be)
+                               i = ss - k->text;
+                               if (s+i+1 >= be)
                                        break;
-                                       if (s != t)
-                                       *s++ = ',';
-                                       strncpy(s, k->text, (unsigned)i);
-                                       s += i;
-                                       *s = '\0';
-                               }
 
-                               if (s+2 >= be)
-                               break;
-
-                               *s++ = '"';
+                               if (s != t)
+                                       *s++ = ',';
+                               strncpy(s, k->text, (unsigned)i);
+                               s += i;
                                *s = '\0';
-
-                               ctl_putdata(buf, (unsigned)( s - buf ), 0);
                        }
-                       break;
+                       if (s+2 >= be)
+                               break;
+
+                       *s++ = '"';
+                       *s = '\0';
+                       ctl_putdata(buf, (unsigned)( s - buf ), 0);
+               }
+               break;
        }
 }
 #endif
@@ -1610,15 +1745,14 @@ ctl_getitem(
        /*
         * Delete leading commas and white space
         */
-       while (reqpt < reqend && (*reqpt == ',' || isspace((int)*reqpt))) {
+       while (reqpt < reqend && (*reqpt == ',' ||
+           isspace((int)*reqpt)))
                reqpt++;
-       }
-
        if (reqpt >= reqend)
-               return 0;
+               return (0);
 
        if (var_list == (struct ctl_var *)0)
-               return &eol;
+               return (&eol);
 
        /*
         * Look for a first character match on the tag.  If we find
@@ -1629,7 +1763,8 @@ ctl_getitem(
        while (!(v->flags & EOV)) {
                if (!(v->flags & PADDING) && *cp == *(v->text)) {
                        tp = v->text;
-                       while (*tp != '\0' && *tp != '=' && cp < reqend && *cp == *tp) {
+                       while (*tp != '\0' && *tp != '=' && cp <
+                           reqend && *cp == *tp) {
                                cp++;
                                tp++;
                        }
@@ -1647,9 +1782,11 @@ ctl_getitem(
                                if (*cp == '=') {
                                        cp++;
                                        tp = buf;
-                                       while (cp < reqend && isspace((int)*cp))
+                                       while (cp < reqend &&
+                                           isspace((int)*cp))
                                                cp++;
-                                       while (cp < reqend && *cp != ',')
+                                       while (cp < reqend && *cp !=
+                                           ',')
                                                *tp++ = *cp++;
                                        if (cp < reqend)
                                                cp++;
@@ -1658,7 +1795,7 @@ ctl_getitem(
                                                *(--tp) = '\0';
                                        reqpt = cp;
                                        *data = buf;
-                                       return v;
+                                       return (v);
                                }
                        }
                        cp = reqpt;
@@ -1701,7 +1838,7 @@ control_unspec(
 
 /*
  * read_status - return either a list of associd's, or a particular
- *              peer's status.
+ * peer's status.
  */
 /*ARGSUSED*/
 static void
@@ -1712,14 +1849,14 @@ read_status(
 {
        register int i;
        register struct peer *peer;
-       u_short ass_stat[CTL_MAX_DATA_LEN/sizeof(u_short)];
+       u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)];
 
 #ifdef DEBUG
-       if (debug >= 2)
+       if (debug > 2)
                printf("read_status: ID %d\n", res_associd);
 #endif
        /*
-        * Two choices here.  If the specified association ID is
+        * Two choices here. If the specified association ID is
         * zero we return all known assocation ID's.  Otherwise
         * we return a bunch of stuff about the particular peer.
         */
@@ -1730,19 +1867,22 @@ read_status(
                rpkt.status = htons(ctlsysstatus());
                for (i = 0; i < HASH_SIZE; i++) {
                        for (peer = assoc_hash[i]; peer != 0;
-                                peer = peer->ass_next) {
+                               peer = peer->ass_next) {
                                ass_stat[n++] = htons(peer->associd);
-                               ass_stat[n++] = htons(ctlpeerstatus(peer));
-                               if (n == CTL_MAX_DATA_LEN/sizeof(u_short)) {
+                               ass_stat[n++] =
+                                   htons(ctlpeerstatus(peer));
+                               if (n ==
+                                   CTL_MAX_DATA_LEN/sizeof(u_short)) {
                                        ctl_putdata((char *)ass_stat,
-                                                       n * sizeof(u_short), 1);
+                                           n * sizeof(u_short), 1);
                                        n = 0;
                                }
                        }
                }
 
                if (n != 0)
-                       ctl_putdata((char *)ass_stat, n * sizeof(u_short), 1);
+                       ctl_putdata((char *)ass_stat, n *
+                           sizeof(u_short), 1);
                ctl_flushpkt(0);
        } else {
                peer = findpeerbyassoc((int)res_associd);
@@ -1755,8 +1895,8 @@ read_status(
                        if (res_authokay)
                                peer->num_events = 0;
                        /*
-                        * For now, output everything we know about the peer.
-                        * May be more selective later.
+                        * For now, output everything we know about the
+                        * peer. May be more selective later.
                         */
                        for (cp = def_peer_var; *cp != 0; cp++)
                                ctl_putpeer((int)*cp, peer);
@@ -1780,11 +1920,11 @@ read_variables(
        register int i;
        char *valuep;
        u_char *wants;
-       unsigned int gotvar = (CS_MAXCODE>CP_MAXCODE) ? (CS_MAXCODE+1) : (CP_MAXCODE+1);
-
+       unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE +
+           1) : (CP_MAXCODE + 1);
        if (res_associd == 0) {
                /*
-                * Wants system variables.      Figure out which he wants
+                * Wants system variables. Figure out which he wants
                 * and give them to him.
                 */
                rpkt.status = htons(ctlsysstatus());
@@ -1796,13 +1936,15 @@ read_variables(
                gotvar = 0;
                while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
                        if (v->flags & EOV) {
-                               if ((v = ctl_getitem(ext_sys_var, &valuep)) != 0) {
+                               if ((v = ctl_getitem(ext_sys_var,
+                                   &valuep)) != 0) {
                                        if (v->flags & EOV) {
                                                ctl_error(CERR_UNKNOWNVAR);
                                                free((char *)wants);
                                                return;
                                        }
-                                       wants[CS_MAXCODE+1+v->code] = 1;
+                                       wants[CS_MAXCODE + 1 +
+                                           v->code] = 1;
                                        gotvar = 1;
                                        continue;
                                } else {
@@ -1815,27 +1957,31 @@ read_variables(
                if (gotvar) {
                        for (i = 1; i <= CS_MAXCODE; i++)
                                if (wants[i])
-                               ctl_putsys(i);
-                       for (i = 0; ext_sys_var && !(ext_sys_var[i].flags & EOV); i++)
-                               if (wants[i+CS_MAXCODE+1])
-                               ctl_putdata(ext_sys_var[i].text,
-                                               strlen(ext_sys_var[i].text), 0);
+                                       ctl_putsys(i);
+                       for (i = 0; ext_sys_var &&
+                           !(ext_sys_var[i].flags & EOV); i++)
+                               if (wants[i + CS_MAXCODE + 1])
+                                       ctl_putdata(ext_sys_var[i].text,
+                                           strlen(ext_sys_var[i].text),
+                                           0);
                } else {
                        register u_char *cs;
                        register struct ctl_var *kv;
 
                        for (cs = def_sys_var; *cs != 0; cs++)
                                ctl_putsys((int)*cs);
-                       for (kv = ext_sys_var; kv && !(kv->flags & EOV); kv++)
+                       for (kv = ext_sys_var; kv && !(kv->flags & EOV);
+                           kv++)
                                if (kv->flags & DEF)
-                               ctl_putdata(kv->text, strlen(kv->text), 0);
+                                       ctl_putdata(kv->text,
+                                           strlen(kv->text), 0);
                }
                free((char *)wants);
        } else {
                register struct peer *peer;
 
                /*
-                * Wants info for a particular peer.  See if we know
+                * Wants info for a particular peer. See if we know
                 * the guy.
                 */
                peer = findpeerbyassoc((int)res_associd);
@@ -1843,7 +1989,6 @@ read_variables(
                        ctl_error(CERR_BADASSOC);
                        return;
                }
-
                rpkt.status = htons(ctlpeerstatus(peer));
                if (res_authokay)
                        peer->num_events = 0;
@@ -1862,7 +2007,7 @@ read_variables(
                if (gotvar) {
                        for (i = 1; i <= CP_MAXCODE; i++)
                                if (wants[i])
-                               ctl_putpeer(i, peer);
+                                       ctl_putpeer(i, peer);
                } else {
                        register u_char *cp;
 
@@ -1876,8 +2021,8 @@ read_variables(
 
 
 /*
- * write_variables - write into variables.     We only allow leap bit writing
- *                      this way.
+ * write_variables - write into variables. We only allow leap bit
+ * writing this way.
  */
 /*ARGSUSED*/
 static void
@@ -1890,7 +2035,6 @@ write_variables(
        register int ext_var;
        char *valuep;
        long val;
-      /*int leapind, leapwarn;*/
 
        /*
         * If he's trying to write into a peer tell him no way
@@ -1906,20 +2050,14 @@ write_variables(
        rpkt.status = htons(ctlsysstatus());
 
        /*
-        * Set flags to not-in-sync so we can tell when we get something.
-        */
-       /*
-       leapind = ~0;
-       leapwarn = ~0;
-       */
-
-       /*
-        * Look through the variables.  Dump out at the first sign of trouble.
+        * Look through the variables. Dump out at the first sign of
+        * trouble.
         */
        while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
                ext_var = 0;
                if (v->flags & EOV) {
-                       if ((v = ctl_getitem(ext_sys_var, &valuep)) != 0) {
+                       if ((v = ctl_getitem(ext_sys_var, &valuep)) !=
+                           0) {
                                if (v->flags & EOV) {
                                        ctl_error(CERR_UNKNOWNVAR);
                                        return;
@@ -1933,7 +2071,8 @@ write_variables(
                        ctl_error(CERR_PERMISSION);
                        return;
                }
-               if (!ext_var && (*valuep == '\0' || !atoint(valuep, &val))) {
+               if (!ext_var && (*valuep == '\0' || !atoint(valuep,
+                   &val))) {
                        ctl_error(CERR_BADFMT);
                        return;
                }
@@ -1943,7 +2082,8 @@ write_variables(
                }
 
                if (ext_var) {
-                       char *s = (char *)emalloc(strlen(v->text)+strlen(valuep)+2);
+                       char *s = (char *)emalloc(strlen(v->text) +
+                           strlen(valuep) + 2);
                        const char *t;
                        char *tt = s;
 
@@ -1953,24 +2093,24 @@ write_variables(
 
                        *tt++ = '=';
                        strcat(tt, valuep);
-
                        set_sys_var(s, strlen(s)+1, v->flags);
                        free(s);
                } else {
                        /*
-                        * This one seems sane.  Save it.
+                        * This one seems sane. Save it.
                         */
                        switch(v->code) {
-                               case CS_LEAP:
-                               default:
-                               ctl_error(CERR_UNSPEC); /* our fault, really */
+
+                       case CS_LEAP:
+                       default:
+                               ctl_error(CERR_UNSPEC); /* really */
                                return;
                        }
                }
        }
 
        /*
-        * If we got anything, do it.
+        * If we got anything, do it. xxx nothing to do ***
         */
        /*
          if (leapind != ~0 || leapwarn != ~0) {
@@ -2009,18 +2149,20 @@ read_clock_status(
        struct refclockstat clock_stat;
 
        if (res_associd == 0) {
+
                /*
                 * Find a clock for this jerk.  If the system peer
                 * is a clock use it, else search the hash tables
                 * for one.
                 */
-               if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK)) {
+               if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK))
+                   {
                        peer = sys_peer;
                } else {
                        peer = 0;
                        for (i = 0; peer == 0 && i < HASH_SIZE; i++) {
                                for (peer = assoc_hash[i]; peer != 0;
-                                        peer = peer->ass_next) {
+                                       peer = peer->ass_next) {
                                        if (peer->flags & FLAG_REFCLOCK)
                                                break;
                                }
@@ -2039,30 +2181,32 @@ read_clock_status(
        }
 
        /*
-        * If we got here we have a peer which is a clock.      Get his status.
+        * If we got here we have a peer which is a clock. Get his
+        * status.
         */
        clock_stat.kv_list = (struct ctl_var *)0;
-
-       refclock_control(&peer->srcadr, (struct refclockstat *)0, &clock_stat);
+       refclock_control(&peer->srcadr, (struct refclockstat *)0,
+           &clock_stat);
 
        /*
         * Look for variables in the packet.
         */
        rpkt.status = htons(ctlclkstatus(&clock_stat));
-       gotvar = CC_MAXCODE+1+count_var(clock_stat.kv_list);
+       gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list);
        wants = (u_char *)emalloc(gotvar);
        memset((char*)wants, 0, gotvar);
        gotvar = 0;
        while ((v = ctl_getitem(clock_var, &valuep)) != 0) {
                if (v->flags & EOV) {
-                       if ((v = ctl_getitem(clock_stat.kv_list, &valuep)) != 0) {
+                       if ((v = ctl_getitem(clock_stat.kv_list,
+                           &valuep)) != 0) {
                                if (v->flags & EOV) {
                                        ctl_error(CERR_UNKNOWNVAR);
                                        free((char*)wants);
                                        free_varlist(clock_stat.kv_list);
                                        return;
                                }
-                               wants[CC_MAXCODE+1+v->code] = 1;
+                               wants[CC_MAXCODE + 1 + v->code] = 1;
                                gotvar = 1;
                                continue;
                        } else {
@@ -2077,19 +2221,23 @@ read_clock_status(
                for (i = 1; i <= CC_MAXCODE; i++)
                        if (wants[i])
                        ctl_putclock(i, &clock_stat, 1);
-               for (i = 0; clock_stat.kv_list && !(clock_stat.kv_list[i].flags & EOV); i++)
-                       if (wants[i+CC_MAXCODE+1])
-                       ctl_putdata(clock_stat.kv_list[i].text,
-                                       strlen(clock_stat.kv_list[i].text), 0);
+               for (i = 0; clock_stat.kv_list &&
+                   !(clock_stat.kv_list[i].flags & EOV); i++)
+                       if (wants[i + CC_MAXCODE + 1])
+                               ctl_putdata(clock_stat.kv_list[i].text,
+                                   strlen(clock_stat.kv_list[i].text),
+                                   0);
        } else {
                register u_char *cc;
                register struct ctl_var *kv;
 
                for (cc = def_clock_var; *cc != 0; cc++)
                        ctl_putclock((int)*cc, &clock_stat, 0);
-               for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++)
+               for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV);
+                   kv++)
                        if (kv->flags & DEF)
-                       ctl_putdata(kv->text, strlen(kv->text), 0);
+                               ctl_putdata(kv->text, strlen(kv->text),
+                                   0);
        }
 
        free((char*)wants);
@@ -2114,11 +2262,10 @@ write_clock_status(
 }
 
 /*
- * Trap support from here on down.     We send async trap messages when the
- * upper levels report trouble.  Traps can by set either by control
+ * Trap support from here on down. We send async trap messages when the
+ * upper levels report trouble. Traps can by set either by control
  * messages or by configuration.
  */
-
 /*
  * set_trap - set a trap in response to a control message
  */
@@ -2150,7 +2297,7 @@ set_trap(
         * an error if it can't assign the trap.
         */
        if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
-                       (int)res_version))
+           (int)res_version))
                ctl_error(CERR_NORESOURCE);
        ctl_flushpkt(0);
 }
@@ -2168,11 +2315,10 @@ unset_trap(
        int traptype;
 
        /*
-        * We don't prevent anyone from removing his own
-        * trap unless the trap is configured.  Note we also
-        * must be aware of the possibility that restriction
-        * flags were changed since this guy last set his trap.
-        * Set the trap type based on this.
+        * We don't prevent anyone from removing his own trap unless the
+        * trap is configured. Note we also must be aware of the
+        * possibility that restriction flags were changed since this
+        * guy last set his trap. Set the trap type based on this.
         */
        traptype = TRAP_TYPE_PRIO;
        if (restrict_mask & RES_LPTRAP)
@@ -2207,69 +2353,77 @@ ctlsettrap(
         */
        if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
                switch (traptype) {
-                       case TRAP_TYPE_CONFIG:
+
+               case TRAP_TYPE_CONFIG:
                        tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
                        break;
-                       case TRAP_TYPE_PRIO:
+
+               case TRAP_TYPE_PRIO:
                        if (tp->tr_flags & TRAP_CONFIGURED)
-                               return 1;       /* don't change anything */
+                               return (1); /* don't change anything */
                        tp->tr_flags = TRAP_INUSE;
                        break;
-                       case TRAP_TYPE_NONPRIO:
+
+               case TRAP_TYPE_NONPRIO:
                        if (tp->tr_flags & TRAP_CONFIGURED)
-                               return 1;       /* don't change anything */
+                               return (1); /* don't change anything */
                        tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
                        break;
                }
                tp->tr_settime = current_time;
                tp->tr_resets++;
-               return 1;
+               return (1);
        }
 
        /*
         * First we heard of this guy.  Try to find a trap structure
         * for him to use, clearing out lesser priority guys if we
-        * have to.  Clear out anyone who's expired while we're at it.
+        * have to. Clear out anyone who's expired while we're at it.
         */
        tptouse = NULL;
        for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
                if ((tp->tr_flags & TRAP_INUSE) &&
-                       !(tp->tr_flags & TRAP_CONFIGURED) &&
-                       ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
+                   !(tp->tr_flags & TRAP_CONFIGURED) &&
+                   ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
                        tp->tr_flags = 0;
                        num_ctl_traps--;
                }
-
                if (!(tp->tr_flags & TRAP_INUSE)) {
                        tptouse = tp;
                } else if (!(tp->tr_flags & TRAP_CONFIGURED)) {
                        switch (traptype) {
-                               case TRAP_TYPE_CONFIG:
+
+                       case TRAP_TYPE_CONFIG:
                                if (tptouse == NULL) {
                                        tptouse = tp;
                                        break;
                                }
-                               if (tptouse->tr_flags & TRAP_NONPRIO
-                                       && !(tp->tr_flags & TRAP_NONPRIO))
+                               if (tptouse->tr_flags & TRAP_NONPRIO &&
+                                   !(tp->tr_flags & TRAP_NONPRIO))
                                        break;
+
                                if (!(tptouse->tr_flags & TRAP_NONPRIO)
-                                       && tp->tr_flags & TRAP_NONPRIO) {
+                                   && tp->tr_flags & TRAP_NONPRIO) {
                                        tptouse = tp;
                                        break;
                                }
-                               if (tptouse->tr_origtime < tp->tr_origtime)
+                               if (tptouse->tr_origtime <
+                                   tp->tr_origtime)
                                        tptouse = tp;
                                break;
-                               case TRAP_TYPE_PRIO:
+
+                       case TRAP_TYPE_PRIO:
                                if (tp->tr_flags & TRAP_NONPRIO) {
                                        if (tptouse == NULL ||
-                                               (tptouse->tr_flags & TRAP_INUSE
-                                                && tptouse->tr_origtime
-                                                < tp->tr_origtime))
+                                           (tptouse->tr_flags &
+                                           TRAP_INUSE &&
+                                           tptouse->tr_origtime <
+                                           tp->tr_origtime))
                                                tptouse = tp;
                                }
                                break;
-                               case TRAP_TYPE_NONPRIO:
+
+                       case TRAP_TYPE_NONPRIO:
                                break;
                        }
                }
@@ -2279,7 +2433,7 @@ ctlsettrap(
         * If we don't have room for him return an error.
         */
        if (tptouse == NULL)
-               return 0;
+               return (0);
 
        /*
         * Set up this structure for him.
@@ -2290,19 +2444,18 @@ ctlsettrap(
        tptouse->tr_addr = *raddr;
        tptouse->tr_localaddr = linter;
        tptouse->tr_version = version;
-
        tptouse->tr_flags = TRAP_INUSE;
        if (traptype == TRAP_TYPE_CONFIG)
                tptouse->tr_flags |= TRAP_CONFIGURED;
        else if (traptype == TRAP_TYPE_NONPRIO)
                tptouse->tr_flags |= TRAP_NONPRIO;
        num_ctl_traps++;
-       return 1;
+       return (1);
 }
 
 
 /*
- * ctlclrtrap - called to clr a trap
+ * ctlclrtrap - called to clear a trap
  */
 int
 ctlclrtrap(
@@ -2314,15 +2467,15 @@ ctlclrtrap(
        register struct ctl_trap *tp;
 
        if ((tp = ctlfindtrap(raddr, linter)) == NULL)
-               return 0;
+               return (0);
 
        if (tp->tr_flags & TRAP_CONFIGURED
                && traptype != TRAP_TYPE_CONFIG)
-               return 0;
+               return (0);
 
        tp->tr_flags = 0;
        num_ctl_traps--;
-       return 1;
+       return (1);
 }
 
 
@@ -2338,11 +2491,11 @@ ctlfindtrap(
        register struct ctl_trap *tp;
 
        for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
-               if (tp->tr_flags & TRAP_INUSE
-                       && NSRCADR(raddr) == NSRCADR(&tp->tr_addr)
-                       && NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr)
-                       && linter == tp->tr_localaddr)
-                       return tp;
+               if (tp->tr_flags & TRAP_INUSE && NSRCADR(raddr) ==
+                   NSRCADR(&tp->tr_addr) && NSRCPORT(raddr) ==
+                   NSRCPORT(&tp->tr_addr) && linter ==
+                   tp->tr_localaddr)
+                       return (tp);
        }
        return (struct ctl_trap *)NULL;
 }
@@ -2368,14 +2521,15 @@ report_event(
                        ctl_sys_num_events++;
                if (ctl_sys_last_event != (u_char)err) {
                        NLOG(NLOG_SYSEVENT)
-                               msyslog(LOG_INFO, "system event '%s' (0x%02x) status '%s' (0x%02x)",
-                                       eventstr(err), err,
-                                       sysstatstr(ctlsysstatus()), ctlsysstatus());
+                           msyslog(LOG_INFO, "system event '%s' (0x%02x) status '%s' (0x%02x)",
+                           eventstr(err), err,
+                           sysstatstr(ctlsysstatus()), ctlsysstatus());
 #ifdef DEBUG
                        if (debug)
                                printf("report_event: system event '%s' (0x%02x) status '%s' (0x%02x)\n",
-                                  eventstr(err), err,
-                                  sysstatstr(ctlsysstatus()), ctlsysstatus());
+                                   eventstr(err), err,
+                                   sysstatstr(ctlsysstatus()),
+                                   ctlsysstatus());
 #endif
                        ctl_sys_last_event = (u_char)err;
                }
@@ -2393,19 +2547,25 @@ report_event(
                if (peer->num_events < CTL_PEER_MAXEVENTS)
                        peer->num_events++;
                NLOG(NLOG_PEEREVENT)
-                       msyslog(LOG_INFO, "peer %s event '%s' (0x%02x) status '%s' (0x%02x)",
-                               src, eventstr(err), err,
-                               peerstatstr(ctlpeerstatus(peer)), ctlpeerstatus(peer));
+                   msyslog(LOG_INFO, "peer %s event '%s' (0x%02x) status '%s' (0x%02x)",
+                   src, eventstr(err), err,
+                   peerstatstr(ctlpeerstatus(peer)),
+                   ctlpeerstatus(peer));
 #ifdef DEBUG
                if (debug)
                        printf( "peer %s event '%s' (0x%02x) status '%s' (0x%02x)\n",
-                               src, eventstr(err), err,
-                               peerstatstr(ctlpeerstatus(peer)), ctlpeerstatus(peer));
+                           src, eventstr(err), err,
+                           peerstatstr(ctlpeerstatus(peer)),
+                           ctlpeerstatus(peer));
 #endif
        } else {
-               msyslog(LOG_ERR, "report_event: err '%s' (0x%02x), no peer", eventstr(err), err);
+               msyslog(LOG_ERR,
+                   "report_event: err '%s' (0x%02x), no peer",
+                   eventstr(err), err);
 #ifdef DEBUG
-               printf("report_event: peer event '%s' (0x%02x), no peer\n", eventstr(err), err);
+               printf(
+                   "report_event: peer event '%s' (0x%02x), no peer\n",
+                   eventstr(err), err);
 #endif
                return;
        }
@@ -2425,38 +2585,42 @@ report_event(
        res_authenticate = 0;
        datapt = rpkt.data;
        dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
-
        if (!(err & PEER_EVENT)) {
                rpkt.associd = 0;
                rpkt.status = htons(ctlsysstatus());
 
                /*
                 * For now, put everything we know about system
-                * variables.  Maybe more selective later
+                * variables. Don't send crypto strings.
                 */
-               for (i = 1; i <= CS_MAXCODE; i++)
+               for (i = 1; i <= CS_MAXCODE; i++) {
+#ifdef PUBKEY
+                       if (i > CS_VARLIST)
+                               continue;
+#endif /* PUBKEY */
                        ctl_putsys(i);
+               }
 #ifdef REFCLOCK
                /*
-                * for clock exception events:
-                *        add clock variables to reflect info on exception
+                * for clock exception events: add clock variables to
+                * reflect info on exception
                 */
                if (err == EVNT_CLOCKEXCPT) {
                        struct refclockstat clock_stat;
                        struct ctl_var *kv;
 
                        clock_stat.kv_list = (struct ctl_var *)0;
-
                        refclock_control(&peer->srcadr,
-                                        (struct refclockstat *)0, &clock_stat);
-                       ctl_puthex("refclockstatus", ctlclkstatus(&clock_stat));
-
+                           (struct refclockstat *)0, &clock_stat);
+                       ctl_puthex("refclockstatus",
+                           ctlclkstatus(&clock_stat));
                        for (i = 1; i <= CC_MAXCODE; i++)
                                ctl_putclock(i, &clock_stat, 0);
-                       for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++)
+                       for (kv = clock_stat.kv_list; kv &&
+                           !(kv->flags & EOV); kv++)
                                if (kv->flags & DEF)
-                               ctl_putdata(kv->text, strlen(kv->text), 0);
-
+                                       ctl_putdata(kv->text,
+                                           strlen(kv->text), 0);
                        free_varlist(clock_stat.kv_list);
                }
 #endif /*REFCLOCK*/
@@ -2465,34 +2629,37 @@ report_event(
                rpkt.status = htons(ctlpeerstatus(peer));
 
                /*
-                * Dump it all.  Later, maybe less.
+                * Dump it all. Later, maybe less.
                 */
                for (i = 1; i <= CP_MAXCODE; i++)
+#ifdef PUBKEY
+                       if (i > CP_VARLIST)
+                               continue;
+#endif /* PUBKEY */
                        ctl_putpeer(i, peer);
 #ifdef REFCLOCK
                /*
-                * for clock exception events:
-                *        add clock variables to reflect info on exception
+                * for clock exception events: add clock variables to
+                * reflect info on exception
                 */
                if (err == EVNT_PEERCLOCK) {
                        struct refclockstat clock_stat;
                        struct ctl_var *kv;
 
                        clock_stat.kv_list = (struct ctl_var *)0;
-
                        refclock_control(&peer->srcadr,
-                                        (struct refclockstat *)0,
-                                        &clock_stat);
+                           (struct refclockstat *)0, &clock_stat);
 
                        ctl_puthex("refclockstatus",
-                                  ctlclkstatus(&clock_stat));
+                           ctlclkstatus(&clock_stat));
 
                        for (i = 1; i <= CC_MAXCODE; i++)
                                ctl_putclock(i, &clock_stat, 0);
-                       for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++)
+                       for (kv = clock_stat.kv_list; kv &&
+                           !(kv->flags & EOV); kv++)
                                if (kv->flags & DEF)
-                               ctl_putdata(kv->text, strlen(kv->text), 0);
-
+                                       ctl_putdata(kv->text,
+                                           strlen(kv->text), 0);
                        free_varlist(clock_stat.kv_list);
                }
 #endif /*REFCLOCK*/
@@ -2537,14 +2704,12 @@ count_var(
        register u_long c;
 
        if (!k)
-           return 0;
+               return (0);
 
        c = 0;
-
        while (!(k++->flags & EOV))
-           c++;
-
-       return c;
+               c++;
+       return (c);
 }
 
 char *
@@ -2561,12 +2726,11 @@ add_var(
 
        k = *kv;
        *kv  = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var));
-       if (k)
-       {
-               memmove((char *)*kv, (char *)k, sizeof(struct ctl_var)*c);
+       if (k) {
+               memmove((char *)*kv, (char *)k,
+                   sizeof(struct ctl_var)*c);
                free((char *)k);
        }
-
        (*kv)[c].code  = (u_short) c;
        (*kv)[c].text  = (char *)emalloc(size);
        (*kv)[c].flags = def;
@@ -2592,21 +2756,16 @@ set_var(
        if (!data || !size)
                return;
 
-       if ((k = *kv))
-       {
-               while (!(k->flags & EOV))
-               {
+       if ((k = *kv)) {
+               while (!(k->flags & EOV)) {
                        s = data;
                        t = k->text;
-                       if (t)
-                       {
-                               while (*t != '=' && *s - *t == 0)
-                               {
+                       if (t)  {
+                               while (*t != '=' && *s - *t == 0) {
                                        s++;
                                        t++;
                                }
-                               if (*s == *t && ((*t == '=') || !*t))
-                               {
+                               if (*s == *t && ((*t == '=') || !*t)) {
                                        free((void *)k->text);
                                        td = (char *)emalloc(size);
                                        memmove(td, data, size);
@@ -2614,9 +2773,7 @@ set_var(
                                        k->flags = def;
                                        return;
                                }
-                       }
-                       else
-                       {
+                       } else {
                                td = (char *)emalloc(size);
                                memmove(td, data, size);
                                k->text = td;
@@ -2646,10 +2803,9 @@ free_varlist(
        )
 {
        struct ctl_var *k;
-       if (kv)
-       {
+       if (kv) {
                for (k = kv; !(k->flags & EOV); k++)
-                   free((void *)k->text);
+                       free((void *)k->text);
                free((void *)kv);
        }
 }
diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c
new file mode 100644 (file)
index 0000000..cc72171
--- /dev/null
@@ -0,0 +1,1053 @@
+/*
+ * ntp_crypto.c - NTP version 4 public key routines
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef AUTOKEY
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+#include "ntpd.h"
+#include "ntp_stdlib.h"
+#include "ntp_string.h"
+#include "ntp_crypto.h"
+
+/*
+ * Extension field message formats
+ *
+ *   +-------+-------+   +-------+-------+   +-------+-------+
+ * 0 |   3   |  len  |   |   4   |  len  |   |  1/5  |  len  |
+ *   +-------+-------+   +-------+-------+   +-------+-------+
+ * 1 |    assoc ID   |   |    assoc ID   |   |    assoc ID   |
+ *   +---------------+   +---------------+   +---------------+
+ * 2 |  current seq  |   |  peer cookie  |   |   value len   |
+ *   +---------------+   +---------------+   +---------------+
+ * 3 |   final seq   |   | signature len |   |               |
+ *   +---------------+   +---------------+   =     value     =
+ * 4 |   final key   |   |               |   |               |
+ *   +---------------+   =   signature   =   +---------------+
+ * 5 | signature len |   |               |   CRYPTO_PUBL rsp 
+ *   +---------------+   +---------------+   CRYPTO_DH cmd
+ * 6 |               |   CRYPTO_PRIV rsp     CRYPTO_DH rsp
+ *   =   signature   =
+ *   |               |   Other commands and responses have only the
+ *   +---------------+   first three words plus one word of padding.
+ *   CRYPTO_AUTO rsp
+ *
+ *   CRYPTO_PUBL  1  request/respond for public key
+ *   CRYPTO_ASSOC 2  request/respond association ID
+ *   CRYPTO_AUTO  3  request/respond autokey values
+ *   CRYPTO_PRIV  4  request/respond cookie
+ *   CRYPTO_DH    5  send public value/receive signature
+ *
+ *   Note: commands carry the association ID of the receiver; responses
+ *   carry the association ID of the sender.
+ */
+
+#ifdef PUBKEY
+/*
+ * Cryptodefines
+ */
+#define MAX_KEYLEN     1024    /* maximum key length */
+
+/*
+ * Cryptodata
+ */
+static R_DH_PARAMS dh_params;  /* Diffie-Hellman parameters */
+static u_int dh_keyLen;                /* Diffie-Hellman key length */
+static u_char *dh_public;      /* Diffie-Hellman public value */
+static u_char *dh_private;     /* Diffie-Hellman private value */
+static R_RSA_PRIVATE_KEY private_key; /* RSA private key */
+static R_RSA_PUBLIC_KEY public_key; /* RSA public key */
+
+int    crypto_enable;          /* master switch */
+int    crypto_flags;           /* flags that wave cryptically */
+char   *private_key_file = "ntpkey"; /* private key file */
+char   *public_key_file = NULL; /* public key file */
+char   *dh_params_file = "ntpkey_dh"; /* D-H parameters file */
+char   *keysdir = "/usr/local/etc/"; /* crypto keys directory */
+
+/*
+ * Cryptotypes
+ */
+static int     crypto_read     P((u_char *, u_char *, u_int));
+static void    crypto_line     P((FILE *, u_char **, u_int *));
+#endif /* PUBKEY */
+
+/*
+ * session_key - generate session key
+ *
+ * This routine generates a session key from the source address,
+ * destination address, key ID and private value. The value of the
+ * session key is the MD5 hash of these values, while the next key ID is
+ * the first four octets of the hash.
+ */
+keyid_t                                /* returns next key ID */
+session_key(
+       struct sockaddr_in *srcadr, /* source address */
+       struct sockaddr_in *dstadr, /* destination address */
+       keyid_t keyno,          /* key ID */
+       keyid_t private,        /* private value */
+       u_long lifetime         /* key lifetime */
+       )
+{
+       MD5_CTX ctx;            /* MD5 context */
+       keyid_t keyid;          /* key identifer */
+       u_int32 header[4];      /* data in network byte order */
+       u_char digest[16];      /* message digest */
+
+       /*
+        * Generate the session key and key ID. If the lifetime is
+        * greater than zero, install the key and call it trusted.
+        */
+       header[0] = srcadr->sin_addr.s_addr;
+       header[1] = dstadr->sin_addr.s_addr;
+       header[2] = htonl(keyno);
+       header[3] = htonl(private);
+       MD5Init(&ctx);
+       MD5Update(&ctx, (u_char *)header, sizeof(header));
+       MD5Final(digest, &ctx);
+       memcpy(&keyid, digest, 4);
+       keyid = ntohl(keyid);
+       if (lifetime != 0) {
+               MD5auth_setkey(keyno, digest, 16);
+               authtrust(keyno, lifetime);
+       }
+#ifdef DEBUG
+       if (debug > 1)
+               printf(
+                   "session_key: %s > %s %08x %08x hash %08x life %lu\n",
+                   numtoa(header[0]), numtoa(header[1]), keyno,
+                   private, keyid, lifetime);
+#endif
+       return (keyid);
+}
+
+
+/*
+ * make_keylist - generate key list
+ *
+ * This routine constructs a pseudo-random sequence by repeatedly
+ * hashing the session key starting from a given source address,
+ * destination address, private value and the next key ID of the
+ * preceeding session key. The last entry on the list is saved along
+ * with its sequence number and public signature.
+ */
+void
+make_keylist(
+       struct peer *peer       /* peer structure pointer */
+       )
+{
+       keyid_t keyid;          /* next key ID */
+       keyid_t cookie;         /* private value */
+       u_long ltemp;
+       int i, n;
+#ifdef PUBKEY
+       R_SIGNATURE_CTX ctx;    /* signature context */
+       int rval;               /* return value */
+       u_int32 xpkt[2];        /* data in network byte order */
+#endif /* PUBKEY */
+
+       /*
+        * Allocate the key list if necessary.
+        */
+       if (peer->keylist == 0)
+               peer->keylist = (keyid_t *)emalloc(sizeof(keyid_t) *
+                   NTP_MAXSESSION);
+
+       /*
+        * Generate an initial key ID which is unique and greater than
+        * NTP_MAXKEY.
+        */
+       while (1) {
+               keyid = (u_long)RANDOM & 0xffffffff;
+               if (keyid <= NTP_MAXKEY)
+                       continue;
+               if (authhavekey(keyid))
+                       continue;
+               break;
+       }
+
+       /*
+        * Generate up to NTP_MAXSESSION session keys. Stop if the
+        * next one would not be unique or not a session key ID or if
+        * it would expire before the next poll. The private value
+        * included in the hash is zero if broadcast mode, the peer
+        * cookie if client mode or the host cookie if symmetric modes.
+        */
+       ltemp = sys_automax;
+       peer->hcookie = session_key(&peer->dstadr->sin, &peer->srcadr,
+           0, sys_private, 0);
+       n = NTP_MINSESSION;
+       if (peer->hmode == MODE_BROADCAST) {
+               cookie = 0;
+               n = NTP_MAXSESSION;
+       } else if (peer->hmode == MODE_SERVER) {
+               cookie = peer->hcookie;
+       } else {
+               cookie = peer->pcookie;
+       }
+       for (i = 0; i < n; i++) {
+               peer->keylist[i] = keyid;
+               peer->keynumber = i;
+               keyid = session_key(&peer->dstadr->sin, (peer->hmode ==
+                   MODE_BROADCAST) ? &peer->dstadr->bcast :
+                   &peer->srcadr, keyid, cookie, ltemp);
+               ltemp -= 1 << peer->hpoll;
+               if (auth_havekey(keyid) || keyid <= NTP_MAXKEY ||
+                   ltemp <= (1 << (peer->hpoll + 1)))
+                       break;
+       }
+
+       /*
+        * Save the last session key ID and sequence number, then sign
+        * these values for later retrieval by the clients. Be careful
+        * not to use invalid key media.
+        */
+       peer->lastseq = peer->keynumber;
+       peer->lastkey = keyid;
+#if DEBUG
+       if (debug)
+               printf("make_keys: %d %08x\n", peer->lastseq,
+                   peer->lastkey);
+#endif
+#ifdef PUBKEY
+       if (private_key.bits < MIN_RSA_MODULUS_BITS ||
+           private_key.bits > MAX_RSA_MODULUS_BITS) {
+               rval = -1;
+       } else {
+               if (peer->sign == NULL)
+                       peer->sign = emalloc(MAX_SIGNATURE_LEN);
+               xpkt[0] = htonl(peer->lastseq);
+               xpkt[1] = htonl(peer->lastkey);
+               R_SignInit(&ctx, DA_MD5);
+               R_SignUpdate(&ctx, (u_char *)xpkt, 8);
+               rval = R_SignFinal(&ctx, peer->sign, &peer->signlen,
+                   &private_key);
+       }
+       if (rval != 0)
+               msyslog(LOG_ERR, "make_keylist: signature fails %x",
+                   rval);
+#endif /* PUBKEY */
+}
+
+
+/*
+ * crypto_recv - parse extension fields
+ *
+ * This routine is called when the packet has been matched to an
+ * association and passed sanity, format and authentication checks.
+ */
+void
+crypto_recv(
+       struct peer *peer,      /* peer structure pointer */
+       struct recvbuf *rbufp   /* packet buffer pointer */
+       )
+{
+       u_int32 *pkt;           /* packet pointer */
+       int has_mac;            /* length of MAC field */
+       int authlen;            /* offset of MAC field */
+       int len;                /* extension field length */
+       u_int code;             /* extension field opcode */
+       int i;
+       u_int temp;
+#ifdef PUBKEY
+       R_SIGNATURE_CTX ctx;    /* signature context */
+       u_int modulus;          /* modulus length */
+       int rval;               /* return value */
+#endif /* PUBKEY */
+
+       /*
+        * Initialize. Note that the packet has already been checked for
+        * valid format and extension field lengths.
+        */
+       pkt = (u_int32 *)&rbufp->recv_pkt;
+       authlen = LEN_PKT_NOMAC;
+       while ((has_mac = rbufp->recv_length - authlen) > MAX_MAC_LEN) {
+               i = authlen / 4;
+               len = ntohl(pkt[i]) & 0xffff;
+               code = (ntohl(pkt[i]) >> 16) & 0xffff;
+               if (code & CRYPTO_RESP)
+                       peer->assoc = ntohl(pkt[i + 1]);
+#ifdef DEBUG
+               if (debug)
+                       printf(
+                           "crypto_recv: ext field offset %d length %d code %x assoc ID %d\n",
+                           authlen, len, code, (u_int32)ntohl(pkt[i +
+                           1]));
+#endif
+               switch (code) {
+
+               /*
+                * Exchange association IDs. This is used in multicast
+                * server mode and is a NOP here.
+                */
+               case CRYPTO_ASSOC | CRYPTO_RESP:
+                       break;
+
+               /*
+                * Install autokey values. We believe the values only if
+                * the public key is valid and the signature has valid
+                * length and is verified. This is used in multicast
+                * client and symmetric modes.
+                */
+               case CRYPTO_AUTO | CRYPTO_RESP:
+                       peer->recseq = ntohl(pkt[i + 2]);
+#ifdef PUBKEY
+                       temp = ntohl(pkt[i + 5]);
+                       if (temp == 0 || peer->pubkey == NULL) {
+                               rval = -1;
+                       } else {
+                               R_VerifyInit(&ctx, DA_MD5);
+                               R_VerifyUpdate(&ctx, (char *)&pkt[i +
+                                   3], 8);
+                               rval = R_VerifyFinal(&ctx,
+                                   (char *)&pkt[i + 6], temp,
+                                   (R_RSA_PUBLIC_KEY *)peer->pubkey);
+                       }
+#ifdef DEBUG
+                       if (debug)
+                               printf(
+                                   "crypto_recv: verify %x autokey %d %08x\n",
+                                   rval, (u_int32)ntohl(pkt[i + 3]),
+                                   (u_int32)ntohl(pkt[i + 4]));
+#endif
+                       if (rval != 0) {
+                               peer->flags &= ~FLAG_AUTOKEY;
+                               break;
+                       }
+                       peer->flags |= FLAG_AUTOKEY;
+#endif /* PUBKEY */
+                       peer->flash &= ~TEST10;
+                       peer->finlseq = ntohl(pkt[i + 3]);
+                       peer->finlkey = peer->pkeyid = ntohl(pkt[i +
+                           4]);
+                       break;
+
+               /*
+                * Install session cookie. We believe the value only if
+                * the public key is valid and the signature has valid
+                * length and is verified. This is used in client mode.
+                */
+               case CRYPTO_PRIV | CRYPTO_RESP:
+#ifdef PUBKEY
+                       temp = ntohl(pkt[i + 3]);
+                       if (temp == 0 || peer->pubkey == NULL) {
+                               rval = -1;
+                               temp = 0;
+                       } else {
+                               R_VerifyInit(&ctx, DA_MD5);
+                               R_VerifyUpdate(&ctx, (char *)&pkt[i +
+                                   2], 4);
+                               rval = R_VerifyFinal(&ctx,
+                                   (char *)&pkt[i + 4], temp,
+                                   (R_RSA_PUBLIC_KEY *)peer->pubkey);
+                               temp = ntohl(pkt[i + 2]);
+                       }
+#ifdef DEBUG
+                       if (debug)
+                               printf(
+                           "crypto_recv: verify %x cookie %08x\n",
+                                   rval, temp);
+#endif
+                       if (rval != 0) {
+                               peer->flags &= ~FLAG_AUTOKEY;
+                               break;
+                       }
+                       peer->flags |= FLAG_AUTOKEY;
+#else
+                       temp = ntohl(pkt[i + 2]);
+#endif /* PUBKEY */
+                       peer->flash &= ~TEST10;
+                       if (temp != peer->pcookie) {
+                               key_expire(peer);
+                               peer->pcookie = temp;
+                       }
+                       break;
+
+#ifdef PUBKEY
+               /*
+                * Compute Diffie-Hellman key agreement. We allocate
+                * space and save the public value to compute the
+                * signature later, Then we allocate space for the
+                * agreed key, run the agreement algorithm and stash the
+                * key vale. We use only the first u_int32 for the host
+                * cookie. Wasteful. This is used in symmetric modes.
+                */
+               case CRYPTO_DH:
+                       temp = ntohl(pkt[i + 2]);
+                       if (temp == 0 || temp != dh_params.primeLen) {
+                               rval = -1;
+                               temp = 0;
+                       } else {
+                               if (peer->dh_public == NULL) 
+                                       peer->dh_public =
+                                           (u_char *)emalloc(temp);
+                               memcpy(peer->dh_public,
+                                   (char *)&pkt[i + 3], temp);
+                               if (peer->dh_key == NULL) 
+                                       peer->dh_key =
+                                           (u_char *)emalloc(temp);
+                               rval = R_ComputeDHAgreedKey(
+                                   peer->dh_key, peer->dh_public,
+                                   dh_private, dh_keyLen, &dh_params);
+                               temp = ntohl(*((u_int *)peer->dh_key));
+                       }
+#ifdef DEBUG
+                       if (debug)
+                               printf(
+                                   "crypto_recv: d-h agree %x %08x\n",
+                                   rval, temp);
+#endif
+                       if (rval != 0) {
+                               peer->flags &= ~FLAG_AUTOKEY;
+                               break;
+                       }
+                       peer->flash &= ~TEST10;
+                       if (temp != peer->pcookie)
+                               peer->pcookie = 0;
+                       peer->cmmd = ntohl(pkt[i]);
+                       break;
+
+               /*
+                * Verify signature of Diffie-Hellman public values. The
+                * verification fails if the signature length does not
+                * match the modulus length or any of the public values
+                * or the agreed key is not valid. This is used in
+                * symmetric modes.
+                */
+               case CRYPTO_DH | CRYPTO_RESP:
+                       temp = ntohl(pkt[i + 2]);
+                       if (temp == 0 || temp != dh_params.primeLen ||
+                           peer->pubkey == NULL || peer->dh_public ==
+                           NULL || dh_public == NULL || peer->dh_key ==
+                           NULL) {
+                               rval = -1;
+                               temp = 0;
+                       } else {
+                               R_VerifyInit(&ctx, DA_MD5);
+                               R_VerifyUpdate(&ctx,
+                                   (u_char *)peer->dh_public,
+                                   dh_params.primeLen);
+                               R_VerifyUpdate(&ctx, dh_public,
+                                   dh_params.primeLen);
+                               rval = R_VerifyFinal(&ctx,
+                                   (u_char *)&pkt[i + 3], temp,
+                                   (R_RSA_PUBLIC_KEY *)peer->pubkey);
+                               temp = ntohl(*((u_int *)peer->dh_key));
+                       }
+#ifdef DEBUG
+                       if (debug)
+                               printf(
+                                   "crypto_recv: d-h verify %x %08x\n",
+                                   rval, temp);
+#endif
+                       if (rval != 0) {
+                               peer->flags &= ~FLAG_AUTOKEY;
+                               break;
+                       }
+                       peer->flash &= ~TEST10;
+                       peer->flags |= FLAG_AUTOKEY;
+                       if (temp != peer->pcookie) {
+                               key_expire(peer);
+                               peer->pcookie = temp;
+                       }
+                       break;
+
+               /*
+                * Install peer public key. This is rather raucus, since
+                * the extension field is in network order and the first
+                * word is a u_int32; however, the corresponding word of
+                * the key is a u_int, which can be 32 or 64 bits
+                * depending on architecture. We don't do anything
+                * unless the length and modulus are valid. Picky,
+                * picky.
+                */
+               case CRYPTO_PUBL | CRYPTO_RESP:
+                       temp = sizeof(R_RSA_PUBLIC_KEY) - sizeof(u_int);
+                       if (ntohl(pkt[i + 2]) != temp + 4)
+                               break;
+                       modulus = ntohl(pkt[i + 3]);
+                       if ( modulus < MIN_RSA_MODULUS_BITS ||
+                           modulus > MAX_RSA_MODULUS_BITS)
+                               break;
+                       if (peer->pubkey == NULL)
+                               peer->pubkey =
+                                   emalloc(sizeof(R_RSA_PUBLIC_KEY));
+                       ((R_RSA_PUBLIC_KEY *)peer->pubkey)->bits =
+                           modulus;
+                       memcpy(
+                           ((R_RSA_PUBLIC_KEY *)peer->pubkey)->modulus,
+                           (u_char *)&(pkt[i + 4]), temp);
+                       break;
+#endif /* PUBKEY */
+
+               /*
+                * For other commands, save the command code for later;
+                * for unknown responses or errors, just ignore for now.
+                */
+               default:
+                       if (code & (CRYPTO_RESP | CRYPTO_ERROR))
+                               break;
+                       peer->cmmd = ntohl(pkt[i]);
+                       break;
+
+               }
+               authlen += len;
+       }
+       return;
+}
+
+
+/*
+ * crypto_xmit - construct extension fields
+ *
+ * This routine is called both when an association is configured and
+ * when one is not. The only case where this matters now is to retrieve
+ * the autokey information, in which case the caller has to provide the
+ * association ID to match the association.
+ */
+int                            /* return length of extension field */
+crypto_xmit(
+       u_int32 *xpkt,          /* packet pointer */
+       int start,              /* offset to extension field */
+       u_int code,             /* extension field code */
+       keyid_t cookie,         /* session cookie */
+       int associd             /* association ID */
+       )
+{
+       struct peer *peer;      /* peer structure pointer */
+       int len;                /* extension field length */
+       u_int opcode;           /* extension field opcode */
+       int i;
+#ifdef PUBKEY
+       R_SIGNATURE_CTX ctx;    /* signature context */
+       int rval;               /* return value */
+       u_int temp;
+#endif /* PUBKEY */
+
+       /*
+        * Generate the requested extension field command code, length
+        * and association ID.
+        */
+       i = start / 4;
+       opcode = code;
+       xpkt[i + 1] = htonl(associd);
+       len = 8;
+       switch (opcode) {
+
+       /*
+        * Exchange association IDs. This is used in multicast server
+        * mode and is a NOP here.
+        */
+       case CRYPTO_ASSOC | CRYPTO_RESP:
+               break;
+
+       /*
+        * Find peer and send autokey data and signature. We send the
+        * data only if the peer exists and the make_keylist routine has
+        * previously constructed the list and successfully signed the
+        * data. This is used in multicast server and symmetric modes.
+        */
+       case CRYPTO_AUTO | CRYPTO_RESP:
+               peer = findpeerbyassoc(associd);
+               if (peer == NULL) {
+                       opcode |= CRYPTO_ERROR;
+                       break;
+               }
+               xpkt[i + 2] = htonl(peer->keynumber);
+               xpkt[i + 3] = htonl(peer->lastseq);
+               xpkt[i + 4] = htonl(peer->lastkey);
+               xpkt[i + 5] = 0;
+               len += 16;
+#ifdef PUBKEY
+               if (peer->signlen == 0)
+                       break;
+               xpkt[i + 5] = htonl(peer->signlen);
+               memcpy((u_char *)&xpkt[i + 6], peer->sign,
+                   peer->signlen);
+               len += peer->signlen;
+#endif /* PUBKEY */
+               break;
+
+       /*
+        * Send peer cookie and signature. We send the signature only if
+        * the private key exists and is valid. This is used in server
+        * mode.
+        */
+       case CRYPTO_PRIV | CRYPTO_RESP:
+               xpkt[i + 2] = htonl(cookie);
+               xpkt[i + 3] = 0;
+               len += 8;
+#ifdef PUBKEY
+               if (private_key.bits < MIN_RSA_MODULUS_BITS ||
+                   private_key.bits > MAX_RSA_MODULUS_BITS) {
+                       rval = -1;
+               } else {
+                       R_SignInit(&ctx, DA_MD5);
+                       R_SignUpdate(&ctx, (u_char *)&xpkt[i + 2], 4);
+                       rval = R_SignFinal(&ctx, (u_char *)&xpkt[i + 4],
+                           &temp, &private_key);
+               }
+               if (rval != 0) {
+                       msyslog(LOG_ERR,
+                           "crypto_xmit: signature fails %x", rval);
+                       break;
+               }
+               xpkt[i + 3] = htonl(temp);
+               len += temp;
+#endif /* PUBKEY */
+               break;
+
+#ifdef PUBKEY
+       /*
+        * Send Diffie-Hellman public value. We send only if the
+        * parameters have been initialized and the public/private
+        * values have been set up. This is used in symmetric modes.
+        */
+       case CRYPTO_DH:
+               xpkt[i + 2] = 0;
+               len += 4;
+               if (dh_params.primeLen == 0 || dh_public == NULL)
+                       break;
+               xpkt[i + 2] = htonl(dh_params.primeLen);
+               memcpy((u_char *)&xpkt[i + 3], dh_public,
+                   dh_params.primeLen);
+               len += dh_params.primeLen;
+               break;
+
+       /*
+        * Find peer and send signature of Diffie-Hellman public values.
+        * This takes a leap of faith, or maybe just a stumble of
+        * depravity. This is used in symmetric modes.
+        */
+       case CRYPTO_DH | CRYPTO_RESP:
+               peer = findpeerbyassoc(associd);
+               if (peer == NULL) {
+                       opcode |= CRYPTO_ERROR;
+                       break;
+               }
+               xpkt[i + 2] = 0;
+               len += 4;
+               if (private_key.bits < MIN_RSA_MODULUS_BITS ||
+                   private_key.bits > MAX_RSA_MODULUS_BITS ||
+                   dh_public == NULL || peer->dh_public == NULL) {
+                       rval = -1;
+               } else {
+                       R_SignInit(&ctx, DA_MD5);
+                       R_SignUpdate(&ctx, dh_public,
+                           dh_params.primeLen);
+                       R_SignUpdate(&ctx, (u_char *)peer->dh_public,
+                           dh_params.primeLen);
+                       rval = R_SignFinal(&ctx, (u_char *)&xpkt[i + 3],
+                           &temp, &private_key);
+               }
+               if (rval != 0) {
+                       msyslog(LOG_ERR,
+                           "crypto_xmit: signature fails %x", rval);
+                       break;
+               }
+               xpkt[i + 2] = htonl(temp);
+               len += temp;
+               break;
+
+       /*
+        * Send public key. We send the public key only if it exists and
+        * is valid. This is used in all modes.
+        */
+       case CRYPTO_PUBL | CRYPTO_RESP:
+               xpkt[i + 2] = 0;
+               len += 4;
+               if (public_key.bits < MIN_RSA_MODULUS_BITS ||
+                   public_key.bits > MAX_RSA_MODULUS_BITS)
+                       break;
+               temp = sizeof(R_RSA_PUBLIC_KEY) - sizeof(u_int);
+               xpkt[i + 2] = htonl(temp + 4);
+               xpkt[i + 3] = htonl(public_key.bits);
+               memcpy((u_char *)&xpkt[i + 4],
+                   (u_char *)&public_key.modulus, temp);
+               len += temp + 4;
+               break;
+#endif /* PUBKEY */
+
+       /*
+        * Default - Fall through for commands; for unknown responses,
+        * flag as error.
+        */
+       default:
+               if (opcode & CRYPTO_RESP)
+                       opcode |= CRYPTO_ERROR;
+               break;
+       }
+
+       /*
+        * Round up the field length to a multiple of 8 bytes and save
+        * the command code and length.
+        */
+       len = ((len + 7) / 8) * 8;
+       if (len >= 4) {
+               xpkt[i] = htonl((u_int32)((opcode << 16) | len));
+#ifdef DEBUG
+               if (debug)
+                       printf(
+                           "crypto_xmit: ext field offset %d length %d code %x assoc ID %d\n",
+                           start, len, code, associd);
+#endif
+       }
+       return (len);
+}
+
+
+#ifdef PUBKEY
+/*
+ * crypto_read - read RSA key, decode and check for errors
+ */
+int
+crypto_read(
+       u_char *cp,             /* file name */
+       u_char *key,            /* key pointer */
+       u_int keylen            /* key length */
+       )
+{
+       FILE *str;
+       u_char buf[MAX_KEYLEN];
+       u_char encoded_key[MAX_KEYLEN];
+       char filename[MAXFILENAME];
+       u_int modulus;
+       u_int buflen;
+       char *rptr;
+       int rval;
+
+       /*
+        * Open the key file and discard comment lines.
+        */
+       if (strlen(cp) == 0 || strlen(cp) >= MAXFILENAME - 1) {
+               msyslog(LOG_ERR, "invalid key file name length %d",
+                   strlen(filename));
+               return (0);
+       } else if (*cp == '/') {
+               strcpy(filename, cp);
+       } else {
+               sprintf(filename, "%s%s", keysdir, cp);
+       }
+       str = fopen(filename, "r");
+       if (str == NULL) {
+               msyslog(LOG_ERR, "key file %s not found", filename);
+               return (0);
+       }
+       while ((rptr = fgets(buf, MAX_KEYLEN - 1, str)) != NULL) {
+               buflen = strlen(buf);
+               if (buflen < 1)
+                       continue;
+               if (*buf == '#' || *buf == '\r' || *buf == '\0')
+                       continue;
+               break;
+       }
+
+       /*
+        * We are rather paranoid here, since an intruder can cause a
+        * coredump by infiltrating a naughty key. The line must contain
+        * a single integer followed by a PEM encoded, null-terminated
+        * string.
+        */
+       if (rptr == NULL) {
+               msyslog(LOG_ERR, "invalid key file %s", filename);
+               return (0);
+       }
+       if (sscanf(buf, "%d %s", &modulus, encoded_key) != 2) {
+               msyslog(LOG_ERR, "invalid key format %s", filename);
+               return (0);
+       }
+
+       /*
+        * Initialize the key with the decoded PEM string, but leave
+        * room for the modulus length in the key structure.
+        */
+       rval = R_DecodePEMBlock(&key[sizeof(u_int)], &buflen,
+           encoded_key, strlen(encoded_key));
+       if (rval != 0) {
+               msyslog(LOG_ERR, "invalid key %s %x", filename, rval);
+               return (0);
+       }
+
+       /*
+        * Make sure the structure has the required length.
+        */
+       buflen += sizeof(u_int);
+       if (buflen != keylen) {
+               msyslog(LOG_ERR, "invalid key length %s %d", filename,
+                   buflen);
+               return (0);
+       }
+
+       /*
+        * Make sure the modulus length is within limits.
+        */
+       if (modulus < MIN_RSA_MODULUS_BITS || modulus >
+           MAX_RSA_MODULUS_BITS) {
+               msyslog(LOG_ERR, "invalid key modulus %s %d", filename,
+                   modulus);
+               return (0);
+       }
+       ((u_int *)key)[0] = modulus;
+#ifdef DEBUG
+       if (debug)
+               printf(
+                   "crypto_read: RSA key file %s length %d modulus %d\n",
+                   cp, keylen, modulus);
+#endif
+       return (1);
+}
+
+
+/*
+ * crypto_public - read and install the public key from the public key
+ * file. The name of the file is in the form "ntpkey_host", where host
+ * is the DNS canonical name of the host. If the file is not found or
+ * has errors, we just keep going and expect the host to fetch the
+ * public key from the peer via the extension field.
+ */
+void
+crypto_public(
+       struct peer *peer,      /* peer structure pointer */
+       u_char *cp              /* file name */
+       )
+{
+       R_RSA_PUBLIC_KEY keybuf;
+       u_int keylen = sizeof(R_RSA_PUBLIC_KEY);
+       char filename[MAXFILENAME];
+
+       sprintf(filename, "ntpkey_%s", cp);
+       if (!crypto_read(filename, (u_char *)&keybuf, keylen))
+               return;
+       if (peer->keystr != NULL)
+               free(peer->keystr);
+       peer->keystr = emalloc(strlen(filename) + 1);
+       strcpy(peer->keystr, filename);
+       if (peer->pubkey == NULL)
+               peer->pubkey = emalloc(keylen);
+       memcpy(peer->pubkey, (char *)&keybuf, keylen);
+}
+
+
+/*
+ * crypto_line - read, decode and install Diffie-Hellman prime and
+ * generator. Be very parannoyed here if every little thing is not
+ * exactly right.
+ */
+void
+crypto_line(
+       FILE *str,              /* file handle */
+       u_char **key,           /* decoded string pointer */
+       u_int *len              /* length */
+       )
+{
+       u_char buf[MAX_KEYLEN];
+       u_char encoded_key[MAX_KEYLEN];
+       u_int temp, temp1, temp2;
+       char *rptr;
+
+       /*
+        * Read key and length. Bail out if the length word doesn't
+        * match the decoded string length.
+        */
+       *key = NULL;
+       *len = 0;
+       while ((rptr = fgets(buf, MAX_KEYLEN - 1, str)) != NULL) {
+               if (strlen(buf) < 1)
+                       continue;
+               if (*buf == '#' || *buf == '\r' || *buf == '\0')
+                       continue;
+               break;
+       }
+       if (sscanf(buf, "%d %s", &temp, encoded_key) != 2)
+               return;
+       temp2 = DECODED_CONTENT_LEN(strlen(encoded_key));
+       if (R_DecodePEMBlock(buf, &temp1, encoded_key,
+           strlen(encoded_key)))
+               return;
+       if (temp != temp1 || temp > temp2)
+               return;
+       *key = (u_char *)emalloc(temp2);
+       memcpy(*key, buf, temp2);
+       *len = temp;
+       return;
+}
+
+
+/*
+ * crypto_setup - read RSA private key, RSA public key and Diffie-
+ * Hellman parameter files and initialize cryptographic data.
+ */
+void
+crypto_setup(void)
+{
+       FILE *str;
+       struct utsname utsnamebuf;
+       u_char filename[MAXFILENAME];
+
+       /*
+        * Load RSA private key from file.
+        */
+       if (private_key_file == NULL)
+               private_key_file = "ntpkey";
+       crypto_read(private_key_file, (u_char *)&private_key,
+           sizeof(R_RSA_PRIVATE_KEY));
+
+       /*
+        * Load RSA public key from file, default "ntpkey_host", where
+        * host is the DNS name of this machine.
+        */
+       if (public_key_file == NULL) {
+               uname(&utsnamebuf);
+               sprintf(filename, "ntpkey_%s", utsnamebuf.nodename);
+               public_key_file = emalloc(strlen(filename) + 1);
+               strcpy(public_key_file, filename);
+       }
+       crypto_read(public_key_file, (u_char *)&public_key,
+           sizeof(R_RSA_PUBLIC_KEY));
+
+       /*
+        * Load Diffie-Hellman key agreement parameters from file.
+        */
+       if (dh_params_file == NULL)
+               dh_params_file = "ntpkey_dh";
+       if (*dh_params_file == '/')
+               strcpy(filename, dh_params_file);
+       else
+               sprintf(filename, "%s%s", keysdir, dh_params_file);
+
+       str = fopen(filename, "r");
+       if (str == NULL) {
+               msyslog(LOG_ERR, "key file %s not found",
+                   filename);
+               return;
+       }
+
+       /*
+        * Read prime and generator. Note that the private value length
+        * is set arbitrarily at half the prime length.
+        */
+       crypto_line(str, &dh_params.prime, &dh_params.primeLen);
+       crypto_line(str, &dh_params.generator, &dh_params.generatorLen);
+       if (dh_params.primeLen == 0|| dh_params.generatorLen == 0) {
+               msyslog(LOG_ERR,
+                   "invalid Diffie-Hellman file format or value");
+               return;
+       }
+       dh_keyLen = dh_params.primeLen / 2;
+}
+
+
+/*
+ * crypto_agree - compute public and private Diffie-Hellman values from
+ * given prime and generator.
+ */
+void
+crypto_agree(void)
+{
+       R_RANDOM_STRUCT randomstr;
+       u_int len, temp;
+       int rval, i;
+
+       /*
+        * Note that the length of the private value is set arbitrarily
+        * to half the prime length.
+        */
+       if (dh_params.primeLen == 0)
+               return;
+       R_RandomInit(&randomstr);
+       R_GetRandomBytesNeeded(&len, &randomstr);
+       for (i = 0; i < len; i++) {
+               temp = random();
+               R_RandomUpdate(&randomstr, (u_char *)&temp, 1);
+       }
+       if (dh_private == NULL)
+               dh_private = (u_char *)emalloc(dh_keyLen);
+       if (dh_public == NULL)
+               dh_public = (u_char *)emalloc(dh_params.primeLen);
+       rval = R_SetupDHAgreement(dh_public, dh_private, dh_keyLen,
+           &dh_params, &randomstr);
+       if (rval != 0)
+               msyslog(LOG_ERR, "invalid Diffie-Hellman parameters");
+#ifdef DEBUG
+       if (debug)
+               printf(
+                   "cypto_init: Diffie-Hellman prime %d generator %d key %d\n",
+                   dh_params.primeLen, dh_params.generatorLen,
+                   dh_keyLen);
+#endif
+}
+
+
+/*
+ * crypto_config - configure crypto data.
+ */
+void
+crypto_config(
+       int item,               /* configuration item */
+       char *cp                /* file name */
+       )
+{
+       switch (item) {
+
+       /*
+        * Initialize flags
+        */
+       case CRYPTO_CONF_FLAGS:
+               crypto_flags = atoi(cp);
+               break;
+       /*
+        * Override the default Diffie-Hellman parameter file name.
+        */
+       case CRYPTO_CONF_DH:
+               dh_params_file = emalloc(strlen(cp) + 1);
+               strcpy(dh_params_file, cp);
+               break;
+
+       /*
+        * Override the default RSA private key file name.
+        */
+       case CRYPTO_CONF_PRIV:
+               private_key_file = emalloc(strlen(cp) + 1);
+               strcpy(private_key_file, cp);
+               break;
+
+       /*
+        * Override the default RSA public key file name.
+        */
+       case CRYPTO_CONF_PUBL:
+               public_key_file = emalloc(strlen(cp) + 1);
+               strcpy(public_key_file, cp);
+               break;
+
+       /*
+        * Override the default crypto keys directory.
+        */
+       case CRYPTO_CONF_KEYS:
+               keysdir = emalloc(strlen(cp) + 1);
+               strcpy(keysdir, cp);
+               break;
+       }
+}
+
+
+/*
+ * crypto_init () - initialize things.
+ */
+void
+crypto_init(void)
+{
+       /*
+        * Zeroize sensitive crypto data.
+        */
+       memset((char *)&private_key, 0, sizeof(private_key));
+       memset((char *)&public_key, 0, sizeof(public_key));
+       memset((char *)&dh_params, 0, sizeof(dh_params));
+}
+#endif /* PUBKEY */
+#endif /* AUTOKEY */
index e9a387e075908dd53787bf84bb03c9b7d9ad6453..ed9fe0872804aa23e776a79048b9e7183ed43d8e 100644 (file)
 #include <netdb.h>
 #include <signal.h>
 
+/**/
+#include <netinet/in.h>
+#include <arpa/inet.h>
+/**/
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>                /* MAXHOSTNAMELEN (often) */
+#endif
+
 #include "ntpd.h"
 #include "ntp_io.h"
 #include "ntp_request.h"
@@ -52,6 +60,7 @@ struct conf_entry {
 #define        ce_flags        ce_config.flags
 #define ce_ttl         ce_config.ttl
 #define        ce_keyid        ce_config.keyid
+#define ce_keystr      ce_config.keystr
 
 /*
  * confentries is a pointer to the list of configuration entries
@@ -73,7 +82,6 @@ static struct conf_entry *confentries = NULL;
 #define        MAXRESOLVE      32
 #define        CONFIG_TIME     2
 #define        ALARM_TIME      30
-
 #define        SLEEPTIME       2
 
 static volatile int config_timer = 0;
@@ -107,7 +115,8 @@ static      int resolve_value;      /* next value of resolve timer */
 #define        TOK_FLAGS       5
 #define TOK_TTL                6
 #define        TOK_KEYID       7
-#define        NUMTOK          8
+#define TOK_KEYSTR     8
+#define        NUMTOK          9
 
 #define        MAXLINESIZE     512
 
@@ -120,7 +129,7 @@ static      int sockfd = -1;
 
 /* stuff to be filled in by caller */
 
-u_long req_keyid;      /* request keyid */
+keyid_t req_keyid;     /* request keyid */
 char *req_file;                /* name of the file with configuration info */
 
 /* end stuff to be filled in */
@@ -129,7 +138,8 @@ char *req_file;             /* name of the file with configuration info */
 static RETSIGTYPE bong         P((int));
 static void    checkparent     P((void));
 static void    removeentry     P((struct conf_entry *));
-static void    addentry        P((char *, int, int, int, int, int, int, u_long));
+static void    addentry        P((char *, int, int, int, int, int,
+                                  int, keyid_t, char *));
 static int     findhostaddr    P((struct conf_entry *));
 static void    openntp         P((void));
 static int     request         P((struct conf_peer *));
@@ -137,10 +147,48 @@ static    char *  nexttoken       P((char **));
 static void    readconf        P((FILE *, char *));
 static void    doconfigure     P((int));
 
+struct ntp_res_t_pkt {         /* Tagged packet: */
+       void *tag;              /* For the caller */
+       u_int32 paddr;          /* IP to look up, or 0 */
+       char name[MAXHOSTNAMELEN]; /* Name to look up (if 1st byte is not 0) */
+};
+
+struct ntp_res_c_pkt {         /* Control packet: */
+       char name[MAXHOSTNAMELEN];
+       u_int32 paddr;
+       int mode;
+       int version;
+       int minpoll;
+       int maxpoll;
+       int flags;
+       int ttl;
+       keyid_t keyid;
+       u_char keystr[MAXFILENAME];
+};
+
+
+/*
+ * ntp_res_recv: Process an answer from the resolver
+ */
+
+void
+ntp_res_recv(void)
+{
+       /*
+         We have data ready on our descriptor.
+         It may be an EOF, meaning the resolver process went away.
+         Otherwise, it will be an "answer".
+       */
+}
+
+
 /*
- * assumes:  req_key, req_keyid, conffile valid
- *  syslog still open
+ * ntp_intres needs;
+ *
+ *     req_key(???), req_keyid, req_file valid
+ *     syslog still open
  */
+
 void
 ntp_intres(void)
 {
@@ -149,7 +197,7 @@ ntp_intres(void)
        sigset_t set;
 
        sigemptyset(&set);
-#endif /* NTP_POSIX_SOURCE */
+#endif /* HAVE_SIGSUSPEND */
 
 #ifdef DEBUG
        if (debug > 1) {
@@ -160,7 +208,7 @@ ntp_intres(void)
        /* check out auth stuff */
        if (sys_authenticate) {
                if (!authistrusted(req_keyid)) {
-                       msyslog(LOG_ERR, "invalid request keyid %lu",
+                       msyslog(LOG_ERR, "invalid request keyid %08x",
                            req_keyid );
                        exit(1);
                }
@@ -180,7 +228,7 @@ ntp_intres(void)
        (void) fclose(in);
 
        if (!debug )
-           (void) unlink(req_file);
+               (void) unlink(req_file);
 
        /*
         * Sleep a little to make sure the server is completely up
@@ -192,12 +240,13 @@ ntp_intres(void)
         * Make a first cut at resolving the bunch
         */
        doconfigure(1);
-       if (confentries == NULL)
+       if (confentries == NULL) {
 #if defined SYS_WINNT
-               ExitThread(0); /* Don't want to kill whole NT process */
+               ExitThread(0);  /* Don't want to kill whole NT process */
 #else
-           exit(0);            /* done that quick */
+               exit(0);        /* done that quick */
 #endif
+       }
        
        /*
         * Here we've got some problem children.  Set up the timer
@@ -239,11 +288,11 @@ ntp_intres(void)
                 * There is a race in here.  Is okay, though, since
                 * all it does is delay things by 30 seconds.
                 */
-#ifdef HAVE_SIGSUSPEND
+# ifdef HAVE_SIGSUSPEND
                sigsuspend(&set);
-#else
+# else
                sigpause(0);
-#endif /* HAVE_SIGSUSPEND */
+# endif /* HAVE_SIGSUSPEND */
 #else
                if (config_timer > 0)
                    config_timer--;
@@ -338,15 +387,23 @@ addentry(
        int maxpoll,
        int flags,
        int ttl,
-       u_long keyid
+       keyid_t keyid,
+       char *keystr
        )
 {
        register char *cp;
        register struct conf_entry *ce;
        unsigned int len;
 
+#ifdef DEBUG
+       if (debug > 1)
+               msyslog(LOG_INFO, 
+                       "intres: <%s> %d %d %d %d %d %d %u %s\n",
+                       name, mode, version,
+                       minpoll, maxpoll, flags, ttl, keyid, keystr);
+#endif
        len = strlen(name) + 1;
-       cp = (char*)emalloc(len);
+       cp = (char *)emalloc(len);
        memmove(cp, name, len);
 
        ce = (struct conf_entry *)emalloc(sizeof(struct conf_entry));
@@ -359,6 +416,7 @@ addentry(
        ce->ce_flags = (u_char)flags;
        ce->ce_ttl = (u_char)ttl;
        ce->ce_keyid = keyid;
+       strncpy(ce->ce_keystr, keystr, MAXFILENAME);
        ce->ce_next = NULL;
 
        if (confentries == NULL) {
@@ -375,12 +433,12 @@ addentry(
 
 
 /*
- * findhostaddr - resolve a host name into an address
+ * findhostaddr - resolve a host name into an address (Or vice-versa)
  *
- * The routine sticks the address into the entry's ce_peeraddr if it
- * gets one.  It returns 1 for "success" and 0 for an uncorrectable
- * failure.  Note that "success" includes try again errors.  You can
- * tell that you got a try again since ce_peeraddr will still be zero.
+ * Given one of {ce_peeraddr,ce_name}, find the other one.
+ * It returns 1 for "success" and 0 for an uncorrectable failure.
+ * Note that "success" includes try again errors.  You can tell that you
+ *  got a "try again" since {ce_peeraddr,ce_name} will still be zero.
  */
 static int
 findhostaddr(
@@ -391,28 +449,75 @@ findhostaddr(
 
        checkparent();          /* make sure our guy is still running */
 
-       hp = gethostbyname(entry->ce_name);
+       if (entry->ce_name && entry->ce_peeraddr) {
+               /* HMS: Squawk? */
+               msyslog(LOG_ERR, "findhostaddr: both ce_name and ce_peeraddr are defined...");
+               return 1;
+       }
+
+       if (!entry->ce_name && !entry->ce_peeraddr) {
+               msyslog(LOG_ERR, "findhostaddr: both ce_name and ce_peeraddr are undefined!");
+               return 0;
+       }
+
+       if (entry->ce_name) {
+#ifdef DEBUG
+               if (debug > 2)
+                       msyslog(LOG_DEBUG, "findhostaddr: Resolving <%s>",
+                               entry->ce_name);
+#endif DEBUG
+               hp = gethostbyname(entry->ce_name);
+       } else {
+#ifdef DEBUG
+               if (debug > 2)
+                       msyslog(LOG_DEBUG, "findhostaddr: Resolving %x>",
+                               entry->ce_peeraddr);
+#endif
+               hp = gethostbyaddr((const char *)entry->ce_peeraddr,
+                                  sizeof entry->ce_peeraddr,
+                                  AF_INET);
+       }
 
        if (hp == NULL) {
-#ifndef NODNS
                /*
                 * If the resolver is in use, see if the failure is
                 * temporary.  If so, return success.
                 */
                if (h_errno == TRY_AGAIN)
                    return (1);
-#endif
                return (0);
        }
 
-       /*
-        * Use the first address.  We don't have any way to
-        * tell preferences and older gethostbyname() implementations
-        * only return one.
-        */
-       memmove((char *)&(entry->ce_peeraddr),
-               (char *)hp->h_addr,
-               sizeof(struct in_addr));
+       if (entry->ce_name) {
+#ifdef DEBUG
+               if (debug > 2)
+                       msyslog(LOG_DEBUG, "findhostaddr: name resolved.");
+#endif
+               /*
+                * Use the first address.  We don't have any way to tell
+                * preferences and older gethostbyname() implementations
+                * only return one.
+                */
+               memmove((char *)&(entry->ce_peeraddr),
+                       (char *)hp->h_addr,
+                       sizeof(struct in_addr));
+               if (entry->ce_keystr[0] == '*')
+                       strncpy((char *)&(entry->ce_keystr), hp->h_name,
+                               MAXFILENAME);
+       } else {
+               char *cp;
+               size_t s;
+
+#ifdef DEBUG
+               if (debug > 2)
+                       msyslog(LOG_DEBUG, "findhostaddr: address resolved.");
+#endif
+               s = strlen(hp->h_name) + 1;
+               cp = emalloc(s);
+               strcpy(cp, hp->h_name);
+               entry->ce_name = cp;
+       }
+                  
        return (1);
 }
 
@@ -460,7 +565,7 @@ openntp(void)
 #endif /* O_NONBLOCK */
 #else  /* SYS_WINNT */
        {
-               int on=1;
+               int on = 1;
                if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) {
                        msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m");
                        exit(1); /* Windows NT - set socket in non-blocking mode */
@@ -470,7 +575,7 @@ openntp(void)
 
 
        if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
-               msyslog(LOG_ERR, "connect() failed: %m");
+               msyslog(LOG_ERR, "openntp: connect() failed: %m");
                exit(1);
        }
 }
@@ -552,7 +657,7 @@ request(
        }
 #else
        /* In the NT world, documentation seems to indicate that there
-        * exist _write and _read routines that can be used to so blocking
+        * exist _write and _read routines that can be used to do blocking
         * I/O on sockets. Problem is these routines require a socket
         * handle obtained through the _open_osf_handle C run-time API
         * of which there is no explanation in the documentation. We need
@@ -830,7 +935,7 @@ readconf(
                        }
                }
 
-               for (i = 1; i < NUMTOK; i++) {
+               for (i = 1; i < NUMTOK - 1; i++) {
                        if (!atouint(token[i], &intval[i])) {
                                msyslog(LOG_ERR,
                                        "format error for integer token `%s', file `%s', quitting",
@@ -893,7 +998,7 @@ readconf(
                addentry(token[TOK_HOSTNAME], (int)intval[TOK_HMODE],
                         (int)intval[TOK_VERSION], (int)intval[TOK_MINPOLL],
                         (int)intval[TOK_MAXPOLL], flags, (int)intval[TOK_TTL],
-                        intval[TOK_KEYID]);
+                        intval[TOK_KEYID], token[TOK_KEYSTR]);
        }
 }
 
@@ -909,16 +1014,12 @@ doconfigure(
        register struct conf_entry *ce;
        register struct conf_entry *ceremove;
 
-#ifdef DEBUG
-       if (debug > 1)
-           msyslog(LOG_INFO, "doconfigure(%d)", dores);
-#endif
-
        ce = confentries;
        while (ce != NULL) {
 #ifdef DEBUG
                if (debug > 1)
-                   msyslog(LOG_INFO, "doconfigure: <%s> has peeraddr %#x",
+                       msyslog(LOG_INFO,
+                           "doconfigure: <%s> has peeraddr %#x",
                            ce->ce_name, ce->ce_peeraddr);
 #endif
                if (dores && ce->ce_peeraddr == 0) {
@@ -931,28 +1032,10 @@ doconfigure(
                                removeentry(ceremove);
                                continue;
                        }
-#ifdef DEBUG
-                       if (debug > 1) {
-                               msyslog(LOG_INFO,
-                                       "doconfigure:findhostaddr() worked");
-                       }
-#endif
                }
 
                if (ce->ce_peeraddr != 0) {
-#ifdef DEBUG
-                       if (debug > 1) {
-                               msyslog(LOG_INFO,
-                                       "doconfigure: calling request()");
-                       }
-#endif
                        if (request(&ce->ce_config)) {
-#ifdef DEBUG
-                               if (debug > 1) {
-                                       msyslog(LOG_INFO,
-                                               "doconfigure: request() OK, removing this entry");
-                               }
-#endif
                                ceremove = ce;
                                ce = ceremove->ce_next;
                                removeentry(ceremove);
@@ -961,7 +1044,7 @@ doconfigure(
 #ifdef DEBUG
                        if (debug > 1) {
                                msyslog(LOG_INFO,
-                                       "doconfigure: request() FAILED, maybe next time.");
+                                   "doconfigure: request() FAILED, maybe next time.");
                        }
 #endif
                }
index 15b625de6f2009c9ced2a20166a0864ba748068a..88f61bf17e0e840fabfd777b2060fdd00db2399f 100644 (file)
@@ -583,14 +583,14 @@ local_clock(
        sys_rootdispersion = peer->rootdispersion + dtemp;
        (void)record_loop_stats();
 #ifdef DEBUG
-       if (debug)
+       if (debug > 1)
                printf(
        "local_clock: mu %.0f allan %.0f fadj %.3f fll %.3f pll %.3f\n",
                    mu, allan_xpt, clock_frequency * 1e6, flladj * 1e6,
                    plladj * 1e6);
 #endif /* DEBUG */
 #ifdef DEBUG
-       if (debug)
+       if (debug > 1)
                printf(
        "local_clock: jitter %.6f freq %.3f stab %.3f poll %d count %d\n",
                    sys_error, drift_comp * 1e6, clock_stability * 1e6,
index 90646abcfac7123611d631c9369b293cbfce2862..470a107f3334f67bb3a2ceca35a71755442cef95 100644 (file)
@@ -10,6 +10,9 @@
 
 #include "ntpd.h"
 #include "ntp_stdlib.h"
+#ifdef PUBKEY
+#include "ntp_crypto.h"
+#endif /* PUBKEY */
 
 /*
  *                  Table of valid association combinations
@@ -127,7 +130,6 @@ static struct peer init_peer_alloc[INIT_PEER_ALLOC];
 /* static u_long init_peer_starttime; */
 
 static void    getmorepeermem  P((void));
-static void    key_expire      P((struct peer *));
 
 /*
  * init_peer - initialize peer data structures and counters
@@ -285,21 +287,17 @@ findpeer(
                }
        }
 
-#ifdef DEBUG
-       if (debug > 1)
-               printf("pkt_mode %d action %d\n", pkt_mode, *action);
-#endif
-       /* if no matching association is found */
+       /*
+        * If no matching association is found
+        */
        if (peer == 0) {
                *action = MATCH_ASSOC(NO_PEER, pkt_mode);
-#ifdef DEBUG
-               if (debug > 1)
-                       printf("pkt_mode %d action %d\n", pkt_mode, *action);
-#endif
                return (struct peer *)0;
        }
 
-       /* reset the default interface to something more meaningful */
+       /*
+        * Reset the default interface to something more meaningful
+        */
        if ((peer->dstadr == any_interface))
                peer->dstadr = dstadr;
        return peer;
@@ -368,31 +366,10 @@ findmanycastpeer(
        return manycast_peer;
 }
 
+#ifdef AUTOKEY
 /*
- * key_expire - garbage collect keys
- */
-static void
-key_expire(
-       struct peer *peer
-       )
-{
-       int i;
-
-       if (peer->keylist != 0) {
-               for (i = 0; i <= peer->keynumber; i++)
-                       authtrust(peer->keylist[i], 0);
-               free(peer->keylist);
-               peer->keylist = 0;
-       }
-       if (peer->keyid > NTP_MAXKEY) {
-               authtrust(peer->keyid, 0);
-               peer->keyid = 0;
-       }
-}
-
-/*
- * key_rekey - expire all keys and roll a new private value. Note the
- * 32-bit mask is necessary for 64-bit u_longs.
+ * key_expire - expire all keys and roll a new private value. Note the
+ * 32-bit mask is necessary for 64-bit u_ints.
  */
 void
 key_expire_all(
@@ -404,16 +381,21 @@ key_expire_all(
        for (n = 0; n < HASH_SIZE; n++) {
                for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
                        next_peer = peer->next;
-                       key_expire(peer);
+                       peer_clear(peer);
                }
        }
-       sys_private = (u_long)RANDOM & 0xffffffff;
+       sys_private = (u_int32)RANDOM & 0xffffffff;
+#ifdef PUBKEY
+       crypto_agree();
+#endif /* PUBKEY */
 #ifdef DEBUG
        if (debug)
-               printf("key_expire_all: at %lu private %08lx\n",
-                   current_time, sys_private);
+               printf("key_expire_all: at %lu private %08x next %lu\n",
+                   current_time, sys_private, current_time + sys_revoke);
 #endif
 }
+#endif /* AUTOKEY */
+
 /*
  * unpeer - remove peer structure from hash table and free structure
  */
@@ -424,16 +406,22 @@ unpeer(
 {
        int hash;
 
+       peer_associations--;
 #ifdef DEBUG
-       if (debug > 1)
-               printf("demobilize %u\n", peer_to_remove->associd);
+       if (debug)
+               printf("demobilize %u %d\n", peer_to_remove->associd,
+                   peer_associations);
 #endif
-       key_expire(peer_to_remove);
+       peer_clear(peer_to_remove);
+       if (peer_to_remove->keystr != 0)
+               free(peer_to_remove->keystr);
+#ifdef PUBKEY
+       if (peer_to_remove->pubkey != 0)
+               free(peer_to_remove->pubkey);
+#endif /* PUBKEY */
        hash = HASH_ADDR(&peer_to_remove->srcadr);
        peer_hash_count[hash]--;
        peer_demobilizations++;
-       peer_associations--;
-
 #ifdef REFCLOCK
        /*
         * If this peer is actually a clock, shut it down first
@@ -502,7 +490,8 @@ peer_config(
        int maxpoll,
        int flags,
        int ttl,
-       u_long key
+       keyid_t key,
+       u_char *keystr
        )
 {
        register struct peer *peer;
@@ -515,7 +504,7 @@ peer_config(
        if (dstadr != 0) {
                while (peer != 0) {
                        if (peer->dstadr == dstadr)
-                           break;
+                               break;
                        peer = findexistingpeer(srcadr, peer, hmode);
                }
        }
@@ -533,30 +522,36 @@ peer_config(
                peer->flags = flags | FLAG_CONFIG |
                        (peer->flags & FLAG_REFCLOCK);
                peer->cast_flags = (hmode == MODE_BROADCAST) ?
-                       IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)) ? MDF_MCAST : MDF_BCAST : MDF_UCAST;
+                   IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)) ?
+                   MDF_MCAST : MDF_BCAST : MDF_UCAST;
                peer->ttl = (u_char)ttl;
                peer->keyid = key;
-               peer->keynumber = 0;
-               return peer;
-       }
+       } else {
 
-       /*
-        * If we're here this guy is unknown to us.  Make a new peer
-        * structure for him.
-        */
-       peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
-                      ttl, key);
-       if (peer != 0) {
+               /*
+                * If we're here this guy is unknown to us.  Make a new peer
+                * structure for him.
+                */
+               peer = newpeer(srcadr, dstadr, hmode, version, minpoll,
+                   maxpoll, ttl, key);
+               if (peer == 0)
+                       return (peer);
                peer->flags |= flags | FLAG_CONFIG;
+       }
 #ifdef DEBUG
-               if (debug)
-                       printf("peer_config: %s mode %d vers %d min %d max %d flags 0x%04x ttl %d key %lu\n",
-                           ntoa(&peer->srcadr), peer->hmode, peer->version,
-                           peer->minpoll, peer->maxpoll, peer->flags,
-                           peer->ttl, peer->keyid);
+       if (debug)
+               printf(
+                   "peer_config: %s mode %d vers %d min %d max %d flags 0x%04x ttl %d key %08x\n",
+                   ntoa(&peer->srcadr), peer->hmode, peer->version,
+                   peer->minpoll, peer->maxpoll, peer->flags, peer->ttl,
+                   peer->keyid);
 #endif
-       }
-       return peer;
+#ifdef PUBKEY
+       if (!(peer->flags & FLAG_SKEY))
+               return (peer);
+       crypto_public(peer, keystr);
+#endif /* PUBKEY */
+       return (peer);
 }
 
 
@@ -583,7 +578,7 @@ newpeer(
         * knowlege of our system state.
         */
        if (peer_free_count == 0)
-           getmorepeermem();
+               getmorepeermem();
 
        peer = peer_free;
        peer_free = peer->next;
@@ -593,12 +588,11 @@ newpeer(
        /*
         * Initialize the structure.  This stuff is sort of part of
         * the receive procedure and part of the clear procedure rolled
-                * into one.
-                *
+        * into one.
+        *
         * Zero the whole thing for now.  We might be pickier later.
         */
        memset((char *)peer, 0, sizeof(struct peer));
-
        peer->srcadr = *srcadr;
        if (dstadr != 0)
                peer->dstadr = dstadr;
@@ -630,15 +624,13 @@ newpeer(
        peer_clear(peer);
        peer->update = peer->outdate = current_time;
        peer->nextdate = peer->outdate + RANDPOLL(NTP_MINPOLL);
-       if (peer->flags & FLAG_BURST)
-               peer->burst = NTP_SHIFT;
 
        /*
         * Assign him an association ID and increment the system variable
         */
        peer->associd = current_association_ID;
        if (++current_association_ID == 0)
-           ++current_association_ID;
+               ++current_association_ID;
 
        /*
         * Note time on statistics timers.
@@ -680,9 +672,9 @@ newpeer(
        assoc_hash[i] = peer;
        assoc_hash_count[i]++;
 #ifdef DEBUG
-       if (debug > 1)
-               printf("mobilize %u next %lu\n", peer->associd,
-                   peer->nextdate - peer->outdate);
+       if (debug)
+               printf("mobilize %u %d next %lu\n", peer->associd,
+                   peer_associations, peer->nextdate - peer->outdate);
 #endif
        return peer;
 }
@@ -775,7 +767,6 @@ peer_reset(
        peer->oldpkt = 0;
        peer->seldisptoolarge = 0;
        peer->selbroken = 0;
-       peer->seltooold = 0;
        peer->timereset = current_time;
 }
 
index a24c0e3e567fc82f7941226cf2f76cb51087fad4..7c1142a660a8a98cd478976d7058b029d1fa3039 100644 (file)
@@ -14,6 +14,7 @@
 #include "ntp_unixtime.h"
 #include "ntp_control.h"
 #include "ntp_string.h"
+#include "ntp_crypto.h"
 
 #if defined(VMS) && defined(VMS_LOCALUNIT)     /*wjm*/
 #include "ntp_refclock.h"
@@ -24,7 +25,7 @@
 #endif
 
 /*
- * System variables are declared here. See Section 3.2 of the
+ * System variables are declared here. See Section 3.2 of the
  * specification.
  */
 u_char sys_leap;               /* system leap indicator */
@@ -36,7 +37,9 @@ u_int32 sys_refid;            /* reference source for local clock */
 static double sys_offset;      /* current local clock offset */
 l_fp   sys_reftime;            /* time we were last updated */
 struct peer *sys_peer;         /* our current peer */
+#ifdef AUTOKEY
 u_long sys_automax;            /* maximum session key lifetime */
+#endif /* AUTOKEY */
 
 /*
  * Nonspecified system state variables.
@@ -49,7 +52,7 @@ static        u_long sys_authdly[2];  /* authentication delay shift reg */
 static u_char leap_consensus;  /* consensus of survivor leap bits */
 static double sys_maxd;        /* select error (squares) */
 static double sys_epsil;       /* system error (squares) */
-u_long sys_private;            /* private value for session seed */
+keyid_t        sys_private;            /* private value for session seed */
 int    sys_manycastserver;     /* 1 => respond to manycast client pkts */
 
 /*
@@ -68,12 +71,10 @@ u_long      sys_limitrejected;      /* pkts rejected due to client count per net */
 static double  root_distance   P((struct peer *));
 static double  clock_combine   P((struct peer **, int));
 static void    peer_xmit       P((struct peer *));
-static void    fast_xmit       P((struct recvbuf *, int, u_long));
+static void    fast_xmit       P((struct recvbuf *, int, keyid_t));
 static void    clock_update    P((void));
 int    default_get_precision   P((void));
-#ifdef MD5
-static void    make_keylist    P((struct peer *));
-#endif /* MD5 */
+
 
 /*
  * transmit - Transmit Procedure. See Section 3.4.2 of the
@@ -101,22 +102,30 @@ transmit(
                        peer->valid++;
                if (oreach & 0x80)
                        peer->valid--;
-               if (!(peer->flags & FLAG_CONFIG) && peer->valid >
-                   NTP_SHIFT / 2 && (peer->reach & 0x80) &&
-                   peer->status < CTL_PST_SEL_SYNCCAND)
-                       peer->reach = 0;
                peer->reach <<= 1;
                if (peer->reach == 0) {
 
                        /*
-                        * If this is an uncofigured association and
-                        * has become unreachable, demobilize it.
+                        * If this association has become unreachable,
+                        * clear it and raise a trap.
                         */
                        if (oreach != 0) {
                                report_event(EVNT_UNREACH, peer);
                                peer->timereachable = current_time;
                                peer_clear(peer);
-                               if (!(peer->flags & FLAG_CONFIG)) {
+                       }
+
+                       /*
+                        * If this association is unreachable and not
+                        * configured, we give it a little while before
+                        * pulling the plug. This is to allow semi-
+                        * persistent things like cryptographic
+                        * authentication to complete the dance. There
+                        * is a denial-of-service hazard here.
+                        */
+                       if (!(peer->flags & FLAG_CONFIG)) {
+                               peer->tailcnt++;
+                               if (peer->tailcnt > NTP_TAILMAX) {
                                        unpeer(peer);
                                        return;
                                }
@@ -133,14 +142,19 @@ transmit(
                         */
                        peer->ppoll = peer->maxpoll;
                        if (peer->unreach < NTP_UNREACH) {
-                               if (peer->hmode == MODE_CLIENT)
+                               if (peer->hmode == MODE_CLIENT ||
+                                   peer->hmode == MODE_ACTIVE)
                                        peer->unreach++;
                                hpoll = peer->minpoll;
                        } else {
                                hpoll++;
                        }
-                       if (peer->flags & FLAG_BURST)
-                               peer->burst = 2;
+                       if (peer->flags & FLAG_BURST) {
+                               if (peer->flags & FLAG_MCAST2)
+                                       peer->burst = NTP_SHIFT;
+                               else
+                                       peer->burst = 2;
+                       }
 
                } else {
 
@@ -162,7 +176,7 @@ transmit(
                                clock_filter(peer, 0., 0., MAXDISPERSE);
                                clock_select();
                        }
-                       if (peer->valid <= 2)
+                       if (peer->valid <= 2 && hpoll > peer->minpoll)
                                hpoll--;
                        else if (peer->valid >= NTP_SHIFT - 2)
                                hpoll++;
@@ -172,9 +186,20 @@ transmit(
        } else {
                peer->burst--;
                if (peer->burst == 0) {
+
+                       /*
+                        * If a broadcast client at this point, the
+                        * burst has concluded, so we turn off the
+                        * burst, switch to client mode and purge the
+                        * keylist, since no further transmissions will
+                        * be made.
+                        */
                        if (peer->flags & FLAG_MCAST2) {
                                peer->flags &= ~FLAG_BURST;
                                peer->hmode = MODE_BCLIENT;
+#ifdef AUTOKEY
+                               key_expire(peer);
+#endif /* AUTOKEY */
                        }
                        clock_select();
                        poll_update(peer, hpoll);
@@ -216,203 +241,232 @@ receive(
        int hismode;
        int oflags;
        int restrict_mask;
-       int has_mac;                    /* has MAC field */
-       int authlen;                    /* length of MAC field */
+       int has_mac;                    /* length of MAC field */
+       int authlen;                    /* offset of MAC field */
        int is_authentic;               /* cryptosum ok */
-       int is_mystic;                  /* session key exists */
        int is_error;                   /* parse error */
-/*     u_long pkeyid; */
-       u_long skeyid, tkeyid;
+       keyid_t pkeyid, skeyid, tkeyid; /* cryptographic keys */
        struct peer *peer2;
        int retcode = AM_NOMATCH;
 
        /*
-        * Monitor the packet and get restrictions
+        * Monitor the packet and get restrictions. Note that the packet
+        * length for control and private mode packets must be checked
+        * by the service routines. Note that no statistics counters are
+        * recorded for restrict violations, since these counters are in
+        * the restriction routine.
         */
        ntp_monitor(rbufp);
        restrict_mask = restrictions(&rbufp->recv_srcadr);
 #ifdef DEBUG
-       if (debug > 1)
-               printf("receive: from %s restrict %02x\n",
-                   ntoa(&rbufp->recv_srcadr), restrict_mask);
+       if (debug > 2)
+               printf("receive: at %ld %s restrict %02x\n",
+                   current_time, ntoa(&rbufp->recv_srcadr),
+                   restrict_mask);
 #endif
        if (restrict_mask & RES_IGNORE)
-               return;
-
-       /*
-        * Discard packets with invalid version number.
-        */
+               return;                         /* no amything */
        pkt = &rbufp->recv_pkt;
        if (PKT_VERSION(pkt->li_vn_mode) >= NTP_VERSION)
                sys_newversionpkt++;
        else if (PKT_VERSION(pkt->li_vn_mode) >= NTP_OLDVERSION)
                sys_oldversionpkt++;
        else {
-               sys_unknownversion++;
+               sys_unknownversion++;           /* unknown version */
                return;
        }
-
-       /*
-        * Restrict control/private mode packets. Note that packet
-        * length has to be checked in the control/private mode protocol
-        * module.
-        */
        if (PKT_MODE(pkt->li_vn_mode) == MODE_PRIVATE) {
                if (restrict_mask & RES_NOQUERY)
-                   return;
+                   return;                     /* no query private */
                process_private(rbufp, ((restrict_mask &
                    RES_NOMODIFY) == 0));
                return;
        }
        if (PKT_MODE(pkt->li_vn_mode) == MODE_CONTROL) {
                if (restrict_mask & RES_NOQUERY)
-                   return;
+                   return;                     /* no query control */
                process_control(rbufp, restrict_mask);
                return;
        }
-
-       /*
-        * Restrict revenue packets.
-        */
        if (restrict_mask & RES_DONTSERVE)
-               return;
-
-        /*
-        * See if we only accept limited number of clients from the net
-        * this guy is from. Note: the flag is determined dynamically
-        * within restrictions()
-        */
+               return;                         /* no time service */
        if (restrict_mask & RES_LIMITED) {
                sys_limitrejected++;
-                return;
+                return;                                /* too many clients */
         }
+       if (rbufp->recv_length < LEN_PKT_NOMAC) {
+               sys_badlength++;
+               return;                         /* no runt packets */
+       }
 
        /*
-        * If we are not a broadcast client, ignore broadcast packets.
+        * Figure out his mode and validate the packet. This has some
+        * legacy raunch that probably should be removed. If from NTPv1
+        * mode zero, The NTPv4 mode is determined from the source port.
+        * If the port number is zero, it is from a symmetric active
+        * association; otherwise, it is from a client association. From
+        * NTPv2 on, all we do is toss out mode zero packets, since
+        * control and private mode packets have already been handled.
+        * In either case, toss out broadcast packets if we are not a
+        * broadcast client. 
         */
+       hismode = (int)PKT_MODE(pkt->li_vn_mode);
+       if (PKT_VERSION(pkt->li_vn_mode) == NTP_OLDVERSION && hismode ==
+           0) {
+               if (SRCPORT(&rbufp->recv_srcadr) == NTP_PORT)
+                       hismode = MODE_ACTIVE;
+               else
+                       hismode = MODE_CLIENT;
+       } else {
+               if (hismode == MODE_UNSPEC) {
+                       sys_badlength++;
+                       return;                 /* invalid mode */
+               }
+       }
        if ((PKT_MODE(pkt->li_vn_mode) == MODE_BROADCAST &&
            !sys_bclient))
                return;
 
        /*
-        * This is really awful ugly. We figure out whether an extension
-        * field is present and then measure the MAC size. If the number
-        * of words following the packet header is less than or equal to
-        * 5, no extension field is present and these words constitute
-        * the MAC. If the number of words is greater than 5, an
-        * extension field is present and the first word contains the
-        * length of the extension field and the MAC follows that.
+        * Parse the extension field if present. We figure out whether
+        * an extension field is present by measuring the MAC size. If
+        * the number of words following the packet header is 0 or 1, no
+        * MAC is present and the packet is not authenticated. If 1, the
+        * packet is a reply to a previous request that failed to
+        * authenticate. If 3, the packet is authenticated with DES; if
+        * 5, the packet is authenticated with MD5. If greater than 5,
+        * an extension field is present. If 2 or 4, the packet is a
+        * runt and thus discarded.
         */
-       has_mac = 0;
-/*     pkeyid = 0; */
-       skeyid = tkeyid = 0;
+       pkeyid = skeyid = tkeyid = 0;
        authlen = LEN_PKT_NOMAC;
-       has_mac = rbufp->recv_length - authlen;
-       if (has_mac <= 5 * sizeof(u_int32)) {
-               skeyid = (u_long)ntohl(pkt->keyid1) & 0xffffffff;
-       } else {
-               authlen += (u_long)ntohl(pkt->keyid1) & 0xffffffff;
-               has_mac = rbufp->recv_length - authlen;
-               if (authlen <= 0) {
+       while ((has_mac = rbufp->recv_length - authlen) > 0) {
+               int temp;
+               if (has_mac % 4 != 0 || has_mac < 0) {
                        sys_badlength++;
                        return;
                }
-
-               /*
-                * Note that keyid3 is actually the key ident of the
-                * MAC itself.
-                */
-/*             pkeyid = (u_long)ntohl(pkt->keyid2) & 0xffffffff; */
-               skeyid = tkeyid = (u_long)ntohl(pkt->keyid3) &
-                   0xffffffff;
-       }
-
-       /*
-        * Figure out his mode and validate it.
-        */
-       hismode = (int)PKT_MODE(pkt->li_vn_mode);
-       if (PKT_VERSION(pkt->li_vn_mode) == NTP_OLDVERSION && hismode ==
-               0) {
-               /*
-                * Easy.  If it is from the NTP port it is
-                * a sym act, else client.
-                */
-               if (SRCPORT(&rbufp->recv_srcadr) == NTP_PORT)
-                       hismode = MODE_ACTIVE;
-               else
-                       hismode = MODE_CLIENT;
-       } else {
-               if (hismode != MODE_ACTIVE && hismode != MODE_PASSIVE &&
-                       hismode != MODE_SERVER && hismode != MODE_CLIENT &&
-                       hismode != MODE_BROADCAST)
+               if (has_mac == 1 * 4 || has_mac == 3 * 4 || has_mac ==
+                   MAX_MAC_LEN) {
+                       skeyid =
+                           (u_long)ntohl(((u_int32 *)pkt)[authlen /
+                           4]) & 0xffffffff;
+                       break;
+               } else if (has_mac > MAX_MAC_LEN) {
+                       temp = ntohl(((u_int32 *)pkt)[authlen / 4]) &
+                           0xffff;
+                       if (temp < 4) {
+                               sys_badlength++;
+                               return;
+                       }
+                       authlen += temp;
+               } else {
+                       sys_badlength++;
                        return;
+               }
        }
 
        /*
-        * If he included a mac field, decrypt it to see if it is
-        * authentic.
+        * We have tossed out as many buggy packets as possible early in
+        * the game to reduce the exposure to a clogging attack. Now we
+        * have to burn some cycles to find the association and
+        * authenticate the packet if required. Note that we burn only
+        * MD5 or DES cycles, again to reduce exposure. There may be no
+        * matching association and that's okay.
         */
-       is_authentic = is_mystic = 0;
+       peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr, rbufp->fd,
+           hismode, &retcode);
+       is_authentic = 0;
        if (has_mac == 0) {
 #ifdef DEBUG
                if (debug)
-                       printf("receive: at %ld from %s mode %d\n",
-                               current_time, ntoa(&rbufp->recv_srcadr),
-                               hismode);
+                       printf("receive: at %ld %s mode %d code %d\n",
+                           current_time, ntoa(&rbufp->recv_srcadr),
+                           hismode, retcode);
 #endif
        } else {
-               is_mystic = authistrusted(skeyid);
-#ifdef MD5
-               if (skeyid > NTP_MAXKEY && !is_mystic) {
+#ifdef AUTOKEY
+               /*
+                * For autokey modes, generate the session key
+                * and install in the key cache. Use the socket
+                * multicast or unicast address as appropriate.
+                * Remember, we don't know these addresses until
+                * the first packet has been received. Bummer.
+                */
+               if (skeyid > NTP_MAXKEY) {
+               
+                       /*
+                        * More on the autokey dance (AKD). A cookie is
+                        * constructed from public and private values.
+                        * For broadcast packets and packets with
+                        * extension fields, the cookie is public
+                        * (zero); for packets that match no
+                        * association, the cookie is hashed from the
+                        * addresses and private value. For server and
+                        * symmetric packets, the cookie has been
+                        * previously obtained from the server via an
+                        * extension field. for symmetric modes, a
+                        * common cookie is constructed as the exclusive
+                        * OR of the two cookies.
+                        */
+                       if (authlen > LEN_PKT_NOMAC || hismode ==
+                           MODE_BROADCAST)
+                               pkeyid = 0;
+                       else if (peer == 0)
+                               pkeyid = session_key(
+                                   &rbufp->recv_srcadr,
+                                   &rbufp->dstadr->sin, 0, sys_private,
+                                   0);
+                       else if (hismode == MODE_CLIENT)
+                               pkeyid = peer->hcookie;
+                       else
+                               pkeyid = peer->pcookie;
 
                        /*
-                        * For multicast mode, generate the session key
-                        * and install in the key cache. For client
-                        * mode, generate the session key for the
-                        * unicast address. For server mode, the session
-                        * key should already be in the key cache, since
-                        * it was generated when the last request was
-                        * sent.
+                        * The session key includes both the public
+                        * values and cookie. We have to be careful to
+                        * use the right socket addresses for broadcast
+                        * and unicast packets. Note the hash is saved
+                        * for use later in the AKD mambo.
                         */
-                       if (hismode == MODE_BROADCAST) {
+                       if (hismode == MODE_BROADCAST)
                                tkeyid = session_key(
-                                       ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr),
-                                       ntohl(rbufp->dstadr->bcast.sin_addr.s_addr),
-                                       skeyid, (u_long)(4 * (1 << pkt->ppoll)));
-                       } else if (hismode != MODE_SERVER) {
+                                   &rbufp->recv_srcadr,
+                                   &rbufp->dstadr->bcast, skeyid,
+                                   pkeyid, 2);
+                       else
                                tkeyid = session_key(
-                                       ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr),
-                                       ntohl(rbufp->dstadr->sin.sin_addr.s_addr),
-                                       skeyid, (u_long)(4 * (1 << pkt->ppoll)));
-                       }
-
+                                   &rbufp->recv_srcadr,
+                                   &rbufp->dstadr->sin, skeyid, pkeyid,
+                                   2);
                }
-#endif /* MD5 */
+#endif /* AUTOKEY */
 
                /*
                 * Compute the cryptosum. Note a clogging attack may
-                * succceed in bloating the key cache.
+                * succeed in bloating the key cache. If an autokey,
+                * purge it immediately, since we won't be needing it
+                * again.
                 */
                if (authdecrypt(skeyid, (u_int32 *)pkt, authlen,
                    has_mac))
                        is_authentic = 1;
                else
                        sys_badauth++;
+#ifdef AUTOKEY
+               if (skeyid > NTP_MAXKEY)
+                       authtrust(skeyid, 0);
+#endif /* AUTOKEY */
 #ifdef DEBUG
                if (debug)
                        printf(
-                               "receive: at %ld %s mode %d keyid %08lx mac %d auth %d\n",
-                               current_time, ntoa(&rbufp->recv_srcadr),
-                               hismode, skeyid, has_mac, is_authentic);
+                           "receive: at %ld %s mode %d code %d keyid %08x len %d mac %d auth %d\n",
+                           current_time, ntoa(&rbufp->recv_srcadr),
+                           hismode, retcode, skeyid, authlen, has_mac,
+                           is_authentic);
 #endif
        }
 
-       /*
-        * Find the peer.  This will return a null if this guy isn't in
-        * the database.
-        */
-       peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr, rbufp->fd,
-               hismode, &retcode);
        /*
         * The new association matching rules are driven by a table
         * specified in ntp.h. We have replaced the *default* behaviour
@@ -442,14 +496,7 @@ receive(
                        else
                                fast_xmit(rbufp, MODE_SERVER, 0);
                }
-
-               /*
-                * We can't get here if an association is mobilized, so
-                * just toss the key, if appropriate.
-                */
-               if (!is_mystic && skeyid > NTP_MAXKEY)
-                       authtrust(skeyid, 0);
-                       return;
+               return;
 
        case AM_MANYCAST:
 
@@ -505,8 +552,8 @@ receive(
                 * properly authenticated.
                 */
                if ((sys_authenticate && !is_authentic)) {
-                       is_error = 1;
-                       break;
+                       fast_xmit(rbufp, MODE_PASSIVE, 0);
+                       return;
                }
                peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr,
                    MODE_PASSIVE, PKT_VERSION(pkt->li_vn_mode),
@@ -557,141 +604,151 @@ receive(
                 * throw the structure away without fear of breaking
                 * anything.
                 */
-               if (!is_mystic && skeyid > NTP_MAXKEY)
-                       authtrust(skeyid, 0);
                if (peer != 0)
                        if (!(peer->flags & FLAG_CONFIG))
                                unpeer(peer);
 #ifdef DEBUG
                if (debug)
-                       printf("match error code %d assoc %d\n",
-                           retcode, peer_associations);
+                       printf("receive: bad protocol %d\n", retcode);
 #endif
                return;
        }
 
        /*
-        * If the peer isn't configured, set his keyid and authenable
-        * status based on the packet.
+        * If the peer isn't configured, set his authenable and autokey
+        * status based on the packet. Once the status is set, it can't
+        * be unset. It seems like a silly idea to do this here, rather
+        * in the configuration routine, but in some goofy cases the
+        * first packet sent cannot be authenticated and we need a way
+        * for the dude to change his mind.
         */
        oflags = peer->flags;
        peer->timereceived = current_time;
+       peer->received++;
        if (!(peer->flags & FLAG_CONFIG) && has_mac) {
                peer->flags |= FLAG_AUTHENABLE;
-               if (skeyid > NTP_MAXKEY) {
-                       if (peer->flags & FLAG_MCAST2)
-                               peer->keyid = skeyid;
-                       else
-                               peer->flags |= FLAG_SKEY;
-               }
+#ifdef AUTOKEY
+               if (skeyid > NTP_MAXKEY)
+                       peer->flags |= FLAG_SKEY;
+#endif /* AUTOKEY */
        }
 
        /*
-        * Determine if this guy is basically trustable. If not, flush
-        * the bugger. If this is the first packet that is
-        * authenticated, flush the clock filter. This is to foil
-        * clogging attacks that might starve the poor dear.
+        * A valid packet must be from an authentic and allowed source.
+        * All packets must pass the authentication allowed tests.
+        * Autokey authenticated packets must pass additional tests and
+        * public-key authenticated packets must have the credentials
+        * verified. If all tests are passed, the packet is forwarded
+        * for processing. If not, the packet is discarded and the
+        * association demobilized if appropriate.
         */
        peer->flash = 0;
-       if (is_authentic)
+       if (is_authentic) {
                peer->flags |= FLAG_AUTHENTIC;
-       else
+               peer->tailcnt = 0;
+       } else {
                peer->flags &= ~FLAG_AUTHENTIC;
-       if (peer->hmode == MODE_BROADCAST && (restrict_mask &
-           RES_DONTTRUST))
-               peer->flash |= TEST10;          /* access denied */
+       }
+       if (peer->hmode == MODE_BROADCAST &&
+           (restrict_mask & RES_DONTTRUST))    /* test 9 */
+               peer->flash |= TEST9;           /* access denied */
        if (peer->flags & FLAG_AUTHENABLE) {
-               if (!(peer->flags & FLAG_AUTHENTIC))
+               if (!(peer->flags & FLAG_AUTHENTIC)) { /* test 5 */
                        peer->flash |= TEST5;   /* auth failed */
-               else if (skeyid == 0)
-                       peer->flash |= TEST9;   /* peer not auth */
-               else if (!(oflags & FLAG_AUTHENABLE)) {
-                       peer_clear(peer);
+#ifdef AUTOKEY
+                       peer->pcookie = 0;
+#endif /* AUTOKEY */
+               } else if (!(oflags & FLAG_AUTHENABLE)) {
                        report_event(EVNT_PEERAUTH, peer);
                }
        }
-       if ((peer->flash & ~(u_int)TEST9) != 0) {
-
-               /*
-                * The packet is bogus, so we throw it away before
-                * becoming a denial-of-service hazard. We don't throw
-                * the current association away if it is configured or
-                * if it has prior reachable friends.
-                */
-               if (!is_mystic && skeyid > NTP_MAXKEY)
-                       authtrust(skeyid, 0);
-               if (!(peer->flags & FLAG_CONFIG) && peer->reach == 0)
-                       unpeer(peer);
+       if (peer->flash) {
 #ifdef DEBUG
                if (debug)
-                       printf(
-                           "invalid packet 0x%02x code %d assoc %d\n",
-                           peer->flash, retcode, peer_associations);
+                       printf("receive: bad packet %03x\n",
+                           peer->flash);
 #endif
                return;
        }
 
-#ifdef MD5
+#ifdef AUTOKEY
        /*
-        * The autokey dance. The cha-cha requires that the hash of the
-        * current session key matches the previous key identifier.
-        * Heaps of trouble if the steps falter.
+        * More autokey dance. The rules of the cha-cha are as follows:
+        *
+        * 1. If there is no key or the key is not auto, do nothing.
+        *
+        * 2. If this is a server reply, check only to see that the
+        *    transmitted key ID matches the received key ID.
+        *
+        * 3. If there are no extension fields or if this is a
+        *    broadcast, the cookie is zero. Dance the conga line and
+        *    check to see that one or more hashes of the current key ID
+        *    matches the previous key ID or ultimate original key ID
+        *    obtained from the broadcaster or symmetric peer. If no
+        *    match, arm for an autokey values update.
+        *
+        * 4. The only remaining case is where an extension field is
+        *    present and did not contain a verified signature and this 
+        *    is a symmetric mode reply. This reply cannot be verified,
+        *    so just let the packet header check kick it out and hope
+        *    the next packet can be verified.
         */
-       if (skeyid > NTP_MAXKEY) {
-               int i;
+       if (peer->flags & FLAG_SKEY) {
+               int i = 0;
 
-               /*
-                * In the case of a new autokey, verify the hash matches
-                * one of the previous four hashes. If not, raise the
-                * authentication flasher and hope the next one works.
-                */
+               peer->flash |= TEST10;
+               crypto_recv(peer, rbufp);
                if (hismode == MODE_SERVER) {
-                       peer->pkeyid = peer->keyid;
-               } else if (peer->flags & FLAG_MCAST2) {
-                       if (peer->pkeyid > NTP_MAXKEY)
-                               authtrust(peer->pkeyid, 0);
-                       for (i = 0; i < 4 && tkeyid != peer->pkeyid;
-                           i++) {
-                               tkeyid = session_key(
-                                       ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr),
-                                       ntohl(rbufp->dstadr->bcast.sin_addr.s_addr),
-                                       tkeyid, 0);
+                       if (skeyid == peer->keyid)
+                               peer->flash &= ~TEST10;
+               } else if (authlen == LEN_PKT_NOMAC || hismode ==
+                   MODE_BROADCAST) {
+                       for (i = 0;; i++) {
+                               if (tkeyid == peer->pkeyid ||
+                                   tkeyid == peer->finlkey) {
+                                       peer->flash &= ~TEST10;
+                                       peer->pkeyid = skeyid;
+                                       break;
+                               }
+                               if (i > peer->finlseq) {
+                                       peer->finlseq = 0;
+                                       break;
+                               }
+                               if (hismode == MODE_BROADCAST)
+                                       tkeyid = session_key(
+                                           &rbufp->recv_srcadr,
+                                           &rbufp->dstadr->bcast,
+                                           tkeyid, pkeyid, 0);
+                               else
+                                       tkeyid = session_key(
+                                           &rbufp->recv_srcadr,
+                                           &rbufp->dstadr->sin,
+                                           tkeyid, pkeyid, 0);
                        }
-               } else {
-                       if (peer->pkeyid > NTP_MAXKEY)
-                               authtrust(peer->pkeyid, 0);
-                       for (i = 0; i < 4 && tkeyid != peer->pkeyid;
-                           i++) {
-                               tkeyid = session_key(
-                                   ntohl((&rbufp->recv_srcadr)->sin_addr.s_addr),
-                                   ntohl(rbufp->dstadr->sin.sin_addr.s_addr),
-                                   tkeyid, 0);
+#ifdef PUBKEY
+                       /*
+                        * If the autokey boogie fails, the server may
+                        * be bogus or worse. Raise an alarm and rekey
+                        * this thing.
+                        */
+                       if (authlen == LEN_PKT_NOMAC) {
+                               if (peer->flash & TEST10)
+                                       peer->flags &= ~FLAG_AUTOKEY;
+                               if (!(peer->flags & FLAG_AUTOKEY))
+                                       peer->flash |= TEST11;
                        }
+#endif /* PUBKEY */
                }
-#ifdef XXX /* temp until certificate code is mplemented */
-               if (tkeyid != peer->pkeyid)
-                       peer->flash |= TEST9;   /* peer not authentic */
-#endif
-               peer->pkeyid = skeyid;
        }
-#endif /* MD5 */
+#endif /* AUTOKEY */
 
        /*
-        * Gawdz, it's come to this. Process the dang packet. If
-        * something breaks and the association doesn't deserve to live,
-        * toss it. Be careful in active mode and return a packet
-        * anyway.
+        * We have survived the gaunt. Forward to the packet routine. If
+        * a symmetric passive association has been mobilized and the
+        * association doesn't deserve to live, it will die in the
+        * transmit routine if not reachable after timeout.
         */
-       process_packet(peer, pkt, &(rbufp->recv_time));
-       if (!(peer->flags & FLAG_CONFIG) && peer->reach == 0) {
-               if (peer->hmode == MODE_PASSIVE) {
-                       if (is_authentic)
-                               fast_xmit(rbufp, MODE_PASSIVE, skeyid);
-                       else
-                               fast_xmit(rbufp, MODE_PASSIVE, 0);
-               }
-               unpeer(peer);
-       }
+       process_packet(peer, pkt, &rbufp->recv_time);
 }
 
 
@@ -701,7 +758,7 @@ receive(
  *     reasonable expectation that we will be having a long term
  *     relationship with this host.
  */
-int
+void
 process_packet(
        register struct peer *peer,
        register struct pkt *pkt,
@@ -716,7 +773,10 @@ process_packet(
        int pmode;
 
        /*
-        * Swap header fields and keep the books.
+        * Swap header fields and keep the books. The books amount to
+        * the receive timestamp and poll interval in the header. We
+        * need these even if there are other problems in order to crank
+        * up the state machine.
         */
        sys_processed++;
        peer->processed++;
@@ -741,20 +801,17 @@ process_packet(
        if (L_ISEQU(&peer->org, &p_xmt))        /* test 1 */
                peer->flash |= TEST1;           /* duplicate packet */
        if (PKT_MODE(pkt->li_vn_mode) != MODE_BROADCAST) {
-               if (!L_ISEQU(&peer->xmt, &p_org)) { /* test 2 */
-                       peer->bogusorg++;
+               if (!L_ISEQU(&peer->xmt, &p_org)) /* test 2 */
                        peer->flash |= TEST2;   /* bogus packet */
-               }
-               if (L_ISZERO(&p_rec) || L_ISZERO(&p_org))
-                       peer->flash |= TEST3;   /* unsynchronized */
-       } else {
-               if (L_ISZERO(&p_org))
+               if (L_ISZERO(&p_rec) || L_ISZERO(&p_org)) /* test 3 */
                        peer->flash |= TEST3;   /* unsynchronized */
        }
+       if (L_ISZERO(&p_xmt))                   /* test 3 */
+               peer->flash |= TEST3;           /* unsynchronized */
        peer->org = p_xmt;
 
        /*
-        * Test for valid header (tests 5 through 10)
+        * Test for valid packet header (tests 6 through 8)
         */
        ci = p_xmt;
        L_SUB(&ci, &p_reftime);
@@ -765,35 +822,33 @@ process_packet(
                peer->flash |= TEST6;   /* peer clock unsynchronized */
        if (!(peer->flags & FLAG_CONFIG) && sys_peer != 0) { /* test 7 */
                if (PKT_TO_STRATUM(pkt->stratum) > sys_stratum) {
-                       peer->flash |= TEST7; /* peer stratum too high */
+                       peer->flash |= TEST7;   /* peer stratum too high */
                        sys_badstratum++;
                }
        }
-       if (fabs(p_del) >= MAXDISPERSE  /* test 8 */
+       if (fabs(p_del) >= MAXDISPERSE          /* test 8 */
            || p_disp >= MAXDISPERSE)
-               peer->flash |= TEST8;   /* delay/dispersion too high */
+               peer->flash |= TEST8;           /* delay/dispersion too high */
 
        /*
-        * If the packet header is invalid (tests 5 through 10), exit.
-        * XXX we let TEST9 sneak by until the certificate code is
-        * implemented, but only to mobilize the association.
+        * If the packet header is invalid, abandon ship. Otherwise
+        * capture the header data.
         */
-       if (peer->flash & (TEST5 | TEST6 | TEST7 | TEST8 | TEST10)) {
+       if (peer->flash & ~(u_int)(TEST1 | TEST2 | TEST3 | TEST4)) {
 #ifdef DEBUG
                if (debug)
-                       printf(
-                           "invalid packet header 0x%02x mode %d\n",
-                           peer->flash, pmode);
+                       printf("packet: bad header %03x\n",
+                           peer->flash);
 #endif
-               return (0);
+               return;
        }
 
        /*
-        * Valid header; update our state.
+        * The header is valid. Capture the remaining header values and
+        * mark as reachable.
         */
        record_raw_stats(&peer->srcadr, &peer->dstadr->sin,
            &p_org, &p_rec, &p_xmt, &peer->rec);
-
        peer->leap = PKT_LEAP(pkt->li_vn_mode);
        peer->pmode = pmode;            /* unspec */
        peer->stratum = PKT_TO_STRATUM(pkt->stratum);
@@ -849,12 +904,17 @@ process_packet(
         */
        if (pmode == MODE_BROADCAST) {
                if (peer->flags & FLAG_MCAST1) {
-                       if (peer->hmode == MODE_BCLIENT)
-                               peer->flags &= ~FLAG_MCAST1;
                        LFPTOD(&ci, p_offset);
                        peer->estbdelay = peer->offset - p_offset;
-                       return (1);
-
+                       if (peer->hmode != MODE_BCLIENT) {
+#ifdef DEBUG
+                               if (debug)
+                                       printf("packet: bclient %03x\n",
+                                           peer->flash);
+#endif
+                               return;
+                       }
+                       peer->flags &= ~FLAG_MCAST1;
                }
                DTOLFP(peer->estbdelay, &t10);
                L_ADD(&ci, &t10);
@@ -870,27 +930,22 @@ process_packet(
                peer->flash |= TEST4;   /* delay/dispersion too big */
 
        /*
-        * If the packet data are invalid (tests 1 through 4), exit.
+        * If the packet data are invalid (tests 1 through 4), abandon
+        * ship. Otherwise, forward to the clock filter.
         */
        if (peer->flash) {
 #ifdef DEBUG
                if (debug)
-                       printf("invalid packet data 0x%02x mode %d\n",
-                           peer->flash, pmode);
+                       printf("packet: bad data %03x\n",
+                           peer->flash);
 #endif
-               return(1);
+               return;
        }
-
-
-       /*
-        * This one is valid. Mark it so, give it to clock_filter().
-        */
        clock_filter(peer, p_offset, p_del, fabs(p_disp));
        clock_select();
        record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
            peer->offset, peer->delay, peer->disp,
            SQRT(peer->variance));
-       return(1);
 }
 
 
@@ -983,7 +1038,7 @@ poll_update(
        int hpoll
        )
 {
-       long update;
+       long update, oldpoll;
 
        /*
         * The wiggle-the-poll-interval dance. Broadcasters dance only
@@ -992,6 +1047,7 @@ poll_update(
         * clock. Broadcast clients are usually lead by their broadcast
         * partner, but faster in the initial mating dance.
         */
+       oldpoll = peer->hpoll;
        if (peer->hmode == MODE_BROADCAST) {
                peer->hpoll = peer->minpoll;
        } else if (peer->flags & FLAG_SYSPEER) {
@@ -1018,11 +1074,22 @@ poll_update(
                    peer->minpoll);
                peer->nextdate = peer->outdate + RANDPOLL(update);
        }
+
+       /*
+        * Bit of crass arrogance at this point. If the poll interval
+        * has changed and we have a keylist, the lifetimes in the
+        * keylist are probably bogus. In this case purge the keylist
+        * and regenerate it later.
+        */
+#ifdef AUTOKEY
+       if (peer->hpoll != oldpoll)
+               key_expire(peer);
+#endif /* AUTOKEY */
 #ifdef DEBUG
        if (debug > 1)
-               printf("poll_update: at %lu %s poll %d burst %d last %lu next %lu\n",
-                   current_time, ntoa(&peer->srcadr), hpoll,
-                   peer->burst, peer->outdate, peer->nextdate);
+               printf("poll_update: at %lu %s flags %04x poll %d burst %d last %lu next %lu\n",
+                   current_time, ntoa(&peer->srcadr), peer->flags,
+                   hpoll, peer->burst, peer->outdate, peer->nextdate);
 #endif
 }
 
@@ -1037,6 +1104,40 @@ peer_clear(
 {
        register int i;
 
+       /*
+        * If cryptographic credentials have been acquired, toss them to
+        * Valhalla. Note that autokeys are ephemeral, in that they are
+        * tossed immediately upon use. Therefore, the keylist can be
+        * purged anytime without needing to preserve random keys. Note
+        * that, if the peer is purged, the cryptographic variables are
+        * purged, too. This makes it much harder to sneak in some
+        * unauthenticated data in the clock filter.
+        */
+#ifdef DEBUG
+       if (debug)
+               printf("peer_clear: at %ld\n", current_time);
+#endif
+#ifdef AUTOKEY
+       key_expire(peer);
+#ifdef PUBKEY
+       if (peer->sign != NULL)
+               free(peer->sign);
+       if (peer->dh_public != NULL)
+               free(peer->dh_public);
+       if (peer->dh_key != NULL)
+               free(peer->dh_key);
+#endif /* PUBKEY */
+#endif /* AUTOKEY */
+
+       /*
+        * If he dies as a multicast client, he comes back to life as
+        * a multicast client in client mode in order to recover the
+        * initial autokey values.
+        */
+       if (peer->flags & FLAG_MCAST2) {
+               peer->flags |= FLAG_MCAST1 | FLAG_BURST;
+               peer->hmode = MODE_CLIENT;
+       }
        memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO);
        peer->estbdelay = sys_bdelay;
        peer->hpoll = peer->minpoll;
@@ -1073,21 +1174,22 @@ clock_filter(
        double sample_disp
        )
 {
-       register int i, j, k, n = 0;
+       register int i, j, k, n;
        register u_char *ord;
        double distance[NTP_SHIFT];
-       double x, y, z, off;
+       double off, dly, var, dsp, dtemp, etemp;
 
        /*
-        * Update error bounds and calculate distances. Also initialize
-        * sort index vector.
+        * Update error bounds and calculate distances. The distance for
+        * each sample is equal to the sample dispersion plus one-half
+        * the sample delay. Also initialize the sort index vector.
         */
-       x = CLOCK_PHI * (current_time - peer->update);
+       dtemp = CLOCK_PHI * (current_time - peer->update);
        peer->update = current_time;
        ord = peer->filter_order;
        j = peer->filter_nextpt;
        for (i = 0; i < NTP_SHIFT; i++) {
-               peer->filter_disp[j] += x;
+               peer->filter_disp[j] += dtemp;
                if (peer->filter_disp[j] > MAXDISPERSE)
                        peer->filter_disp[j] = MAXDISPERSE;
                distance[i] = fabs(peer->filter_delay[j]) / 2 +
@@ -1098,15 +1200,19 @@ clock_filter(
        }
 
        /*
-        * Insert the new sample at the beginning of the register.
+        * Shift the new sample into the register and discard the oldest
+        * one. The new offset and delay come directly from the caller.
+        * The dispersion from the caller is increased by the sum of the
+        * precision in the the packet header and the precision of this
+        * machine.
         */
        peer->filter_offset[peer->filter_nextpt] = sample_offset;
        peer->filter_delay[peer->filter_nextpt] = sample_delay;
-       x = LOGTOD(peer->precision) + LOGTOD(sys_precision) +
+       dsp = LOGTOD(peer->precision) + LOGTOD(sys_precision) +
            sample_disp;
-       peer->filter_disp[peer->filter_nextpt] = min(x, MAXDISPERSE);
+       peer->filter_disp[peer->filter_nextpt] = min(dsp, MAXDISPERSE);
        peer->filter_epoch[peer->filter_nextpt] = current_time;
-       distance[0] = min(x + fabs(sample_delay) / 2, MAXDISTANCE);
+       distance[0] = min(dsp + fabs(sample_delay) / 2, MAXDISTANCE);
        peer->filter_nextpt++;
        if (peer->filter_nextpt >= NTP_SHIFT)
                peer->filter_nextpt = 0;
@@ -1116,44 +1222,49 @@ clock_filter(
         * sample will be in ord[0]. Sort the samples only if they
         * are younger than the Allen intercept.
         */
-       y = min(allan_xpt, NTP_SHIFT * ULOGTOD(sys_poll));
-       for (n = 0; n < NTP_SHIFT && current_time -
-           peer->filter_epoch[ord[n]] <= y; n++) {
+       dtemp = min(allan_xpt, NTP_SHIFT * ULOGTOD(sys_poll));
+       for (n = 0; n < NTP_SHIFT; n++) {
+               if (n > 0 && current_time - peer->filter_epoch[ord[n]] >
+                   dtemp)
+                       break;
                for (j = 0; j < n; j++) {
                        if (distance[j] > distance[n]) {
-                               x = distance[j];
+                               etemp = distance[j];
                                k = ord[j];
                                distance[j] = distance[n];
                                ord[j] = ord[n];
-                               distance[n] = x;
+                               distance[n] = etemp;
                                ord[n] = k;
                        }
                }
        } 
        
        /*
-        * Compute the error bound and standard error.
+        * Compute the offset, delay, variance (squares) and error
+        * bound. The offset, delay and variance are weighted by the
+        * reciprocal of distance and normalized. The error bound is
+        * weighted exponentially.
         */
-       x = y = z = off = 0.;
+       off = dly = var = dsp = dtemp = 0;
        for (i = NTP_SHIFT - 1; i >= 0; i--) {
-               x = NTP_FWEIGHT * (x + peer->filter_disp[ord[i]]);
-               if (i < n) {
-                       z += 1. / distance[i];
+               dsp = NTP_FWEIGHT * (dsp + peer->filter_disp[ord[i]]);
+               if (i < n && distance[i] < MAXDISTANCE) {
+                       dtemp += 1. / distance[i];
                        off += peer->filter_offset[ord[i]] /
                            distance[i];
-                       y += DIFF(peer->filter_offset[ord[i]],
-                           peer->filter_offset[ord[0]]);
+                       dly += peer->filter_delay[ord[i]] /
+                           distance[i];
+                       var += DIFF(peer->filter_offset[ord[i]],
+                           peer->filter_offset[ord[0]]) /
+                           SQUARE(distance[i]);
                }
        }
-       peer->delay = peer->filter_delay[ord[0]];
-       peer->variance = min(y / n, MAXDISPERSE);
-       peer->disp = min(x, MAXDISPERSE);
+       peer->delay = dly / dtemp;
+       peer->variance = min(var / SQUARE(dtemp), MAXDISPERSE);
+       peer->disp = min(dsp, MAXDISPERSE);
        peer->epoch = current_time;
-       x = peer->offset;
-       if (peer->flags & FLAG_BURST)
-               peer->offset = off / z;
-       else
-               peer->offset = peer->filter_offset[ord[0]];
+       etemp = peer->offset;
+       peer->offset = off / dtemp;
 
        /*
         * A new sample is useful only if it is younger than the last
@@ -1174,15 +1285,21 @@ clock_filter(
         * poll interval, consider the update a popcorn spike and ignore
         * it.
         */
-       if (fabs(x - peer->offset) > CLOCK_SGATE &&
+       if (fabs(etemp - peer->offset) > CLOCK_SGATE &&
            peer->filter_epoch[ord[0]] - peer->epoch < (1 <<
            (sys_poll + 1))) {
 #ifdef DEBUG
                if (debug)
-                       printf("clock_filter: popcorn spike %.6f\n", x);
+                       printf("clock_filter: popcorn spike %.6f\n",
+                           off);
 #endif
                return;
        }
+
+       /*
+        * The mitigated sample statistics are saved for later
+        * processing, but can be processed only once.
+        */
        peer->epoch = peer->filter_epoch[ord[0]];
        peer->pollsw = TRUE;
 #ifdef DEBUG
@@ -1219,10 +1336,10 @@ clock_select(void)
 
        static int list_alloc = 0;
        static struct endpoint *endpoint = NULL;
-       static int *index = NULL;
+       static int *indx = NULL;
        static struct peer **peer_list = NULL;
        static u_int endpoint_size = 0;
-       static u_int index_size = 0;
+       static u_int indx_size = 0;
        static u_int peer_list_size = 0;
 
        /*
@@ -1238,17 +1355,17 @@ clock_select(void)
        if (nlist > list_alloc) {
                if (list_alloc > 0) {
                        free(endpoint);
-                       free(index);
+                       free(indx);
                        free(peer_list);
                }
                while (list_alloc < nlist) {
                        list_alloc += 5;
                        endpoint_size += 5 * 3 * sizeof *endpoint;
-                       index_size += 5 * 3 * sizeof *index;
+                       indx_size += 5 * 3 * sizeof *indx;
                        peer_list_size += 5 * sizeof *peer_list;
                }
                endpoint = (struct endpoint *)emalloc(endpoint_size);
-               index = (int *)emalloc(index_size);
+               indx = (int *)emalloc(indx_size);
                peer_list = (struct peer **)emalloc(peer_list_size);
        }
 
@@ -1313,40 +1430,41 @@ clock_select(void)
                        f = root_distance(peer);
                        e = e + f;
                        for (i = nl3 - 1; i >= 0; i--) {
-                               if (e >= endpoint[index[i]].val)
+                               if (e >= endpoint[indx[i]].val)
                                        break;
-                               index[i + 3] = index[i];
+                               indx[i + 3] = indx[i];
                        }
-                       index[i + 3] = nl3;
+                       indx[i + 3] = nl3;
                        endpoint[nl3].type = 1;
                        endpoint[nl3++].val = e;
 
                        e = e - f;              /* Center point */
                        for ( ; i >= 0; i--) {
-                               if (e >= endpoint[index[i]].val)
+                               if (e >= endpoint[indx[i]].val)
                                        break;
-                               index[i + 2] = index[i];
+                               indx[i + 2] = indx[i];
                        }
-                       index[i + 2] = nl3;
+                       indx[i + 2] = nl3;
                        endpoint[nl3].type = 0;
                        endpoint[nl3++].val = e;
 
                        e = e - f;              /* Lower end */
                        for ( ; i >= 0; i--) {
-                               if (e >= endpoint[index[i]].val)
+                               if (e >= endpoint[indx[i]].val)
                                        break;
-                               index[i + 1] = index[i];
+                               indx[i + 1] = indx[i];
                        }
-                       index[i + 1] = nl3;
+                       indx[i + 1] = nl3;
                        endpoint[nl3].type = -1;
                        endpoint[nl3++].val = e;
                }
        }
 #ifdef DEBUG
-       if (debug > 1)
+       if (debug > 2)
                for (i = 0; i < nl3; i++)
-               printf("select: endpoint %2d %.6f\n",
-                  endpoint[index[i]].type, endpoint[index[i]].val);
+                       printf("select: endpoint %2d %.6f\n",
+                          endpoint[indx[i]].type,
+                          endpoint[indx[i]].val);
 #endif
        i = 0;
        j = nl3 - 1;
@@ -1355,23 +1473,23 @@ clock_select(void)
        while (allow > 0) {
                allow--;
                for (n = 0; i <= j; i++) {
-                       n += endpoint[index[i]].type;
+                       n += endpoint[indx[i]].type;
                        if (n < 0)
                                break;
-                       if (endpoint[index[i]].type == 0)
+                       if (endpoint[indx[i]].type == 0)
                                found++;
                }
                for (n = 0; i <= j; j--) {
-                       n += endpoint[index[j]].type;
+                       n += endpoint[indx[j]].type;
                        if (n > 0)
                                break;
-                       if (endpoint[index[j]].type == 0)
+                       if (endpoint[indx[j]].type == 0)
                                found++;
                }
                if (found > allow)
                        break;
-               low = endpoint[index[i++]].val;
-               high = endpoint[index[j--]].val;
+               low = endpoint[indx[i++]].val;
+               high = endpoint[indx[j--]].val;
        }
 
        /*
@@ -1402,7 +1520,7 @@ clock_select(void)
                }
        }
 #ifdef DEBUG
-       if (debug > 1)
+       if (debug > 2)
                printf("select: low %.6f high %.6f\n", low, high);
 #endif
 
@@ -1439,7 +1557,7 @@ clock_select(void)
        nlist = j;
 
 #ifdef DEBUG
-       if (debug > 1)
+       if (debug > 2)
                for (i = 0; i < nlist; i++)
                        printf("select: %s distance %.6f\n",
                            ntoa(&peer_list[i]->srcadr), synch[i]);
@@ -1479,7 +1597,7 @@ clock_select(void)
                }
 
 #ifdef DEBUG
-               if (debug > 1)
+               if (debug > 2)
                        printf(
                            "select: survivors %d select %.6f peer %.6f\n",
                            nlist, SQRT(sys_maxd), SQRT(d));
@@ -1494,7 +1612,7 @@ clock_select(void)
                nlist--;
        }
 #ifdef DEBUG
-       if (debug > 1) {
+       if (debug > 2) {
                for (i = 0; i < nlist; i++)
                        printf(
                            "select: %s offset %.6f, distance %.6f poll %d\n",
@@ -1563,7 +1681,7 @@ clock_select(void)
                sys_offset = sys_peer->offset;
                sys_epsil = sys_peer->variance;
 #ifdef DEBUG
-               if (debug > 1)
+               if (debug > 2)
                        printf("select: prefer offset %.6f\n",
                            sys_offset);
 #endif
@@ -1577,7 +1695,7 @@ clock_select(void)
                                msyslog(LOG_INFO, "pps sync enabled");
                pps_control = current_time;
 #ifdef DEBUG
-               if (debug > 1)
+               if (debug > 2)
                        printf("select: pps offset %.6f\n", sys_offset);
 #endif
        } else {
@@ -1587,7 +1705,7 @@ clock_select(void)
                sys_offset = clock_combine(peer_list, nlist);
                sys_epsil = sys_peer->variance + sys_maxd;
 #ifdef DEBUG
-               if (debug > 1)
+               if (debug > 2)
                        printf("select: combine offset %.6f\n",
                           sys_offset);
 #endif
@@ -1639,279 +1757,449 @@ peer_xmit(
        struct peer *peer       /* peer structure pointer */
        )
 {
-       struct pkt xpkt;
+       struct pkt xpkt;        /* transmit packet */
        int find_rtt = (peer->cast_flags & MDF_MCAST) &&
-               peer->hmode != MODE_BROADCAST;
-       int sendlen;
+           peer->hmode != MODE_BROADCAST;
+       int sendlen, pktlen;
+       keyid_t xkeyid;         /* transmit key ID */
+       l_fp xmt_tx;
 
        /*
-        * Initialize protocol fields.
+        * Initialize transmit packet header fields.
         */
-       xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
-               peer->version, peer->hmode);
+       xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, peer->version,
+           peer->hmode);
        xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
        xpkt.ppoll = peer->hpoll;
        xpkt.precision = sys_precision;
        xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
        xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion +
-               LOGTOD(sys_precision)));
+           LOGTOD(sys_precision)));
        xpkt.refid = sys_refid;
        HTONL_FP(&sys_reftime, &xpkt.reftime);
        HTONL_FP(&peer->org, &xpkt.org);
        HTONL_FP(&peer->rec, &xpkt.rec);
 
        /*
-        * Authenticate the packet if enabled and either configured or
-        * the previous packet was authenticated. If for some reason the
-        * key associated with the key identifier is not in the key
-        * cache, then honk key zero.
+        * If the received packet contains a MAC, the transmitted packet
+        * is authenticated and contains a MAC. If not, the transmitted
+        * packet is not authenticated.
+        *
+        * In the current I/O semantics we can't find the local
+        * interface address to generate a session key until after
+        * receiving a packet. So, the first packet goes out
+        * unauthenticated. That's why the really icky test next is
+        * here.
         */
        sendlen = LEN_PKT_NOMAC;
-       if (peer->flags & FLAG_AUTHENABLE) {
-               u_long xkeyid;
-               l_fp xmt_tx;
-
-               /*
-                * Transmit encrypted packet compensated for the
-                * encryption delay.
-                */
-#ifdef MD5
-               if (peer->flags & FLAG_SKEY) {
-
-                       /*
-                        * In autokey mode, allocate and initialize a
-                        * key list if not already done. Then, use the
-                        * list in inverse order, discarding keys once
-                        * used. Keep the latest key around until the
-                        * next one, so clients can use client/server
-                        * packets to compute propagation delay. Note we
-                        * have to wait until the receive side of the
-                        * socket is bound and the server address
-                        * confirmed.
-                        */
-                       if (ntohl(peer->dstadr->sin.sin_addr.s_addr) ==
-                           0 &&
-                               ntohl(peer->dstadr->bcast.sin_addr.s_addr) == 0)
-                               peer->keyid = 0;
-                       else {
-                                if (peer->keylist == 0) {
-                                       make_keylist(peer);
-                               } else {
-                                       authtrust(peer->keylist[peer->keynumber], 0);
-                                       if (peer->keynumber == 0)
-                                               make_keylist(peer);
-                                       else {
-                                               peer->keynumber--;
-                                               xkeyid = peer->keylist[peer->keynumber];
-                                               if (!authistrusted(xkeyid))
-                                                       make_keylist(peer);
-                                       }
-                               }
-                               peer->keyid = peer->keylist[peer->keynumber];
-                               xpkt.keyid1 = htonl(2 * sizeof(u_int32));
-                               xpkt.keyid2 = htonl(sys_private);
-                               sendlen += 2 * sizeof(u_int32);
-                       }
-               }
-#endif /* MD5 */
-               xkeyid = peer->keyid;
+       if (!(peer->flags & FLAG_AUTHENABLE) ||
+           (peer->dstadr->sin.sin_addr.s_addr == 0 &&
+           peer->dstadr->bcast.sin_addr.s_addr == 0)) {
                get_systime(&peer->xmt);
-               L_ADD(&peer->xmt, &sys_authdelay);
                HTONL_FP(&peer->xmt, &xpkt.xmt);
-               sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt,
-                   sendlen);
-               get_systime(&xmt_tx);
                sendpkt(&peer->srcadr, find_rtt ? any_interface :
                    peer->dstadr, ((peer->cast_flags & MDF_MCAST) &&
                    !find_rtt) ? ((peer->cast_flags & MDF_ACAST) ? -7 :
-                   peer->ttl) : -7, &xpkt, sendlen);
-
-               /*
-                * Calculate the encryption delay. Keep the minimum over
-                * the latest two samples.
-                */
-               L_SUB(&xmt_tx, &peer->xmt);
-               L_ADD(&xmt_tx, &sys_authdelay);
-               sys_authdly[1] = sys_authdly[0];
-               sys_authdly[0] = xmt_tx.l_uf;
-               if (sys_authdly[0] < sys_authdly[1])
-                       sys_authdelay.l_uf = sys_authdly[0];
-               else
-                       sys_authdelay.l_uf = sys_authdly[1];
+                   peer->ttl) : -8, &xpkt, sendlen);
                peer->sent++;
 #ifdef DEBUG
                if (debug)
-                       printf(
-                           "transmit: at %ld to %s mode %d keyid %08lx index %d\n",
+                       printf("transmit: at %ld %s mode %d\n",
                            current_time, ntoa(&peer->srcadr),
-                           peer->hmode, xkeyid, peer->keynumber);
+                           peer->hmode);
 #endif
-       } else {
+               return;
+       }
+
+       /*
+        * The received packet contains a MAC, so the transmitted packet
+        * must be authenticated. If autokey is enabled, fuss with the
+        * various modes; otherwise, private key cryptography is used.
+        */
+#ifdef AUTOKEY
+       if ((peer->flags & FLAG_SKEY)) {
+               u_int cmmd;
+
                /*
-                * Transmit non-authenticated packet.
+                * The Public Key Dance (PKD): Cryptographic credentials
+                * are contained in extension fields, each including a
+                * 4-octet length/code word followed by a 4-octet
+                * association ID and optional additional data. Optional
+                * data includes a 4-octet data length field followd by
+                * the data itself. Request messages are sent from a
+                * configured association; response messages can be sent
+                * from a configured association or can take the fast
+                * path without ever matching an association. Response
+                * messages have the same code as the request, but have
+                * a response bit and possibly an error bit set. In this
+                * implementation, a message may contain no more than
+                * one command and no more than one response.
+                *
+                * Cryptographic session keys include both a public and
+                * a private componet. Request and response messages
+                * using extension fields are always sent with the
+                * private component set to zero. Packets without
+                * extension fields indlude the private component when
+                * the session key is generated.
                 */
-               get_systime(&(peer->xmt));
-               HTONL_FP(&peer->xmt, &xpkt.xmt);
-               sendpkt(&(peer->srcadr), find_rtt ? any_interface :
-                   peer->dstadr, ((peer->cast_flags & MDF_MCAST) &&
-                   !find_rtt) ? ((peer->cast_flags & MDF_ACAST) ? -7 :
-                   peer->ttl) : -8, &xpkt, sendlen);
-               peer->sent++;
+               while (1) {
+               
+                       /*
+                        * Allocate and initialize a keylist if not
+                        * already done. Then, use the list in inverse
+                        * order, discarding keys once used. Keep the
+                        * latest key around until the next one, so
+                        * clients can use client/server packets to
+                        * compute propagation delay.
+                        *
+                        * Note that once a key is used from the list,
+                        * it is retained in the key cache until the
+                        * next key is used. This is to allow a client
+                        * to retrieve the encrypted session key
+                        * identifier to verify authenticity.
+                        *
+                        * If for some reason a key is no longer in the
+                        * key cache, a birthday has happened and the
+                        * pseudo-random sequence is probably broken. In
+                        * that case, purge the keylist and regenerate
+                        * it.
+                        */
+                       if (peer->keynumber == 0)
+                               make_keylist(peer);
+                       else
+                               peer->keynumber--;
+                       xkeyid = peer->keylist[peer->keynumber];
+                       if (authistrusted(xkeyid))
+                               break;
+                       else
+                               key_expire(peer);
+               }
+               peer->keyid = xkeyid;
+               switch (peer->hmode) {
+
+               /*
+                * In broadcast mode and a new keylist; otherwise, send
+                * the association ID so the client can request the
+                * values at other times.
+                */
+               case MODE_BROADCAST:
+                       if (peer->keynumber == peer->lastseq)
+                               cmmd = CRYPTO_AUTO | CRYPTO_RESP;
+                       else
+                               cmmd = CRYPTO_ASSOC | CRYPTO_RESP;
+                       sendlen += crypto_xmit((u_int32 *)&xpkt,
+                           sendlen, cmmd, peer->hcookie,
+                           peer->associd);
+                       break;
+
+               /*
+                * In symmetric modes the public key, Diffie-Hellman
+                * values and autokey values are required. In principle,
+                * these values can be provided in any order; however,
+                * the protocol is most efficient if the values are
+                * provided in the order listed. This happens with the
+                * following rules:
+                *
+                * 1. Don't send anything except a public-key request or
+                *    a public-key response until the public key has
+                *    been stored. 
+                *
+                * 2. If a public-key response is pending, always send
+                *    it first before any other command or response.
+                *
+                * 3. Once the public key has been stored, don't send
+                *    anything except Diffie-Hellman commands or
+                *    responses until the agreed key has been stored.
+                *
+                * 4. If a Diffie-Hellman response is pending, always
+                *    send it last after any other command or response.
+                *
+                * 5. When the agreed key has been stored and the key
+                *    list is regenerated, send the autokey values
+                *    gratis.
+                */
+               case MODE_ACTIVE:
+               case MODE_PASSIVE:
+                       if (peer->cmmd != 0 && peer->cmmd >> 16 !=
+                           CRYPTO_DH) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, (peer->cmmd >> 16) |
+                                   CRYPTO_RESP, peer->hcookie,
+                                   peer->associd);
+                               peer->cmmd = 0;
+                       }
+#ifdef PUBKEY
+                       if (peer->pubkey == 0) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, CRYPTO_PUBL, peer->hcookie,
+                                   peer->assoc);
+                       } else if (peer->pcookie == 0) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, CRYPTO_DH, peer->hcookie,
+                                   peer->assoc);
+                       } else
+#endif /* PUBKEY */
+                       if (peer->finlseq == 0) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, CRYPTO_AUTO, peer->hcookie,
+                                   peer->assoc);
+                       } else if (peer->keynumber == peer->lastseq) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, CRYPTO_AUTO | CRYPTO_RESP,
+                                   peer->hcookie, peer->associd);
+                       }
+                       if (peer->cmmd != 0) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, (peer->cmmd >> 16) |
+                                   CRYPTO_RESP, peer->hcookie,
+                                   peer->associd);
+                               peer->cmmd = 0;
+                       }
+                       break;
+
+               /*
+                * In client mode, the public key, host cookie and
+                * autokey values are required. In broadcast client
+                * mode, these values must be acquired during the
+                * client/server exchange to avoid having to wait until
+                * the next key list regeneration. Otherwise, the poor
+                * dude may die a lingering death until becoming
+                * unreachable and attempting rebirth.
+                */
+               case MODE_CLIENT:
+                       if (peer->cmmd != 0) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, (peer->cmmd >> 16) |
+                                   CRYPTO_RESP, peer->hcookie,
+                                   peer->associd);
+                               peer->cmmd = 0;
+                       }
+#ifdef PUBKEY
+                       if (peer->pubkey == 0) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, CRYPTO_PUBL, peer->hcookie,
+                                   peer->assoc);
+                       } else
+#endif /* PUBKEY */
+                       if (peer->pcookie == 0) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, CRYPTO_PRIV, peer->hcookie,
+                                   peer->assoc);
+                       } else if (peer->finlseq == 0 && peer->flags &
+                           FLAG_MCAST2) {
+                               sendlen += crypto_xmit((u_int32 *)&xpkt,
+                                   sendlen, CRYPTO_AUTO, peer->hcookie,
+                                   peer->assoc);
+                       }
+                       break;
+               }
+
+               /*
+                * If extension fields are present, we must use a
+                * private value of zero. Most intricate.
+                */
+               if (sendlen > LEN_PKT_NOMAC)
+                       session_key(&peer->dstadr->sin,
+                           (peer->hmode == MODE_BROADCAST) ?
+                           &peer->dstadr->bcast : &peer->srcadr,
+                           xkeyid, 0, 2);
+       } 
+#endif /* AUTOKEY */
+       xkeyid = peer->keyid;
+       get_systime(&peer->xmt);
+       L_ADD(&peer->xmt, &sys_authdelay);
+       HTONL_FP(&peer->xmt, &xpkt.xmt);
+       pktlen = sendlen + authencrypt(xkeyid, (u_int32 *)&xpkt,
+           sendlen);
+#ifdef AUTOKEY
+       if (xkeyid > NTP_MAXKEY)
+               authtrust(xkeyid, 0);
+#endif /* AUTOKEY */
+       get_systime(&xmt_tx);
+       sendpkt(&peer->srcadr, find_rtt ? any_interface : peer->dstadr,
+           ((peer->cast_flags & MDF_MCAST) && !find_rtt) ?
+           ((peer->cast_flags & MDF_ACAST) ? -7 : peer->ttl) : -7,
+           &xpkt, pktlen);
+
+       /*
+        * Calculate the encryption delay. Keep the minimum over
+        * the latest two samples.
+        */
+       L_SUB(&xmt_tx, &peer->xmt);
+       L_ADD(&xmt_tx, &sys_authdelay);
+       sys_authdly[1] = sys_authdly[0];
+       sys_authdly[0] = xmt_tx.l_uf;
+       if (sys_authdly[0] < sys_authdly[1])
+               sys_authdelay.l_uf = sys_authdly[0];
+       else
+               sys_authdelay.l_uf = sys_authdly[1];
+       peer->sent++;
+#ifdef AUTOKEY
 #ifdef DEBUG
-               if (debug)
-                       printf("transmit: at %ld to %s mode %d\n",
-                               current_time, ntoa(&peer->srcadr),
-                               peer->hmode);
+       if (debug)
+               printf(
+                   "transmit: at %ld %s mode %d keyid %08x len %d mac %d index %d\n",
+                   current_time, ntoa(&peer->srcadr), peer->hmode,
+                   xkeyid, sendlen, pktlen - sendlen, peer->keynumber);
 #endif
-       }
+#else
+#ifdef DEBUG
+       if (debug)
+               printf(
+                   "transmit: at %ld %s mode %d keyid %08x len %d mac %d\n",
+                   current_time, ntoa(&peer->srcadr), peer->hmode,
+                   xkeyid, sendlen, pktlen - sendlen);
+#endif
+#endif /* AUTOKEY */
 }
 
+
 /*
- * fast_xmit - Send packet for nonpersistent association.
+ * fast_xmit - Send packet for nonpersistent association. Note that
+ * neither the source or destination can be a broadcast address.
  */
 static void
 fast_xmit(
        struct recvbuf *rbufp,  /* receive packet pointer */
        int xmode,              /* transmit mode */
-       u_long xkeyid           /* transmit key ID */
+       keyid_t xkeyid          /* transmit key ID */
        )
 {
-       struct pkt xpkt;
-       struct pkt *rpkt;
-       int sendlen;
-       l_fp xmt_ts;
+       struct pkt xpkt;        /* transmit packet structure */
+       struct pkt *rpkt;       /* receive packet structure */
+       l_fp xmt_ts;            /* transmit timestamp */
+       l_fp xmt_tx;            /* transmit timestamp after authent */
+       int sendlen, pktlen;
 
        /*
-        * Initialize transmit packet header fields in the receive
+        * Initialize transmit packet header fields from the receive
         * buffer provided. We leave some fields intact as received.
         */
        rpkt = &rbufp->recv_pkt;
        xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
-               PKT_VERSION(rpkt->li_vn_mode), xmode);
+           PKT_VERSION(rpkt->li_vn_mode), xmode);
        xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
        xpkt.ppoll = rpkt->ppoll;
        xpkt.precision = sys_precision;
        xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
        xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion +
-               LOGTOD(sys_precision)));
+           LOGTOD(sys_precision)));
        xpkt.refid = sys_refid;
        HTONL_FP(&sys_reftime, &xpkt.reftime);
        xpkt.org = rpkt->xmt;
        HTONL_FP(&rbufp->recv_time, &xpkt.rec);
-       sendlen = LEN_PKT_NOMAC;
-       if (rbufp->recv_length > sendlen) {
-               l_fp xmt_tx;
 
-               /*
-                * Transmit encrypted packet compensated for the
-                * encryption delay.
-                */
-               if (xkeyid > NTP_MAXKEY) {
-                       xpkt.keyid1 = htonl(2 * sizeof(u_int32));
-                       xpkt.keyid2 = htonl(sys_private);
-                       sendlen += 2 * sizeof(u_int32);
-               }
+       /*
+        * If the received packet contains a MAC, the transmitted packet
+        * is authenticated and contains a MAC. If not, the transmitted
+        * packet is not authenticated.
+        */
+       sendlen = LEN_PKT_NOMAC;
+       if (rbufp->recv_length == sendlen) {
                get_systime(&xmt_ts);
-               L_ADD(&xmt_ts, &sys_authdelay);
                HTONL_FP(&xmt_ts, &xpkt.xmt);
-               sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt,
-                   sendlen);
-               get_systime(&xmt_tx);
-               sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -9, &xpkt,
+               sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -10, &xpkt,
                    sendlen);
-
-               /*
-                * Calculate the encryption delay. Keep the minimum over
-                * the latest two samples.
-                */
-               L_SUB(&xmt_tx, &xmt_ts);
-               L_ADD(&xmt_tx, &sys_authdelay);
-               sys_authdly[1] = sys_authdly[0];
-               sys_authdly[0] = xmt_tx.l_uf;
-               if (sys_authdly[0] < sys_authdly[1])
-                       sys_authdelay.l_uf = sys_authdly[0];
-               else
-                       sys_authdelay.l_uf = sys_authdly[1];
 #ifdef DEBUG
                if (debug)
-                       printf(
-                           "transmit: at %ld to %s mode %d keyid %08lx\n",
-                               current_time, ntoa(&rbufp->recv_srcadr),
-                               xmode, xkeyid);
+                       printf("transmit: at %ld %s mode %d\n",
+                           current_time, ntoa(&rbufp->recv_srcadr),
+                           xmode);
 #endif
-       } else {
+               return;
+       }
 
-               /*
-                * Transmit non-authenticated packet.
-                */
-               get_systime(&xmt_ts);
-               HTONL_FP(&xmt_ts, &xpkt.xmt);
-               sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -10, &xpkt,
-                       sendlen);
+       /*
+        * The received packet contains a MAC, so the transmitted packet
+        * must be authenticated. For private-key cryptography, use the
+        * the public and private values to generate the cookie, which
+        * is unique for every source-destination-key ID combination. If
+        * an extension field is present, do what needs, but with
+        * private value of zero so the poor jerk can decode it. If no
+        * extension field is present, use the cookie to generate the
+        * session key.
+        */
+#ifdef AUTOKEY
+       if (xkeyid > NTP_MAXKEY) {
+               keyid_t cookie;
+               u_int code;
+
+               if (xmode == MODE_SERVER)
+                       cookie = session_key(&rbufp->recv_srcadr,
+                           &rbufp->dstadr->sin, 0, sys_private, 0);
+               else
+                       cookie = session_key(&rbufp->dstadr->sin,
+                           &rbufp->recv_srcadr, 0, sys_private, 0);
+               if (rbufp->recv_length >= sendlen + MAX_MAC_LEN + 2 *
+                   sizeof(u_int32)) {
+                       session_key(&rbufp->dstadr->sin,
+                           &rbufp->recv_srcadr, xkeyid, 0, 2);
+                       code = (htonl(rpkt->exten[0]) >> 16) |
+                           CRYPTO_RESP;
+                       sendlen += crypto_xmit((u_int32 *)&xpkt,
+                           sendlen, code, cookie,
+                           (int)htonl(rpkt->exten[1]));
+               } else {
+                       session_key(&rbufp->dstadr->sin,
+                           &rbufp->recv_srcadr, xkeyid, cookie, 2);
+               }
+       }
+#endif /* AUTOKEY */
+       get_systime(&xmt_ts);
+       L_ADD(&xmt_ts, &sys_authdelay);
+       HTONL_FP(&xmt_ts, &xpkt.xmt);
+       pktlen = sendlen + authencrypt(xkeyid, (u_int32 *)&xpkt,
+           sendlen);
+#ifdef AUTOKEY
+       if (xkeyid > NTP_MAXKEY)
+               authtrust(xkeyid, 0);
+#endif /* AUTOKEY */
+       get_systime(&xmt_tx);
+       sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, -9, &xpkt, pktlen);
+
+       /*
+        * Calculate the encryption delay. Keep the minimum over the
+        * latest two samples.
+        */
+       L_SUB(&xmt_tx, &xmt_ts);
+       L_ADD(&xmt_tx, &sys_authdelay);
+       sys_authdly[1] = sys_authdly[0];
+       sys_authdly[0] = xmt_tx.l_uf;
+       if (sys_authdly[0] < sys_authdly[1])
+               sys_authdelay.l_uf = sys_authdly[0];
+       else
+               sys_authdelay.l_uf = sys_authdly[1];
 #ifdef DEBUG
-               if (debug)
-                       printf("transmit: at %ld to %s mode %d\n",
-                               current_time, ntoa(&rbufp->recv_srcadr),
-                               xmode);
+       if (debug)
+               printf(
+                   "transmit: at %ld %s mode %d keyid %08x len %d mac %d\n",
+                   current_time, ntoa(&rbufp->recv_srcadr),
+                   xmode, xkeyid, sendlen, pktlen - sendlen);
 #endif
-       }
 }
 
-#ifdef MD5
+
+#ifdef AUTOKEY
 /*
- * Compute key list
+ * key_expire - purge the key list
  */
-static void
-make_keylist(
-       struct peer *peer
+void
+key_expire(
+       struct peer *peer       /* peer structure pointer */
        )
 {
        int i;
-       u_long keyid;
-       u_long ltemp;
 
-       /*
-        * Allocate the key list if necessary.
-        */
-       if (peer->keylist == 0)
-               peer->keylist = (u_long *)emalloc(sizeof(u_long) *
-                   NTP_MAXSESSION);
-
-       /*
-        * Generate an initial key ID which is unique and greater than
-        * NTP_MAXKEY.
-        */
-       while (1) {
-               keyid = (u_long)RANDOM & 0xffffffff;
-               if (keyid <= NTP_MAXKEY)
-                       continue;
-               if (authhavekey(keyid))
-                       continue;
-               break;
-       }
-
-       /*
-        * Generate up to NTP_MAXSESSION session keys. Stop if the
-        * next one would not be unique or not a session key ID or if
-        * it would expire before the next poll.
-        */
-       ltemp = sys_automax;
-       for (i = 0; i < NTP_MAXSESSION; i++) {
-               peer->keylist[i] = keyid;
-               peer->keynumber = i;
-               keyid = session_key(
-                   ntohl(peer->dstadr->sin.sin_addr.s_addr),
-                   (peer->hmode == MODE_BROADCAST || (peer->flags &
-                   FLAG_MCAST2)) ?
-                   ntohl(peer->dstadr->bcast.sin_addr.s_addr):
-                   ntohl(peer->srcadr.sin_addr.s_addr), keyid, ltemp);
-               ltemp -= 1 << peer->hpoll;
-               if (auth_havekey(keyid) || keyid <= NTP_MAXKEY ||
-                   ltemp <= (1 << (peer->hpoll + 1)))
-                       break;
+       if (peer->keylist != NULL) {
+               for (i = 0; i <= peer->keynumber; i++)
+                       authtrust(peer->keylist[i], 0);
+               free(peer->keylist);
+               peer->keylist = NULL;
        }
+       peer->keynumber = peer->lastseq = 0;
+       peer->lastkey = 0;
 }
-#endif /* MD5 */
+#endif /* AUTOKEY */
 
 /*
  * Find the precision of this particular machine
@@ -2055,7 +2343,9 @@ init_proto(void)
        sys_processed = 0;
        sys_badauth = 0;
        sys_manycastserver = 0;
+#ifdef AUTOKEY
        sys_automax = 1 << NTP_AUTOMAX;
+#endif /* AUTOKEY */
 
        /*
         * Default these to enable
index eb4b37bc1e28e75f3b5bbd6afa590916147011c7..cdadf72b07d6b5e51c3f1351907d27a945a0cd81 100644 (file)
@@ -60,6 +60,7 @@ static        void    mem_stats       P((struct sockaddr_in *, struct interface *, struct req_pk
 static void    io_stats        P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    timer_stats     P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    loop_info       P((struct sockaddr_in *, struct interface *, struct req_pkt *));
+static void    dns_a           P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    do_conf         P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    do_unconf       P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    set_sys_flag    P((struct sockaddr_in *, struct interface *, struct req_pkt *));
@@ -77,7 +78,7 @@ static        void    reset_peer      P((struct sockaddr_in *, struct interface *, struct req_p
 static void    do_key_reread   P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    trust_key       P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    untrust_key     P((struct sockaddr_in *, struct interface *, struct req_pkt *));
-static void    do_trustkey     P((struct sockaddr_in *, struct interface *, struct req_pkt *, int));
+static void    do_trustkey     P((struct sockaddr_in *, struct interface *, struct req_pkt *, u_long));
 static void    get_auth_info   P((struct sockaddr_in *, struct interface *, struct req_pkt *));
 static void    reset_auth_stats P((void));
 static void    req_get_traps   P((struct sockaddr_in *, struct interface *, struct req_pkt *));
@@ -112,6 +113,7 @@ static      struct req_proc ntp_codes[] = {
        { REQ_MEM_STATS,        NOAUTH, 0,      mem_stats },
        { REQ_LOOP_INFO,        NOAUTH, 0,      loop_info },
        { REQ_TIMER_STATS,      NOAUTH, 0,      timer_stats },
+       { REQ_HOSTNAME_ASSOCID, AUTH, sizeof(struct info_dns_assoc), dns_a },
        { REQ_CONFIG,       AUTH, sizeof(struct conf_peer), do_conf },
        { REQ_UNCONFIG,     AUTH, sizeof(struct conf_unpeer), do_unconf },
        { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), set_sys_flag },
@@ -150,7 +152,7 @@ static      struct req_proc ntp_codes[] = {
  * Authentication keyid used to authenticate requests.  Zero means we
  * don't allow writing anything.
  */
-u_long info_auth_keyid;
+keyid_t info_auth_keyid;
 
 /*
  * Statistic counters to keep track of requests and responses.
@@ -533,7 +535,8 @@ process_private(
        if (proc->sizeofitem != 0)
            if (proc->sizeofitem*INFO_NITEMS(inpkt->err_nitems)
                > sizeof(inpkt->data)) {
-                   msyslog(LOG_ERR, "sizeofitem*NITEMS > data: %d > %d",
+                   msyslog(LOG_ERR, "sizeofitem(%d)*NITEMS(%d) > data: %d > %d",
+                           proc->sizeofitem, INFO_NITEMS(inpkt->err_nitems),
                            proc->sizeofitem*INFO_NITEMS(inpkt->err_nitems),
                            sizeof(inpkt->data));
                    req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
@@ -619,14 +622,16 @@ peer_list_sum(
                        if (debug > 3)
                            printf("sum: got one\n");
 #endif
-                       ips->dstadr = (pp->processed) ?
-                               pp->cast_flags == MDF_BCAST ?
-                               pp->dstadr->bcast.sin_addr.s_addr:
-                               pp->cast_flags ?
-                               pp->dstadr->sin.sin_addr.s_addr ?
-                               pp->dstadr->sin.sin_addr.s_addr:
-                               pp->dstadr->bcast.sin_addr.s_addr:
-                               1 : 5;
+                       ips->dstadr =
+                           (pp->processed)
+                           ? pp->cast_flags == MDF_BCAST
+                             ? pp->dstadr->bcast.sin_addr.s_addr
+                             : pp->cast_flags
+                               ? pp->dstadr->sin.sin_addr.s_addr
+                                 ? pp->dstadr->sin.sin_addr.s_addr
+                                 : pp->dstadr->bcast.sin_addr.s_addr
+                               : 1
+                           : 5;
                        ips->srcadr = pp->srcadr.sin_addr.s_addr;
                        ips->srcport = pp->srcadr.sin_port;
                        ips->stratum = pp->stratum;
@@ -695,14 +700,16 @@ peer_info (
                ipl++;
                if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
                    continue;
-               ip->dstadr = (pp->processed) ?
-                       pp->cast_flags == MDF_BCAST ?
-                       pp->dstadr->bcast.sin_addr.s_addr:
-                       pp->cast_flags ?
-                       pp->dstadr->sin.sin_addr.s_addr ?
-                       pp->dstadr->sin.sin_addr.s_addr:
-                       pp->dstadr->bcast.sin_addr.s_addr:
-                       2 : 6;
+               ip->dstadr =
+                   (pp->processed)
+                   ? pp->cast_flags == MDF_BCAST
+                     ? pp->dstadr->bcast.sin_addr.s_addr
+                     : pp->cast_flags
+                       ? pp->dstadr->sin.sin_addr.s_addr
+                         ? pp->dstadr->sin.sin_addr.s_addr
+                         : pp->dstadr->bcast.sin_addr.s_addr
+                       : 2
+                   : 6;
                ip->srcadr = NSRCADR(&pp->srcadr);
                ip->srcport = NSRCPORT(&pp->srcadr);
                ip->flags = 0;
@@ -797,14 +804,16 @@ peer_stats (
                ipl++;
                if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
                    continue;
-               ip->dstadr = (pp->processed) ?
-                       pp->cast_flags == MDF_BCAST ?
-                       pp->dstadr->bcast.sin_addr.s_addr:
-                       pp->cast_flags ?
-                       pp->dstadr->sin.sin_addr.s_addr ?
-                       pp->dstadr->sin.sin_addr.s_addr:
-                       pp->dstadr->bcast.sin_addr.s_addr:
-                       3 : 7;
+               ip->dstadr =
+                   (pp->processed)
+                   ? pp->cast_flags == MDF_BCAST
+                     ? pp->dstadr->bcast.sin_addr.s_addr
+                     : pp->cast_flags
+                       ? pp->dstadr->sin.sin_addr.s_addr
+                         ? pp->dstadr->sin.sin_addr.s_addr
+                         : pp->dstadr->bcast.sin_addr.s_addr
+                       : 3
+                   : 7;
                ip->srcadr = NSRCADR(&pp->srcadr);
                ip->srcport = NSRCPORT(&pp->srcadr);
                ip->flags = 0;
@@ -1198,8 +1207,8 @@ do_conf(
                peeraddr.sin_addr.s_addr = cp->peeraddr;
                /* XXX W2DO? minpoll/maxpoll arguments ??? */
                if (peer_config(&peeraddr, (struct interface *)0,
-                               cp->hmode, cp->version, cp->minpoll, cp->maxpoll,
-                               fl, cp->ttl, cp->keyid) == 0) {
+                       cp->hmode, cp->version, cp->minpoll, cp->maxpoll,
+                       fl, cp->ttl, cp->keyid, cp->keystr) == 0) {
                        req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
                        return;
                }
@@ -1210,6 +1219,86 @@ do_conf(
 }
 
 
+/*
+ * dns_a - Snarf DNS info for an association ID
+ */
+static void
+dns_a(
+       struct sockaddr_in *srcadr,
+       struct interface *inter,
+       struct req_pkt *inpkt
+       )
+{
+       register struct info_dns_assoc *dp;
+       register int items;
+       struct sockaddr_in peeraddr;
+       int fl;
+
+       msyslog(LOG_DEBUG, "dns_a: We're here...");
+       /*
+        * Do a check of everything to see that it looks
+        * okay.  If not, complain about it.  Note we are
+        * very picky here.
+        */
+       items = INFO_NITEMS(inpkt->err_nitems);
+       dp = (struct info_dns_assoc *)inpkt->data;
+
+       /*
+        * Looks okay, try it out
+        */
+       items = INFO_NITEMS(inpkt->err_nitems);
+       dp = (struct info_dns_assoc *)inpkt->data;
+       memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
+       peeraddr.sin_family = AF_INET;
+       peeraddr.sin_port = htons(NTP_PORT);
+
+       /*
+        * Make sure the address is valid
+        */
+       if (
+#ifdef REFCLOCK
+               !ISREFCLOCKADR(&peeraddr) &&
+#endif
+               ISBADADR(&peeraddr)) {
+#ifdef REFCLOCK
+               msyslog(LOG_ERR, "dns_a: !ISREFCLOCK && ISBADADR");
+#else
+               msyslog(LOG_ERR, "dns_a: ISBADADR");
+#endif
+               req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+               return;
+       }
+
+       while (items-- > 0) {
+               u_short associd;
+               size_t hnl;
+               char *cp;
+
+               associd = dp->associd; /* Validate this value? */
+               peeraddr.sin_addr.s_addr = dp->peeraddr;
+               for (hnl = 0; *dp->hostname && hnl < sizeof dp->hostname; ++hnl) ;
+               if (hnl >= sizeof dp->hostname) {
+                       /* Squawk bad data */
+               }
+               cp = emalloc(hnl + 1);
+               strncpy(cp, dp->hostname, hnl);
+
+               msyslog(LOG_DEBUG, "dns_a: <%s> for %s, AssocID %d",
+                       cp, inet_ntoa(peeraddr.sin_addr), associd);
+
+               /* Do Something in the "if" line to use the info we got */
+               if (0) {
+                       /* If it didn't work */
+                       req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+                       return;
+               }
+               dp++;
+       }
+
+       req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
 /*
  * do_unconf - remove a peer from the configuration list
  */
@@ -1760,7 +1849,7 @@ do_trustkey(
        struct sockaddr_in *srcadr,
        struct interface *inter,
        struct req_pkt *inpkt,
-       int trust
+       u_long trust
        )
 {
        register u_long *kp;
@@ -2005,7 +2094,7 @@ set_request_keyid(
        struct req_pkt *inpkt
        )
 {
-       u_long keyid;
+       keyid_t keyid;
 
        /*
         * Restrict ourselves to one item only.
@@ -2033,8 +2122,8 @@ set_control_keyid(
        struct req_pkt *inpkt
        )
 {
-       u_long keyid;
-       extern u_long ctl_auth_keyid;
+       keyid_t keyid;
+       extern keyid_t ctl_auth_keyid;
 
        /*
         * Restrict ourselves to one item only.
diff --git a/ntpd/ntp_resolver.c b/ntpd/ntp_resolver.c
new file mode 100644 (file)
index 0000000..601cc6b
--- /dev/null
@@ -0,0 +1,893 @@
+/*
+ * ripped off from ../ntpres/ntpres.c by Greg Troxel 4/2/92
+ * routine callable from ntpd, rather than separate program
+ * also, key info passed in via a global, so no key file needed.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <signal.h>
+
+/**/
+#include <netinet/in.h>
+#include <arpa/inet.h>
+/**/
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>                /* MAXHOSTNAMELEN (often) */
+#endif
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_request.h"
+#include "ntp_stdlib.h"
+#include "ntp_syslog.h"
+
+#define        STREQ(a, b)     (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+/*
+ * Each item we are to resolve and configure gets one of these
+ * structures defined for it.
+ */
+struct dns_entry {
+       struct dns_entry *de_next;
+       struct info_dns_assoc de_info; /* DNS info for peer */
+};
+#define        de_associd      de_info.associd
+#define        de_peeraddr     de_info.peeraddr
+#define        de_hostname     de_info.hostname
+
+/*
+ * dns_entries is a pointer to the list of configuration entries
+ * we have left to do.
+ */
+static struct dns_entry *dns_entries = NULL;
+
+/*
+ * We take an interrupt every thirty seconds, at which time we decrement
+ * config_timer and resolve_timer.  The former is set to 2, so we retry
+ * unsucessful reconfigurations every minute.  The latter is set to
+ * an exponentially increasing value which starts at 2 and increases to
+ * 32.  When this expires we retry failed name resolutions.
+ *
+ * We sleep SLEEPTIME seconds before doing anything, to give the server
+ * time to arrange itself.
+ */
+#define        MINRESOLVE      2
+#define        MAXRESOLVE      32
+#define        CONFIG_TIME     2
+#define        ALARM_TIME      30
+
+#define        SLEEPTIME       2
+
+static volatile int config_timer = 0;
+static volatile int resolve_timer = 0;
+
+static int resolve_value;      /* next value of resolve timer */
+
+/*
+ * Big hack attack
+ */
+#define        LOCALHOST       0x7f000001      /* 127.0.0.1, in hex, of course */
+#define        SKEWTIME        0x08000000      /* 0.03125 seconds as a l_fp fraction */
+
+/*
+ * Select time out.  Set to 2 seconds.  The server is on the local machine,
+ * after all.
+ */
+#define        TIMEOUT_SEC     2
+#define        TIMEOUT_USEC    0
+
+
+/*
+ * File descriptor for ntp request code.
+ */
+static int sockfd = -1;
+
+/*
+ * Pipe descriptors
+ */
+int p_fd[2] = { -1, -1 };
+
+/* stuff to be filled in by caller */
+
+extern keyid_t req_keyid;      /* request keyid */
+
+/* end stuff to be filled in */
+
+void           ntp_res         P((void));
+static RETSIGTYPE bong         P((int));
+static void    checkparent     P((void));
+static void    removeentry     P((struct dns_entry *));
+static void    addentry        P((char *, u_int32, u_short));
+static int     findhostaddr    P((struct dns_entry *));
+static void    openntp         P((void));
+static int     host_assoc      P((struct info_dns_assoc *));
+static void    doconfigure     P((int));
+
+struct ntp_res_t_pkt {         /* Tagged packet: */
+       void *tag;              /* For the caller */
+       u_int32 paddr;          /* IP to look up, or 0 */
+       char name[NTP_MAXHOSTNAME]; /* Name to look up (if 1st byte is not 0) */
+};
+
+struct ntp_res_c_pkt {         /* Control packet: */
+       char name[NTP_MAXHOSTNAME];
+       u_int32 paddr;
+       int mode;
+       int version;
+       int minpoll;
+       int maxpoll;
+       int flags;
+       int ttl;
+       keyid_t keyid;
+       u_char keystr[MAXFILENAME];
+};
+/*
+ * ntp_res_send
+ *
+ */
+
+void
+ntp_res_send(
+       void *tag,              /* Return this with the answer */
+       char *name,             /* Name to resolve (or NIL) */
+       u_int32 paddr,          /* Address to resolve (or 0) */
+       u_short associd         /* Association ID (if available) */
+       )
+{
+       pid_t pid;
+
+       /*
+        * fork.
+        * - parent returns
+        * - child stuffs data and calls ntp_res(NTP_RES_V2)
+        */
+
+       msyslog(LOG_INFO, "ntp_res_send: req_keyid %d\n", req_keyid);
+       for (pid = -1; pid == -1;) {
+#ifdef RES_TEST
+               pid = 0;
+#else
+               pid = fork();
+#endif
+               if (pid == -1) {
+                       msyslog(LOG_ERR, "ntp_res_send: fork() failed: %m");
+                       sleep(2);
+               }
+       }
+       switch (pid) {
+           case -1:    /* Error */
+               msyslog(LOG_DEBUG, "ntp_res_send: error...");
+               /* Can't happen */
+               break;
+
+           case 0:     /* Child */
+               closelog();
+               kill_asyncio();
+               (void) signal_no_reset(SIGCHLD, SIG_DFL);
+#ifndef LOG_DAEMON
+               openlog("ntp_res", LOG_PID);
+# else /* LOG_DAEMON */
+#  ifndef LOG_NTP
+#   define     LOG_NTP LOG_DAEMON
+#  endif
+               openlog("ntp_res_send", LOG_PID | LOG_NDELAY, LOG_NTP);
+#endif
+
+               msyslog(LOG_DEBUG, "ntp_res_send: in child...");
+               addentry(name, paddr, associd);
+               msyslog(LOG_DEBUG, "ntp_res_send: back from addentry()");
+               ntp_res();
+               msyslog(LOG_DEBUG, "ntp_res_send: in child...DONE");
+               break;
+
+           default:    /* Parent */
+               msyslog(LOG_DEBUG, "ntp_res_send: in parent...");
+               /* Nothing to do.  (In Real Life, this never happens.) */
+               return;
+       }
+}
+
+/*
+ * ntp_res needs;
+ *
+ *     req_key(???), req_keyid valid
+ *     syslog still open
+ */
+
+void
+ntp_res(void)
+{
+#ifdef HAVE_SIGSUSPEND
+       sigset_t set;
+
+       sigemptyset(&set);
+#endif /* HAVE_SIGSUSPEND */
+
+#ifdef DEBUG
+       if (debug) {
+               msyslog(LOG_INFO, "NTP_RESOLVER running");
+       }
+#endif
+
+       /*
+        * Make a first cut at resolving the bunch
+        */
+       doconfigure(1);
+       if (dns_entries == NULL) {
+               if (debug) {
+                       msyslog(LOG_INFO, "NTP_RESOLVER done!");
+               }
+#if defined SYS_WINNT
+               ExitThread(0);  /* Don't want to kill whole NT process */
+#else
+               exit(0);        /* done that quick */
+#endif
+       }
+       
+       /*
+        * Here we've got some problem children.  Set up the timer
+        * and wait for it.
+        */
+       resolve_value = resolve_timer = MINRESOLVE;
+       config_timer = CONFIG_TIME;
+#ifndef SYS_WINNT
+       (void) signal_no_reset(SIGALRM, bong);
+       alarm(ALARM_TIME);
+#endif /* SYS_WINNT */
+
+       for (;;) {
+               if (dns_entries == NULL)
+                   exit(0);
+
+               checkparent();
+
+               if (resolve_timer == 0) {
+                       if (resolve_value < MAXRESOLVE)
+                           resolve_value <<= 1;
+                       resolve_timer = resolve_value;
+#ifdef DEBUG
+                       msyslog(LOG_INFO, "resolve_timer: 0->%d", resolve_timer);
+#endif
+                       config_timer = CONFIG_TIME;
+                       doconfigure(1);
+                       continue;
+               } else if (config_timer == 0) {
+                       config_timer = CONFIG_TIME;
+#ifdef DEBUG
+                       msyslog(LOG_INFO, "config_timer: 0->%d", config_timer);
+#endif
+                       doconfigure(0);
+                       continue;
+               }
+#ifndef SYS_WINNT
+               /*
+                * There is a race in here.  Is okay, though, since
+                * all it does is delay things by 30 seconds.
+                */
+# ifdef HAVE_SIGSUSPEND
+               sigsuspend(&set);
+# else
+               sigpause(0);
+# endif /* HAVE_SIGSUSPEND */
+#else
+               if (config_timer > 0)
+                   config_timer--;
+               if (resolve_timer > 0)
+                   resolve_timer--;
+               sleep(ALARM_TIME);
+#endif /* SYS_WINNT */
+       }
+}
+
+
+#ifndef SYS_WINNT
+/*
+ * bong - service and reschedule an alarm() interrupt
+ */
+static RETSIGTYPE
+bong(
+       int sig
+       )
+{
+       if (config_timer > 0)
+           config_timer--;
+       if (resolve_timer > 0)
+           resolve_timer--;
+       alarm(ALARM_TIME);
+}
+#endif /* SYS_WINNT */
+
+/*
+ * checkparent - see if our parent process is still running
+ *
+ * No need to worry in the Windows NT environment whether the
+ * main thread is still running, because if it goes
+ * down it takes the whole process down with it (in
+ * which case we won't be running this thread either)
+ * Turn function into NOP;
+ */
+
+static void
+checkparent(void)
+{
+#if !defined (SYS_WINNT) && !defined (SYS_VXWORKS)
+
+       /*
+        * If our parent (the server) has died we will have been
+        * inherited by init.  If so, exit.
+        */
+       if (getppid() == 1) {
+               msyslog(LOG_INFO, "parent died before we finished, exiting");
+               exit(0);
+       }
+#endif /* SYS_WINNT && SYS_VXWORKS*/
+}
+
+
+/*
+ * removeentry - we are done with an entry, remove it from the list
+ */
+static void
+removeentry(
+       struct dns_entry *entry
+       )
+{
+       register struct dns_entry *de;
+
+       de = dns_entries;
+       if (de == entry) {
+               dns_entries = de->de_next;
+               return;
+       }
+
+       while (de != NULL) {
+               if (de->de_next == entry) {
+                       de->de_next = entry->de_next;
+                       return;
+               }
+               de = de->de_next;
+       }
+}
+
+
+/*
+ * addentry - add an entry to the configuration list
+ */
+static void
+addentry(
+       char *name,
+       u_int32 paddr,
+       u_short associd
+       )
+{
+       register struct dns_entry *de;
+
+#ifdef DEBUG
+       if (debug > 1) {
+               struct in_addr si;
+
+               si.s_addr = paddr;
+               msyslog(LOG_INFO, 
+                       "ntp_res_send: <%s> %s associd %d\n",
+                       (name) ? name : "", inet_ntoa(si), associd);
+       }
+#endif
+
+       de = (struct dns_entry *)emalloc(sizeof(struct dns_entry));
+       if (name) {
+               strncpy(de->de_hostname, name, sizeof de->de_hostname);
+       } else {
+               de->de_hostname[0] = 0;
+       }
+       de->de_peeraddr = paddr;
+       de->de_associd = associd;
+       de->de_next = NULL;
+
+       if (dns_entries == NULL) {
+               dns_entries = de;
+       } else {
+               register struct dns_entry *dep;
+
+               for (dep = dns_entries; dep->de_next != NULL;
+                    dep = dep->de_next)
+                   /* nothing */;
+               dep->de_next = de;
+       }
+}
+
+
+/*
+ * findhostaddr - resolve a host name into an address (Or vice-versa)
+ *
+ * Given one of {de_peeraddr,de_hostname}, find the other one.
+ * It returns 1 for "success" and 0 for an uncorrectable failure.
+ * Note that "success" includes try again errors.  You can tell that you
+ *  got a "try again" since {de_peeraddr,de_hostname} will still be zero.
+ */
+static int
+findhostaddr(
+       struct dns_entry *entry
+       )
+{
+       struct hostent *hp;
+
+       checkparent();          /* make sure our guy is still running */
+
+       if (entry->de_hostname[0] && entry->de_peeraddr) {
+               struct in_addr si;
+
+               si.s_addr = entry->de_peeraddr;
+               /* HMS: Squawk? */
+               msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are defined: <%s>/%s", &entry->de_hostname[0], inet_ntoa(si));
+               return 1;
+       }
+
+       if (!entry->de_hostname[0] && !entry->de_peeraddr) {
+               msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are undefined!");
+               return 0;
+       }
+
+       if (entry->de_hostname[0]) {
+#ifdef DEBUG
+               if (debug > 2)
+                       msyslog(LOG_DEBUG, "findhostaddr: Resolving <%s>",
+                               &entry->de_hostname[0]);
+#endif DEBUG
+               hp = gethostbyname(&entry->de_hostname[0]);
+       } else {
+#ifdef DEBUG
+               if (debug > 2) {
+                       struct in_addr si;
+
+                       si.s_addr = entry->de_peeraddr;
+                       msyslog(LOG_DEBUG, "findhostaddr: Resolving %s",
+                               inet_ntoa(si));
+               }
+#endif
+               hp = gethostbyaddr((const char *)&entry->de_peeraddr,
+                                  sizeof entry->de_peeraddr,
+                                  AF_INET);
+       }
+
+       if (hp == NULL) {
+               /*
+                * If the resolver is in use, see if the failure is
+                * temporary.  If so, return success.
+                */
+               if (h_errno == TRY_AGAIN)
+                   return (1);
+               return (0);
+       }
+
+       if (entry->de_hostname[0]) {
+#ifdef DEBUG
+               if (debug > 2)
+                       msyslog(LOG_DEBUG, "findhostaddr: name resolved.");
+#endif
+               /*
+                * Use the first address.  We don't have any way to tell
+                * preferences and older gethostbyname() implementations
+                * only return one.
+                */
+               memmove((char *)&(entry->de_peeraddr),
+                       (char *)hp->h_addr,
+                       sizeof(struct in_addr));
+       } else {
+#ifdef DEBUG
+               if (debug > 2)
+                       msyslog(LOG_DEBUG, "findhostaddr: address resolved.");
+#endif
+               strncpy(&entry->de_hostname[0], hp->h_name, sizeof entry->de_hostname);
+       }
+                  
+       return (1);
+}
+
+
+/*
+ * openntp - open a socket to the ntp server
+ */
+static void
+openntp(void)
+{
+       struct sockaddr_in saddr;
+
+       if (sockfd >= 0)
+           return;
+       
+       sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sockfd == -1) {
+               msyslog(LOG_ERR, "socket() failed: %m");
+               exit(1);
+       }
+
+       memset((char *)&saddr, 0, sizeof(saddr));
+       saddr.sin_family = AF_INET;
+       saddr.sin_port = htons(NTP_PORT);               /* trash */
+       saddr.sin_addr.s_addr = htonl(LOCALHOST);       /* garbage */
+
+       /*
+        * Make the socket non-blocking.  We'll wait with select()
+        */
+#ifndef SYS_WINNT
+# if defined(O_NONBLOCK)
+       if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) {
+               msyslog(LOG_ERR, "fcntl(O_NONBLOCK) failed: %m");
+               exit(1);
+       }
+# else
+#  if defined(FNDELAY)
+       if (fcntl(sockfd, F_SETFL, FNDELAY) == -1) {
+               msyslog(LOG_ERR, "fcntl(FNDELAY) failed: %m");
+               exit(1);
+       }
+#  else
+#   include "Bletch: NEED NON BLOCKING IO"
+#  endif /* FNDDELAY */
+# endif /* O_NONBLOCK */
+#else  /* SYS_WINNT */
+       {
+               int on = 1;
+
+               if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) {
+                       msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m");
+                       exit(1); /* Windows NT - set socket in non-blocking mode */
+               }
+       }
+#endif /* SYS_WINNT */
+
+
+       if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
+               msyslog(LOG_ERR, "openntp: connect() failed: %m");
+               exit(1);
+       }
+}
+
+
+/*
+ * host_assoc: Send the resolved hostname for the associd
+ */
+static int
+host_assoc(
+       struct info_dns_assoc *conf
+       )
+{
+       fd_set fdset;
+       struct timeval tvout;
+       struct req_pkt reqpkt;
+       l_fp ts;
+       int n;
+#ifdef SYS_WINNT
+       HANDLE hReadWriteEvent = NULL;
+       BOOL ret;
+       DWORD NumberOfBytesWritten, NumberOfBytesRead, dwWait;
+       OVERLAPPED overlap;
+#endif /* SYS_WINNT */
+
+       checkparent();          /* make sure our guy is still running */
+
+       if (sockfd < 0)
+           openntp();
+       
+#ifdef SYS_WINNT
+       hReadWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+#endif /* SYS_WINNT */
+
+       /*
+        * Try to clear out any previously received traffic so it
+        * doesn't fool us.  Note the socket is nonblocking.
+        */
+       tvout.tv_sec =  0;
+       tvout.tv_usec = 0;
+       FD_ZERO(&fdset);
+       FD_SET(sockfd, &fdset);
+       while (select(sockfd + 1, &fdset, (fd_set *)0, (fd_set *)0, &tvout) >
+              0) {
+               recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0);
+               FD_ZERO(&fdset);
+               FD_SET(sockfd, &fdset);
+       }
+
+       /*
+        * Make up a request packet with the configuration info
+        */
+       memset((char *)&reqpkt, 0, sizeof(reqpkt));
+
+       reqpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0);
+       reqpkt.auth_seq = AUTH_SEQ(1, 0);       /* authenticated, no seq */
+       reqpkt.implementation = IMPL_XNTPD;     /* local implementation */
+       reqpkt.request = REQ_HOSTNAME_ASSOCID;  /* Hostname for associd */
+       reqpkt.err_nitems = ERR_NITEMS(0, 1);   /* one item */
+       reqpkt.mbz_itemsize = MBZ_ITEMSIZE(sizeof(struct info_dns_assoc));
+       memmove(reqpkt.data, (char *)conf, sizeof(struct info_dns_assoc));
+       reqpkt.keyid = htonl(req_keyid);
+
+       get_systime(&ts);
+       L_ADDUF(&ts, SKEWTIME);
+       HTONL_FP(&ts, &reqpkt.tstamp);
+       n = 0;
+       if (sys_authenticate)
+               n = authencrypt(req_keyid, (u_int32 *)&reqpkt, REQ_LEN_NOMAC);
+
+       /*
+        * Done.  Send it.
+        */
+#ifndef SYS_WINNT
+       n = send(sockfd, (char *)&reqpkt, (unsigned)(REQ_LEN_NOMAC + n), 0);
+       if (n < 0) {
+               msyslog(LOG_ERR, "send to NTP server failed: %m");
+               return 0;       /* maybe should exit */
+       }
+#else
+       /* In the NT world, documentation seems to indicate that there
+        * exist _write and _read routines that can be used to do blocking
+        * I/O on sockets. Problem is these routines require a socket
+        * handle obtained through the _open_osf_handle C run-time API
+        * of which there is no explanation in the documentation. We need
+        * nonblocking write's and read's anyway for our purpose here.
+        * We're therefore forced to deviate a little bit from the Unix
+        * model here and use the ReadFile and WriteFile Win32 I/O API's
+        * on the socket
+        */
+       overlap.Offset = overlap.OffsetHigh = (DWORD)0;
+       overlap.hEvent = hReadWriteEvent;
+       ret = WriteFile((HANDLE)sockfd, (char *)&reqpkt, REQ_LEN_NOMAC + n,
+                       (LPDWORD)&NumberOfBytesWritten, (LPOVERLAPPED)&overlap);
+       if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) {
+               msyslog(LOG_ERR, "send to NTP server failed: %m");
+               return 0;
+       }
+       dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000);
+       if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) {
+               if (dwWait == WAIT_FAILED)
+                   msyslog(LOG_ERR, "WaitForSingleObject failed: %m");
+               return 0;
+       }
+#endif /* SYS_WINNT */
+    
+
+       /*
+        * Wait for a response.  A weakness of the mode 7 protocol used
+        * is that there is no way to associate a response with a
+        * particular request, i.e. the response to this configuration
+        * request is indistinguishable from that to any other.  I should
+        * fix this some day.  In any event, the time out is fairly
+        * pessimistic to make sure that if an answer is coming back
+        * at all, we get it.
+        */
+       for (;;) {
+               FD_ZERO(&fdset);
+               FD_SET(sockfd, &fdset);
+               tvout.tv_sec = TIMEOUT_SEC;
+               tvout.tv_usec = TIMEOUT_USEC;
+
+               n = select(sockfd + 1, &fdset, (fd_set *)0,
+                          (fd_set *)0, &tvout);
+
+               if (n < 0)
+               {
+                       msyslog(LOG_ERR, "select() fails: %m");
+                       return 0;
+               }
+               else if (n == 0)
+               {
+                       if(debug)
+                           msyslog(LOG_DEBUG, "select() returned 0.");
+                       return 0;
+               }
+
+#ifndef SYS_WINNT
+               n = recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0);
+               if (n <= 0) {
+                       if (n < 0) {
+                               msyslog(LOG_ERR, "recv() fails: %m");
+                               return 0;
+                       }
+                       continue;
+               }
+#else /* Overlapped I/O used on non-blocking sockets on Windows NT */
+               ret = ReadFile((HANDLE)sockfd, (char *)&reqpkt, (DWORD)REQ_LEN_MAC,
+                              (LPDWORD)&NumberOfBytesRead, (LPOVERLAPPED)&overlap);
+               if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) {
+                       msyslog(LOG_ERR, "ReadFile() fails: %m");
+                       return 0;
+               }
+               dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000);
+               if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) {
+                       if (dwWait == WAIT_FAILED) {
+                               msyslog(LOG_ERR, "WaitForSingleObject fails: %m");
+                               return 0;
+                       }
+                       continue;
+               }
+               n = NumberOfBytesRead;
+#endif /* SYS_WINNT */
+
+               /*
+                * Got one.  Check through to make sure it is what
+                * we expect.
+                */
+               if (n < RESP_HEADER_SIZE) {
+                       msyslog(LOG_ERR, "received runt response (%d octets)",
+                               n);
+                       continue;
+               }
+
+               if (!ISRESPONSE(reqpkt.rm_vn_mode)) {
+#ifdef DEBUG
+                       if (debug > 1)
+                           msyslog(LOG_INFO, "received non-response packet");
+#endif
+                       continue;
+               }
+
+               if (ISMORE(reqpkt.rm_vn_mode)) {
+#ifdef DEBUG
+                       if (debug > 1)
+                           msyslog(LOG_INFO, "received fragmented packet");
+#endif
+                       continue;
+               }
+
+               if ( ( (INFO_VERSION(reqpkt.rm_vn_mode) < 2)
+                      || (INFO_VERSION(reqpkt.rm_vn_mode) > NTP_VERSION))
+                    || INFO_MODE(reqpkt.rm_vn_mode) != MODE_PRIVATE) {
+#ifdef DEBUG
+                       if (debug > 1)
+                           msyslog(LOG_INFO,
+                                   "version (%d/%d) or mode (%d/%d) incorrect",
+                                   INFO_VERSION(reqpkt.rm_vn_mode),
+                                   NTP_VERSION,
+                                   INFO_MODE(reqpkt.rm_vn_mode),
+                                   MODE_PRIVATE);
+#endif
+                       continue;
+               }
+
+               if (INFO_SEQ(reqpkt.auth_seq) != 0) {
+#ifdef DEBUG
+                       if (debug > 1)
+                           msyslog(LOG_INFO,
+                                   "nonzero sequence number (%d)",
+                                   INFO_SEQ(reqpkt.auth_seq));
+#endif
+                       continue;
+               }
+
+               if (reqpkt.implementation != IMPL_XNTPD ||
+                   reqpkt.request != REQ_HOSTNAME_ASSOCID) {
+#ifdef DEBUG
+                       if (debug > 1)
+                           msyslog(LOG_INFO,
+                                   "implementation (%d/%d) or request (%d/%d) incorrect",
+                                   reqpkt.implementation, IMPL_XNTPD,
+                                   reqpkt.request, REQ_HOSTNAME_ASSOCID);
+#endif
+                       continue;
+               }
+
+               if (INFO_NITEMS(reqpkt.err_nitems) != 0 ||
+                   INFO_MBZ(reqpkt.mbz_itemsize) != 0 ||
+                   INFO_ITEMSIZE(reqpkt.mbz_itemsize) != 0) {
+#ifdef DEBUG
+                       if (debug > 1)
+                           msyslog(LOG_INFO,
+                                   "nitems (%d) mbz (%d) or itemsize (%d) nonzero",
+                                   INFO_NITEMS(reqpkt.err_nitems),
+                                   INFO_MBZ(reqpkt.mbz_itemsize),
+                                   INFO_ITEMSIZE(reqpkt.mbz_itemsize));
+#endif
+                       continue;
+               }
+
+               n = INFO_ERR(reqpkt.err_nitems);
+               switch (n) {
+                   case INFO_OKAY:
+                       /* success */
+                       return 1;
+               
+                   case INFO_ERR_IMPL:
+                       msyslog(LOG_ERR,
+                               "server reports implementation mismatch!!");
+                       return 0;
+               
+                   case INFO_ERR_REQ:
+                       msyslog(LOG_ERR,
+                               "server claims configuration request is unknown");
+                       return 0;
+               
+                   case INFO_ERR_FMT:
+                       msyslog(LOG_ERR,
+                               "server indicates a format error occurred(!!)");
+                       return 0;
+
+                   case INFO_ERR_NODATA:
+                       msyslog(LOG_ERR,
+                               "server indicates no data available (shouldn't happen)");
+                       return 0;
+               
+                   case INFO_ERR_AUTH:
+                       msyslog(LOG_ERR,
+                               "server returns a permission denied error");
+                       return 0;
+
+                   default:
+                       msyslog(LOG_ERR,
+                               "server returns unknown error code %d", n);
+                       return 0;
+               }
+       }
+}
+
+
+/*
+ * doconfigure - attempt to resolve names and configure the server
+ */
+static void
+doconfigure(
+       int dores
+       )
+{
+       register struct dns_entry *de;
+       register struct dns_entry *deremove;
+
+       de = dns_entries;
+       while (de != NULL) {
+#ifdef DEBUG
+               if (debug > 1) {
+                       struct in_addr si;
+
+                       si.s_addr = de->de_peeraddr;
+                       msyslog(LOG_INFO,
+                           "doconfigure: name: <%s> peeraddr: %s",
+                           de->de_hostname, inet_ntoa(si));
+               }
+#endif
+               if (dores && (de->de_hostname[0] == 0 || de->de_peeraddr == 0)) {
+                       if (!findhostaddr(de)) {
+                               struct in_addr si;
+
+                               si.s_addr = de->de_peeraddr;
+                               msyslog(LOG_ERR,
+                                       "couldn't resolve <%s>/%s, giving up on it",
+                                       de->de_hostname, inet_ntoa(si));
+                               deremove = de;
+                               de = deremove->de_next;
+                               removeentry(deremove);
+                               continue;
+                       }
+               }
+
+               if (de->de_hostname[0] && de->de_peeraddr != 0) {
+                       /* Send the answer */
+                       if (host_assoc(&de->de_info)) {
+                               struct in_addr si;
+
+                               si.s_addr = de->de_peeraddr;
+                               msyslog(LOG_INFO,
+                                       "resolved <%s>/%s, done with it",
+                                       de->de_hostname, inet_ntoa(si));
+
+                               deremove = de;
+                               de = deremove->de_next;
+                               removeentry(deremove);
+                               continue;
+                       }
+#ifdef DEBUG
+                       if (debug > 1) {
+                               msyslog(LOG_INFO,
+                                   "doconfigure: host_assoc() FAILED, maybe next time.");
+                       }
+#endif
+               }
+               de = de->de_next;
+       }
+}
index 0e2dc88cbe95c265cebe7b71abe6f446922b6af3..8d0e1281274490c2cb391da74af6bd1b28ce4446 100644 (file)
@@ -41,8 +41,10 @@ volatile int alarm_flag;
 static u_long adjust_timer;            /* second timer */
 static u_long keys_timer;              /* minute timer */
 static u_long hourly_timer;            /* hour timer */
+#ifdef AUTOKEY
 static u_long revoke_timer;            /* keys revoke timer */
-u_long sys_revoke = KEY_REVOKE;        /* keys revoke timeout */
+u_long sys_revoke = 1 << KEY_REVOKE;   /* keys revoke timeout */
+#endif /* AUTOKEY */
 
 /*
  * Statistics counter for the interested.
@@ -250,12 +252,14 @@ timer(void)
        }
 
        /*
-        * Garbage collect revoked keys
+        * Garbage collect old keys and generate new private value
         */
+#ifdef AUTOKEY
        if (revoke_timer <= current_time) {
-               revoke_timer += RANDPOLL(sys_revoke);
+               revoke_timer += sys_revoke;
                key_expire_all();
        }
+#endif /* AUTOKEY */
 
        /*
         * Finally, call the hourly routine.
index c53255a0a62b5c28379323e9f0c078e4613885d4..20861b0a73d735cab28506a619ac9bb7d816860f 100644 (file)
@@ -2,16 +2,20 @@
  * ntp_util.c - stuff I didn't have any other place for
  */
 #ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
 #endif
 
 #include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
-# ifdef HAVE_SYS_IOCTL_H
-#  include <sys/ioctl.h>
-# endif
-# include <sys/time.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#include <sys/time.h>
+
+#ifdef HAVE_IEEEFP_H
+# include <ieeefp.h>
+#endif
 
 #include "ntpd.h"
 #include "ntp_io.h"
@@ -341,12 +345,18 @@ stats_config(
                        break;
                }
                if (fscanf(fp, "%lf", &old_drift) != 1) {
-                       msyslog(LOG_ERR, "invalid frequency from %s", 
+                       msyslog(LOG_ERR, "Un-parsable frequency in %s", 
                            stats_drift_file);
                        (void) fclose(fp);
                        break;
                }
                (void) fclose(fp);
+               if (   !finite(old_drift)
+                   || (fabs(old_drift) > (sys_maxfreq * 1e6))) {
+                       msyslog(LOG_ERR, "invalid frequency (%lf) in %s", 
+                           old_drift, stats_drift_file);
+                       exit(1);
+               }
                msyslog(LOG_INFO, "frequency initialized %.3f from %s",
                    old_drift, stats_drift_file);
                loop_config(LOOP_DRIFTCOMP, old_drift / 1e6);
index b9b27acc0cedba239eb1e3d49db15769598c608a..30e7f5fcf6639b4ac748a7ff4ea48bb109d2dd90 100644 (file)
 # include <sys/ci/ciioctl.h>
 #endif
 
+#ifdef PUBKEY
+#include "ntp_crypto.h"
+#endif /* PUBKEY */
+
 /*
  * Signals we catch for debugging.     If not debugging we ignore them.
  */
@@ -378,10 +382,13 @@ ntpdmain(
        }
        addSourceToRegistry("NTP", szMsgPath);
 #endif
+       getstartup(argc, argv); /* startup configuration, may set debug */
 
+       /*
+        * Initialize random generator and public key pair
+        */
        get_systime(&now);
        SRANDOM((int)(now.l_i * now.l_uf));
-       getstartup(argc, argv); /* startup configuration, may set debug */
 
 #if !defined(VMS)
 # ifndef NODETACH
@@ -714,12 +721,14 @@ service_main(
 #ifdef REFCLOCK
        init_refclock();
 #endif
+#ifdef PUBKEY
+       crypto_init();          /* Call *before* going to high-priority */
+#endif /* PUBKEY */
        set_process_priority();
-       init_proto();
+       init_proto();           /* Call at high priority */
        init_io();
        init_loopfilter();
-
-       mon_start(MON_ON);              /* monitor on by default now      */
+       mon_start(MON_ON);      /* monitor on by default now      */
                                /* turn off in config if unwanted */
 
        /*
@@ -728,7 +737,10 @@ service_main(
         * for the gizmo board.
         */
        getconfig(argc, argv);
-
+#ifdef PUBKEY
+       if (crypto_enable)
+               crypto_setup();
+#endif /* PUBKEY */
        initializing = 0;
 
 #if defined(SYS_WINNT) && !defined(NODETACH)
index 9af4ace544573ffa6da7a8ce4575894d077176e4..3ffa5c59b39b458e12e2e1fa167e4971336ba64b 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 86ac988d5579ffe79eacab687a5a211ddef5d07d..2ac99257c97ec01484713eaabf1993096b7d38b1 100644 (file)
@@ -702,7 +702,7 @@ transmit(
        if (sys_authenticate) {
                int len;
 
-               xpkt.keyid1 = htonl(sys_authkey);
+               xpkt.exten[0] = htonl(sys_authkey);
                get_systime(&server->xmt);
                L_ADDUF(&server->xmt, sys_authdelay);
                HTONL_FP(&server->xmt, &xpkt.xmt);
@@ -810,11 +810,11 @@ receive(
 
                if (debug > 3)
                        printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n",
-                          (long int)ntohl(rpkt->keyid1), (long int)sys_authkey,
+                          (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey,
                           (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt,
                                LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC)));
 
-               if (has_mac && ntohl(rpkt->keyid1) == sys_authkey &&
+               if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey &&
                        authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC,
                        (int)(rbufp->recv_length - LEN_PKT_NOMAC)))
                        is_authentic = 1;
index bf618cad987203d94e1624c3b1bbcc51862b5423..fb9e7e07acf531b0f4ad2154ed5a877cd2b786cd 100644 (file)
@@ -892,7 +892,7 @@ transmit(
        if (sys_authenticate) {
                int len;
 
-               xpkt.keyid1 = htonl(sys_authkey);
+               xpkt.exten[0] = htonl(sys_authkey);
                get_systime(&server->xmt);
                L_ADDUF(&server->xmt, sys_authdelay);
                HTONL_FP(&server->xmt, &xpkt.xmt);
@@ -1051,11 +1051,11 @@ receive(
 
                if (debug > 3)
                        printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n",
-                          (long int)ntohl(rpkt->keyid1), (long int)sys_authkey,
+                          (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey,
                           (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt,
                                LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC)));
 
-               if (has_mac && ntohl(rpkt->keyid1) == sys_authkey &&
+               if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey &&
                        authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC,
                        (int)(rbufp->recv_length - LEN_PKT_NOMAC)))
                        is_authentic = 1;
index cec54cad6c2ecf2baf9b03648b5f1b6018ff05d5..1b6cda61a7da59809b36738e0f955af9f4f295f4 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 6d656dd925c2e240b46fa5632c3e21e546261269..b288deaf6be8c39384c5ca69b0fd256b73bf912e 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 5a1f05284b1c64a71203c795533f8c226a6d3e59..27795d129d9ee59fed00b51f3f2a2abba49baa1c 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 58450bc0cb35dcd2841bd600400b9e416008f663..3d1dc06437e393e31cd78fe08a69589a6dd14f72 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 2143524471e0adf5c70c2dee28283795b6db9f43..a296708248b480ad468c902ae0b1e0f71d43cf32 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
index 504c6b0f0831ed44ae5dfecfc7b3630d7574a0d1..985283e59e51a5d0dec644e380c4257c347485af 100644 (file)
@@ -1,8 +1,10 @@
 #AUTOMAKE_OPTIONS = ../ansi2knr no-dependencies
 AUTOMAKE_OPTIONS = ansi2knr
-bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@
-EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntptime \
-precision tickadj testrs6000 timetrim sht
+bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@ @MAKE_NTP_GENKEYS@
+EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntp_genkeys ntptime \
+precision sht testrs6000 tickadj timetrim
+
+ntp_genkeys_LDADD = ../librsaref/librsaref.a
 
 INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/librsaref
 # LDADD might need RESLIB and ADJLIB
index 6a7d5e209f5864c2204d397530c351bb43383855..8b950fbc670892d8302ef6e899fab1f9aea66ebc 100644 (file)
@@ -86,6 +86,7 @@ MAKE_LIBPARSE = @MAKE_LIBPARSE@
 MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
 MAKE_LIBRSAREF = @MAKE_LIBRSAREF@
 MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@
 MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
 MAKE_TICKADJ = @MAKE_TICKADJ@
 PACKAGE = @PACKAGE@
@@ -103,11 +104,13 @@ install_sh = @install_sh@
 
 
 AUTOMAKE_OPTIONS = ansi2knr
-bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@
-EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntptime \
-precision tickadj testrs6000 timetrim sht
+bin_PROGRAMS = @MAKE_TICKADJ@ @MAKE_NTPTIME@ @MAKE_NTP_GENKEYS@
+EXTRA_PROGRAMS = byteorder hist jitter kern longsize ntp_genkeys ntptime \
+precision sht testrs6000 tickadj timetrim
 
 
+ntp_genkeys_LDADD = ../librsaref/librsaref.a
+
 INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/librsaref
 # LDADD might need RESLIB and ADJLIB
 LDADD = ../libntp/libntp.a
@@ -150,6 +153,10 @@ longsize_OBJECTS =  longsize$U.o
 longsize_LDADD = $(LDADD)
 longsize_DEPENDENCIES =  ../libntp/libntp.a
 longsize_LDFLAGS = 
+ntp_genkeys_SOURCES = ntp_genkeys.c
+ntp_genkeys_OBJECTS =  ntp_genkeys$U.o
+ntp_genkeys_DEPENDENCIES =  ../librsaref/librsaref.a
+ntp_genkeys_LDFLAGS = 
 ntptime_SOURCES = ntptime.c
 ntptime_OBJECTS =  ntptime$U.o
 ntptime_LDADD = $(LDADD)
@@ -183,8 +190,9 @@ timetrim_LDFLAGS =
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-DIST_SOURCES =  byteorder.c hist.c jitter.c kern.c longsize.c ntptime.c \
-precision.c sht.c testrs6000.c tickadj.c timetrim.c
+DIST_SOURCES =  byteorder.c hist.c jitter.c kern.c longsize.c \
+ntp_genkeys.c ntptime.c precision.c sht.c testrs6000.c tickadj.c \
+timetrim.c
 DIST_COMMON =  README Makefile.am Makefile.in ansi2knr.1 ansi2knr.c
 
 
@@ -194,11 +202,11 @@ GZIP_ENV = --best
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 DEP_FILES =  @AMDEP@ $(DEPDIR)/byteorder$U.Po $(DEPDIR)/hist$U.Po \
 $(DEPDIR)/jitter$U.Po $(DEPDIR)/kern$U.Po $(DEPDIR)/longsize$U.Po \
-$(DEPDIR)/ntptime$U.Po $(DEPDIR)/precision$U.Po $(DEPDIR)/sht$U.Po \
-$(DEPDIR)/testrs6000$U.Po $(DEPDIR)/tickadj$U.Po \
-$(DEPDIR)/timetrim$U.Po
-SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c ntptime.c precision.c sht.c testrs6000.c tickadj.c timetrim.c
-OBJECTS = byteorder$U.o hist$U.o jitter$U.o kern$U.o longsize$U.o ntptime$U.o precision$U.o sht$U.o testrs6000$U.o tickadj$U.o timetrim$U.o
+$(DEPDIR)/ntp_genkeys$U.Po $(DEPDIR)/ntptime$U.Po \
+$(DEPDIR)/precision$U.Po $(DEPDIR)/sht$U.Po $(DEPDIR)/testrs6000$U.Po \
+$(DEPDIR)/tickadj$U.Po $(DEPDIR)/timetrim$U.Po
+SOURCES = byteorder.c hist.c jitter.c kern.c longsize.c ntp_genkeys.c ntptime.c precision.c sht.c testrs6000.c tickadj.c timetrim.c
+OBJECTS = byteorder$U.o hist$U.o jitter$U.o kern$U.o longsize$U.o ntp_genkeys$U.o ntptime$U.o precision$U.o sht$U.o testrs6000$U.o tickadj$U.o timetrim$U.o
 
 all: all-redirect
 .SUFFIXES:
@@ -291,6 +299,10 @@ longsize: $(longsize_OBJECTS) $(longsize_DEPENDENCIES)
        @rm -f longsize
        $(LINK) $(longsize_LDFLAGS) $(longsize_OBJECTS) $(longsize_LDADD) $(LIBS)
 
+ntp_genkeys: $(ntp_genkeys_OBJECTS) $(ntp_genkeys_DEPENDENCIES)
+       @rm -f ntp_genkeys
+       $(LINK) $(ntp_genkeys_LDFLAGS) $(ntp_genkeys_OBJECTS) $(ntp_genkeys_LDADD) $(LIBS)
+
 ntptime: $(ntptime_OBJECTS) $(ntptime_DEPENDENCIES)
        @rm -f ntptime
        $(LINK) $(ntptime_LDFLAGS) $(ntptime_OBJECTS) $(ntptime_LDADD) $(LIBS)
@@ -324,6 +336,8 @@ kern_.c: kern.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/kern.c; then echo $(srcdir)/kern.c; else echo kern.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > kern_.c
 longsize_.c: longsize.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/longsize.c; then echo $(srcdir)/longsize.c; else echo longsize.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > longsize_.c
+ntp_genkeys_.c: ntp_genkeys.c $(ANSI2KNR)
+       $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntp_genkeys.c; then echo $(srcdir)/ntp_genkeys.c; else echo ntp_genkeys.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntp_genkeys_.c
 ntptime_.c: ntptime.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ntptime.c; then echo $(srcdir)/ntptime.c; else echo ntptime.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > ntptime_.c
 precision_.c: precision.c $(ANSI2KNR)
@@ -336,8 +350,9 @@ tickadj_.c: tickadj.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/tickadj.c; then echo $(srcdir)/tickadj.c; else echo tickadj.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > tickadj_.c
 timetrim_.c: timetrim.c $(ANSI2KNR)
        $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/timetrim.c; then echo $(srcdir)/timetrim.c; else echo timetrim.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > timetrim_.c
-byteorder_.o hist_.o jitter_.o kern_.o longsize_.o ntptime_.o \
-precision_.o sht_.o testrs6000_.o tickadj_.o timetrim_.o : $(ANSI2KNR)
+byteorder_.o hist_.o jitter_.o kern_.o longsize_.o ntp_genkeys_.o \
+ntptime_.o precision_.o sht_.o testrs6000_.o tickadj_.o timetrim_.o : \
+$(ANSI2KNR)
 
 tags: TAGS
 
@@ -391,6 +406,7 @@ distdir: $(DISTFILES)
 @AMDEP@include $(DEPDIR)/jitter$U.Po
 @AMDEP@include $(DEPDIR)/kern$U.Po
 @AMDEP@include $(DEPDIR)/longsize$U.Po
+@AMDEP@include $(DEPDIR)/ntp_genkeys$U.Po
 @AMDEP@include $(DEPDIR)/ntptime$U.Po
 @AMDEP@include $(DEPDIR)/precision$U.Po
 @AMDEP@include $(DEPDIR)/sht$U.Po
diff --git a/util/ntp_genkeys.c b/util/ntp_genkeys.c
new file mode 100644 (file)
index 0000000..1b025cb
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Program to generate MD5 and RSA keys for NTP clients and servers
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/utsname.h>
+#include "ntpd.h"
+#include "ntp_stdlib.h"
+#include "ntp_string.h"
+#include "ntp_crypto.h"
+
+/*
+ * Cryptodefines
+ */
+#define MAXKEYLEN      1024    /* maximum encoded key length */
+#define MODULUSLEN     512     /* length of RSA modulus */
+#define PRIMELEN       512     /* length of D_H prime, generator */
+#define GENLEN         256     /* length of D-H key and subprime */
+
+/*
+ * This program generates four files: ntp.keys containing the DES/MD5
+ * private keys, ntpkey containing the RSA private key, ntpkey_host
+ * containing the RSA public key, where host is the DNS name of the
+ * generating machine, and ntpkey_dh containing the parameters for the
+ * Diffie-Hellman key-agreement algorithm. The files contain
+ * cryptographic values generated by the algorithms of the rsaref20
+ * package and are in printable ASCII format. Since the algorythms are
+ * seeded by the system clock, each run of this program will produce a
+ * different outcome. There are no options or frills of any sort,
+ * although a number of options would seem to be appropriate. Waving
+ * this program in the breeze will no doubt bring a cast of thousands to
+ * wiggle the options this way and that for various useful purposes.
+ *
+ * The ntp.keys file contains 16 MD5 keys. Each key consists of 16
+ * characters randomized over the ASCII 95-character printing subset.
+ * The file is read by the daemon at the location specified by the keys
+ * configuration file command and made visible only to root. An
+ * additional key consisting of a easily remembered password should be
+ * added by hand for use with the ntpdc program. The file must be
+ * distributed by secure means to other servers and clients sharing the
+ * same security compartment.
+ *
+ * The key identifiers for MD5 and DES keys must be less than 65536,
+ * although this program uses only the identifiers from 1 to 16. The key
+ * identifier for each association is specified as the key argument in
+ * the server or peer configuration file command.
+ *
+ * The ntpkey file contains the RSA private key. It is read by the
+ * daemon at the location specified by the private argument of the
+ * crypto configuration file command and made visible only to root. This
+ * file is useful only to the machine that generated it and never shared
+ * with any other daemon or application program.
+ *
+ * The ntpkey_host file contains the RSA public key, where host is the
+ * DNS name of the host that generated it. The file is read by the
+ * daemon at the location specified by the public argument to the server
+ * or peer configuration file command. This file can be widely
+ * distributed and stored without using secure means, since the data are
+ * public values.
+ *
+ * The ntp_dh file contains two Diffie-Hellman parameters, the prime
+ * modulus and the generator. The file is read by the daemon at the
+ * location specified by the dhparams argument of the crypto
+ * configuration file command. This file can be widely distributed and
+ * stored without using secure means, since the data are public values.
+ *
+ * The file formats all begin with two lines, the first containing the
+ * generating system DNS name and the second the datestamp. Lines
+ * beginning with # are considered comments and ignored by the daemon.
+ * In the ntp.keys file, the next 16 lines contain the MD5 keys in
+ * order. In the ntpkey and ntpkey_host files, the next line contains
+ * the modulus length in bits followed by the key as a PEM encoded
+ * string. In the ntpkey_dh file, the next line contains the prime
+ * length in bytes followed by the prime as a PEM encoded string, and
+ * the next and final line contains the generator length in bytes
+ * followed by the generator as a PEM encoded string.
+ *
+ * Note: See the file ./source/rsaref.h in the rsaref20 package for
+ * explanation of return values, if necessary. 
+ */
+int
+main(
+       int argc,
+       char *argv[]
+       )
+{
+       R_RSA_PRIVATE_KEY rsaref_private; /* RSA private key */
+       R_RSA_PUBLIC_KEY rsaref_public; /* RSA public key */
+       R_RSA_PROTO_KEY protokey;       /* RSA prototype key */
+       R_DH_PARAMS dh_params;          /* Diffie-Hellman parameters */
+       R_RANDOM_STRUCT randomstr;      /* random structure */
+       u_char encoded_key[MAXKEYLEN];  /* encoded PEM string buffer */
+       u_int modulus;                  /* modulus length */
+       struct timeval tv;              /* initialization vector */
+       struct utsname utsnamebuf;      /* uname argument structure */
+       u_char sysname[128];            /* DNS host name */
+       u_char md5key[17];              /* generated MD5 key */ 
+       FILE *str;                      /* file handle */
+       int rval;                       /* return value */
+       u_int temp, len;
+       int i, j;
+
+       /*
+        * Generate the file "ntp.keys" containing 16 random MD5 keys in
+        * the format expected at daemon run time.
+        */
+       uname(&utsnamebuf);
+       printf("Generating MD5 keys...\n");
+       str = fopen("ntp.keys", "w");
+       if (str == NULL) {
+               perror("MD5/DES key file");
+               return (-1);
+       }
+       gettimeofday(&tv, 0);
+       srandom((u_int)tv.tv_sec);
+       fprintf(str, "# MD5/DES key file generated by %s\n# %s",
+           utsnamebuf.nodename, ctime(&tv.tv_sec));
+       for (i = 1; i <= 16; i++) {
+               for (j = 0; j < 16; j++) {
+                       while (1) {
+                               temp = random() & 0xff;
+                               if (temp > 0x20 && temp < 0x7f)
+                                       break;
+                       }
+                       md5key[j] = (u_char)temp;
+               }
+               md5key[16] = 0;
+               fprintf(str, "%2d M %16s        # MD5 key\n", i,
+                   md5key);
+       }
+       fclose(str);
+
+       /*
+        * Roll a RSA public/private key pair.
+        */
+       printf("Generating RSA public/private key pair %d bits...\n",
+           MODULUSLEN);
+       protokey.bits = MODULUSLEN;
+       protokey.useFermat4 = 1;
+       R_RandomInit(&randomstr);
+       R_GetRandomBytesNeeded(&len, &randomstr);
+       for (i = 0; i < len; i++) {
+               temp = random();
+               R_RandomUpdate(&randomstr, (u_char *)&temp, 1);
+       }
+       rval = R_GeneratePEMKeys(&rsaref_public, &rsaref_private,
+           &protokey, &randomstr);
+       if (rval) {
+               printf("R_GeneratePEMKeys error %x\n", rval);
+               return (-1);
+       }
+
+       /*
+        * Generate the file "ntpkey" containing the RSA private key in
+        * printable ASCII format.
+        */
+       str = fopen("ntpkey", "w");
+       if (str == NULL) { 
+               perror("RSA private key file");
+               return (-1);
+       }
+       len = sizeof(rsaref_private) - sizeof(rsaref_private.bits);
+       modulus = (u_int32)rsaref_private.bits;
+       fprintf(str, "# RSA private key file generated by %s\n# %s",
+           utsnamebuf.nodename, ctime(&tv.tv_sec));
+       R_EncodePEMBlock(encoded_key, &temp,
+           (u_char *)&rsaref_private.modulus, len);
+       encoded_key[temp] = '\0';
+       fprintf(str, "%d %s\n", modulus, encoded_key);
+       fclose(str);
+
+       /*
+        * Generate the file "ntpkey_host" containing the RSA public key
+        * in printable ASCII format.
+        */
+       sprintf(sysname, "ntpkey_%s", utsnamebuf.nodename); 
+       str = fopen(sysname, "w");
+       if (str == NULL) { 
+               perror("RSA public key file");
+               return (-1);
+       }
+       len = sizeof(rsaref_public) - sizeof(rsaref_public.bits);
+       modulus = (u_int32)rsaref_public.bits;
+       fprintf(str, "# RSA public key file generated by %s\n# %s",
+           utsnamebuf.nodename, ctime(&tv.tv_sec));
+       R_EncodePEMBlock(encoded_key, &temp,
+           (u_char *)&rsaref_public.modulus, len);
+       encoded_key[temp] = '\0';
+       fprintf(str, "%d %s\n", modulus, encoded_key);
+       fclose(str);
+
+       /*
+        * Roll the prime and generator for the Diffie-Hellman key
+        * agreement algorithm.
+        */
+       printf("Generating Diffie-Hellman parameters %d bits...\n",
+           PRIMELEN);
+       str = fopen("ntpkey_dh", "w");
+       if (str == NULL) { 
+               perror("Diffie-Hellman parameters file");
+               return (-1);
+       }
+       R_RandomInit(&randomstr);
+       R_GetRandomBytesNeeded(&len, &randomstr);
+       for (i = 0; i < len; i++) {
+               temp = random();
+               R_RandomUpdate(&randomstr, (u_char *)&temp, 1);
+       }
+
+       /*
+        * Generate the file "ntpkey_dh" containing the Diffie-Hellman
+        * prime and generator in printable ASCII format.
+        */
+       len = DH_PRIME_LEN(PRIMELEN);
+       dh_params.prime = (u_char *)malloc(len);
+       dh_params.generator = (u_char *)malloc(len);
+       rval = R_GenerateDHParams(&dh_params, PRIMELEN, GENLEN,
+           &randomstr);
+       if (rval) {
+               printf("R_GenerateDHParams error %x\n", rval);
+               return (-1);
+       }
+       fprintf(str,
+           "# Diffie-Hellman parameter file generated by %s\n# %s",
+           utsnamebuf.nodename, ctime(&tv.tv_sec));
+       R_EncodePEMBlock(encoded_key, &temp,
+           (u_char *)dh_params.prime, dh_params.primeLen);
+       encoded_key[temp] = '\0';
+       fprintf(str, "%d %s\n", dh_params.primeLen, encoded_key);
+       R_EncodePEMBlock(encoded_key, &temp,
+           (u_char *)dh_params.generator, dh_params.generatorLen);
+       encoded_key[temp] = '\0';
+       fprintf(str, "%d %s\n", dh_params.generatorLen, encoded_key);
+       fclose(str);
+
+       return (0);
+}