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