System: ntp version 3.4
Patch #: 4
Priority: 
Subject:

Don't bother to create the Version file for the distribution any longer.
Define SUN_FLT_BUG rather than just 'sun' to get the a fix for a floating
point problem in ntpsubs; apparantly the DECSTATION 3100 also has the
same problem.
Removed some unused #defines.  Replaced MAXSTRATUM with NTP_INFIN per new
spec.  The variable 'mode' in the peer structure has been renamed 'hmode'
per the new spec.
The variable 'mode' in the peer structure was renamed 'hmode'.  Add 
poll_update() calls in a few places per Mills.  The receive() procedure is
now table driven.  The poll_update procedure only randomized the timer
when the interval changes.  If we lose synchronization, don't zap sys.stratum.
Clean up the sanity_check() routine a bit.
peer->mode has been renamed peer->hmode.  Drop PEER_FL_SYNC since the
PEER_FL_CONFIG flag means much the same thing.
Check for success sending query before trying to listen for answers.  Will 
catch case of no server running and an ICMP port unreachable being returned.
Add -l option to create a log scale plot of the compliance.  Fix the option
handling code so that -S works again.  The drift compensation and compliance
values are now scaled.
From:

Description:

Repeat-By:

Fix:	From rn, say "| patch -p -N -d DIR", where DIR is your ntp source
	directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
	If you don't have the patch program, apply the following by hand,
	or get patch (version 2.0, latest patchlevel).

	After patching:
		make depend
		make
		make install

	If patch indicates that patchlevel is the wrong version, you may need
	to apply one or more previous patches, or the patch may already
	have been applied.  See the patchlevel.h file to find out what has or
	has not been applied.  In any event, don't continue with the patch.

	If you are missing previous patches they can be obtained from me:

	Louis A. Mamakos
	louie@trantor.umd.edu

	You can also get the patches via anonymous FTP from
	trantor.umd.edu.

Index: patchlevel.h
Prereq: 3
1c1
< #define PATCHLEVEL 3
---
> #define PATCHLEVEL 4

Index: Makefile
*** Makefile.old	Wed Mar 29 12:47:37 1989
--- Makefile	Wed Mar 29 12:47:38 1989
***************
*** 1,6 ****
! # $Source: /usr/users/louie/ntp/RCS/Makefile,v $ $Revision: 3.4.1.2 $ $Date: 89/03/22 18:25:14 $
  #
  # $Log:	Makefile,v $
  # Revision 3.4.1.2  89/03/22  18:25:14  louie
  # patch3: Use new and improved RCS headers.
  # 
--- 1,12 ----
! # $Source: /usr/users/louie/ntp/RCS/Makefile,v $ $Revision: 3.4.1.3 $ $Date: 89/03/29 12:21:27 $
  #
  # $Log:	Makefile,v $
+ # Revision 3.4.1.3  89/03/29  12:21:27  louie
+ # Don't bother to create the Version file for the distribution any longer.
+ # Define SUN_FLT_BUG rather than just 'sun' to get the a fix for a floating
+ # point problem in ntpsubs; apparantly the DECSTATION 3100 also has the
+ # same problem.
+ # 
  # Revision 3.4.1.2  89/03/22  18:25:14  louie
  # patch3: Use new and improved RCS headers.
  # 
***************
*** 74,80 ****
  DEFINES=
  
  # for Sun
! #DEFINES= -Dsun
  
  # for Ultrix 2.0/2.2/3.0
  # don't forget to fix the broken definition of inet_addr in netdb.h
--- 80,86 ----
  DEFINES=
  
  # for Sun
! #DEFINES= -DSUN_FLT_BUG
  
  # for Ultrix 2.0/2.2/3.0
  # don't forget to fix the broken definition of inet_addr in netdb.h
***************
*** 169,178 ****
  	mv ntp.tar.Z /usr/ftp/pub/ntp.${VERS}/ntp-test.tar.Z
  
  ntp.tar.Z:	${DIST}
- 	ident ${DIST} | grep Header | \
- 		sed -e 's/^ *.Header: //' -e 's/.\$$//' > Version
  	rm -f ntp.tar ntp.tar.Z
! 	tar cf ntp.tar Version ${DIST}
  	compress  ntp.tar
  
  
--- 175,182 ----
  	mv ntp.tar.Z /usr/ftp/pub/ntp.${VERS}/ntp-test.tar.Z
  
  ntp.tar.Z:	${DIST}
  	rm -f ntp.tar ntp.tar.Z
! 	tar cf ntp.tar ${DIST}
  	compress  ntp.tar
  
  

Index: ntp.h
*** ntp.h.old	Wed Mar 29 12:47:42 1989
--- ntp.h	Wed Mar 29 12:47:43 1989
***************
*** 1,7 ****
! /* $Source: /usr/users/louie/ntp/RCS/ntp.h,v $ $Revision: 3.4.1.2 $ $Date: 89/03/22 18:28:18 $ */
  
  /*
   *  $Log:	ntp.h,v $
   * Revision 3.4.1.2  89/03/22  18:28:18  louie
   * patch3: Use new RCS headers.
   * 
--- 1,12 ----
! /* $Source: /usr/users/louie/ntp/RCS/ntp.h,v $ $Revision: 3.4.1.3 $ $Date: 89/03/29 12:26:18 $ */
  
  /*
   *  $Log:	ntp.h,v $
+  * Revision 3.4.1.3  89/03/29  12:26:18  louie
+  * Removed some unused #defines.  Replaced MAXSTRATUM with NTP_INFIN per new
+  * spec.  The variable 'mode' in the peer structure has been renamed 'hmode'
+  * per the new spec.
+  * 
   * Revision 3.4.1.2  89/03/22  18:28:18  louie
   * patch3: Use new RCS headers.
   * 
***************
*** 71,79 ****
  /*
   *  Definitions for the masses
   */
- #define	MAXNAMELENGTH	80
  #define	JAN_1970	2208988800	/* 1970 - 1900 in seconds */
