Blame contrib/ovmrtg/ovmrtg.pm

Packit 667938
#!/usr/local/bin/perl5
Packit 667938
# -*- mode: Perl -*-
Packit 667938
##################################################################
Packit 667938
# Config file creator
Packit 667938
##################################################################
Packit 667938
# Created by Laurie Gellatly <gellatly@one.net.au>
Packit 667938
# this produces an array of ip address and system names for each
Packit 667938
# ip address passed to it, by pulling info
Packit 667938
# off the device via snmp
Packit 667938
#################################################################
Packit 667938
#
Packit 667938
# Distributed under the GNU copyleft
Packit 667938
#
Packit 667938
# $Id: ovmrtg.pm,v 1.1.1.1 2002/02/26 10:16:36 oetiker Exp $
Packit 667938
#
Packit 667938
package ovmrtg;
Packit 667938
Packit 667938
use Socket;
Packit 667938
use strict;
Packit 667938
use vars qw(@ISA @EXPORT $VERSION);
Packit 667938
use Exporter;
Packit 667938
Packit 667938
$VERSION = '0.00';
Packit 667938
Packit 667938
@ISA = qw(Exporter);
Packit 667938
Packit 667938
@EXPORT = qw(ovsysnms ovcols);
Packit 667938
Packit 667938
sub ovsysnms(@);
Packit 667938
sub ovcols(@);
Packit 667938
Packit 667938
my $DEBUG = 0;
Packit 667938
my($router,$routerip,@res,@result,$cnt); 
Packit 667938
my($op,$vendor); 
Packit 667938
Packit 667938
%snmpget::OIDS = (  'sysDescr' => '1.3.6.1.2.1.1.1.0',
Packit 667938
		    'sysContact' => '1.3.6.1.2.1.1.4.0',
Packit 667938
		    'sysName' => '1.3.6.1.2.1.1.5.0',
Packit 667938
		    'sysLocation' => '1.3.6.1.2.1.1.6.0',
Packit 667938
		    'sysUptime' => '1.3.6.1.2.1.1.3.0',
Packit 667938
		    'ifNumber' =>  '1.3.6.1.2.1.2.1.0',
Packit 667938
		    ###################################
Packit 667938
		    # add the ifNumber ....
Packit 667938
		    'ifDescr' => '1.3.6.1.2.1.2.2.1.2',
Packit 667938
		    'ifType' => '1.3.6.1.2.1.2.2.1.3',
Packit 667938
		    'ifIndex' => '1.3.6.1.2.1.2.2.1.1',
Packit 667938
		    'ifSpeed' => '1.3.6.1.2.1.2.2.1.5', 
Packit 667938
		    'ifOperStatus' => '1.3.6.1.2.1.2.2.1.8',             
Packit 667938
		    'ifAdminStatus' => '1.3.6.1.2.1.2.2.1.7',            
Packit 667938
		    # up 1, down 2, testing 3
Packit 667938
		    'ipAdEntAddr' => '1.3.6.1.2.1.4.20.1.1',
Packit 667938
		    'ipAdEntIfIndex' => '1.3.6.1.2.1.4.20.1.2',
Packit 667938
		    'sysObjectID' => '1.3.6.1.2.1.1.2.0',
Packit 667938
		    'CiscolocIfDescr' => '1.3.6.1.4.1.9.2.2.1.1.28',
Packit 667938
		    'ifAlias' => '1.3.6.1.2.1.31.1.1.1.18'
Packit 667938
		 );
