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