Category: | Networking Code |
Author/Contact Info | fingers |
Description: | Usage: switchcheck.pl options ip { ip ip ... } Designed to get an overview or collect statisics on switchports usage using SNMP. -b option allows you to specify community name on the command line to allow being called in a cron job -l logs basic port usage stats to a dbm file -r is used to read files created by -l -v gives more detailed stats on ports that are up -c generates a csv file, can be used in conjunction with -v Some options are mutually exclusive. The later option takes precedence. Tested with: Perl 5.6.1 RedHat 7.1 against: Cisco 6509,2924XL,3508XL,3512XL,3524XL,3548XL switches I realize it may be a little sloppy and amateur, I definately would appreciate any constructive criticism anyone has about my code. |
#!/usr/bin/perl -w # switchcheck.pl use strict; use Net::SNMP; my($error,$session,$seed_oid,$oid_root,$csvname,$community,$hostname,$ +seed_ip,$serial,$option,$logdir); my(@unique,@hostname); my($ifMIB) = "1.3.6.1.2.1.31.1.1.1"; my(%option)=( verbose => 0, csv => 0, log => 0, batch => 0, help => 0, hostname => 0, read => 0 ); die "\nusage: $0 option ip\n Use $0 -h for list of options\n" unless ( + @ARGV >= 1 ); $logdir="/var/log/sc"; #Begin processing command line arguments #*************************************************************** while(@ARGV){ $option = $ARGV[0]; if($option eq "-v"){ $option{'verbose'} = 1; $option{'log'} = 0; $option{'read'} = 0; } elsif($option eq "-l"){ $option{'log'} = 1; $option{'verbose'} = 0; $option{'read'} = 0; } elsif($option eq "-r"){ $option{'read'} = 1; $option{'verbose'} = 0; $option{'log'} = 0; } elsif($option eq "-b"){ $option{'batch'} = 1; $community = $ARGV[1]; shift @ARGV; } elsif($option eq "-h"){ $option{'help'} = 1; die "\n\n usage: $0 options ip ... \n\n -h This help message -l Logging -v Verbose -c filename Send output to filename.csv -b community Batch, community is the snmp community name -r ip ... Display results from log files for specified IPs\ +n\n\n"; } elsif($option eq "-c"){ $option{'csv'} = 1; $option{'read'} = 0; $option{'log'} = 0; $csvname = ("$ARGV[1]".".csv"); shift @ARGV; } else{ die "usage: $0 ip\n" unless ($option =~ m{\d+\.\d+\.\d+\.\d+}) +; push @hostname , $option; $option{'hostname'} = 1; } shift @ARGV; } die "You need to give at least one IP address as an option\n" unless($ +option{'hostname'}); #End argument processing #************************************************************* #Prompt for SNMP community string unless($option{'batch'}){ print "community: "; chomp($community = <STDIN>); } $oid_root = "1.3.6.1.2.1.2.2.1"; $seed_oid = ("$oid_root".".1"); unless($option{'csv'}){ foreach(@hostname){ undef @unique; $hostname=$_; #Open SNMP session ($session,$error) = Net::SNMP->session(Hostname => $hostname, Comm +unity => $community); die "$error\n" unless($session); get_oids($seed_oid); #Get the SNMP info for this target if($option{'verbose'}){ print "Port Speed Errors/Data In + Errors/Data Out Uptime \n"; print "--------------------------------------------------- +--------------------------------------------------------------------- +-----\n"; SNMP_Grocery_List(); } elsif($option{'log'}){ SNMP_Logging(); } elsif($option{'read'}){ Read_Log(); } else{ SNMP_Light(); } $session->close; } } if($option{'csv'}){ open(CSV,">$csvname")|| die "Can't open $csvname\n"; if($option{'verbose'}){ print CSV "Name,Speed,Errors_In,Data_in,Errors_out,Data_ou +t,Uptime,Switch_IP\n"; foreach(@hostname){ undef @unique; $hostname=$_; #Open SNMP session ($session,$error) = Net::SNMP->session(Hostname => $ho +stname, Community => $community); die "$error\n" unless($session); get_oids($seed_oid); #Get the SNMP info for this targe +t Make_CSV_Verbose(); } $session->close; } else{ print CSV "Switch_IP,Name,Total_Ports,Up,Down,Admin_Down\n"; foreach(@hostname){ undef @unique; $hostname=$_; #Open SNMP session ($session,$error) = Net::SNMP->session(Hostname => $ho +stname, Community => $community); die "$error\n" unless($session); get_oids($seed_oid); #Get the SNMP info for this targe +t Make_CSV(); $session->close; } } close(CSV) || die "Can't close $csvname\n"; } #Subs below here #********************************************************************* +****** #This sub is what walks through and enumerates an oid tree #********************************************************************* +****** sub get_oids{ my($starting_oid , $new_oid , $unique_oid , $result , $crap); $starting_oid = $_[0]; $new_oid = $starting_oid ; while(Net::SNMP::oid_context_match($starting_oid,$new_oid)){ $result = $session->get_next_request(($new_oid)); return unless (defined $result); ($new_oid , $crap) = %$result; if (Net::SNMP::oid_context_match($starting_oid,$new_oid)){ $unique_oid = $new_oid; $unique_oid =~ s/$starting_oid//g; push @unique , $unique_oid ; get_oids($new_oid); } } #This is the sub for -v option #********************************************************************* +****** sub SNMP_Grocery_List{ my($unique , $oper , $admin , $name , $uptime , $speed , $data +in , $dataout , $errorsin , $errorsout); my(%tally); %tally=( total => 0, up => 0, down => 0, admin => 0 ); foreach(@unique){ $unique = $_ ; $tally{'total'}++; $oper = (Get_SNMP_Info("$oid_root".".8"."$unique")); if($oper == 1){ $tally{'up'}++; $name = (Get_SNMP_Info("$ifMIB".".1"."$unique")); $uptime = (Get_SNMP_Info("$oid_root".".9"."$unique")); $speed = (Get_SNMP_Info("$ifMIB".".15"."$unique")); $datain = (Get_SNMP_Info("$oid_root".".10"."$unique")) +; $dataout = (Get_SNMP_Info("$oid_root".".16"."$unique") +); $errorsin = (Get_SNMP_Info("$oid_root".".14"."$unique" +)); $errorsout = (Get_SNMP_Info("$oid_root".".20"."$unique +")); $~="GROCERY"; write; } else { $tally{'down'}++; $admin = (Get_SNMP_Info("$oid_root".".7"."$unique")); if($admin == 2){ $tally{'admin'}++; } } } print "\nSummary: $hostname \n Total Ports: $tally{'total'} \n + Ports Up: $tally{'up'} \n Ports Down: $tally{'down'} \n Admin Down $ +tally{'admin'} \n"; format GROCERY = @<<<<<<<<<< @<<<<<< @>>>>>>>>>>>>>>>>>/@<<<<<<<<<<<<<<<<< @>>>>>>>>> +>>>>>>>>/@<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +<<<<<<< $name,$speed,$errorsin,$datain,$errorsout,$dataout,$uptime . } # Sub for -l option #********************************************************************* +****** sub SNMP_Logging{ my($unique , $oper , $dbm); my(%log); $dbm=("$logdir"."sc"."$hostname"); dbmopen(%log, $dbm, 0644); foreach(@unique){ $unique = $_ ; $oper = (Get_SNMP_Info("$oid_root".".8"."$unique")); if($oper == 1){ $log{$unique}++; } } dbmclose(%log); } #Sub for -r option #********************************************************************* +****** sub Read_Log{ my($dbm,$name,$uptime,$unique,$counter); my(%log); $dbm=("$logdir"."sc"."$hostname"); dbmopen(%log, $dbm, 0644); print "\n\n Switch Check Log for $hostname\n"; print "---------------------------------------------------\n"; while (($unique, $counter) = each(%log)) { $name = (Get_SNMP_Info("$ifMIB".".1"."$unique")); $uptime = (Get_SNMP_Info("$oid_root".".9"."$unique")); $~="READ_LOG"; write; } dbmclose(%log); format READ_LOG = @<<<<<<<<<<<<<< @<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +<<<<<<< $name,$counter,$uptime . } #sub for default operation #********************************************************************* +****** sub SNMP_Light{ my($unique , $oper , $admin); my(%tally); %tally=( total => 0, up => 0, down => 0, admin => 0 ); foreach(@unique){ $unique = $_ ; $tally{'total'}++; $oper = (Get_SNMP_Info("$oid_root".".8"."$unique")); if($oper == 1){ $tally{'up'}++; } else { $tally{'down'}++; $admin = (Get_SNMP_Info("$oid_root".".7"."$unique")); if($admin == 2){ $tally{'admin'}++; } } } print "\nSummary: $hostname \n Total Ports: $tally{'total'} \n + Ports Up: $tally{'up'} \n Ports Down: $tally{'down'} \n Admin Down $ +tally{'admin'} \n"; } #Sub that acually gets the value for a oid #********************************************************************* +****** sub Get_SNMP_Info{ #This sub gets the value of an oid my($crap , $value , $result); my($oid) = $_[0]; $result = $session->get_request("$oid"); return unless (defined $result); ($crap , $value) = %$result; return $value; } #sub for -c and -v #********************************************************************* +****** sub Make_CSV_Verbose{ my($unique , $oper , $admin , $name , $uptime , $speed , $data +in , $dataout , $errorsin , $errorsout); foreach(@unique){ $unique = $_ ; $oper = (Get_SNMP_Info("$oid_root".".8"."$unique")); $name = (Get_SNMP_Info("$ifMIB".".1"."$unique")); $uptime = (Get_SNMP_Info("$oid_root".".9"."$unique")); $speed = (Get_SNMP_Info("$ifMIB".".15"."$unique")); $datain = (Get_SNMP_Info("$oid_root".".10"."$unique")); $dataout = (Get_SNMP_Info("$oid_root".".16"."$unique")); $errorsin = (Get_SNMP_Info("$oid_root".".14"."$unique")); $errorsout = (Get_SNMP_Info("$oid_root".".20"."$unique")); print CSV "$name,$speed,$errorsin,$datain,$errorsout,$data +out,$uptime,$hostname\n"; } } #sub for -c #********************************************************************* +****** sub Make_CSV{ my($unique, $sysname , $oper , $admin); my(%tally); %tally=( total => 0, up => 0, down => 0, admin => 0 ); $sysname = (Get_SNMP_Info("1.3.6.1.2.1.1.5.0")); foreach(@unique){ $unique = $_ ; $tally{'total'}++; $oper = (Get_SNMP_Info("$oid_root".".8"."$unique")); if($oper == 1){ $tally{'up'}++; } else { $tally{'down'}++; $admin = (Get_SNMP_Info("$oid_root".".7"."$unique")); if($admin == 2){ $tally{'admin'}++; } } } print CSV "$hostname,$sysname,$tally{'total'},$tally{'up'},$ta +lly{'down'},$tally{'admin'}\n"; } #********************************************************************* +****** } =head1 Name switchcheck.pl =head1 Summary Usage: switchcheck.pl options ip { ip ip ... } Designed to get an overview or collect statisics on switchports usage + using SNMP. -b option allows you to specify community name on the command line to + allow being called in a cron job -l logs basic port usage stats to a dbm file -r is used to read files created by -l -v gives more detailed stats on ports that are up -c generates a csv file, can be used in conjunction with -v Some options are mutually exclusive. The later option takes precedenc +e. =head1 Tested with: Perl 5.6.1 RedHat 7.1 against: Cisco 6509,2924XL,3508XL,3512XL,3524XL,3548XL switches =head1 Author fingers =head1 Credits Thanks to ybic for answering dumb perl questions and appreciating poo +rly written code =head1 Caveats When looking at the port counts it is important to keep in mind that +vlans and other "interfaces" show up in this count. Look at the output from -v for each type of switch you are using to g +et an idea how many non-port interfaces each switch has. =head1 Todos Add in -i option to add a polling interval, to spread out the bandwi +dth impacts of running against remote equipment. Accept multiple RO strings for use in enviroments where switches may + have different community names. Add in VLAN and MAC information to the -v reports. So far I haven't +been able to identify the oids to use for these. Add in support to log to a real database instead of dbm. =head1 Updates 2001-07-19 Post to perlmonks =cut |
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: switchcheck.pl (Getopt, $_, nonport interfaces)
by ybiC (Prior) on Jul 24, 2001 at 06:01 UTC | |
Re: switchcheck.pl
by Anonymous Monk on Jun 18, 2002 at 19:44 UTC |
Back to
Code Catacombs