ntptrace.in revision 1.1.1.2 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