[c-nsp] snmpwalk for switch port status

Matlock, Kenneth L MatlockK at exempla.org
Wed Nov 18 10:20:04 EST 2009


Seeing this script reminded me of a pet peeve I have with Cisco. Why oh
why did they use a 32-bit int for the uptime of the switch and port, and
use 1/100th second resolution, so after 497 days the counter rolls over
back to 0? Was a 64 bit int (or 1/10 a second resolution) not good
enough? :)

The chassis knows the real uptime (a 'show ver' shows it), why not
expose that value to SNMP, and the same for the port last changed state?

Ken Matlock
Network Analyst
Exempla Healthcare
(303) 467-4671
matlockk at exempla.org


-----Original Message-----
From: cisco-nsp-bounces at puck.nether.net
[mailto:cisco-nsp-bounces at puck.nether.net] On Behalf Of Eric Hoelzle
Sent: Wednesday, November 18, 2009 7:26 AM
To: cisco-nsp at puck.nether.net
Subject: Re: [c-nsp] snmpwalk for switch port status

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 ]----
_______________________________________________
cisco-nsp mailing list  cisco-nsp at puck.nether.net
https://puck.nether.net/mailman/listinfo/cisco-nsp
archive at http://puck.nether.net/pipermail/cisco-nsp/


More information about the cisco-nsp mailing list