#!/afs/athena/contrib/perl/perl
# mapfddi
# $Header: /afs/sipb/user/jhawk/src/cisco/RCS/mapfddi,v 1.3 1995/11/06 03:22:45 jhawk Exp $

@routers = ("ng3", "ng1", "w91-rtr", "192.233.33.12");

#@routers = ("192.52.71.1",
#	    "192.52.71.11",
#	    "192.52.71.6");

require('chat2.pl');

sub send { &chat'print($conn, @_) }
sub waitsend {  &chat'expect($conn, 3, ">$cr", ';',
                                       "TIMEOUT", 'print "Timeout.\n"');
                &chat'print($conn, @_);
}


sub sendpass {
  if (!defined($pass)) {
	system("stty -echo");
	print "Password: ";
	$pass=<>; print "\n";
	system("stty echo");
	}
  &chat'print($conn, $pass);
}

sub askrouter {
  local ($router) = @_;
  local ($done) = 0;
  local (@iface);
  local ($me, $desc, $updown, $up, $down);
 
  $conn = &chat'open_port($router, 23) || die;

  until ($done) { &chat'expect($conn, 3,
	"Password: $cr",     '&sendpass',
	">$cr",		     '$done=1'); }

  &send("ter len 0\n");
  &waitsend("sh ip int brief\n");
   
  $done=0;
  until ($done) { &chat'expect($conn, 3,
    "Fddi.*$cr",  'push(@iface, $&)',
    '>$cr',       '$done=1',
    TIMEOUT,      'print "Timeout1.\n"');
  }
   
  foreach (@iface) {
    local($iname, $rest) = split(/ /,$_);
    &chat'print($conn, "sh int $iname\n");
    $done=0; until ($done) {
    &chat'expect($conn, 3,
      "  Hardware is.*$cr",       '$me=$&',
      "  Description: .*$cr",     '$desc=$&',
      "  Upstream .*$cr",         '$updown=$&',
      "  Last input.*$cr",        '$done=1',
      TIMEOUT,                    '$done=1');}
    
    $me =~ s/.*address is (.*) \(.*/$1/;
    $desc =~ s/.*Description: //; chop ($desc);
    $updown =~ s/.*Upstream neighbor (.*), downstream neighbor (.*)/$1 $2/;
    chop($updown);
    ($up, $down) = split(/ /, $updown);
    
    push(@data, "$router $iname $down $me $up $desc\n");
  }     
  &chat'close($conn);
}

foreach (@routers) {
  &askrouter($_);
}

$format="%-16s %-10s %-15s %-15s %-15s\n";
printf($format, "Router", "Iface","Downstream", "Self", "Upstream");

foreach (@data) {
  ($name, $int, $down, $me, $up, $rest) = split(/ /);
  printf($format, $name, $int, $down, $me, $up);
  $macup{$me}=$up;
  $macup{$down}=$me;

  $macdown{$me}=$down;
  $macdown{$up}=$me;

  $macname{$me}=$name;
}

# heads is broken:
foreach $k (keys (%macdown)) {
	delete($macdown{$macup{$k}}) if (defined($macdown{$k}));
}
@heads = values(%macdown);

print "Heads: @heads\n";
print "\nUpstream is ->. Ring break is //.\n\n";

foreach (@heads) {
    $k=$_;
    if (defined($macup{$k})) {
	while (defined($macup{$k})) {
	    if (defined($n=$macname{$k})) {
		print "-> $n ";
   	    } else {
		print "-> $k ";
	    }
	    $newk=$macup{$k};
	    delete($macup{$k});
	    $k=$newk;
	}
	if (scalar(grep($_ eq $k,@heads))) {
	  print "->\n";
	} else {
	  if (defined($n=$macname{$k})) {
	    print "-> $n -> //\n";
	  } else {
	    print "-> $k -> //\n";
	  }
	}
    }
}
    