- #define	HIGH_BIT	0x80000000	/* sign bit on fixed point */
  
  /*
   *  Daemon specific (ntpd.c)
--- 76,82 ----
***************
*** 100,107 ****
  };
  
  #define	STRMCMP(a, cond, b) \
! 	(((a) == UNSPECIFIED ? MAXSTRATUM+1 : a) cond \
! 	 ((b) == UNSPECIFIED ? MAXSTRATUM+1 : (b)))
  
  
  /*
--- 103,110 ----
  };
  
  #define	STRMCMP(a, cond, b) \
! 	(((a) == UNSPECIFIED ? NTP_INFIN+1 : a) cond \
! 	 ((b) == UNSPECIFIED ? NTP_INFIN+1 : (b)))
  
  
  /*
***************
*** 109,114 ****
--- 112,118 ----
   */
  #define	NTP_VERSION	1
  #define	NTP_PORT	123	/* for ref only (see /etc/services) */
+ #define	NTP_INFIN	15
  #define	NTP_MAXAGE	86400
  #define	NTP_MAXSKW	0.01	/* seconds */
  #define	NTP_MINDIST	0.02	/* seconds */
***************
*** 125,131 ****
  #define	PEER_MAXDISP	64.0	/* Maximum dispersion  */
  #define	PEER_THRESHOLD	0.5	/* dispersion threshold */
  #define	PEER_FILTER	0.5	/* filter weight */
- #define	PEER_SELECT	0.75	/* select weight */
  
  #if	XTAL == 0
  #define	PEER_SHIFT	4
--- 129,134 ----
***************
*** 136,144 ****
  #define	NTP_WINDOW_SHIFT_MASK 0xff
  #define	PEER_SHIFT_MASK	0xff	/* 2^PEER_SHIFT - 1 */
  
- #define	NTP_MAXDELAY	65536.0	/* Maximum dispersion seconds*/
- 
- 
  /*
   *  5.1 Uniform Phase Adjustments
   *  Clock parameters
--- 139,144 ----
***************
*** 261,267 ****
   */
  #define	UNSPECIFIED	0
  #define	PRIM_REF	1	/* radio clock */
- #define	MAXSTRATUM	15
  #define	INFO_QUERY	62	/* **** THIS implementation dependent **** */
  #define	INFO_REPLY	63	/* **** THIS implementation dependent **** */
  
--- 261,266 ----
***************
*** 277,283 ****
  	int	flags;			/* local flags */
  #define	PEER_FL_CONFIG		1
  #define	PEER_FL_AUTHENABLE	2
- #define	PEER_FL_SYNC		0x1000	/* allowed synchronize to this peer */
  #define	PEER_FL_BCAST		0x2000	/* broadcast peer */
  #define	PEER_FL_SELECTED	0x8000	/* actually used by query routine */
  
--- 276,281 ----
***************
*** 284,290 ****
  	int	sock;			/* index into sockets to derive
  					   peer.dstadr and peer.dstport */
  	u_char	leap;			/* receive */
! 	u_char	mode;			/* receive */
  	u_char	stratum;		/* receive */
  	u_char	ppoll;			/* receive */
  	u_char	hpoll;			/* poll update */
--- 282,288 ----
  	int	sock;			/* index into sockets to derive
  					   peer.dstadr and peer.dstport */
  	u_char	leap;			/* receive */
! 	u_char	hmode;			/* receive */
  	u_char	stratum;		/* receive */
  	u_char	ppoll;			/* receive */
  	u_char	hpoll;			/* poll update */
***************
*** 304,310 ****
  	 * first order offsets
  	 */
  	struct	filter {
! 		short samples;
  		double offset[PEER_SHIFT];
  		double delay[PEER_SHIFT];
  	} filter;			/* filter, clear */
--- 302,308 ----
  	 * first order offsets
  	 */
  	struct	filter {
! 		short samples;		/* <<local>> */
  		double offset[PEER_SHIFT];
  		double delay[PEER_SHIFT];
  	} filter;			/* filter, clear */

Index: ntp_proto.c
*** ntp_proto.c.old	Wed Mar 29 12:47:49 1989
--- ntp_proto.c	Wed Mar 29 12:47:51 1989
***************
*** 1,5 ****
  #ifndef	lint
! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntp_proto.c,v $ $Revision: 3.4.1.3 $ $Date: 89/03/22 18:32:31 $";
  #endif
  
  /*
--- 1,5 ----
  #ifndef	lint
! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntp_proto.c,v $ $Revision: 3.4.1.4 $ $Date: 89/03/29 12:29:10 $";
  #endif
  
  /*
***************
*** 10,15 ****
--- 10,22 ----
   *
   *
   * $Log:	ntp_proto.c,v $
+  * Revision 3.4.1.4  89/03/29  12:29:10  louie
+  * The variable 'mode' in the peer structure was renamed 'hmode'.  Add 
+  * poll_update() calls in a few places per Mills.  The receive() procedure is
+  * now table driven.  The poll_update procedure only randomized the timer
+  * when the interval changes.  If we lose synchronization, don't zap sys.stratum.
+  * Clean up the sanity_check() routine a bit.
+  * 
   * Revision 3.4.1.3  89/03/22  18:32:31  louie
   * patch3: Use new RCS headers.
   * 
***************
*** 123,129 ****
  	struct ntpdata *pkt = &ntpframe;
  	int i;
  
! 	pkt->status = sys.leap | NTPVERSION_1 | peer->mode;
  	pkt->stratum = sys.stratum;
  	pkt->ppoll = peer->hpoll;
  	pkt->precision = (char) sys.precision;
--- 130,136 ----
  	struct ntpdata *pkt = &ntpframe;
  	int i;
  
! 	pkt->status = sys.leap | NTPVERSION_1 | peer->hmode;
  	pkt->stratum = sys.stratum;
  	pkt->ppoll = peer->hpoll;
  	pkt->precision = (char) sys.precision;
***************
*** 214,225 ****
  		peer->valid++;
  	else {
  		clock_filter(peer, 0.0, 0.0);	/* call with invalid values */
! 		if (peer == sys.peer) {
! 			select_clock();		/* and try to reselect clock */
! 			if (peer != sys.peer && sys.peer != NULL)
! 				poll_update(sys.peer, NTP_MINPOLL);
! 		}
  	}
  	peer->timer = 1<<(MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)),
  			       NTP_MINPOLL));
  
