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