#!/usr/bin/perl # # Filename: /usr/local/etc/port/portcount.pl # # Purpose: Query Nortel switches for ifInOctets to provide port capacity # utilization statistics. We'll keep a running count of the # ifInOctets for each MIB2 interface and report on how long the # port has been idle (meaning we saw no change in the counter). # # # Switches: Nortel Passport 8600 # Nortel Passport 1600 # Nortel BayStack 470 # Nortel BayStack 470 PoE (PwR) # Nortel BayStack 460 PoE (PwR) # Nortel BayStack 450 # Nortel BayStack 350 # Nortel Business Policy Switch # Nortel BayStack 5510 # Nortel BayStack 5520 PoE (PwR) # Nortel BayStack 5530 # HP GbE2 Switch Blades # Cisco Catalyst 2950, 2960, 3560 # # Author: Michael McNamara (mfm@michaelfmcnamara.com) # # Credits: Stewart Kendric (http://www.skendric.com) # # Date: July 28, 2003 # # Version: 1.5 # # License: # Copyright (C) 2002 Michael McNamara (mfm@michaelfmcnamara.com) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # # Changes: # # August 13, 2010 (M.McNamara) # added support for Cisco 3750E Stacks, also missing 3560E models # June 17, 2010 (M.McNamara) # added support for HP GbE2c # November 19, 2009 (M.McNamara) # added support for Cisco Catalyst 2950, 2960, 3560, 6500 switches # added $ifType eq "other" to skip non-physical interfaces # August, 31, 2009 (M.McNamara) # added $ifType eq "l2vlan" $ifType eq "l3ipvlan" $ifType eq "propVirtual" # to help clean up the non-physical interfaces from the reports # May 9, 2007 (M.McNamara) # added prune_switches sub to query only devices this script supports # October 16, 2006 (M.McNamara) # added code to skip cascasde ports in ifTable on switch stacks # "next if ($ifType eq "propMultiplexor");" # October 2, 2006 (M.McNamara) # added support for BayStack 470 PwR # December 6, 2005 (M.McNamara) # added support for BayStack 5530 24FTD switch # added support for HP GbE2 switch blades (v2.2) # December 30, 2004 (M.McNamara) # added support for BayStack 5520 PWR switch # August 23, 2004 (M.McNamara) # added suppor for BayStack 5510 48T switch # March 14, 2004 (M. McNamara) # added support for BayStack 460 24T PWR swtich # January 21, 2004 (M. McNamara) # added debug command line paramaters # January 13, 2004 (M. McNamara) # change the SNMP version from "2c" to "1" in order to support older equipment # adopted the byKeys sub to sort DNS names and then slot/port numbers in order # to sort and clean up the output of the hash array # added routines to support BayStack 303/304 and BayStack 350F switches # January 07, 2004 (M.McNamara) # Added support for Passport 1600 switches and corrected some bugs # Dec 30, 2003: added ICMP ping check before any SNMP queries # Dec 17, 2003: added fixes for Passport 1648T switch # Dec 01, 2003: added routines to check if switch is reachable # Oct 01, 2003: added fixes for BayStack 24T switch # # Load Modules use strict; use SNMP; use Net::Ping; # Declare constants #use constant DEBUG => 1; # DEBUG settings use constant RETRIES => 3; # SNMP retries use constant TIMEOUT => 1000000; # SNMP timeout, in microseconds use constant SNMPVER => 1; # SNMP version my $DEBUG = 1; # DEBUG Flag for troubleshooting # Setup SNMP Variables $SNMP::verbose = $DEBUG; $SNMP::use_enums = 1; $SNMP::use_sprint_value = 1; &SNMP::initMib(); &SNMP::loadModules('ALL'); #&SNMP::loadModules('+RAPID-CITY'); #&SNMP::loadModules('+SYNOPTICS-ROOT-MIB'); # Declare Hashes, Arrays and Scalar Variables my %disk; # Data Structure from disk my %live; # Data Structure from snmpget my %data; # Data Structure for merge my %totalPorts; # Hash for total port counts my %activePorts; # Hash for list of active ports my %idlePorts; # Hash for list of idle ports my $totalPorts; # Counter for total ports my $activePorts; # Counter for total active ports my $idlePorts; # Counter for total idle ports my $goneDays; my $idleDays; my $idleTime; my $dataFile; my ($sess, @vals); my @found; my ($card, $port); my $community = "5ninety"; # Local Data Files my $switchlist = "/usr/local/etc/allswitches"; # List of switches #my $switchlist = "/usr/local/etc/port/test1.txt"; # List of switches my $portDataFile = "/usr/local/etc/port/portdata.txt"; # Datafile my $summaryFile = "/usr/local/etc/port/portsummary.txt"; # Summary Report file my $reportFile = "/usr/local/etc/port/portreport.txt"; # Detailed Report file our @devices; our $snmphost; my %list; my %list1; my $index, my $descr; my $status; my $currTime; my $date; my $time; our ($sysObjectID, $sysName, $sysDescr, $sysUpTime, $sysContact, $sysLocation, $sysSoftware); our @sysObjectIDs = qw/ rcA8610 rcA8606 rcA1648 sreg-EthernetRoutingSwitch5530-24TFD sreg-BayStack5520-48T-PWR sreg-BayStack5520-24T-PWR sreg-BayStack5510-48T-ethSwitchNMM sreg-BayStack5510-24T-ethSwitchNMM sreg-ERS-4548GT-PWR sreg-BayStack470-48T-PWR-ethSwitchNMM sreg-BayStack470-48T-ethSwitchNMM sreg-BayStack470-24T-ethSwitchNMM sreg-BayStack460-24T-PWR-ethSwitchNMM sreg-BayStack450-ethSwitchNMM sreg-BayStack350-24T-ethSwitchNMM sreg-BayStack350-ethSwitchNMM sreg-BPS2000-24T-ethSwitchNMM sreg-BayStack303-304-Sw sreg-SMB-BES-50-GE-24T-PWR hpProLiant-p-GbE2-InterconnectSwitch hpProLiant-GbE2c-InterconnectSwitch catalyst6kMsfc2 catalyst295012 catalyst2924XLv catalyst2924MXL catalyst2950t24 catalyst295048G catalyst295024G catalyst296024 catalyst296048TT catalyst2960G48 catalyst356024PS catalyst3560G48TS catalyst3560E24PD catalyst3560G24PS catalyst3560G48PS catalyst37xxStack /; our @AvayaERSSwtichStacks = qw/ sreg-EthernetRoutingSwitch5530-24TFD sreg-BayStack5520-48T-PWR sreg-BayStack5520-24T-PWR sreg-BayStack5510-48T-ethSwitchNMM sreg-BayStack5510-24T-ethSwitchNMM sreg-ERS-4548GT-PWR sreg-BayStack470-48T-PWR-ethSwitchNMM sreg-BayStack470-48T-ethSwitchNMM sreg-BayStack470-24T-ethSwitchNMM sreg-BayStack460-24T-PWR-ethSwitchNMM sreg-BayStack450-ethSwitchNMM sreg-BayStack350-24T-ethSwitchNMM sreg-BayStack350-ethSwitchNMM sreg-BPS2000-24T-ethSwitchNMM /; # ## ### ## # # SNMP OIDs my $ifstatus = "interfaces.ifTable.ifEntry.ifOperStatus."; my $ifdesc = "interfaces.ifTable.ifEntry.ifDescr."; my $iftotal = "ifNumber.0"; # Timing $idleDays = 45; $goneDays = 10; $idleTime = time - $idleDays*24*60*60; $currTime = time; ($date, $time) = &get_time; # Define global variables $| = 1; # Disable buffering of IO # Stanity check for troubleshooting purposes #print "$currTime\n"; #print "Date = $date & Time = $time\n"; my $program = "portcount.pl"; my $version = "v0.1f"; my $author = "Michael McNamara"; my $purpose = "This Perl script is designed to poll the network electronics via SNMP and provide a report of which Ethernet switch ports are idle and can be re-used for another device."; my $usage = "Usage: $program \[debug\]\n"; my $test = shift @ARGV; if ($test =~ /-help/ ) { die "Program: $program \nVersion: $version \nWritten by: $author \n$purpose\n\n$usage\n"; } elsif ($test =~ /-h/) { die "Program: $program \nVersion: $version \nWritten by: $author \n$purpose\n\n$usage\n"; } elsif ($test eq "debug") { $DEBUG = 1; print "DEBUG: setting DEBUG flag to enable\n"; } ############################################################ # Main Program ############################################################ &loaddevices; # Load hostnames of all switches &prune_switches; # Remove devices we don't support &read_data; # Load all previously stored data &getsnmpdata; # Gather all SNMP data &compare_counts; # Compare the current and stored data &count_ports; # Count the number of ports for reporting &write_data; # Save the new data for furture use &write_report; # Output the idle port report &write_summary; # Output the summary report ############################################################# # End Main Program ############################################################# ############################################################# # Subroutine to load list of targes (switches) ############################################################# sub loaddevices { open(SWITCHLIST, "<$switchlist"); # Walk through data file while () { # Skip blank lines next if (/^\n$/); # Skip comments next if (/^#/); print "DEBUG: adding $_ to our list of devices \n" if ($DEBUG); push (@devices, $_); } close(SWITCHLIST); return 1; } ############################################################################ # Subroutine prune_switches # # Purpose: prune list of switches to those that are support by this script ############################################################################ sub prune_switches { # Declare Local Variables my @list; my $xflag = 0; my $packet = Net::Ping->new('icmp'); foreach $snmphost (@devices) { $xflag = 0; $snmphost =~ s/\n//g; if (!($packet->ping($snmphost))) { next; } #end if if (&grab_snmpsystem == 99) { next; } #end if foreach my $sysobject (@sysObjectIDs) { if ($sysObjectID eq $sysobject) { push(@list, $snmphost); print "DEBUG: $snmphost ($sysObjectID) is supported pushing to list...\n" if ($DEBUG); $xflag = 1; next; } #endif } #end foreach if ($xflag == 0) { print "DEBUG: $snmphost ($sysObjectID) is NOT supported!!!! ******** \n" if ($DEBUG); } } #end foreach @devices = @list; return 1; } # end sub load_switches ############################################################################ ############################################################################ # Subroutine grab_snmpsystem # # Purpose: use SNMP to identify the type of switch we'll be working with ############################################################################ sub grab_snmpsystem { # Declare Local Variables my @vals; my $sess = new SNMP::Session ( DestHost => $snmphost, Community => $community, Version => SNMPVER ); my $vars = new SNMP::VarList( ['sysDescr', 0], ['sysObjectID', 0], ['sysUpTime', 0], ['sysContact', 0], ['sysName', 0], ['sysLocation', 0] ); #print "DEBUG: snmphost = $snmphost and community = $community\n" if ($DEBUG); @vals = $sess->get($vars); # retreive SNMP information if ( $sess->{ErrorStr} ) { print "ERROR: retreiving system for $snmphost\n"; print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n"; } if ($vals[0] eq "") { print "ERROR: Unable to poll the switch $snmphost. !!!\n"; print SENDMAIL "ERROR:Unable to poll the switch $snmphost. !!!
\n"; return 99; } $sysDescr = $vals[0]; $sysObjectID = $vals[1]; $sysUpTime = $vals[2]; $sysContact = $vals[3]; $sysName = $vals[4]; $sysLocation = $vals[5]; $sysObjectID =~ s/.1.3.6.1.4.1/enterprises/; return 1; }; #end sub grab_snmpsystem ######################################## ######################################################################## # Figure out the current time ######################################################################## sub get_time { my ($sec, $min, $hour, $day, $mon, $year, $date, $time, $now); ($sec, $min, $hour, $day, $mon, $year) = (localtime)[0,1,2,3,4,5]; if ($sec < 10) { $sec = "0" . $sec } if ($min < 10) { $min = "0" . $min } if ($hour < 10) { $hour = "0" . $hour } $mon = $mon + 1; $year = $year + 1900; $date = $mon . "-" . $day . "-" . $year; $time = $hour . ":" . $min . ":" . $sec; $now = $date . " at " . $time; return ($date, $time); } ######################################################################## # Read in the data file ######################################################################## sub read_data { # Declare the Local Variables my $count; my $cTime; my $iTime; my $name; my $ifnum; my $card; my $port; my $vTime; # Open data file open DATA, "$portDataFile" or die "Can't open $dataFile: $!\n"; # Walk through data file while () { # Skip blank lines next if (/^\n$/); # Skip comments next if (/^#/); # Read a line of data, throw away iTime using 'space' as the delimeter ($name, $ifnum, $card, $port, $count, $cTime, $vTime) = split(' '); # Build data structure in order to recall the data in the furture $disk{"$name $ifnum $card $port"} = "$name $ifnum $card $port $count $cTime $vTime"; } close DATA; return 1; } ######################################################################## # Write new data file ######################################################################## sub write_data { # Declare the Local Variables my $cTime; my $count; my $iTime; my $key; my $name; my $now; my $ifnum; my $port; my $slot; my $vTime; # Find time $now = time; # Open data file open DATA, ">$portDataFile"; # Output all the following text print DATA < ($now - $goneDays*24*60*60) ); # Calculate idle time $iTime = &calc_idle_time($cTime, $vTime); # Output special formatted text for report printf DATA "%-43s %4s %4s %4s %6s %11s %11s %13s\n", $name, $ifnum, $slot, $port, $count, $cTime, $vTime, $iTime; } # Close the file close DATA; return 1; } ######################################################################## # Compare the current counts to those from the data file & update %disk # After this routine runs, the information we've gathered and stored in # %live has been merged into %disk ######################################################################## sub compare_counts { # Declare the Local Variables my $currCount; # ifInOctets gathered live my $diskCount; # ifInOctets from disk file my $diskCTime; # Last time ifInOctets changed my $diskVTime; # Last time we asked device if ifInOctets # had changed my $flag; my $name; # Host from data file my $ifnum; # Index from data file my $port; # Port from data file my $slot; # Slot from data file # Walk through %live comparing the octet counter we just acquired with # the counter stored on disk for my $triple (keys %live) { # Get the current data $currCount = $live{$triple}; # Grab an entry from the disk file if (exists $disk{$triple}) { ($name, $ifnum, $slot, $port, $diskCount, $diskCTime, $diskVTime) = split (' ', $disk{$triple}); } # Compare if (! exists $disk{$triple} ) { # New port $flag = "new"; $data{$triple} = "$triple $currCount $currTime $currTime"; } elsif ($currCount == $diskCount) { # No change in byte count $flag = "no change"; $data{$triple} = "$triple $diskCount $diskCTime $currTime"; } else { # Recent activity $flag = "activity"; $data{$triple} = "$triple $currCount $currTime $currTime"; } # Debug info if ($DEBUG) { if ($flag eq "new") { print "DEBUG: *NewPort* data{$triple} = $triple $currCount $currTime $currTime\n"; } elsif ($flag eq "no change") { print "DEBUG: *NoDelta* data{$triple} = $triple $diskCount $diskCTime $currTime\n"; } elsif ($flag eq "activity") { print "DEBUG: *Change* data{$triple} = $triple $currCount $currTime $currTime\n"; } } } # Debug info # if ($DEBUG) { # print "DEBUG: Dumping \%data\n"; # for my $triple (sort keys %data) { # print "DEBUG: dumping data{$triple} = $data{$triple}\n"; # } # print "\n"; # } return 1; } ########################################################### # Figure out keys ########################################################### #sub byKeys { # my ($a_host, $a_slot, $a_port, $b_host, $b_slot, $b_port); # ($a_host, $a_slot, $a_port) = split (' ', $a); # ($b_host, $b_slot, $b_port) = split (' ', $b); # if (($a_host cmp $b_host) != 0) { $a_host cmp $b_host; } # elsif (($a_slot <=> $b_slot) != 0) { $a_slot <=> $b_slot; } # elsif (($a_port <=> $b_port) != 0) { $a_port <=> $b_port; } #} ######################################################################## # Subroutine byKeys # # Purpose: sort the DNS domain names from the Hash Array for output ######################################################################## sub byKeys { # Declare Local Variables my ($a_fqdn, $a_host, $a_domain1, $a_domain2, $a_domain3, $a_slot, $a_port); my ($b_fqdn, $b_host, $b_domain1, $b_domain2, $b_domain3, $b_slot, $b_port); ($a_fqdn, $a_slot, $a_port) = split (' ', $a); ($b_fqdn, $b_slot, $b_port) = split (' ', $b); ($a_host, $a_domain1, $a_domain2, $a_domain3) = split (/\./, $a_fqdn); ($b_host, $b_domain1, $b_domain2, $b_domain3) = split (/\./, $b_fqdn); #print "DEBUG: $a_host, $a_domain1, $a_domain2, $a_domain3\n" if ($DEBUG); #print "DEBUG: $b_host, $b_domain1, $b_domain2, $b_domain3\n" if ($DEBUG); #print "DEBUG: a = $a\n" if ($DEBUG); #print "DEBUG: b = $b\n" if ($DEBUG); if (($a_domain3 cmp $b_domain3) != 0) { $a_domain3 cmp $b_domain3; } elsif (($a_domain2 cmp $b_domain2) != 0) { $a_domain2 cmp $b_domain2; } elsif (($a_domain1 cmp $b_domain1) != 0) { $a_domain1 cmp $b_domain1; } elsif (($a_host cmp $b_host) != 0) { $a_host cmp $b_host; } elsif (($a_host cmp $b_host) != 0) { $a_host cmp $b_host; } elsif (($a_slot <=> $b_slot) != 0) { $a_slot <=> $b_slot; } elsif (($a_port <=> $b_port) != 0) { $a_port <=> $b_port; } } #end sub bykeys ######################################################################## # Subroutine byKeys_dns # # Purpose: sort the DNS domain names from the Hash Array for output ######################################################################## sub byKeys_dns { # Declare Local Variables my ($a_fqdn, $a_host, $a_domain1, $a_domain2, $a_domain3, $a_slot, $a_port); my ($b_fqdn, $b_host, $b_domain1, $b_domain2, $b_domain3, $b_slot, $b_port); #($a_fqdn, $a_slot, $a_port) = split (' ', $a); #($b_fqdn, $b_slot, $b_port) = split (' ', $b); ($a_host, $a_domain1, $a_domain2, $a_domain3) = split (/\./, $a); ($b_host, $b_domain1, $b_domain2, $b_domain3) = split (/\./, $b); #print "DEBUG: $a_host, $a_domain1, $a_domain2, $a_domain3\n" if ($DEBUG); #print "DEBUG: $b_host, $b_domain1, $b_domain2, $b_domain3\n" if ($DEBUG); #print "DEBUG: a = $a\n" if ($DEBUG); #print "DEBUG: b = $b\n" if ($DEBUG); if (($a_domain3 cmp $b_domain3) != 0) { $a_domain3 cmp $b_domain3; } elsif (($a_domain2 cmp $b_domain2) != 0) { $a_domain2 cmp $b_domain2; } elsif (($a_domain1 cmp $b_domain1) != 0) { $a_domain1 cmp $b_domain1; } elsif (($a_host cmp $b_host) != 0) { $a_host cmp $b_host; } } #end sub bykeys ########################################################### # Calculate idle time ########################################################### sub calc_idle_time { my $cTime = shift; # ChangeTime: Time at which octet count # last changed my $vTime = shift; # VerifyTime: Time at which we last # talked with this port my $iTime; # IdleTime: for how long has this port # sat idle, expressed as # days:hours:minutes:seconds my ($iDays, $iHours, $iMins, $iSecs); # Do the math if ($cTime != 0) { $iTime = $vTime - $cTime; $iSecs = $iTime % 60; $iTime -= $iSecs; $iMins = $iTime % 3600; $iTime -= $iMins; $iMins /= 60; $iHours = $iTime % 86400; $iTime -= $iHours; $iHours /= 3600; $iDays = $iTime / 86400; if ($iSecs < 10) { $iSecs = "0" . $iSecs } if ($iMins < 10) { $iMins = "0" . $iMins } if ($iHours < 10) { $iHours = "0" . $iHours } } else { $iSecs = 99; $iMins = 99; $iHours = 99; $iDays = 999; } # Put it all together $iTime = "$iDays:$iHours:$iMins:$iSecs"; return $iTime; } ########################################################### ########################################################### # Count ports in various way ########################################################### sub count_ports { my $count; my $cTime; my $name; my $ifnum; my $port; my $slot; my $vTime; # Initialize variables (only relevant in debugging cases) $activePorts = 0; $totalPorts = 0; # Walk through data and count ports for my $triple (sort keys %data) { # Grab next entry ($name, $ifnum, $slot, $port, $count, $cTime, $vTime) = split(' ', $data{$triple}); # Initialize variables unless (exists $totalPorts{$name}) { $totalPorts{$name} = 0 } unless (exists $activePorts{$name}) { $activePorts{$name} = 0 } unless (exists $idlePorts{$name}) { $idlePorts{$name} = 0 } # Increment totalPorts $totalPorts{$name}++; $totalPorts++; # Count idle ports. For ports which have never seen traffic, # CatOS and IOS devices set ifInOctets to 0, whereas CatIOS devices # set this counter to 64. if ($count == 0 or $count == 64 or $cTime < $idleTime) { $idlePorts{$name}++; $idlePorts++; } # Count active ports else { $activePorts{$name}++; $activePorts++; } } # Debug info if ($DEBUG) { for my $name (sort keys %totalPorts) { print "For $name: $activePorts{$name} $totalPorts{$name}\n"; } print "activePorts = $activePorts; totalPorts = $totalPorts\n"; } return 1; } ########################################################### ########################################################### # Subroutine to retreive SNMP data and store it ########################################################### sub getsnmpdata { my $packet = Net::Ping->new('icmp'); foreach $snmphost (@devices) { $snmphost =~ s/\n//g; if ($packet->ping($snmphost)) { my $sess = new SNMP::Session ( DestHost => $snmphost, Community => $community, Version => SNMPVER ); my $total = $sess->get($iftotal); # We need to know the sysObjectID of the switch we are about # to walk so we can make decisions. We also need it to be global # since we will call other subroutines which also need to know # the sysObjectID $sysObjectID = $sess->get('sysObjectID.0'); # Some products behave differently based on software release, so # let's try and determine what software release this switch is running &check_software; if (! defined $total) { print "ERROR: snmp query against $snmphost for number of intfs failed!!! skipping!!!\n"; next; } ##$sysObjectID =~ s/.1.3.6.1.4.1/enterprises/; print "DEBUG: total interfaces for $snmphost equal $total\n" if ($DEBUG); print "DEBUG: system object ID = $sysObjectID\n" if ($DEBUG); my $vars = new SNMP::VarList( ['ifIndex', 0], ['ifInOctets', 0], ['ifType',0] ); while (1) { @vals = $sess->getnext($vars); # print $vars->[0]->tag, "\n" ; # print $vars->[1]->tag, "\n" ; # print $vars->[2]->tag, "\n" ; # print $vars->[3]->tag, "\n" ; my $ifIndex = $vals[0]; my $ifInOctets = $vals[1]; my $ifType = $vals[2]; # Let's skip the interfaces that aren't physical or real next if ( ($ifType eq "propMultiplexor") || ($ifType eq "l2vlan") || ($ifType eq "l3ipvlan") || ($ifType eq "other") || ($ifType eq "propVirtual") ); last unless ($vars->[0]->tag eq 'ifIndex'); #print "DEBUG: ifIndex $ifIndex reports ifInOctets = $ifInOctets \n" if ($DEBUG); if ( ($sysObjectID eq "rcA8610") || ($sysObjectID eq "rcA8606") || # enterprises.2272.30 ($sysObjectID eq "rcA1648") ) { # enterprises.2272.43 # Ethernet Routing Switch 8610/8606/1648 $card = int($ifIndex / 64); $port = ( $ifIndex - ($card * 64) + 1 ); #print "DEBUG: Passport 8600 Interface card=int($ifIndex/64)~$card port=($ifIndex-($card*64)+1)~$port \n" if ($DEBUG) } elsif ( ($sysObjectID eq "sreg-BayStack470-48T-ethSwitchNMM" ) || ($sysObjectID eq "sreg-BayStack470-24T-ethSwitchNMM" ) || ($sysObjectID eq "sreg-BayStack470-48T-PWR-ethSwitchNMM") ) { # BayStack 470 Switch Series $card = int($ifIndex / 64); $port = ( $ifIndex - ($card * 64) ); $card++; } elsif ( ($sysObjectID eq "BPS2000-24T-ethSwitchNMM") || ($sysObjectID eq "sreg-BayStack460-24T-PWR-ethSwitchNMM") || ($sysObjectID eq "sreg-BayStack450-ethSwitchNMM" ) || ($sysObjectID eq "sreg-BayStack350-24T-ethSwitchNMM") ) { $card = int($ifIndex / 32); $port = ( $ifIndex - ($card * 32) ); $card++; } elsif ($sysObjectID eq "sreg-BPS2000-24T-ethSwitchNMM" ) { # Business Policy Switch # sreg-BPS2000-24T-ethSwitchNMM enterprises.45.3.40.1 $card = 1; $port = $ifIndex; } elsif (($sysObjectID eq "sreg-SMB-BES-50-GE-24T-PWR") || ($sysObjectID eq "sreg-BayStack303-304-Sw" ) || ($sysObjectID eq "sreg-BayStack350-ethSwitchNMM" ) || ($sysObjectID eq "sreg-ERS-4548GT-PWR" )) { # sreg-BayStack303-304-Sw enterprises.3.32.1 # sreg-BayStack350-ethSwitchNMM enterprises.3.30.1 # sreg-ERS-4548GT-PWR # sreg-SMB-BES-50-GE-24T-PWR $card = 1; $port = $ifIndex; } elsif (($sysObjectID eq "sreg-BayStack5510-48T-ethSwitchNMM") || ($sysObjectID eq "sreg-BayStack5510-24T-ethSwitchNMM") || ($sysObjectID eq "sreg-BayStack5520-24T-PWR") || ($sysObjectID eq "sreg-BayStack5520-48T-PWR") || ($sysObjectID eq "sreg-EthernetRoutingSwitch5530-24TFD")) { if ( $sysSoftware =~ "6.1" ) { ##$ifnum = (( $slot * 128 ) + $port ) - 128; #### copied from ARP/FDB report script $card = int ($ifIndex / 128); $port = $ifIndex - ($card * 128); $card++; } else { ##$ifnum = (( $slot * 64 ) + $port ) - 64; #### copied from ARP/FDB report script $card = int($ifIndex / 64); $port = $ifIndex - ($card * 64); $card++; } } elsif (($sysObjectID eq "hpProLiant-p-GbE2-InterconnectSwitch" ) || ($sysObjectID eq "hpProLiant-p-GbE2c-InterconnectSwitch") || ($sysObjectID eq "hpProLiant-GbE2c-InterconnectSwitch")) { # HP GbE2/GbE2c Switch Blade hpProLiant-GbE2c-InterconnectSwitch $card = 1; if ($ifIndex > 255) { $port = ( $ifIndex - 256 ); } else { $port = $ifIndex; } } elsif (($sysObjectID eq "catalyst2924XLv") || ($sysObjectID eq "catalyst295048G") || ($sysObjectID eq "catalyst2924MXL") || ($sysObjectID eq "catalyst2950t24") || ($sysObjectID eq "catalyst295048G") || ($sysObjectID eq "catalyst295024G") || ($sysObjectID eq "catalyst6kMsfc2") || ($sysObjectID eq "catalyst295012") ){ # Cisco $card = 1; $port = $ifIndex; } elsif (($sysObjectID eq "catalyst296024") || ($sysObjectID eq "catalyst356024PS") || ($sysObjectID eq "catalyst296048TT") ) { # Cisco 2960 / 3650 Switch $card = 1; if ($ifIndex > 10000) {$port = $ifIndex - 10000;} else { $port = $ifIndex;} } elsif (($sysObjectID eq "catalyst2960G48") || ($sysObjectID eq "catalyst356024PD") || ($sysObjectID eq "catalyst3560E24PD") || ($sysObjectID eq "catalyst3560G48TS") || ($sysObjectID eq "catalyst3560G24PS") || ($sysObjectID eq "catalyst3560G48PS") ) { # Cisco 3560 Switches $card = 1; if ($ifIndex > 10000) { $port = $ifIndex - 10100;} else { $port = $ifIndex;} } elsif (($sysObjectID eq "catalyst37xxStack") ) { # Cisco 3750 Switches if ( ($ifIndex >= 10100) and ($ifIndex < 10200)) { $card = 1; $port = $ifIndex - 10100; } elsif ( ($ifIndex >= 10600) and ($ifIndex < 10700)) { $card = 2; $port = $ifIndex - 10600; } } else { print "ERROR: Unable to determine switch model for $snmphost ($sysObjectID)!!!! \n"; next; } $live{"$snmphost $ifIndex $card $port"} = substr ($ifInOctets, -6, 6); } #end while loop for snmpgetnext } else { #end if packet-ping print "DEBUG: $snmphost did not respond to ICMP ping request\n"; } } #end foreach $snmphost return 1; } ########################################################### ######################################################################## # Print summary ######################################################################## sub write_summary { my $active; # Percent of active ports on this device my $idle; # Percent of idle ports on this device my $per = "%"; # Percent sign my $total; # Sum of activePorts and idlePorts on that host my $totalidle; my $totalidlepercent; # Open report file unless (open SUMMARY, ">$summaryFile") { &print_it ("Cannot open $summaryFile: $!"); return 0; } $totalidle = ($totalPorts - $activePorts); my $temptotalidlepercent = (($totalidle / $totalPorts) *100); # Round number to 3 digits after decimal point #$rounded = sprintf("%.3f", $number); $totalidlepercent = sprintf( "%.3f", $temptotalidlepercent); print SUMMARY <$reportFile") { &print_it ("Cannot open $reportFile: $!"); return 0; } $totalidle = ($totalPorts - $activePorts); #$totalidlepercent = int( (($totalidle / $totalPorts) *100) +.5); my $temptotalidlepercent = (($totalidle / $totalPorts) *100); # Round number to 3 digits after decimal point #$rounded = sprintf("%.3f", $number); $totalidlepercent = sprintf( "%.3f", $temptotalidlepercent); print REPORT < $idleTime) { 0 } # Not old enough else { 1 } # Old enough } ############################################################################ # Subroutine check_software # # Purpose: perform SNMP query against device and return software version ############################################################################ sub check_software { my $check_sess = new SNMP::Session ( DestHost => $snmphost, Community => $community, Version => SNMPVER ); print "DEBUG: check_software $snmphost with $sysObjectID\n" if ($DEBUG); foreach my $supported (@AvayaERSSwtichStacks) { ##print "DEBUG: check_software $sysObjectID == $supported\n" if ($DEBUG); if ($sysObjectID eq $supported) { # Let's get the software release from the Nortel/Avaya switches $sysSoftware = $check_sess->get("s5AgInfoVer.0"); if ( $check_sess->{ErrorStr} ) { print "ERROR: sess->{Errocheck_software rStr} = $check_sess->{ErrorStr}\n"; } print "DEBUG: check_software $snmphost sysSoftware = $sysSoftware\n" if ($DEBUG); } #endif } #end foreach return 1; }; #end sub check_software ########################################