freebsd-nq/contrib/ntp/scripts/support/bin/monl
1999-12-09 13:01:21 +00:00

214 lines
4.5 KiB
Perl

#!/local/bin/perl
%service = ( 0, "unspec",
1, "Active",
2, "Passive",
3, "Client",
4, "Server",
5, "Broadcast",
6, "Control",
7, "Private" );
%nc = ();
@ignpat = ();
$noname = 0;
$verbose = 0;
$retries = 5;
$lastkey = 0;
sub timedelta {
local($tm, $days, $h, $m, $s);
$tm = @_[$[];
$days = 0;
$days = sprintf("%dd+", $days) if $days = int($tm / (60*60*24));
$days = "" unless $days;
$tm = $tm % (60*60*24);
$h = int($tm / (60*60));
$tm = $tm % (60*60);
$m = int($tm / 60);
$s = $tm % 60;
return sprintf("%s%02d:%02d:%02d", $days, $h, $m, $s);
}
sub listentry {
local($host, $mode) = split("$;" , @_[$[]);
local($count, $version, $firsttime) = split("$;" , $_[$[+1]);
local($name);
if (grep($host =~ m/$_/, @ignpat))
{
print "ignored $host ...\n" if $verbose;
return;
}
return if ! $count;
if (defined($nc{$host}))
{
$name = $nc{$host};
}
else
{
if ($noname)
{
$nc{$host} = $name = $host;
}
else
{
$name = (gethostbyaddr(pack("C4", split(/\./, $host)), 2))[$[];
$nc{$host} = $name = $host if ! defined($name);
}
}
printf ($fmt, ($lastkey eq $host) ? "" : $name, $service{$mode}, $count, $version, &timedelta($firsttime), $firsttime / $count);
if (@_[$[+2])
{
$hostcnt++ if $lastkey ne $host;
$packcnt += $count;
$maxtime = $firsttime if $firsttime > $maxtime;
}
$lastkey = $host;
}
while ($ARGV[$[] =~ /^-[nvid]$/)
{
if ($ARGV[$[] eq "-i")
{
shift;
push(@ignpat, shift) unless ! defined($ARGV[$[]);
}
elsif ($ARGV[$[] eq "-d")
{
shift;
$dir = shift unless ! defined($ARGV[$[]);
}
elsif ($ARGV[$[] eq "-n")
{
shift;
$noname = 1;
}
elsif ($ARGV[$[] eq "-v")
{
shift;
$verbose = 1;
}
}
$dir = "/tmp" unless defined($dir);
$gone = 60*60*48;
$fmt = "%48s %10s %7d %7d %13s %14.3f\n";
$sfmt = "%48s %10s %7s %7s %13s %14s\n";
@lbl = ("Host", "Mode", "Count", "Version", "Time active", "Packetinterval");
if (!defined($ARGV[$[]))
{
$hostname = `hostname`;
chop($hostname);
unshift(@ARGV, $hostname);
}
foreach $hostname (@ARGV)
{
$dbmfile = $dir . "/monlstats-" . $hostname;
$monl = "xntpdc -c 'hostnames no' -c monl $hostname | tail +3 |";
$hostcnt = 0;
$packcnt = 0;
$maxtime = 0;
%Seen = ();
%New = ();
%Old = ();
print "Monitor Status of $hostname\n\n";
$cnt = $retries;
do
{
open(MONL, $monl) || die("$monl failed $!");
@monlout = <MONL>;
close(MONL);
} while (! @monlout && $cnt--);
if (! @monlout)
{
print "not available.\n";
next;
}
dbmopen(Clients, $dbmfile, 0644) || die("dbmopen(.., $dbmfile, ...): $!");
foreach (@monlout)
{
chop;
split;
($host, $count, $mode, $version, $lasttime, $firsttime) =
(@_[$[, $[+2 .. $[+4, $#_-1,$#_]);
$Seen{$host, $mode} = 1;
if (!defined($Clients{$host, $mode}))
{
if ($lasttime <= $gone)
{
## got a new one
$Clients{$host, $mode} = $New{$host, $mode} = join("$;", $count, $version, $firsttime, $lasttime);
}
}
else
{
## throw out the old ones
if ($lasttime > $gone)
{
$Old{$host, $mode} = $Clients{$host, $mode};
delete $Clients{$host, $mode};
}
else
{
$Clients{$host, $mode} = join("$;", $count, $version, $firsttime, $lasttime);
}
}
}
grep(($Seen{$_} || ($Old{$_} = delete $Clients{$_})), keys(%Clients));
if (grep(($tmp = $_ , !grep($tmp =~ m/$_/, @ignpat)), keys(%New)))
{
print "New customers\n";
print "-------------\n";
printf $sfmt, @lbl;
grep( &listentry($_, $New{$_}, 1), sort(keys(%New)) );
print "\n";
}
if (grep((!defined($New{$_}) && ($tmp = $_, !grep($tmp =~ m/$_/, @ignpat))), keys(%Clients)))
{
print "Current customers\n";
print "-----------------\n";
printf $sfmt, @lbl;
grep( defined($New{$_}) || &listentry($_, $Clients{$_}, 1) , sort(keys(%Clients)) );
print "\n";
}
if (grep(($tmp = $_, !grep($tmp =~ m/$_/, @ignpat)), keys(%Old)))
{
print "Discarded customers\n";
print "-------------------\n";
printf $sfmt, @lbl;
grep( &listentry($_, $Old{$_}, 0) , sort(keys(%Old)) );
print "\n";
}
dbmclose(Clients);
print "\nSummary:\n";
print "--------\n";
printf("Elapsed time: %13s\n", &timedelta($maxtime));
printf(" Hosts: %13d\n", $hostcnt);
printf(" Packets: %13d\n", $packcnt);
printf(" Rate: %13.2f\n", $packcnt / $maxtime) if $maxtime;
print "\n";
}