--- 221,231 ----
  		peer->valid++;
  	else {
  		clock_filter(peer, 0.0, 0.0);	/* call with invalid values */
! 		select_clock();		/* and try to reselect clock */
! 		if (sys.peer != NULL)
! 			poll_update(sys.peer, NTP_MINPOLL);
  	}
+ 
  	peer->timer = 1<<(MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)),
  			       NTP_MINPOLL));
  
***************
*** 240,245 ****
--- 246,267 ----
  	struct ntp_peer *peer;
  	int peer_mode;
  
+ #define	ACT_ERROR	1
+ #define	ACT_RECV	2
+ #define	ACT_XMIT	3
+ #define	ACT_PKT		4
+ 
+ 	static char actions[5][5] = {
+ 
+  /*      Sym Act   Sym Pas    Client     Server     Broadcast  |Host /       */
+  /*      --------   --------  --------   ---------  ---------  |    / Peer   */
+  /*                                                            ------------  */
+ 	{ACT_PKT,  ACT_PKT,   ACT_RECV,  ACT_XMIT,  ACT_XMIT},	/* Sym Act   */
+ 	{ACT_PKT,  ACT_ERROR, ACT_RECV,  ACT_ERROR, ACT_ERROR},	/* Sym Pas   */
+ 	{ACT_XMIT, ACT_XMIT,  ACT_ERROR, ACT_XMIT,  ACT_XMIT},	/* Client    */
+ 	{ACT_PKT,  ACT_ERROR, ACT_RECV,  ACT_ERROR, ACT_ERROR},	/* Server    */
+ 	{ACT_PKT,  ACT_ERROR, ACT_RECV,  ACT_ERROR, ACT_ERROR}};/* Broadcast */
+ 
  	/* if we're only going to support NTP Version 2 then this stuff
  	   isn't necessary, right? */
  
***************
*** 277,283 ****
  		make_new_peer(peer);
  		peer->src = *dst;
  		peer->sock = sock;
! 		peer->mode = MODE_SYM_PAS;
  		clear(peer);
  	} else
  		peer = check_peer(dst, sock);
--- 299,305 ----
  		make_new_peer(peer);
  		peer->src = *dst;
  		peer->sock = sock;
! 		peer->hmode = MODE_SYM_PAS;
  		clear(peer);
  	} else
  		peer = check_peer(dst, sock);
***************
*** 292,302 ****
  		peer->src = *dst;
  		peer->sock = sock;	/* remember which socket we heard 
  					   this from */
! 		peer->mode = MODE_SYM_PAS;
  		clear(peer);
  		enqueue(&peer_list, peer);
  	}
  
  #ifdef	BROADCAST_NTP
  	/*
  	 *  Input frame matched a funny broadcast peer;  these peers only
--- 314,333 ----
  		peer->src = *dst;
  		peer->sock = sock;	/* remember which socket we heard 
  					   this from */
! 		peer->hmode = MODE_SYM_PAS;
  		clear(peer);
  		enqueue(&peer_list, peer);
  	}
  
+ 	/* 
+ 	 *  "pre-configured" peers are initially assigned a socket index of
+ 	 *  -1, which means we don't know which interface we'll use to talk
+ 	 *  to them.  Once the first reply comes back, we'll update the
+ 	 *  peer structure
+ 	 */
+ 	if (peer->sock == -1)
+ 		peer->sock = sock;
+ 
  #ifdef	BROADCAST_NTP
  	/*
  	 *  Input frame matched a funny broadcast peer;  these peers only
***************
*** 313,406 ****
  	}
  #endif	/* BROADCAST_NTP */
  
! 	/* 
! 	 *  "pre-configured" peers are initially assigned a socket index of
! 	 *  -1, which means we don't know which interface we'll use to talk
! 	 *  to them.  Once the first reply comes back, we'll update the
! 	 *  peer structure
! 	 */
! 	if (peer->sock == -1)
! 		peer->sock = sock;
  
! 	switch (peer_mode) {
! 	case MODE_SYM_PAS:
! 		if (peer->mode == MODE_SYM_PAS)
! 			goto receive_MODE_BROADCAST;	/* forgive me! */
  
! 		/* * * * * NOTE FALL THRU * * * * */
! 
! 	case MODE_SYM_ACT:
! 		if (! STRMCMP(pkt->stratum, <=, sys.stratum)) {
! 			/*
! 			 *  While not strictly in the spec, pre-configured
! 			 *  peers will have their reachability kept, even 
! 			 *  though they won't be selected.  We might as well
! 			 *  since we've dedicated the resources to have these
! 			 *  peers be persistant.
! 			 */
! 			if (peer->flags & PEER_FL_CONFIG)
! 				peer->reach |= 1;
! 
! 			switch (peer->mode) {
! 			case MODE_SYM_ACT:
! 			case MODE_CLIENT:
! 			case MODE_BROADCAST:
! 				process_packet(dst, pkt, tvp, peer);
! 				break;
! 			default:
! 				process_packet(dst, pkt, tvp, peer);
! 				poll_update(peer, peer->ppoll);
! 				transmit(peer);
! 			}				
  			break;
  		}
! 		/* * * * * NOTE FALL THRU * * * * */
  
! 	case MODE_SERVER:
! 		peer->reach |= 1;
! 		process_packet(dst, pkt, tvp, peer);
! 		break;
! 
! 	case MODE_CLIENT:
! 		if (peer->flags & PEER_FL_CONFIG)
! 			break;
! 
! 		switch (peer->mode) {
! 		case MODE_SYM_ACT:
! 		case MODE_CLIENT:
! 		case MODE_BROADCAST:
  			process_packet(dst, pkt, tvp, peer);
  			break;
- 
- 		default:
- 			peer->mode = MODE_SERVER;
- 			process_packet(dst, pkt, tvp, peer);
- 			poll_update(peer, peer->ppoll);
- 			transmit(peer);
  		}
! 		break;
! 
! #ifdef	BROADCAST_NTP
! 	case MODE_BROADCAST:
! #endif
! 	receive_MODE_BROADCAST:	
! 		if (peer->flags & PEER_FL_CONFIG)
! 			break;
! 
  		process_packet(dst, pkt, tvp, peer);
! 		if (peer != &dummy_peer)
! 			demobilize(&peer_list, peer);
  		break;
  
- #ifdef	DEBUG
  	default:
! 		if (debug)
! 			printf("Unknown mode %d for peer at %s\n",
! 			       peer_mode, inet_ntoa(dst->sin_addr));
! #endif
  	}
  }
  
  /* 3.4.3 Packet procedure */
  void
  process_packet(dst, pkt, tvp, peer)