Packit 667938
Packit 667938
sub ovcols(@) {
Packit 667938
   my @args = @_;  
Packit 667938
   my @r;
Packit 667938
   $op = $args[0];
Packit 667938
   shift @args;
Packit 667938
   if ($op eq "+"){
Packit 667938
      $op = "C";
Packit 667938
   } else {
Packit 667938
      $op = "XC";
Packit 667938
   }
Packit 667938
   while($router=$args[0]){
Packit 667938
  my($sysDescr,$sysContact,$sysName,$sysLocation,$ifNumber,$sysObjectID) =
Packit 667938
    snmpget($router,
Packit 667938
	    'sysDescr','sysContact','sysName',  'sysLocation', 'ifNumber', 'sysObjectID');
Packit 667938
Packit 667938
   my ($sint2mon);
Packit 667938
   my $cc = " ";
Packit 667938
   $sysDescr =~ s/\r/
/g; # Change returns to
Packit 667938
   my($ciscobox) = ($sysObjectID =~ /cisco/);
Packit 667938
   my($portmaster) = ($sysObjectID =~ /livingston/);
Packit 667938
   $vendor = ($ciscobox || $portmaster) ;
Packit 667938
   my($ifInErrors) = '1.3.6.1.2.1.2.2.1.14';
Packit 667938
   my($ifOutErrors) = '1.3.6.1.2.1.2.2.1.20';
Packit 667938
Packit 667938
  my @ipadent = snmpgettable($router, 'ipAdEntAddr');
Packit 667938
  print STDERR "Got Addresses\n" if $DEBUG;
Packit 667938
  my @ipadentif = snmpgettable($router, 'ipAdEntIfIndex');
Packit 667938
  print STDERR "Got IfTable\n" if $DEBUG;
Packit 667938
Packit 667938
  my(%ipaddr, %iphost,$index);
Packit 667938
  while (scalar @ipadentif){
Packit 667938
    $index = shift @ipadentif;
Packit 667938
    $ipaddr{$index} = shift @ipadent;
Packit 667938
    $iphost{$index} = 
Packit 667938
      gethostbyaddr(pack('C4',split(/\./,$ipaddr{$index})), AF_INET);
Packit 667938
    if ($iphost{$index} eq ''){
Packit 667938
	 $iphost{$index} = $ipaddr{$index};
Packit 667938
    }   
Packit 667938
    
Packit 667938
  }
Packit 667938
Packit 667938
  my(@ifdescr) = snmpgettable($router, 'ifDescr');
Packit 667938
  print STDERR "Got IfDescr\n" if $DEBUG;
Packit 667938
  my(@iftype) = snmpgettable($router, 'ifType');
Packit 667938
  print STDERR "Got IfType\n" if $DEBUG;
Packit 667938
  my(@ifspeed) = snmpgettable($router, 'ifSpeed');
Packit 667938
  print STDERR "Got IfSpeed\n" if $DEBUG;
Packit 667938
  my(@ifadminstatus) = snmpgettable($router, 'ifAdminStatus');
Packit 667938
  print STDERR "Got IfStatus\n" if $DEBUG;
Packit 667938
  my(@ifoperstatus) = snmpgettable($router, 'ifOperStatus');
Packit 667938
  print STDERR "Got IfOperStatus\n" if $DEBUG;
Packit 667938
  my(@ifindex) = snmpgettable($router, 'ifIndex');
Packit 667938
  print STDERR "Got IfIndex\n" if $DEBUG;
Packit 667938
Packit 667938
  my(%sifdesc,%siftype,%sifspeed,%sifadminstatus,%sifoperstatus,%sciscodescr);
Packit 667938
Packit 667938
  ### May need the cisco IOS version number so we know which oid to use
Packit 667938
  ###   to get the cisco description.
Packit 667938
  ###
Packit 667938
  ### - mjd 2/5/98 (Mike Diehn) (mdiehn@mindspring.net)
Packit 667938
  ###
Packit 667938
  my ($cisco_ver, $cisco_descr_oid, @ciscodescr);
Packit 667938
  if ( $ciscobox ) {
Packit 667938
    ($cisco_ver) = ($sysDescr =~ /Version\s+([\d.]+)/);
Packit 667938
    $cisco_descr_oid = ($cisco_ver ge "11.3") ? "ifAlias" : "CiscolocIfDescr";
Packit 667938
  }
Packit 667938
  
Packit 667938
  while (scalar @ifindex) {
Packit 667938
Packit 667938
  # as these arrays get filled from the bottom, 
Packit 667938
  # we need to empty them from the botom as well ...
Packit 667938
  # fifo
Packit 667938
Packit 667938
    $index = shift @ifindex;
Packit 667938
    $sifdesc{$index} = shift @ifdescr;
Packit 667938
    $siftype{$index} = shift @iftype;
Packit 667938
    $sifspeed{$index} = shift @ifspeed;
Packit 667938
    $sifadminstatus{$index} = shift @ifadminstatus;
Packit 667938
    $sifoperstatus{$index} = shift @ifoperstatus;
Packit 667938
Packit 667938
    if ($portmaster) {
Packit 667938
      # Trying to extract extra info livingston
Packit 667938
      # We can only approximate speeds
Packit 667938
      # 
Packit 667938
      # so we think that ppp can do 76800 bit/s, and slip 38400.
Packit 667938
      # (actualy, slip is a bit faster, but usualy users with newer modems
Packit 667938
      # use ppp). Alternatively, you can set async speed to 115200 or
Packit 667938
      # 230400 (the maximum speed supported by portmaster).
Packit 667938
      # 
Packit 667938
      # But if the interface is ptpW (sync), max speed is 128000
Packit 667938
      # change it to your needs. On various Portmasters there are
Packit 667938
      # various numbers of sync interfaces, so modify it.
Packit 667938
      # 
Packit 667938
      #  The most commonly used PM-2ER has only one sync.
Packit 667938
      # 
Packit 667938
      #  Paul Makeev (mac@redline.ru)
Packit 667938
      # 
Packit 667938
Packit 667938
      if ($siftype{$index} eq 'ppp') {
Packit 667938
	      if ($sifdesc{$index} eq 'ptpW1') {
Packit 667938
		      $sifspeed{$index} = 128000;
Packit 667938
	      } else {
Packit 667938
		      $sifspeed{$index} = 76800;
Packit 667938
	      }
Packit 667938
      } elsif ($siftype{$index} eq 'slip') {
Packit 667938
	      $sifspeed{$index} = 38400;
Packit 667938
      } elsif ($siftype{$index} eq 'ethernetCsmacd') {
Packit 667938
	      $sifspeed{$index} = 10000000;
Packit 667938
      }
Packit 667938
    }
Packit 667938
Packit 667938
    ### Move this section south so we know what type of
Packit 667938
    ###  circuit we're looking at before we retrieve
Packit 667938
    ###  the cisco interface alias.
Packit 667938
    ###
Packit 667938
    ### This whole cicso thing should be re-written, but since
Packit 667938
    ###   this script doesn't need to run quickly...
Packit 667938
    ###
Packit 667938
    ###  - mjd 2/5/98
Packit 667938
    ###
Packit 667938
    # Get the user configurable interface description entered in the config 
Packit 667938
    # if it's a cisco-box
Packit 667938
    #
Packit 667938
    if ($ciscobox) {
Packit 667938
Packit 667938
	my ($enoid, @descr);
Packit 667938
Packit 667938
	$enoid = $snmpget::OIDS{"$cisco_descr_oid"} . "." . $index;
Packit 667938
Packit 667938
	if ( $cisco_ver ge "11.2" or $siftype{$index} ne 'frame-relay' ) {
Packit 667938
Packit 667938
	  ### This is either not a frame-relay sub-interface or
Packit 667938
	  ###  this router is running IOS 11.2+ and interface
Packit 667938
	  ###  type won't matter. In either of these cases, it's
Packit 667938
	  ###  ok to try getting the ifAlias or ciscoLocIfDesc.
Packit 667938
	  ###
Packit 667938
	  @descr = snmpget($router, $enoid);
Packit 667938
Packit 667938
	} else {
Packit 667938
Packit 667938
	  ### This is a frame-relay sub-interface *and* the router
Packit 667938
	  ###  is running an IOS older than 11.2. Therefore, we can
Packit 667938
	  ###  get neither ifAlias nor ciscoLocIfDesc. Do something
Packit 667938
	  ###  useful.
Packit 667938
	  ###
Packit 667938
	  @descr = ("Cisco PVCs descriptions require IOS 11.2+.");
Packit 667938
Packit 667938
	} # end if else
Packit 667938
Packit 667938
	### Put whatever I got into the array we'll use later to append the result
Packit 667938
	###   of this operation onto the results from the ifDescr fetch.
Packit 667938
	###
Packit 667938
	push @ciscodescr, shift @descr;
Packit 667938
Packit 667938
    } # end if ($ciscobox)
Packit 667938
Packit 667938
    # especially since cisco does not return a if
Packit 667938
    # descr for each interface it has ...
Packit 667938
    ## JB 2/8/97 - sometimes IOS inserts E1 controllers in the standard-MIB
Packit 667938
    ## interface table, but not in the local interface table. This puts the
Packit 667938
    ## local interface description table out-of-sync. the following 
Packit 667938
    ## modification skips over E1 cards as interfaces.
Packit 667938
    #
Packit 667938
    ### I suspect that the mod I made above, to use the ifAlias
Packit 667938
    ###   oid if possible, may cause problems here. If it seems
Packit 667938
    ###   that your descriptions are out of sync, try commenting
Packit 667938
    ###   out the "if ( condition )" and it's closing right brace
Packit 667938
    ###   so that the "shift @ciscodescr" get executed for *all*
Packit 667938
    ###   iterations of this loop.
Packit 667938
    ###
Packit 667938
    ### - mjd 2/5/95
Packit 667938
    ###
Packit 667938
    if ($ciscobox && $siftype{$index} ne 'ds1') {
Packit 667938
	  $sciscodescr{$index} = "
" . (shift @ciscodescr) if @ciscodescr;
Packit 667938
    }
Packit 667938
}
Packit 667938
Packit 667938
  foreach $index ( sort { $a <=> $b } keys %sifdesc) {
Packit 667938
    my $speed = int($sifspeed{$index} / 8); # bits to byte
Packit 667938
# LJG Change to report in Bits
Packit 667938
#    my $speed_str=&fmi($speed);
Packit 667938
    my $speed_str=&fmi($sifspeed{$index});
Packit 667938
    my $name="$router.$index";
Packit 667938
    my $namerr="$router.$index.err";
Packit 667938
Packit 667938
  if (($sifadminstatus{$index} ne "up")
Packit 667938
# this check added by Josh - don't query E1-stack controllers
Packit 667938
      || ($siftype{$index} eq 'ds1')
Packit 667938
	|| ($siftype{$index} eq 'softwareLoopback')
Packit 667938
	|| ($speed == 0 ) 
Packit 667938
# LJG Change to report all in Bits
Packit 667938
#	|| ($speed > 400 * 10**6)  #speeds of 400 MByte/s are not realistic
Packit 667938
	|| ($speed > 3200 * 10**6)  #speeds of 400 MByte/s are not realistic
Packit 667938
        || ($sifoperstatus{$index} eq 'down')
Packit 667938
        || (($sifdesc{$index}=~ /Dialer/) && ($ciscobox))) {
Packit 667938
########
Packit 667938
######## This Interface is one of the following
Packit 667938
######## - administratively not UP
Packit 667938
######## - it is in test mode
Packit 667938
######## - it is a softwareLoopback interface
Packit 667938
######## - has a unrealistic speed setting
Packit 667938
######## It is commented out for this reason.
Packit 667938
########
Packit 667938
  }else {
Packit 667938
    $sint2mon = $sint2mon .$cc.$index;
Packit 667938
    $cc = ",";
Packit 667938
  }
Packit 667938
  }
Packit 667938
  if ($ciscobox){
Packit 667938
      $r[@r]="MIB .1.3.6.1.4.1.9.2.1.58 avgBusy5 units INTEGER R";
Packit 667938
      $r[@r]="$op $router .1.3.6.1.* 300 > 0 1 <= 0 1 xA s 58720263 ALL -";
Packit 667938
   }
Packit 667938
  $r[@r]="MIB .1.3.6.1.2.1.1.3 sysUpTime units TIMETICKS R";
Packit 667938
  $r[@r]="$op $router .1.3.6.1.* 300 > 0 1 <= 0 1 xA s 58720263  ALL -";
Packit 667938
  $r[@r]="MIB .1.3.6.1.2.1.2.2.1.10 IfInOctets units/sec COUNTER R";
Packit 667938
  $r[@r]="$op $router .1.3.6.1.* 300 > 0 1 <= 0 1 xA s 58720263 LIST $sint2mon";
Packit 667938
  $r[@r]="MIB .1.3.6.1.2.1.2.2.1.16 IfOutOctets units/sec COUNTER R";
Packit 667938
  $r[@r]="$op $router .1.3.6.1.* 300 > 0 1 <= 0 1 xA s 58720263 LIST $sint2mon";
Packit 667938
  $r[@r]="MIB .1.3.6.1.2.1.2.2.1.14 IfInErrors units/sec COUNTER R";
Packit 667938
  $r[@r]="$op $router .1.3.6.1.* 300 > 0 1 <= 0 1 xA s 58720263 LIST $sint2mon";
Packit 667938
  $r[@r]="MIB .1.3.6.1.2.1.2.2.1.20 IfOutErrors units/sec COUNTER R";
Packit 667938
  $r[@r]="$op $router .1.3.6.1.* 300 > 0 1 <= 0 1 xA s 58720263 LIST $sint2mon";
Packit 667938
  shift @args;
Packit 667938
   }
Packit 667938
   return (@r);
Packit 667938
}
Packit 667938
  
