1#! @PATH_PERL@ -w
2
3# John Hay -- John.Hay@icomtek.csir.co.za / jhay@FreeBSD.org
4
5use Socket;
6use Getopt::Std;
7use vars qw($opt_n $opt_m);
8
9$ntpq = "ntpq";
10
11$Getopt::Std::STANDARD_HELP_VERSION=1;
12getopts('nm:');
13
14$dodns = 1;
15$dodns = 0 if (defined($opt_n));
16
17$max_hosts = (defined($opt_m) ? $opt_m :  99);
18$max_hosts = 0 if ( $max_hosts !~ /^\d+$/ );
19$nb_host = 1;
20
21$host = shift;
22$host ||= "127.0.0.1";
23
24for (;;) {
25	$nb_host++;
26	$rootdelay = 0;
27	$rootdispersion = 0;
28	$stratum = 255;
29	$cmd = "$ntpq -n -c rv $host";
30	open(PH, $cmd . "|") || die "failed to start command $cmd: $!";
31	while (<PH>) {
32		$stratum = $1 if (/stratum=(\d+)/);
33		$peer = $1 if (/peer=(\d+)/);
34		# Very old servers report phase and not offset.
35		$offset = $1 if (/(?:offset|phase)=([^\s,]+)/);
36		$rootdelay = $1 if (/rootdelay=([^\s,]+)/);
37		$rootdispersion = $1 if (/rootdispersion=([^\s,]+)/);
38		$refid = $1 if (/refid=([^\s,]+)/);
39	}
40	close(PH) || die "$cmd failed";
41	last if ($stratum == 255);
42	$offset /= 1000;
43	$syncdistance = ($rootdispersion + ($rootdelay / 2)) / 1000;
44	$dhost = $host;
45	# Only do lookups of IPv4 addresses. The standard lookup functions
46	# of perl only do IPv4 and I don't know if we should require extras.
47	if ($dodns && $host =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/) {
48		$iaddr = inet_aton($host);
49		$name = (gethostbyaddr($iaddr, AF_INET))[0];
50		$dhost = $name if (defined($name));
51	}
52	printf("%s: stratum %d, offset %f, synch distance %f",
53	    $dhost, $stratum, $offset, $syncdistance);
54	printf(", refid '%s'", $refid) if ($stratum == 1);
55	printf("\n");
56	last if ($stratum == 0 || $stratum == 1 || $stratum == 16);
57	last if ($refid =~ /^127\.127\.\d{1,3}\.\d{1,3}$/);
58	last if ($nb_host > $max_hosts);
59
60	$cmd = "$ntpq -n -c \"pstat $peer\" $host";
61	open(PH, $cmd . "|") || die "failed to start command $cmd: $!";
62	$thost = "";
63	while (<PH>) {
64		$thost = $1, last if (/srcadr=(\S+),/);
65	}
66	close(PH) || die "$cmd failed";
67	last if ($thost eq "");
68	last if ($thost =~ /^127\.127\.\d{1,3}\.\d{1,3}$/);
69	$host = $thost;
70}
71
72