#!/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 ########################################