--- 344,403 ----
  	}
  #endif	/* BROADCAST_NTP */
  
! #if	0
! 	if ((peer->flags & PEER_FL_AUTHENABLE) &&
! 	    pkt->mac) {
! 		/* verify computed crypto-checksum */
! 	}
! #endif
  
! #ifdef	DEBUG
! 	if (peer_mode < MODE_SYM_ACT || peer_mode > MODE_BROADCAST ||
! 	    peer->hmode < MODE_SYM_ACT || peer->hmode > MODE_BROADCAST) {
! 		printf("Bogus peer_mode or peer->hmode\n");
! 		abort();
! 	}
! #endif
  
! 	switch (actions[peer_mode - 1][peer->hmode - 1]) {
! 	case ACT_RECV:
! 		if (!(peer->flags & PEER_FL_CONFIG == 0 &&
! 		      STRMCMP(pkt->stratum, >, sys.stratum))) {
! 			peer->reach |= 1;
! 			process_packet(dst, pkt, tvp, peer);
  			break;
  		}
! 		/* Note fall-through */
! 	case ACT_ERROR:
! 		if ((peer != &dummy_peer) && (peer->flags & PEER_FL_CONFIG))
! 			demobilize(peer);
! 		return;
  
! 	case ACT_PKT:
! 		if (!((peer->flags & PEER_FL_CONFIG == 0) &&
! 		    STRMCMP(pkt->stratum, >, sys.stratum))) {
! 			peer->reach |= 1;
  			process_packet(dst, pkt, tvp, peer);
  			break;
  		}
! 		/* note fall-through */
! 	case ACT_XMIT:
  		process_packet(dst, pkt, tvp, peer);
! 		poll_update(peer, peer->ppoll);
! 		transmit(peer);
  		break;
  
  	default:
! 		abort();
  	}
  }
  
+ #undef	ACT_ERROR
+ #undef	ACT_RECV
+ #undef	ACT_XMIT
+ #undef	ACT_PKT
+ 
+ 
  /* 3.4.3 Packet procedure */
  void
  process_packet(dst, pkt, tvp, peer)
***************
*** 508,518 ****
  {
  	double temp;
  	extern int adj_logical();
- 	struct ntp_peer *old_selection = sys.peer;
  
  	select_clock();
! 
! 	if (old_selection != sys.peer && sys.peer != NULL)
  		poll_update(sys.peer, NTP_MINPOLL);
  
  	/*
--- 505,513 ----
  {
  	double temp;
  	extern int adj_logical();
  
  	select_clock();
! 	if (sys.peer != NULL)
  		poll_update(sys.peer, NTP_MINPOLL);
  
  	/*
***************
*** 631,637 ****
  	peer->estdisp = PEER_MAXDISP;
  	for (i = 0; i < NTP_WINDOW; i++)
  		peer->filter.offset[i] = 0.0;
! 	peer->filter.samples = 0;
  	peer->reach = 0;
  	peer->valid = 0;
  	peer->org.int_part = peer->org.fraction = 0;
--- 626,632 ----
  	peer->estdisp = PEER_MAXDISP;
  	for (i = 0; i < NTP_WINDOW; i++)
  		peer->filter.offset[i] = 0.0;
! 	peer->filter.samples = 0;	/* Implementation specific */
  	peer->reach = 0;
  	peer->valid = 0;
  	peer->org.int_part = peer->org.fraction = 0;
***************
*** 639,644 ****
--- 634,641 ----
  	peer->xmt.int_part = peer->xmt.fraction = 0;
  	poll_update(peer, NTP_MINPOLL);
  	select_clock();
+ 	if (sys.peer != NULL)
+ 		poll_update(sys.peer, NTP_MINPOLL);
  }
  
  
***************
*** 660,665 ****
--- 657,666 ----
  	interval = 1 << (MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)),
  		       NTP_MINPOLL));
  
+ 	if (interval == peer->timer)
+ 		return;
+ 
+ 	/* only randomize when poll interval changes */
  	if (interval < peer->timer)
  		peer->timer = interval;
  
***************
*** 745,752 ****
  
  		peer->estdelay = delay[0];
  		peer->estoffset = offset[0];
! 	} else
! 		peer->estoffset = peer->estdelay = 0.0;
  
  	temp = 0.0;
  	w = 1.0;
--- 746,752 ----
  
  		peer->estdelay = delay[0];
  		peer->estoffset = offset[0];
! 	}
  
  	temp = 0.0;
  	w = 1.0;
***************
*** 821,828 ****
  			printf("select_clock: no candidates\n");
  #endif
  		sys.peer = NULL;
! 		sys.stratum = 0;
! 		sys.refid = htonl('N'<<24 | 'O'<<16 | 'N'<<8 | 'E');
  		return;
  	}
  
--- 821,832 ----
  			printf("select_clock: no candidates\n");
  #endif
  		sys.peer = NULL;
! 		/*
! 		 * leave sys.stratum and sys.refid intact after losing 
! 		 * reachability to all clocks.  After 24 hours, we'll
! 		 * set the alarm condition if we didn't get any clock
! 		 * updates.
! 		 */
  		return;
  	}
  
***************
*** 984,1009 ****
  		printf("Checking peer %s stratum %d\n",
  		       inet_ntoa(peer->src.sin_addr), peer->stratum);
  #endif
! 	/* are we allowed to sync to this clock? */
! 	if ((peer->flags & PEER_FL_SYNC) == 0)
  		return(0);
  
! 	/* is peer reachable?		XXX */
! 	if (peer->reach == 0)
  		return(0);
  
