xref: /freebsd/contrib/ntp/scripts/ntptrace/ntptrace.in (revision 2b15cb3d0922bd70ea592f0da9b4a5b167f4d53f)
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