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