 \
\
ACME Network Infrastructure Switch Backup Report
\n
Date : $sdate
Server: $SERVER
This is an automated message concerning the status of the
automated switch configuration backups for all Nortel
Ethernet Switch 450/460/470/BPS/4548/5510/5520/5530 and Ethernet Routing Switches 8600 and 1600.\n
This message is being generated from the CentOS 5 Linux server running
the Perl Script switchtftpbackup.pl from /usr/local/etc.
 
We are now also backing up the Cisco Catalyst Switches from Riddle Hospital.
 
Procedures for recovering the switch configurations can be found at this location 
Perl Script last updated on $LASTUPDATEDDATE \n
 
The following is a list of the switches and their backup status. \n
 
EOF
return 1;
} #end sub start_html_report 
############################################################################
# Subroutine finish_html_report
#
# Purpose: use SNMP to instruct Passport 1600 switches to TFTP upload their
# configuration file to the central TFTP server
############################################################################
sub finish_html_report {
   print SENDMAIL < 
\\\\mdcvtech\\Infrastructure\\Documentation\\Restoring an Ethernet Switch Configuration.doc

\n

\n
EOF
   close(SENDMAIL);
   return 1;
} #end sub finish_html_report
############################################################################
# Subroutine hpgbe2_tftp_config
#
# Purpose: use SNMP to instruct HP GbE2 Switch Blades to TFTP upload their
# configuration file to the central TFTP server. This is specifically for
# the HP GbE2 (p-Class) interconnects. These SNMP MIB OIDs do not seem to 
# work for the HP GbE2c (c-Class) interconnects.
############################################################################
sub hpgbe2_tftp_config {
   # Local Variables
   my $setresult;
   &check_filename($filename);
   my $sess = new SNMP::Session (  DestHost  => $snmphost,
                                   Community => $community,
                                   Version   => SNMPVER );
   my $vars = new SNMP::VarList(
         ['agTftpServer', 0, "$TFTPSERVER",],
         ['agTftpCfgFileName', 0, "$filename",] );
   my $go = new SNMP::VarList(
         ['agTftpAction', 0, 4,] );
   # Set TFTP source and destination strings
   my $test = $sess->set($vars);
   # Start TFTP copy
   $test = $sess->set($go);
   # Pause while the TFTP copy completes
   sleep $PAUSE;
   # Check to see if the TFTP copy completed
   $test = $sess->get('agTftpLastActionStatus.0');
   # If TFTP failed output error message
   if ($test =~ /Success/) {
      print SENDMAIL "$snmphost ($sysObjectID) was successful
\n";
      print "DEBUG: $snmphost ($sysObjectID) was successful\n";
   } else {
      print "ERROR: $snmphost ($sysObjectID) config upload *FAILED*!\n";
      print SENDMAIL "ERROR:$snmphost ($sysObjectID) config upload *FAILED*!
\n";
   } #end if
   print "DEBUG: upload config file results = $test\n" if (DEBUG);
   return 0;
} # end sub hpgbe2_tftp_config
############################################################################
# Subroutine hpgbe2c_tftp_config
#
# Purpose: use SNMP to instruct HP GbE2 Switch Blades to TFTP upload their
# configuration file to the central TFTP server. This is specifically for
# the HP GbE2 (p-Class) interconnects. These SNMP MIB OIDs do not seem to
# work for the HP GbE2c (c-Class) interconnects.
############################################################################
sub hpgbe2c_tftp_config {
   # Local Variables
   my $setresult;
   &check_filename($filename);
   my $sess = new SNMP::Session (  DestHost  => $snmphost,
                                   Community => $community,
                                   Version   => SNMPVER );
   my $vars = new SNMP::VarList(
         ['agTransferServer', 0, "$TFTPSERVER",],
         ['agTransferCfgFileName', 0, "$filename",] );
   my $go = new SNMP::VarList(
         ['agTransferAction', 0, 4,] );
   # Set TFTP source and destination strings
   my $test = $sess->set($vars);
   # Start TFTP copy
   $test = $sess->set($go);
   # Pause while the TFTP copy completes
   sleep $PAUSE;
   # Check to see if the TFTP copy completed
   $test = $sess->get('agTransferLastActionStatus.0');
   # If TFTP failed output error message
   if ($test =~ /Success/) {
      print SENDMAIL "$snmphost ($sysObjectID) was successful
\n";
      print "DEBUG: $snmphost ($sysObjectID) was successful\n";
   } else {
      print "ERROR: $snmphost ($sysObjectID) config upload *FAILED*!\n";
      print SENDMAIL "ERROR:$snmphost ($sysObjectID) config upload *FAILED*!
\n";
   } #end if
   print "DEBUG: upload config file results = $test\n" if (DEBUG);
   return 0;
} # end sub hpgbe2_tftp_config
############################################################################
# Subroutine ws5100_config
#
# Purpose: copy system:running-config to TFTP server for backup purposes.
# This is for the WS5100 v3.x or RFS7000 v1.x or later Motorola (formerly 
# Symbol) Wireless LAN switches. This code will not work with the WS5000
# or WS5100 running 2.x software.
############################################################################
sub ws5100_config {
   # Local Variables
   my $setresult;
   &check_filename($filename);
   my $sess = new SNMP::Session (  DestHost  => $snmphost,
                                   Community => $community,
                                   Version   => SNMPVER );
   my $vars = new SNMP::VarList(
         ['wsInfraFileManageSrc', 0, "system:running-config",],
         ['wsInfraFileManageDest', 0, "tftp://$TFTPSERVER/$filename",] );
   my $go = new SNMP::VarList(
         ['wsInfraFileManageStart', 0, 1,] );
   # Set TFTP source and destination strings
   my $test = $sess->set($vars);
   # Start TFTP copy
   $test = $sess->set($go);
   # Pause while the TFTP copy completes
   sleep $PAUSE;
   # Check to see if the TFTP copy completed
   $test = $sess->get('wsInfraFileManageStatus.0');
   # If TFTP failed output error message
   if ($test =~ /success/) {
      print SENDMAIL "$snmphost ($sysObjectID) was successful
\n";
      print "DEBUG: $snmphost ($sysObjectID) was successful\n";
   } else {
      print "ERROR: $snmphost ($sysObjectID) config upload *FAILED*!\n";
      print SENDMAIL "ERROR:$snmphost ($sysObjectID) config upload *FAILED*!
\n";
   } #end if
   print "DEBUG: upload config file results = $test\n" if (DEBUG);
   return 0;
} #end sub ws5100_config
############################################################################
# Subroutine cisco_tftp_config
#
# Purpose: use SNMP to instruct Cisco switches to TFTP upload their running
# configuration to the central TFTP server. These SNMP OIDs do not appear
# to work with the Cisco Nexus 7010 or 5010 switches.
#
# snmpset -v1 -c$COMMUNITY $HOST ccCopyProtocol.101 i 1
# snmpset -v1 -c$COMMUNITY $HOST ccCopySourceFileType.101 i 4
# snmpset -v1 -c$COMMUNITY $HOST ccCopyDestFileType.101 i 1
# snmpset -v1 -c$COMMUNITY $HOST ccCopyServerAddress.101 a "10.103.24.250"
# snmpset -v1 -c$COMMUNITY $HOST ccCopyFileName.101 s "sw-train1-2900-24-rmh.cfg"
# snmpset -v1 -c$COMMUNITY $HOST ccCopyEntryRowStatus.101 i 1
# sleep 5
# snmpget -v1 -c$COMMUNITY $HOST ccCopyState.101
# snmpset -v1 -c$COMMUNITY $HOST ccCopyEntryRowStatus.101 i 6
#
############################################################################
sub cisco_tftp_config {
   # Local Variables
   my $test;
   my $go;
   my $copyresult;
   &check_filename($filename);
   my $snmpsession = rand(100);
   my $sess = new SNMP::Session (       DestHost  => $snmphost,
                                        Community => $community,
                                        Version   => SNMPVER );
   my $vars = new SNMP::VarList(
       ['ccCopyProtocol', 101, 1,],
       ['ccCopySourceFileType', 101, 4,],
       ['ccCopyDestFileType', 101, 1,],
       ['ccCopyServerAddress', 101, "$TFTPSERVER",],
       ['ccCopyFileName', 101, $filename,]
    );
#       ['ccCopyEntryRowStatus', 101, 1,] 
#   );
   my $go  = new SNMP::VarList(
       ['ccCopyEntryRowStatus', 101, 1,] );
   my $vars1 = new SNMP::VarList(
       ['ccCopyEntryRowStatus', 101, 6,] );
   # Set TFTP source and destination strings
   print "DEBUG: $snmphost about to set SNMP values\n" if (DEBUG);
   my $test = $sess->set($vars);
   if ( $sess->{ErrorStr} ) {
      print "DEBUG: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   # Start TFTP copy
   $test = $sess->set($go);
   if ( $sess->{ErrorStr} ) {
      print "DEBUG: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   # Check to see if the TFTP copy completed
   print "DEBUG: $snmphost checking ccCopyState before pausing\n" if (DEBUG);
   $copyresult = $sess->get('ccCopyState.101');
   if ( $sess->{ErrorStr} ) {
      print "DEBUG: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   print "DEBUG: ccCopyState = $copyresult \n" if (DEBUG);
   # Pause while the TFTP copy completes
   print "DEBUG: Sleeping 3 seconds while TFTP backup occurs... \n" if (DEBUG);
   sleep $PAUSE;
   # Check to see if the TFTP copy completed
   print "DEBUG: $snmphost checking ccCopyState after pausing\n" if (DEBUG);
   $copyresult = $sess->get('ccCopyState.101');
   if ( $sess->{ErrorStr} ) {
      print "DEBUG: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   print "DEBUG: ccCopyState = $copyresult \n" if (DEBUG);
   # If TFTP failed output error message
   if ($copyresult ne "successful") {
        while ($copyresult eq "running") {
           print "DEBUG: config upload status = $copyresult (waiting)\n" if (DEBUG);
           sleep $PAUSE;
           $copyresult = $sess->get('ccCopyState.101');
           print "DEBUG: ccCopyState = $copyresult \n" if (DEBUG);
        }
   };
   if (($copyresult ne "successful") & ($copyresult ne "other"))  {
      print "DEBUG: result <> complete and <> other = $copyresult \n" if (DEBUG);
      print "ERROR: $snmphost ($sysObjectID) config upload *FAILED*!\n";
      print SENDMAIL "ERROR:$snmphost ($sysObjectID) config upload *FAILED*!
\n";
   } elsif ($copyresult eq "successful") {
      print SENDMAIL "$snmphost ($sysObjectID) was successful
\n";
      print "$snmphost ($sysObjectID) was successful\n";
   }
   # Clean up the SNMP session
   print "DEBUG: $snmphost destroying SNMP session\n" if (DEBUG);
   $test = $sess->set($vars1);
   if ( $sess->{ErrorStr} ) {
      print "DEBUG: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   print "DEBUG: upload config file results = $copyresult\n" if (DEBUG);
   return 1;
} #end sub cisco_tftp_config
############################################################################
# Subroutine baystack_tftp_config_ascii
#
# Purpose: use SNMP to instruct BayStack switches to TFTP upload their
# ASCII configuration file to the central TFTP server
############################################################################
sub baystack_tftp_config_ascii {
#s5AgSysTftpServerAddress 
#s5AgSysAsciiConfigFilename 
#s5AgSysAsciiConfigManualUpload (NOT IN THE MIBS) USE 1.3.6.1.4.1.45.1.6.4.4.19.0
# snmpset -v2c -cpublic 10.101.255.254 1.3.6.1.4.1.45.1.6.4.4.19.0 i 4
#
# Updated December 23, 2010 - SNMP OID NOW IN MIBS DOES NOT WORK FOR 4500
# s5AgSysAsciiConfigManualUpload OBJECT-TYPE
#        SYNTAX     INTEGER {
#                      passed(1),
#                      inProgress(2),
#                      failed(3),
#                      uploadNow(4),
#                      uploadToUsb(5)
#                   }
   # Declare Local Variables
   my $setresult;
   $filename = &tftp_filename($snmphost);
   &check_filename($filename);
   print "DEBUG: ASCII config upload subroutine starting **********\n" if (DEBUG); 
   
   my $sess = new SNMP::Session (  DestHost  => $snmphost,
                                   Community => $community,
                                   Version   => SNMPVER );
   my $vars = new SNMP::VarList(
                        ['s5AgSysTftpServerAddress', 0, "$TFTPSERVER",],
                        ['s5AgSysAsciiConfigFilename', 0, $filename,] );
   my $go = new SNMP::VarList(
                        ['.1.3.6.1.4.1.45.1.6.4.4.19', 0, 4, 'INTEGER'] );
   # Set TFTP source and destination strings
   $setresult = $sess->set($vars);
   if ( $sess->{ErrorStr} ) {
      print "ERROR: {BayStack} problem setting the TFTP parameters (TFTP IP, FILENAME) for $snmphost\n";
      print "ERROR: {BayStack} sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   # Start TFTP copy
   $setresult = $sess->set($go);
   if ( $sess->{ErrorStr} ) {
      print "ERROR: {BayStack} problem setting the TFTP action bit for $snmphost\n";
      print "ERROR: {BayStack} sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   # Pause while the TFTP copy completes
   sleep $PAUSE;
   # Check to see if the TFTP copy completed
   # s5AgSysAsciiConfigManualUpload.0  = .1.3.6.1.4.1.45.1.6.4.4.19.0 
   $setresult = $sess->get('s5AgSysAsciiConfigManualUpload.0');
   if ( $sess->{ErrorStr} ) {
      print "ERROR: problem checking the TFTP result for $snmphost\n";
      print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }
   # If TFTP failed output error message
   if ($setresult ne "passed") {				# passed(1)
        while ($setresult eq "inProgress") { 			# inProgress(2)
           print "DEBUG: config upload status = $setresult (waiting)\n" if (DEBUG);
           sleep $PAUSE;
           $setresult = $sess->get('s5AgSysAsciiConfigManualUpload.0');
        } #end while
   } #end if $test ne "success"
   # If the upload command failed let's try again
   if ($setresult eq "failed") {				# failed(3)
      print "DEBUG: initial command returned $setresult\n" if (DEBUG);
      print "DEBUG: lets try the upload command again\n" if (DEBUG);
      # Let's pause here for a few seconds since the previous command failed
      sleep $PAUSE;
      # Start TFTP copy
      $setresult = $sess->set($go);
      if ( $sess->{ErrorStr} ) {
         print "ERROR: problem setting the TFTP action bit for $snmphost\n";
         print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
      }
      # Pause while the TFTP copy completes
      sleep $PAUSE;
      # Check to see if the TFTP copy completed
      $setresult = $sess->get('s5AgSysAsciiConfigManualUpload.0');
         if ( $sess->{ErrorStr} ) {
            print "ERROR: problem checking the TFTP result for $snmphost\n";
            print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
      }
      # If TFTP failed output error message
      if ($setresult ne "passed") {				# passed(1)
         while ($setresult eq "inProgress") {			# inProgress(2)
            print "DEBUG: config upload status = $setresult (waiting)\n" if (DEBUG);
            sleep $PAUSE;
            $setresult = $sess->get('s5AgSysAsciiConfigManualUpload.0');
         } #end while
      } #end if
   } #end if
   if ($setresult eq "failed") {				# failed(3)
      print "DEBUG: $snmphost setresult = $setresult\n";
      print "DEBUG: $snmphost config upload *FAILED*!\n";
      print SENDMAIL "ERROR:$snmphost ($sysObjectID) config (ASCII) upload *FAILED*!
\n";
   } elsif ($setresult eq "passed") {				# passed(1)
      print SENDMAIL "$snmphost ($sysObjectID) was successful (ASCII)
\n";
      print "DEBUG: $snmphost ($sysObjectID) was successful (ASCII)\n";
   } else {
      print "DEBUG: unknown error return = $setresult (ASCII)" if (DEBUG);
   } #end if
   print "DEBUG: upload config file results = $setresult (ASCII)\n" if (DEBUG);
   return 1;
} #end sub baystack_tftp_config_ascii
############################################################################
# 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 $packet = Net::Ping->new('icmp');
   # Loop across all the assets/devices
   foreach $snmphost (@devices) {
      # Remove CR/LF
      $snmphost =~ s/\n//g;
      # Let's ping the asset/device to make sure it responds else remove
      # it from processing so it doesn't slow down the script.
      # FUTURE - add additional code to report error to user via email.
      if (!($packet->ping($snmphost))) {
         print "DEBUG: host $snmphost fails to respond to ICMP ping\n" if (DEBUG);
         next;
      } #end if
      # Let's add it to the list of assets/devices
      push(@list, $snmphost);
      #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);
      #      next;
      #   } #end if
      #} #end foreach
   } #end foreach
   @devices = @list;
   return 1;
} # end sub load_switches
############################################################################