#!/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 = ; 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"; }