Hi guys, I'm writing a simple script that uses snmpget statements to check the errors received by ports on a router and have the results going to a file. I've never worked with Perl before but one of my coworkers had a really basic script that I've been trying to rework into something better suited to this and I have a few questions regarding it.

1. Is there a way to make the IP addresses and OID's dynamic? Could I do an snmpwalk or something similar until it didn't find an OID? The reason I'm asking is because we're going to need to put this script on many client's machines and want little to no configuration required.

2. As of now, if the snmpget command times out trying to reach a router, you have to wait ~10 seconds before it tries the next OID it's given. Is there a way to check if the host is available before? Or if the IP isn't available, read back in the output from the console window somehow and have a simple if/else statement to skip that router?


I think that's it for now. Here's a copy of the code that I have so far. Like I said, I've never worked with Perl, but it's what he had a simple script written in and I tried to port it to C++ but had LOTS of problems with snmp libraries and could never get them to link correctly. Any help would be appreciated.

#!perl -w
use strict;

open LOG, ">>C:/log.txt";
my $now = localtime time;
print LOG "----------------------------------\n";
print LOG "$now\n----------------------------------\n";
my $SNMP_Get_Cmd = "snmpget -v1 -c wdpfRO -Ovq";
my $IP_Target;
my $SNMP_OID = ".1.3.6.1.2.1.2.2.1.14.";
my $Switch_Port = 0;
my $row = 0;
my $col = 0;
my $noRows = 3;   # Number of Rows
my $noCols = 25;  # Number of Columns
my $temp;
my @Error_Count = ( #IP ADDRESS, PORT: 1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24 
                  ["192.168.3.1",     "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0"],
                  ["192.168.3.2",     "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0"],
                  ["192.168.3.17",    "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0"]
                  );
 
  # Retrieve Data From Switches
   for($row = 0; $row<$noRows; $row++)
   {
      $IP_Target = $Error_Count[$row][0];
      $temp = 'ping_check';
      chomp($temp);
      unless($temp=1)
	{$row++;}

 
      #If (output = "Timeout: No Response from " IP ".");
      #$row++;

      for($col = 1; $col<$noCols; $col++)
      {  # The column is the port number
         $temp = `${SNMP_Get_Cmd} ${IP_Target} ${SNMP_OID}${col}`;
         chomp($temp);
         $Error_Count[$row][$col] = $temp;
      }
   } 


   # Print A Table of all errors
      print LOG "\n\t\t${Error_Count[0][0]}\t${Error_Count[1][0]}\t${Error_Count[2][0]}\n";
      
      for($col = 1; $col<$noCols; $col++)
      {
         print LOG "Port ${col}: \t${Error_Count[0][$col]}\t\t${Error_Count[1][$col]}\t\t${Error_Count[2][$col]}\n";
      }
print LOG "____________________________________________________________________\n\n\n";
close LOG;

Also, this needs to be usable in both Windows and Solaris. I'm not familiar with Solaris, but would the open file command and such work with it?

Can you append to the beginning of a file too? Since this is going to be a diagnostic tool run like once a week, it would be better to have the newest dates at the top rather then the oldest.

I already downloaded a module that allows me to use the snmp functions, but it's just a matter of implementing them correctly that I have questions about. Unless you linked something completely different and I just missed the point. ><

OK, but the code you posted is not loading any modules so I thought you were trying to do it all by hand. As far as Windows/Solaris goes the open() command works on both. You can prepend to a file but it is much easier to append to a file. To prepend you can use perls inplace editor or open a new file and add the new data, then open the old file and add the old file data to the new file, then delete the old file and rename the new file to the old file.

I see what you mean about the modules now. What I had downloaded before was Net SNMP but not the module for perl so I now am running that and am starting to get general grasp on the code. I reworked it a little but I have one question.

#!perl -w
use strict;
use Net::SNMP;
use POSIX qw(strftime);


my $now = localtime time;
my $filename = (strftime "%Y%m%d", localtime(time)) . ".txt";     #yyyymmdd.txt 
open  LOG, ">>/SNMP Script Logs/$filename";                       #C:/SNMP Script Logs/Date.txt
print LOG "----------------------------------\n";
print LOG "$now\n----------------------------------\n";


my $OIDbase = '1.3.6.1.2.1.2.2.1.14.';
my $OID;
my $row = 0;
my $col = 0;
my $noRows = 3;   # Number of Rows
my $noCols = 25;  # Number of Columns
my $result;
my @Error_Count = ( #IP ADDRESS, PORT: 1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23  24 
                  ["192.168.3.1",     "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0"],
                  ["192.168.3.2",     "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0"],
                  ["192.168.3.17",    "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0"]
                  );

 

  # Retrieve Data From Switches
   for($row = 0; $row<$noRows; $row++)
   {
	my ($session, $error) = Net::SNMP->session
	(
    	  -hostname  => shift || $Error_Count[$row][0],
     	  -timeout   => shift || 5, 
    	  -version   => shift || 1
	);

	if (!defined($session))
   	{
    	  printf("ERROR: %s.\n", $error);
	  print LOG "ERROR: \n", $session->error, "\n";
   	}


      for($col = 1; $col<$noCols; $col++)
      {  # The column is the port number
	
	$OID = ${OIDbase} . ${col};
   	$result = $session->get_request(-varbindlist      => [$OID]);

	   if (!defined($result))                             
	   {
     	     printf("ERROR: %s.\n", $session->error);
	     print LOG "ERROR: \n", $session->error, "\n";
     	     $session->close;
             last;                                             #break out of loop
  	   }

         $Error_Count[$row][$col] = $result;

      }
	$session->close;
   } 


   # Print A Table of all errors
      print LOG "\n\t\t${Error_Count[0][0]}\t${Error_Count[1][0]}\t${Error_Count[2][0]}\n";
      
      for($col = 1; $col<$noCols; $col++)
      {
         print LOG "Port ${col}: \t${Error_Count[0][$col]}\t\t${Error_Count[1][$col]}\t\t${Error_Count[2][$col]}\n";
      }

print LOG "____________________________________________________________________\n\n\n";
close LOG;
exit 0;

How would I pull the IP Address from a router config file? I don't know the general layout of the files, but I will, I'm just asking now for a basic code to match a line in a file. For example, if the line starts with 'IP:'. Then how would I pull the information following the :? Can you do pattern matching in perl?

After reading on a website how to check if a line contains a word, I found

# Set the file path and name.
my $data_file = '/var/www/cgi-bin/mydata/data.txt';

   # Open the file for reading.
open DATA, "$data_file" or die "can't open $data_file $!";
my @array_of_data = <DATA>;
close (DATA);


# start foreach loop, and assign each line,
# one at a time to the variable $line.
foreach my $line (@array_of_data)
{
   # Start an if statement, the condition of which is
        # "If this particular line contains the word dangerous."
     if ($line =~ m/dangerous/i;)
        {
        # If the line contains "dangerous" then print the line out.
        print "This line contains the word dangerous: $line\n";
        } # End the if condition here.
} # End the foreach loop here.

In this example, how would I get the text following the word dangerous, since I would now know which line it lies on.

This article has been dead for over six months. Start a new discussion instead.