! 	/* is peer synchronized? */
! 	if (peer->leap == ALARM)
! 		return(0);
  
- 	/* is peer worse off than us?	XXX */
- 	if (STRMCMP(peer->stratum, >, sys.stratum) ||
- 	    (peer->stratum >= MAXSTRATUM))
- 		return(0);
- 
- 	/* 4.2 "if peer.stratum is greater than one (synchronized via NTP),
- 	   peer.refid must not match peer.dstadr" */
- 
  	if (peer->stratum > 1) {
  		register int i;
  		for (i = 1; i < nintf; i++)
--- 988,1005 ----
  		printf("Checking peer %s stratum %d\n",
  		       inet_ntoa(peer->src.sin_addr), peer->stratum);
  #endif
! 	/* Sanity check 0. ?? */
! 	if (!(peer->flags & PEER_FL_CONFIG))
  		return(0);
  
! 	/* Sanity check 1. */
! 	if (peer->stratum <= 0 || peer->stratum >= NTP_INFIN)
  		return(0);
  
! 	/* Sanity check 2.
! 	   if peer.stratum is greater than one (synchronized via NTP),
! 	   peer.refid must not match peer.dstadr */
  
  	if (peer->stratum > 1) {
  		register int i;
  		for (i = 1; i < nintf; i++)
***************
*** 1011,1035 ****
  				return (0);
  	}
  
! 	/* 
! 	   4.2. "Another check requires that both peer.estdelay and
  	   peer.estdisp to be less than NTP_MAXWGT, which insures that the
! 	   filter register at least half full, yet avoids using data
! 	   from very noisy associations or broken implementations."
! 	*/
  	if (peer->estdisp > (float)NTP_MAXWGT || 
  	    peer->estdelay > (float)NTP_MAXWGT)
  		return(0);
  
! 	/*  4.2 "A third check requires that the interval since the peer
! 	    clock was last updated be less than NTP_MAXAGS */
  
! 	if ((ul_fixed_to_double(&peer->org)
  	     - ul_fixed_to_double(&peer->reftime)) >= NTP_MAXAGE)
- 		return(0);
- 
- 	/* is dispersion reasonable? */
- 	if (s_fixed_to_double(&peer->dispersion) > PEER_THRESHOLD)
  		return(0);
  
  #ifdef	DEBUG
--- 1007,1030 ----
  				return (0);
  	}
  
! 	/* Sanity check 3.
! 	   Both peer.estdelay and
  	   peer.estdisp to be less than NTP_MAXWGT, which insures that the
! 	   filter register at least half full, yet avoids using data from
! 	   very noisy associations or broken implementations.  	*/
  	if (peer->estdisp > (float)NTP_MAXWGT || 
  	    peer->estdelay > (float)NTP_MAXWGT)
  		return(0);
  
! 	/*  Sanity check 4.
! 	    The peer clock must be synchronized... and the interval since
! 	    the peer clock was last updated satisfy
  
! 	    peer.org - peer.reftime < NTP.MAXAGS
! 	 */
! 	if (peer->leap == ALARM ||
! 	    (ul_fixed_to_double(&peer->org)
  	     - ul_fixed_to_double(&peer->reftime)) >= NTP_MAXAGE)
  		return(0);
  
  #ifdef	DEBUG

Index: ntpd.c
*** ntpd.c.old	Wed Mar 29 12:48:00 1989
--- ntpd.c	Wed Mar 29 12:48:03 1989
***************
*** 1,9 ****
  #ifndef	lint
! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntpd.c,v $ $Revision: 3.4.1.3 $ $Date: 89/03/22 18:29:41 $";
  #endif	lint
  
  /*
   *  $Log:	ntpd.c,v $
   * Revision 3.4.1.3  89/03/22  18:29:41  louie
   * patch3: Use new RCS headers.
   * 
--- 1,13 ----
  #ifndef	lint
! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntpd.c,v $ $Revision: 3.4.1.4 $ $Date: 89/03/29 12:30:46 $";
  #endif	lint
  
  /*
   *  $Log:	ntpd.c,v $
+  * Revision 3.4.1.4  89/03/29  12:30:46  louie
+  * peer->mode has been renamed peer->hmode.  Drop PEER_FL_SYNC since the
+  * PEER_FL_CONFIG flag means much the same thing.
+  * 
   * Revision 3.4.1.3  89/03/22  18:29:41  louie
   * patch3: Use new RCS headers.
   * 
***************
*** 238,249 ****
  		setlogmask(LOG_UPTO(LOG_INFO));
  #endif	/* LOG_DAEMON */
  
! 	syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.3 $", prog_name);
  	syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);
  
  #ifdef	DEBUG
  	if (debug)
! 		printf("%s version $Revision: 3.4.1.3 $ patchlevel %d\n",
  		       prog_name, PATCHLEVEL);
  #endif
  	(void) setpriority(PRIO_PROCESS, 0, -10);
--- 242,253 ----
  		setlogmask(LOG_UPTO(LOG_INFO));
  #endif	/* LOG_DAEMON */
  
! 	syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.4 $", prog_name);
  	syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);
  
  #ifdef	DEBUG
  	if (debug)
! 		printf("%s version $Revision: 3.4.1.4 $ patchlevel %d\n",
  		       prog_name, PATCHLEVEL);
  #endif
  	(void) setpriority(PRIO_PROCESS, 0, -10);
***************
*** 455,461 ****
  	peer->src.sin_family = AF_INET;
  	peer->src.sin_port = 0;
  	peer->src.sin_addr.s_addr = 0;
! 	peer->mode = MODE_SYM_PAS;	/* default: symmetric passive mode */
  	peer->flags = 0;
  	peer->timer = 1 << NTP_MINPOLL;
  	peer->stopwatch = 0;
--- 459,465 ----
  	peer->src.sin_family = AF_INET;
  	peer->src.sin_port = 0;
  	peer->src.sin_addr.s_addr = 0;
! 	peer->hmode = MODE_SYM_PAS;	/* default: symmetric passive mode */
  	peer->flags = 0;
  	peer->timer = 1 << NTP_MINPOLL;
  	peer->stopwatch = 0;