Packit 667938
sub snmpgettable{
Packit 667938
  my($host,$var) = @_;
Packit 667938
  my($next_oid,$enoid,$orig_oid, 
Packit 667938
     $response, $bindings, $binding, $t1, $t2,$outoid,
Packit 667938
     $upoid,$oid,@table,$tempo);
Packit 667938
  die "Unknown SNMP var $var\n" 
Packit 667938
    unless $snmpget::OIDS{$var};
Packit 667938
  
Packit 667938
  $orig_oid = $snmpget::OIDS{$var}." ";
Packit 667938
  $enoid=$orig_oid;
Packit 667938
  open(SNMPG, "snmpwalk $host $orig_oid |");
Packit 667938
#  print STDERR $orig_oid;
Packit 667938
  while ($tempo =<SNMPG>){
Packit 667938
#      print STDERR $tempo;
Packit 667938
      ($t1, $t2, $tempo ) = split /:/ , $tempo ,3;
Packit 667938
      if (!$tempo){
Packit 667938
	 if ($t2){
Packit 667938
	    $t1 = $t1 .":".$t2;
Packit 667938
	 }
Packit 667938
	 $tempo = pop(@table)." ".$t1 ;
Packit 667938
      }
Packit 667938
      $tempo=~s/\t/ /g;
Packit 667938
      $tempo=~s/\n/ /g;
Packit 667938
      $tempo=~s/^\s+//;
Packit 667938
      $tempo=~s/\s+$//;
Packit 667938
      push @table, $tempo;
Packit 667938
     
Packit 667938
  }
Packit 667938
 close (SNMPG);    
Packit 667938
  return (@table);
Packit 667938
}
Packit 667938
Packit 667938
sub fmi {
Packit 667938
  my($number) = $_[0];
Packit 667938
  my(@short);
Packit 667938
# LJG Change to report in Bits
Packit 667938
#  @short = ("Bytes/s","kBytes/s","MBytes/s","GBytes/s");
Packit 667938
  @short = ("Bits/s","kBits/s","MBits/s","GBits/s");
Packit 667938
  my $digits=length("".$number);
Packit 667938
  my $divm=0;
Packit 667938
  while ($digits-$divm*3 > 3) { $divm++; }
Packit 667938
  my $divnum = $number/10**($divm*3);
Packit 667938
  return sprintf("%1.1f %s",$divnum,$short[$divm]);
Packit 667938
}
Packit 667938
Packit 667938
sub ovsysnms (@){
Packit 667938
my @args = @_;  
Packit 667938
  while($router = $args[0]){
Packit 667938
  my($sysName)= snmpget($router, 'sysName');
Packit 667938
### The next three lines can be deleted once Someone gives this box a name
Packit 667938
Packit 667938
  if ($router eq '10.26.254.1') {
Packit 667938
      $sysName = 'nrgiga';
Packit 667938
  }
Packit 667938
  if ($sysName eq ""){
Packit 667938
     $sysName = $router;
Packit 667938
  }
Packit 667938
#  $sysName =~ tr/[A-Z]/[a-z]/;
Packit 667938
# Don't like to do it this way but...
Packit 667938
#  @res=`ovtopodump $router`;
Packit 667938
#  for ($cnt = 0 ; $cnt < @res; $cnt++){
Packit 667938
#     $_ = $res[$cnt];
Packit 667938
#     if (/IP ADDR: (.*)/){
Packit 667938
   @res=`ping $router -n 1`;
Packit 667938
   for ($cnt = 0 ; $cnt < @res; $cnt++){
Packit 667938
      $_ = $res[$cnt];
Packit 667938
      if (/from (.*):.*/) {
Packit 667938
         $routerip = $1; 
Packit 667938
         last;
Packit 667938
     }
Packit 667938
   }
Packit 667938
   @res= `ovobjprint -a "IP Hostname" "SNMP sysName"=$sysName`;
Packit 667938
   $_ = $res[4];
Packit 667938
   if(!/NO FIELD VALUES FOUND/){
Packit 667938
      ($router) = ($res[4] =~ m@\"(.*)\"@ );
Packit 667938
   }
Packit 667938
  $result[@result]= $routerip."\,".$sysName."\,".$router;
Packit 667938
  shift @args;
Packit 667938
  }
Packit 667938
  return @result;
Packit 667938
}
Packit 667938
  
Packit 667938
sub snmpget{  
Packit 667938
  my($host,@vars) = @_;
Packit 667938
  my(@enoid, $var,$response, $bindings, $binding, $value, $inoid,$outoid,
Packit 667938
     $upoid,$oid,@retvals,$t1,$t2,@resp,$tempo);
Packit 667938
  my($hackcisco);
Packit 667938
  foreach $var (@vars) {
Packit 667938
    die "Unknown SNMP var $var\n" 
Packit 667938
      unless $snmpget::OIDS{$var} || $var =~ /^\d+[\.\d+]*\.\d+$/;
Packit 667938
    if ($var =~ /^\d+[\.\d+]*\.\d+/) {
Packit 667938
	$value = $value.$var." ";
Packit 667938
	$hackcisco = 1;
Packit 667938
    } else {
Packit 667938
	$value = $value.$snmpget::OIDS{$var}." ";
Packit 667938
	$hackcisco = 0;
Packit 667938
    }
Packit 667938
  }
Packit 667938
  open(SNMPG, "snmpget $host $value |");
Packit 667938
  while ($tempo =<SNMPG>){
Packit 667938
      ($t1, $t2, $tempo ) = split /:/ , $tempo, 3;
Packit 667938
      if (!$tempo){
Packit 667938
	 if ($t2){
Packit 667938
	    $t1 = $t1 .":".$t2;
Packit 667938
	 }
Packit 667938
	 $tempo = pop(@retvals)." ".$t1 ;
Packit 667938
      }
Packit 667938
      $tempo=~s/\t/ /g;
Packit 667938
      $tempo=~s/\n/ /g;
Packit 667938
      $tempo=~s/^\s+//;
Packit 667938
      $tempo=~s/\s+$//;
Packit 667938
      push @retvals,  $tempo;
Packit 667938
  }
Packit 667938
  close (SNMPG);    
Packit 667938
    return (@retvals);
Packit 667938
}
Packit 667938
1;
Packit 667938