[c-nsp] snmpwalk for switch port status

Eric Hoelzle eric.hoelzle at gmail.com
Wed Nov 18 09:25:57 EST 2009


Here's a version in perl that runs on windows or *nix.  Net::SNMP required.

I have an older version using net::snmp::info that reads more cleanly,
but had trouble getting that module to work under ActiveState perl at
my current job.


--
Eric


--------[  begin paste ]-----
use Net::SNMP;

$ARGC = $#ARGV + 1;
if ($ARGC != 2) {
  die "\nUsage: deadports.pl hostname num_days\n\n";
  }

$pulldays = $ARGV[1];
$hostname = $ARGV[0];
$community = 'CHANGEME';

print "Unused Port report on $hostname for $pulldays days.";

## set up SNMP session
my ($session, $error) = Net::SNMP->session(
   -version   => 'snmpv2c',
   -translate => '0',
   -hostname  => $hostname,
   -community => $community,
   -port      => 161
);

if (!defined($session)) {
   printf("ERROR: %s.\n", $error);
   exit 1;
}

## OIDs
my $sysUpTime		= '1.3.6.1.2.1.1.3.0';
my $sysName             = '1.3.6.1.2.1.1.5.0';
my $oid_ifTable		= '1.3.6.1.2.1.2.2';
my $oid_ifIndex		= '1.3.6.1.2.1.2.2.1.1';
my $oid_ifdescr		= '1.3.6.1.2.1.2.2.1.2.';
my $oid_ifoperstatus	= '1.3.6.1.2.1.2.2.1.8.';
my $oid_iflastchange	= '1.3.6.1.2.1.2.2.1.9.';
my $oid_ifadminstatus   = '1.3.6.1.2.1.2.2.1.7.';

## Counters
$tot_ports  = 0;
$pull_ports = 0;


##
# these subs go gather the data basic.
# get_sysuptime has a print at the end as well.
##

&get_sysuptime;

## can't run a report for more days that we have uptime
if (($uptime/8640000) < $pulldays) {
  print "Sorry, the Device hasn't been up $pulldays days yet.\n\n";
  exit 0;
  }

&get_ifindex;



##
# for each interface returned by get_ifindex, gather detail data
#  and print out the status if it's a candidate to be pulled
##

foreach $ifindex(@ifindexes) {
 @args = ($oid_ifdescr . $ifindex, $oid_ifoperstatus . $ifindex,
$oid_ifadminstatus . $ifindex, $oid_iflastchange . $ifindex);
 #print "@args\n";
 my $result = $session->get_request(
   -varbindlist => \@args
   );

 my $desc	= $result->{$oid_ifdescr . $ifindex};
 my $operstatus	= $result->{$oid_ifoperstatus . $ifindex};
 my $lastchange = $result->{$oid_iflastchange . $ifindex};
 my $adminstatus = $result->{$oid_ifadminstatus . $ifindex};
 my $status_time_days = ($uptime - $lastchange) / 8640000;
 $tot_ports++;

 ## are we a pull candidate?  if ifoperstatus 2 == down we are
 if ($operstatus == '2' && $status_time_days >= $pulldays) {
   $pull_ports++;
   $rounded_days = sprintf("%.2f", $status_time_days);
   if ($adminstatus == '1' ) {
     print "$desc has been down for $rounded_days days \n";
     }
   if ($adminstatus == '2' ) {
     print "$desc is ADMINDOWN and has been down for $rounded_days days \n";
     }
   ## die if we see a negative number
   if ($rounded_days < 0) {
      die "\nUh-oh...Looks like we've actually been up more than 498
days.\nThat rocks, but is unfortunate for our purposes.\nReboot this
gear and try again later.\n";
      }
   }


}

## done.  go home.
print "\nTotal interfaces found: $tot_ports\nPorts Unsed for the last
$pulldays Days: $pull_ports";
$session->close;

exit 0;

##
# subs below here
##

sub get_ifindex {
my $tbl_ifIndex = $session->get_table(
   -baseoid => $oid_ifIndex
);


if (!defined($tbl_ifIndex)) {
   printf("ERROR: %s.\n", $session->error);
   $session->close;
   exit 1;
}

foreach $key (keys %$tbl_ifIndex) {
    #print "$key => $$tbl_ifIndex{$key}\n";
    push (@ifindexes, $$tbl_ifIndex{$key});
  }
@ifindexes = sort(@ifindexes);

}


sub get_sysuptime {
   my $result = $session->get_request(
      -varbindlist => [$sysUpTime]
   );
   $uptime = $result->{$sysUpTime};


   my $result = $session->get_request(
      -varbindlist => [$sysName]
   );
   $sysname = $result->{$sysName};




   printf("\nDevice'%s' has been up for %.2f days\n\n",
      $sysname, $uptime/8640000
   );



}
------[ end paste ]----


More information about the cisco-nsp mailing list