1*2b15cb3dSCy Schubert#! @PATH_PERL@ -w 2*2b15cb3dSCy Schubert# John Hay -- John.Hay@icomtek.csir.co.za / jhay@FreeBSD.org 3*2b15cb3dSCy Schubert 4*2b15cb3dSCy Schubertpackage ntptrace; 5*2b15cb3dSCy Schubertuse 5.006_000; 6*2b15cb3dSCy Schubertuse strict; 7*2b15cb3dSCy Schubertuse lib "@PERLLIBDIR@"; 8*2b15cb3dSCy Schubertuse NTP::Util qw(ntp_read_vars do_dns); 9*2b15cb3dSCy Schubert 10*2b15cb3dSCy Schubertexit run(@ARGV) unless caller; 11*2b15cb3dSCy Schubert 12*2b15cb3dSCy Schubertsub run { 13*2b15cb3dSCy Schubert my $opts; 14*2b15cb3dSCy Schubert if (!processOptions(\@_, $opts)) { 15*2b15cb3dSCy Schubert usage(1); 16*2b15cb3dSCy Schubert }; 17*2b15cb3dSCy Schubert 18*2b15cb3dSCy Schubert my $dodns = $opts->{numeric} ? 0 : 1; 19*2b15cb3dSCy Schubert my $max_hosts = $opts->{'max-hosts'}; 20*2b15cb3dSCy Schubert my $host = shift || $opts->{host}; 21*2b15cb3dSCy Schubert my $nb_host = 0; 22*2b15cb3dSCy Schubert 23*2b15cb3dSCy Schubert for (;;) { 24*2b15cb3dSCy Schubert $nb_host++; 25*2b15cb3dSCy Schubert 26*2b15cb3dSCy Schubert my %info = get_info($host); 27*2b15cb3dSCy Schubert last if not %info; 28*2b15cb3dSCy Schubert 29*2b15cb3dSCy Schubert my $dhost = $host; 30*2b15cb3dSCy Schubert if ($dodns) { 31*2b15cb3dSCy Schubert my $name = do_dns($host); 32*2b15cb3dSCy Schubert $dhost = $name if defined $name; 33*2b15cb3dSCy Schubert } 34*2b15cb3dSCy Schubert 35*2b15cb3dSCy Schubert printf "%s: stratum %d, offset %f, synch distance %f", 36*2b15cb3dSCy Schubert $dhost, $info{stratum}, $info{offset}, $info{syncdistance}; 37*2b15cb3dSCy Schubert printf ", refid '%s'", $info{refid} if $info{stratum} == 1; 38*2b15cb3dSCy Schubert print "\n"; 39*2b15cb3dSCy Schubert 40*2b15cb3dSCy Schubert last if $info{stratum} == 0 || $info{stratum} == 1 || 41*2b15cb3dSCy Schubert $info{stratum} == 16; 42*2b15cb3dSCy Schubert last if $info{refid} =~ /^127\.127\.\d{1,3}\.\d{1,3}$/; 43*2b15cb3dSCy Schubert last if $nb_host == $max_hosts; 44*2b15cb3dSCy Schubert 45*2b15cb3dSCy Schubert my $next_host = get_next_host($info{peer}, $host); 46*2b15cb3dSCy Schubert last if $next_host eq ''; 47*2b15cb3dSCy Schubert last if $next_host =~ /^127\.127\.\d{1,3}\.\d{1,3}$/; 48*2b15cb3dSCy Schubert 49*2b15cb3dSCy Schubert $host = $next_host; 50*2b15cb3dSCy Schubert } 51*2b15cb3dSCy Schubert return 0; 52*2b15cb3dSCy Schubert} 53*2b15cb3dSCy Schubert 54*2b15cb3dSCy Schubertsub get_info { 55*2b15cb3dSCy Schubert my ($host) = @_; 56*2b15cb3dSCy Schubert my ($rootdelay, $rootdisp, $info) = (0, 0); 57*2b15cb3dSCy Schubert 58*2b15cb3dSCy Schubert $info = ntp_read_vars(0, [], $host); 59*2b15cb3dSCy Schubert return if not defined $info; 60*2b15cb3dSCy Schubert return if not exists $info->{stratum}; 61*2b15cb3dSCy Schubert 62*2b15cb3dSCy Schubert $info->{offset} /= 1000; 63*2b15cb3dSCy Schubert $info->{syncdistance} = ($info->{rootdisp} + ($info->{rootdelay} / 2)) / 1000; 64*2b15cb3dSCy Schubert 65*2b15cb3dSCy Schubert return %$info; 66*2b15cb3dSCy Schubert} 67*2b15cb3dSCy Schubert 68*2b15cb3dSCy Schubert 69*2b15cb3dSCy Schubertsub get_next_host { 70*2b15cb3dSCy Schubert my ($peer, $host) = @_; 71*2b15cb3dSCy Schubert 72*2b15cb3dSCy Schubert my $info = ntp_read_vars($peer, [qw(srcadr)], $host); 73*2b15cb3dSCy Schubert return if not defined $info; 74*2b15cb3dSCy Schubert return $info->{srcadr}; 75*2b15cb3dSCy Schubert} 76*2b15cb3dSCy Schubert 77*2b15cb3dSCy Schubert@ntptrace_opts@ 78*2b15cb3dSCy Schubert 79*2b15cb3dSCy Schubert1; 80*2b15cb3dSCy Schubert__END__ 81