142 lines
3.5 KiB
Plaintext
142 lines
3.5 KiB
Plaintext
|
|
#! /usr/bin/perl -w
|
||
|
|
# John Hay -- John.Hay@icomtek.csir.co.za / jhay@FreeBSD.org
|
||
|
|
|
||
|
|
package ntptrace;
|
||
|
|
use 5.006_000;
|
||
|
|
use strict;
|
||
|
|
use lib "/usr/share/ntp/lib";
|
||
|
|
use NTP::Util qw(ntp_read_vars do_dns);
|
||
|
|
|
||
|
|
exit run(@ARGV) unless caller;
|
||
|
|
|
||
|
|
sub run {
|
||
|
|
my $opts;
|
||
|
|
if (!processOptions(\@_, $opts)) {
|
||
|
|
usage(1);
|
||
|
|
};
|
||
|
|
|
||
|
|
my $dodns = $opts->{numeric} ? 0 : 1;
|
||
|
|
my $max_hosts = $opts->{'max-hosts'};
|
||
|
|
my $host = shift || $opts->{host};
|
||
|
|
my $nb_host = 0;
|
||
|
|
|
||
|
|
for (;;) {
|
||
|
|
$nb_host++;
|
||
|
|
|
||
|
|
my %info = get_info($host);
|
||
|
|
last if not %info;
|
||
|
|
|
||
|
|
my $dhost = $host;
|
||
|
|
if ($dodns) {
|
||
|
|
my $name = do_dns($host);
|
||
|
|
$dhost = $name if defined $name;
|
||
|
|
}
|
||
|
|
|
||
|
|
printf "%s: stratum %d, offset %f, synch distance %f",
|
||
|
|
$dhost, $info{stratum}, $info{offset}, $info{syncdistance};
|
||
|
|
printf ", refid '%s'", $info{refid} if $info{stratum} == 1;
|
||
|
|
print "\n";
|
||
|
|
|
||
|
|
last if $info{stratum} == 0 || $info{stratum} == 1 ||
|
||
|
|
$info{stratum} == 16;
|
||
|
|
last if $info{refid} =~ /^127\.127\.\d{1,3}\.\d{1,3}$/;
|
||
|
|
last if $nb_host == $max_hosts;
|
||
|
|
|
||
|
|
my $next_host = get_next_host($info{peer}, $host);
|
||
|
|
last if $next_host eq '';
|
||
|
|
last if $next_host =~ /^127\.127\.\d{1,3}\.\d{1,3}$/;
|
||
|
|
|
||
|
|
$host = $next_host;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub get_info {
|
||
|
|
my ($host) = @_;
|
||
|
|
my ($rootdelay, $rootdisp, $info) = (0, 0);
|
||
|
|
|
||
|
|
$info = ntp_read_vars(0, [], $host);
|
||
|
|
return if not defined $info;
|
||
|
|
return if not exists $info->{stratum};
|
||
|
|
|
||
|
|
$info->{offset} /= 1000;
|
||
|
|
$info->{syncdistance} = ($info->{rootdisp} + ($info->{rootdelay} / 2)) / 1000;
|
||
|
|
|
||
|
|
return %$info;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
sub get_next_host {
|
||
|
|
my ($peer, $host) = @_;
|
||
|
|
|
||
|
|
my $info = ntp_read_vars($peer, [qw(srcadr)], $host);
|
||
|
|
return if not defined $info;
|
||
|
|
return $info->{srcadr};
|
||
|
|
}
|
||
|
|
|
||
|
|
# EDIT THIS FILE WITH CAUTION (ntptrace-opts)
|
||
|
|
#
|
||
|
|
# It has been AutoGen-ed August 14, 2018 at 08:09:20 AM by AutoGen 5.18.5
|
||
|
|
# From the definitions ntptrace-opts.def
|
||
|
|
# and the template file perlopt
|
||
|
|
|
||
|
|
use Getopt::Long qw(GetOptionsFromArray);
|
||
|
|
Getopt::Long::Configure(qw(no_auto_abbrev no_ignore_case_always));
|
||
|
|
|
||
|
|
my $usage;
|
||
|
|
|
||
|
|
sub usage {
|
||
|
|
my ($ret) = @_;
|
||
|
|
print STDERR $usage;
|
||
|
|
exit $ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub paged_usage {
|
||
|
|
my ($ret) = @_;
|
||
|
|
my $pager = $ENV{PAGER} || '(less || more)';
|
||
|
|
|
||
|
|
open STDOUT, "| $pager" or die "Can't fork a pager: $!";
|
||
|
|
print $usage;
|
||
|
|
|
||
|
|
exit $ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub processOptions {
|
||
|
|
my $args = shift;
|
||
|
|
|
||
|
|
my $opts = {
|
||
|
|
'numeric' => '',
|
||
|
|
'max-hosts' => '99',
|
||
|
|
'host' => '127.0.0.1',
|
||
|
|
'help' => '', 'more-help' => ''
|
||
|
|
};
|
||
|
|
my $argument = '[host]';
|
||
|
|
my $ret = GetOptionsFromArray($args, $opts, (
|
||
|
|
'numeric|n', 'max-hosts|m=i', 'host|r=s',
|
||
|
|
'help|?', 'more-help'));
|
||
|
|
|
||
|
|
$usage = <<'USAGE';
|
||
|
|
ntptrace - Trace peers of an NTP server - Ver. 4.2.8p12
|
||
|
|
USAGE: ntptrace [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [host]
|
||
|
|
|
||
|
|
-n, --numeric Print IP addresses instead of hostnames
|
||
|
|
-m, --max-hosts=num Maximum number of peers to trace
|
||
|
|
-r, --host=str Single remote host
|
||
|
|
-?, --help Display usage information and exit
|
||
|
|
--more-help Pass the extended usage text through a pager
|
||
|
|
|
||
|
|
Options are specified by doubled hyphens and their name or by a single
|
||
|
|
hyphen and the flag character.
|
||
|
|
USAGE
|
||
|
|
|
||
|
|
usage(0) if $opts->{'help'};
|
||
|
|
paged_usage(0) if $opts->{'more-help'};
|
||
|
|
$_[0] = $opts;
|
||
|
|
return $ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
END { close STDOUT };
|
||
|
|
|
||
|
|
1;
|
||
|
|
__END__
|