***************
*** 469,475 ****
  	peer->filter.samples = 0;
  	for (i = 0; i < NTP_WINDOW; i++) {
  		peer->filter.offset[i] = 0.0;
! 		peer->filter.delay[i] = NTP_MAXDELAY;
  	}
  	peer->pkt_sent = 0;
  	peer->pkt_rcvd = 0;
--- 473,479 ----
  	peer->filter.samples = 0;
  	for (i = 0; i < NTP_WINDOW; i++) {
  		peer->filter.offset[i] = 0.0;
! 		peer->filter.delay[i] = 0.0;
  	}
  	peer->pkt_sent = 0;
  	peer->pkt_rcvd = 0;
***************
*** 615,621 ****
  		}
  #endif
  		next = peer->next;
! 		if (peer->reach != 0 || peer->mode != MODE_SERVER) {
  			peer->stopwatch +=(1<<CLOCK_ADJ);
  			if (peer->timer <= peer->stopwatch) {
  				transmit(peer);
--- 619,625 ----
  		}
  #endif
  		next = peer->next;
! 		if (peer->reach != 0 || peer->hmode != MODE_SERVER) {
  			peer->stopwatch +=(1<<CLOCK_ADJ);
  			if (peer->timer <= peer->stopwatch) {
  				transmit(peer);
***************
*** 663,669 ****
  {
  	struct sockaddr_in sin;
  	char ref_clock[5];
! 	char name[MAXNAMELENGTH + 1];
  	FILE *fp;
  	int error = FALSE, c;
  	struct ntp_peer *peer;
--- 667,673 ----
  {
  	struct sockaddr_in sin;
  	char ref_clock[5];
! 	char name[81];
  	FILE *fp;
  	int error = FALSE, c;
  	struct ntp_peer *peer;
***************
*** 750,756 ****
  			}
  			make_new_peer(peer);
  			peer->flags = PEER_FL_BCAST;
! 			peer->mode = MODE_BROADCAST;
  			peer->src = addrs[i].bcast;
  			peer->sock = i;
  #endif	/* BROADCAST_NTP */
--- 754,760 ----
  			}
  			make_new_peer(peer);
  			peer->flags = PEER_FL_BCAST;
! 			peer->hmode = MODE_BROADCAST;
  			peer->src = addrs[i].bcast;
  			peer->sock = i;
  #endif	/* BROADCAST_NTP */
***************
*** 791,811 ****
  						peer->flags = PEER_FL_CONFIG;
  						switch (mode) {
  						case MODE_SYM_ACT:	/* "peer" */
! 							peer->mode = MODE_SYM_ACT;
! 							/* mark peer as sync-able */
! 							peer->flags |= PEER_FL_SYNC;
  							peer->stopwatch = stagger;
  							stagger += (1<<CLOCK_ADJ);
  							break;
  						case MODE_CLIENT:	/* "server" */
! 							peer->mode = MODE_CLIENT;
! 							peer->flags |= PEER_FL_SYNC;
  							peer->stopwatch = stagger;
  							stagger += (1<<CLOCK_ADJ);
  							break;
  						case MODE_SYM_PAS:	/* "passive" */
! 							peer->mode = MODE_SYM_PAS;
! 							peer->flags |= PEER_FL_SYNC;
  							break;
  						default:
  							printf("can't happen\n");
--- 795,811 ----
  						peer->flags = PEER_FL_CONFIG;
  						switch (mode) {
  						case MODE_SYM_ACT:	/* "peer" */
! 							peer->hmode = MODE_SYM_ACT;
  							peer->stopwatch = stagger;
  							stagger += (1<<CLOCK_ADJ);
  							break;
  						case MODE_CLIENT:	/* "server" */
! 							peer->hmode = MODE_CLIENT;
  							peer->stopwatch = stagger;
  							stagger += (1<<CLOCK_ADJ);
  							break;
  						case MODE_SYM_PAS:	/* "passive" */
! 							peer->hmode = MODE_SYM_PAS;
  							break;
  						default:
  							printf("can't happen\n");
***************
*** 821,827 ****
  							       inet_ntoa(peer->src.sin_addr),
  							       ntohs(peer->src.sin_port),
  							       peer->src.sin_family,
! 							       peer->mode);
  #endif
  					}
  				} else {
--- 821,827 ----
  							       inet_ntoa(peer->src.sin_addr),
  							       ntohs(peer->src.sin_port),
  							       peer->src.sin_family,
! 							       peer->hmode);
  #endif
  					}
  				} else {

Index: ntpdc.c
*** ntpdc.c.old	Wed Mar 29 12:48:09 1989
--- ntpdc.c	Wed Mar 29 12:48:11 1989
***************
*** 1,9 ****
  #ifndef	lint
! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpdc.c,v $ $Revision: 3.4.1.3 $ $Date: 89/03/22 18:29:53 $";
  #endif
  
  /*
   * $Log:	ntpdc.c,v $
   * Revision 3.4.1.3  89/03/22  18:29:53  louie
   * patch3: Use new RCS headers.
   * 
--- 1,13 ----
  #ifndef	lint
! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpdc.c,v $ $Revision: 3.4.1.4 $ $Date: 89/03/29 12:41:56 $";
  #endif
  
  /*
   * $Log:	ntpdc.c,v $
+  * Revision 3.4.1.4  89/03/29  12:41:56  louie
+  * Check for success sending query before trying to listen for answers.  Will 
+  * catch case of no server running and an ICMP port unreachable being returned.
+  * 
   * Revision 3.4.1.3  89/03/22  18:29:53  louie
   * patch3: Use new RCS headers.
   * 
***************
*** 130,135 ****
--- 134,140 ----
  	}
  	if (argc > 1)
  		printf("--- %s ---\n", *argv);
+ 
  	while (argc > 0) {
  		/*
  		 * Get a new socket each time - this will cause us to ignore
***************
*** 145,152 ****
  			fprintf(stderr, "setsockopt SO_RCVBUF\n");
  		}
  #endif
! 		query(*argv);
! 		answer();
  		close(s);
  		argv++;
  		if (argc-- > 1)
--- 150,157 ----
  			fprintf(stderr, "setsockopt SO_RCVBUF\n");
  		}
  #endif
! 		if (query(*argv))
! 			answer(*argv);
  		close(s);
  		argv++;
  		if (argc-- > 1)
***************
*** 155,161 ****
  
  }
  
! answer() {
  	register struct ntpinfo *msg = (struct ntpinfo *) packet;
  	register struct clockinfo *n;
  	struct sockaddr_in from;
--- 160,168 ----
  
  }
  
! answer(host)
! 	char *host;
! {
  	register struct ntpinfo *msg = (struct ntpinfo *) packet;
  	register struct clockinfo *n;
  	struct sockaddr_in from;
***************
*** 184,192 ****
  			     (struct sockaddr *)&from, &fromlen)) <= 0) {
  			if (cc == 0 || errno == EINTR)
  				continue;
! 			perror("recvfrom");
  			(void) close(s);
! 			exit(1);
  		}
  		FD_SET(s, &bits);
  
--- 191,200 ----
  			     (struct sockaddr *)&from, &fromlen)) <= 0) {
  			if (cc == 0 || errno == EINTR)
  				continue;
! 			fflush(stdout);
! 			perror(host);
  			(void) close(s);
! 			return;
  		}
  		FD_SET(s, &bits);
  
***************
*** 228,234 ****
  		printf("Timed out waiting for replies\n");
  }
  
! 
  query(host)
  	char *host;
  {
--- 236,242 ----
  		printf("Timed out waiting for replies\n");
  }
  
! int
  query(host)
  	char *host;
  {
***************
*** 246,252 ****
  		hp = gethostbyname(host);
  		if (hp == 0) {
  			fprintf(stderr,"%s: unknown\n", host);
! 			exit(1);
  		}
  		bcopy(hp->h_addr, (char *) &watcher.sin_addr, hp->h_length);
  	}
--- 254,260 ----
  		hp = gethostbyname(host);
  		if (hp == 0) {
  			fprintf(stderr,"%s: unknown\n", host);
! 			return 0;
  		}
  		bcopy(hp->h_addr, (char *) &watcher.sin_addr, hp->h_length);
  	}
***************
*** 260,271 ****
  	msg->stratum = INFO_QUERY;
  	if (connect(s, (struct sockaddr *) &watcher, sizeof(watcher))) {
  		perror("connect");
! 		exit(1);
  	}
  	if (send(s, packet, sizeof(struct ntpdata), 0) < 0) {
  		perror("send");
! 		exit(2);
  	}
  }
  
  timeout()
--- 268,280 ----
  	msg->stratum = INFO_QUERY;
  	if (connect(s, (struct sockaddr *) &watcher, sizeof(watcher))) {
  		perror("connect");
! 		return 0;
  	}
  	if (send(s, packet, sizeof(struct ntpdata), 0) < 0) {
  		perror("send");
! 		return 0;
  	}
+ 	return 1;
  }
  
  timeout()
***************
*** 290,296 ****
  	del = (long) ntohl(n->estdelay);	/* leave in milliseconds */
  	off = (long) ntohl(n->estoffset);	/* leave in milliseconds */
  	c = ' ';
! 	if (ntohs(n->flags))
  		c = '-';		/* mark pre-configured */
  	if (ntohs(n->flags) & PEER_FL_SELECTED)
  		c = '*';		/* mark peer selection */
--- 299,305 ----
  	del = (long) ntohl(n->estdelay);	/* leave in milliseconds */
  	off = (long) ntohl(n->estoffset);	/* leave in milliseconds */
  	c = ' ';
! 	if (ntohs(n->flags) & PEER_FL_CONFIG)
  		c = '-';		/* mark pre-configured */
  	if (ntohs(n->flags) & PEER_FL_SELECTED)
  		c = '*';		/* mark peer selection */
***************
*** 331,339 ****
  	       ntohs(n->flags),
  	       n->leap);
  	if (n->stratum == 1 || n->stratum == 0) {
! 		u_long TmP;
! 
! 		(void) strncpy(ref_clock, (char *) &TmP, 4);
  		ref_clock[4] = '\0';
  		printf("Reference clock ID: %s", ref_clock);
  	} else {
--- 340,346 ----
  	       ntohs(n->flags),
  	       n->leap);
  	if (n->stratum == 1 || n->stratum == 0) {
! 		(void) strncpy(ref_clock, (char *) &n->refid, 4);
  		ref_clock[4] = '\0';
  		printf("Reference clock ID: %s", ref_clock);
  	} else {

Index: ntpsubs.c
*** ntpsubs.c.old	Wed Mar 29 12:48:14 1989
--- ntpsubs.c	Wed Mar 29 12:48:15 1989
***************
*** 1,9 ****
  #ifndef	lint
! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpsubs.c,v $ $Revision: 3.4.1.1 $ $Date: 89/03/22 18:32:19 $";
  #endif	lint
  
  /*
   *  $Log:	ntpsubs.c,v $
   * Revision 3.4.1.1  89/03/22  18:32:19  louie
   * patch3: Use new RCS headers.
   * 
--- 1,13 ----
  #ifndef	lint
! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpsubs.c,v $ $Revision: 3.4.1.2 $ $Date: 89/03/29 12:46:02 $";
  #endif	lint
  
  /*
   *  $Log:	ntpsubs.c,v $
+  * Revision 3.4.1.2  89/03/29  12:46:02  louie
+  * Check for success sending query before trying to listen for answers.  Will 
+  * catch case of no server running and an ICMP port unreachable being returned.
+  * 
   * Revision 3.4.1.1  89/03/22  18:32:19  louie
   * patch3: Use new RCS headers.
   * 
***************
*** 181,187 ****
  	results in the value 2^31.  Neither 4.2bsd nor VMS have this
  	problem.  Reported it to Bob O'Brien of SMI
  */
! #ifdef	sun
  tstamp(stampp, tvp)
  	struct l_fixedpt *stampp;
  	struct timeval *tvp;
--- 185,191 ----
  	results in the value 2^31.  Neither 4.2bsd nor VMS have this
  	problem.  Reported it to Bob O'Brien of SMI
  */
! #ifdef	SUN_FLT_BUG
  tstamp(stampp, tvp)
  	struct l_fixedpt *stampp;
  	struct timeval *tvp;
***************
*** 202,208 ****
  	stampp->int_part = ntohl((u_long) (JAN_1970 + tvp->tv_sec));
  	stampp->fraction = ntohl((u_long) ((float) tvp->tv_usec * 4294.967295));
  }
