#!/afs/net/tools/@sys/perl
#
# named_stats --- collect statistics for the MIT nameservers.
#
# This program connects to a pre-arranged port on four hosts and dumps the 
# name daemon statistics in a nice tabular form.  This program has been
# written for MIT.  You will need to change things to make them work for
# your site.
#
# Written by Theodore Ts'o, Copyright 1991.  
#
# Use this code however you want, as long as you don't try to make
# money off of it and as long as you don't claim it's yours.
#

#
# Change this to be whatever port number you assign in /etc/services
#
$default_nstats_port = XXXXX;

#
# Change this to be the list of hosts that you're interested in.
#
@hosts = ("bitsy.mit.edu", "strawb.mit.edu", "w20ns.mit.edu", 
	"lithium.lcs.mit.edu");

@querytypes = ("A", "NS", "MD", "MF", "CNAME", "SOA", "MB", "MG",
	"MR", "NULL", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT",
	"UINFO", "UID", "GID", "UNSPEC", "UNSPECA", 
	"AXFR", "MAILB", "MAILA", "ANY");
$boottime = "time since boot (secs)";

($name, $aliases, $nstats_port) = getservbyname("nstats", 'tcp');
if (!$nstats_port) {
	$nstats_port = $default_nstats_port;
}

grep(s/$/ queries/, @querytypes);
foreach $query (@querytypes) {
	$added{$query} = 1;
}

foreach $host (@hosts) {
	($hostname = $host) =~ s/\..*//;
	push(@hostnames, $hostname);
	($name, $aliases, $type, $len, $thisaddr) = gethostbyname($host);
	$port = $nstats_port;
	&mkport($thisaddr,$port);
	$dateline = <SERVER>;
	$dateline =~ s/###//;
	printf("%8-s:%s", $hostname,$dateline);
	while (<SERVER>) {
		chop;
		($num, $var) = /([0-9]+)\s+(.*)/;
		$data{$hostname, $var} = $num;
		$total{$var} += $num;
		$seen{$var} = 1;
		if (!$added{$var}) {
			$added{$var} = 1;
			push(@varnames, $var);
		}
	}
}
print "\n";

printf("%25-s", "");
foreach $host (@hostnames) {
	printf("%10s", $host);
}
printf("%10s", "TOTAL");
print "\n";

foreach $var (@varnames,@querytypes) {
	if ((!$seen{$var}) || ($total{$var} == 0)) {
		next;
	}
	printf("%25-s", $var);
	foreach $host (@hostnames) {
		$num = $data{$host, $var};
		printf("%10d", $num);
	}
	#
	# Totals don't make sense for some stats
	#
	if ($var =~ /^time since/) {
		print "\n";
		next;
	}
	printf("%10s", $total{$var});
	print "\n";
}

#
# End of main program, subroutines begin here
#

sub mkport {
  $port = $_[1];
  $saddr = $_[0];

#  print "$saddr,$port\n";
  $sockaddr = 'S n a4 x8';
  $sin = pack($sockaddr, 2, $port, $saddr);

  socket(SERVER, 2, 1, 0) || ((print "socket:$!\n"), return $FAIL);
#  setsockopt(SERVER,&SOL_SOCKET,&SO_KEEPALIVE,1)
#       || (print "Server setsockopt failed\n");
  connect(SERVER, $sin) || ((print "connect:$!\n"), return $FAIL);
  $sockname = getsockname(SERVER)
        || ((print "getsockname:$!\n"), return $FAIL);
  ($family, $port, $addr) =  unpack($sockaddr, $sockname);
  @addr = unpack("CCCC", $addr);

#  select(SERVER); $| = 1; select(STDOUT); $| = 1;
  $connecting = 1;
}

