xref: /freebsd/usr.sbin/ntp/scripts/ntptrace (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
16cb84f0cSOllivier Robert#! /usr/local/bin/perl -w
26cb84f0cSOllivier Robert#
36cb84f0cSOllivier Robert
46cb84f0cSOllivier Robert# John Hay -- John.Hay@icomtek.csir.co.za / jhay@FreeBSD.org
56cb84f0cSOllivier Robert
66cb84f0cSOllivier Robertuse Socket;
76cb84f0cSOllivier Robertuse Getopt::Std;
86cb84f0cSOllivier Robertuse vars qw($opt_n);
96cb84f0cSOllivier Robert
106cb84f0cSOllivier Robert$ntpq = "ntpq";
116cb84f0cSOllivier Robert
126cb84f0cSOllivier Robertgetopts('n');
136cb84f0cSOllivier Robert
146cb84f0cSOllivier Robert$dodns = 1;
156cb84f0cSOllivier Robert$dodns = 0 if (defined($opt_n));
166cb84f0cSOllivier Robert
176cb84f0cSOllivier Robert$host = shift;
186cb84f0cSOllivier Robert$host ||= "127.0.0.1";
196cb84f0cSOllivier Robert
206cb84f0cSOllivier Robertfor (;;) {
216cb84f0cSOllivier Robert	$stratum = 255;
226cb84f0cSOllivier Robert	$cmd = "$ntpq -n -c rv $host";
236cb84f0cSOllivier Robert	open(PH, $cmd . "|") || die "failed to start command $cmd: $!";
246cb84f0cSOllivier Robert	while (<PH>) {
256cb84f0cSOllivier Robert		$stratum = $1 if (/stratum=(\d+)/);
266cb84f0cSOllivier Robert		$peer = $1 if (/peer=(\d+)/);
276cb84f0cSOllivier Robert		# Very old servers report phase and not offset.
286cb84f0cSOllivier Robert		$offset = $1 if (/(?:offset|phase)=([^\s,]+)/);
296cb84f0cSOllivier Robert		$rootdelay = $1 if (/rootdelay=([^\s,]+)/);
306cb84f0cSOllivier Robert		$refid = $1 if (/refid=([^\s,]+)/);
316cb84f0cSOllivier Robert	}
326cb84f0cSOllivier Robert	close(PH) || die "$cmd failed";
336cb84f0cSOllivier Robert	last if ($stratum == 255);
346cb84f0cSOllivier Robert	$offset /= 1000;
356cb84f0cSOllivier Robert	$rootdelay /= 1000;
366cb84f0cSOllivier Robert	$dhost = $host;
376cb84f0cSOllivier Robert	# Only do lookups of IPv4 addresses. The standard lookup functions
386cb84f0cSOllivier Robert	# of perl only do IPv4 and I don't know if we should require extras.
396cb84f0cSOllivier Robert	if ($dodns && $host =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/) {
406cb84f0cSOllivier Robert		$iaddr = inet_aton($host);
416cb84f0cSOllivier Robert		$name = (gethostbyaddr($iaddr, AF_INET))[0];
426cb84f0cSOllivier Robert		$dhost = $name if (defined($name));
436cb84f0cSOllivier Robert	}
446cb84f0cSOllivier Robert	printf("%s: stratum %d, offset %f, root distance %f",
456cb84f0cSOllivier Robert	    $dhost, $stratum, $offset, $rootdelay);
466cb84f0cSOllivier Robert	printf(", refid '%s'", $refid) if ($stratum == 1);
476cb84f0cSOllivier Robert	printf("\n");
486cb84f0cSOllivier Robert	last if ($stratum == 0 || $stratum == 1 || $stratum == 16);
496cb84f0cSOllivier Robert	last if ($refid =~ /^127\.127\.\d{1,3}\.\d{1,3}$/);
506cb84f0cSOllivier Robert
516cb84f0cSOllivier Robert	$cmd = "$ntpq -n -c \"pstat $peer\" $host";
526cb84f0cSOllivier Robert	open(PH, $cmd . "|") || die "failed to start command $cmd: $!";
536cb84f0cSOllivier Robert	$thost = "";
546cb84f0cSOllivier Robert	while (<PH>) {
556cb84f0cSOllivier Robert		$thost = $1, last if (/srcadr=(\S+),/);
566cb84f0cSOllivier Robert	}
576cb84f0cSOllivier Robert	close(PH) || die "$cmd failed";
586cb84f0cSOllivier Robert	last if ($thost eq "");
596cb84f0cSOllivier Robert	$host = $thost;
606cb84f0cSOllivier Robert}
616cb84f0cSOllivier Robert
62