! #endif	sun
  
  /*
   * ntoa is similar to inet_ntoa, but cycles through a set of 8 buffers
--- 206,212 ----
  	stampp->int_part = ntohl((u_long) (JAN_1970 + tvp->tv_sec));
  	stampp->fraction = ntohl((u_long) ((float) tvp->tv_usec * 4294.967295));
  }
! #endif
  
  /*
   * ntoa is similar to inet_ntoa, but cycles through a set of 8 buffers

Index: stat.pl
Prereq: 3.4.1.2
*** stat.pl.old	Wed Mar 29 12:48:18 1989
--- stat.pl	Wed Mar 29 12:48:19 1989
***************
*** 1,9 ****
  #!/usr/bin/perl  
! # $Source: /usr/users/louie/ntp/RCS/stat.pl,v $ $Revision: 3.4.1.2 $ $Date: 89/03/22 18:32:28 $
  #
  #  Make plots from ntpd syslog messages.  Invoked as:
  #
! #   stat.pl [-o outputfile] [-i interval] [-t termtype] [-S] < logmessages
  #
  #  Where interval is the number of hours per plot, default is all data on
  #  on set of plots.
--- 1,9 ----
  #!/usr/bin/perl  
! # $Source: /usr/users/louie/ntp/RCS/stat.pl,v $ $Revision: 3.4.1.3 $ $Date: 89/03/29 12:47:32 $
  #
  #  Make plots from ntpd syslog messages.  Invoked as:
  #
! #   stat.pl [-o outputfile] [-i interval] [-t termtype] [-S] [-l] < logmessages
  #
  #  Where interval is the number of hours per plot, default is all data on
  #  on set of plots.
***************
*** 14,19 ****
--- 14,21 ----
  #  output file is the name of the file which will receive plot data.  The
  #  default is "stats.plot".
  #
+ #  The -l option will also create log scale plots.
+ #
  #  The -S option will "save" the intermedite data files, which are normally
  #  deleted.
  #
***************
*** 47,56 ****
  $clocks = 1;
  $clk{'UNSYNCED'} = 0;
  
! do Getopt('tiSo');
  
  if ($opt_h) {
!    die "Usage: $scriptfile [-o outputfile] [-i interval] [-t termtype] [-S] < logmessages\n";
  }
  
  if ($opt_t) {
--- 49,58 ----
  $clocks = 1;
  $clk{'UNSYNCED'} = 0;
  
! do Getopt('tio');
  
  if ($opt_h) {
!    die "Usage: $scriptfile [-o outputfile] [-i interval] [-t termtype] [-l] [-S] < logmessages\n";
  }
  
  if ($opt_t) {
***************
*** 92,98 ****
  			$clk{$in[8]} = $clocks++;
  		}
  		$t = $t - $start;
! 		printf CLK "%f %f\n",$t,$clk{$in[8]};
  
  	}
  	if (/.* ntpd\[[0-9]*\]: adjust:/) {
--- 94,100 ----
  			$clk{$in[8]} = $clocks++;
  		}
  		$t = $t - $start;
! 		print CLK $t,$clk{$in[8]},"\n";
  
  	}
  	if (/.* ntpd\[[0-9]*\]: adjust:/) {
***************
*** 113,120 ****
  		# offset=11 drift=13 compliance=15
  
  		print OFF $t, " ", $in[11],"\n";
! 		print DRIFT $t," ",$in[13],"\n";
! 		print COMP $t," ",$in[15],"\n";
  	}
  }
  
--- 115,129 ----
  		# offset=11 drift=13 compliance=15
  
  		print OFF $t, " ", $in[11],"\n";
! 		#
! 		#  Scale the drift compensation by 256.0 to convert to PPM.
! 		#
! 		print DRIFT $t," ", $in[13]/256.0, "\n";
! 
! 		#
! 		#  Scale compliance by T (2**18)
! 		#
! 		print COMP $t," ",$in[15] * 2**18, "\n";
  	}
  }
  
***************
*** 123,129 ****
  } else {
  	$last = int($t);
  }
! printf "%d records spanning %4.2f hours.\n", $recs, $t;
  
  close OFF;
  close DRIFT;
--- 132,138 ----
  } else {
  	$last = int($t);
  }
! print "$recs records spanning %t hours.\n";
  
  close OFF;
  close DRIFT;
***************
*** 169,174 ****
--- 178,188 ----
  	print TMP "set autoscale\n";
  	print TMP "plot [$start:$end] ",'"stats.drift"'," with lines\n";
  	print TMP "plot [$start:$end] ",'"stats.comp"'," with lines\n";
+ 	if ($opt_l) {
+ 		print TMP "set logscale y\n";
+ 		print TMP "plot [$start:$end] ",'"stats.comp"'," with lines\n";
+ 		print TMP "set nologscale\n";
+ 	}
  	print TMP "plot [$start:$end] [-0.1:0.1] ",
  		'"stats.off"'," with lines\n";
  	print TMP "plot [$start:$end] [0:$clocks]",
***************
*** 192,198 ****
  	unlink "stats.clk";
  }
  
! ;# $Header: /usr/users/louie/ntp/RCS/stat.pl,v 3.4.1.2 89/03/22 18:32:28 louie Exp $
  
  ;# Process single-character switches with switch clustering.  Pass one argument
  ;# which is a string containing all switches that take an argument.  For each
--- 206,212 ----
  	unlink "stats.clk";
  }
  
! ;# $Header: /usr/users/louie/ntp/RCS/stat.pl,v 3.4.1.3 89/03/29 12:47:32 louie Exp Locker: louie $
  
  ;# Process single-character switches with switch clustering.  Pass one argument
  ;# which is a string containing all switches that take an argument.  For each
