Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Reading IP from a file and SNMP

by theroninwins (Friar)
on Aug 26, 2004 at 13:40 UTC ( #386016=perlquestion: print w/replies, xml ) Need Help??

theroninwins has asked for the wisdom of the Perl Monks concerning the following question:

I have the little Problem that i am new to perl. (my 2nd day) I need to checkout a bunch of infos from an IP and a MIB node (e.g. .1.3.6.1.47.1.1.1.1). I have to read the IP from a file. I have no idea how to read it out and more then that how to get the SNMP to work. Any Idea how to do this??

Corion: Unconsidered title change. Was at Keep/Edit/Delete: 6/38/0

Replies are listed 'Best First'.
Re: Reading IP from a file and SNMP
by gellyfish (Monsignor) on Aug 26, 2004 at 14:19 UTC

    Probably the simplest module to work with for getting at arbitrary MIBs is Net::SNMP - the following example (hacked from the code in my Net::SNMP::Interfaces ) walks the ifTable for hosts who's IP are specified in the file ipfile.txt (one per line) and and prints the description of the interface:

    use Net::SNMP; use strict; use warnings; + open IPFILE, "ipfile.txt" or die "Can't get IPs - $!\n"; + my $community = 'public'; my $ifIndex = '1.3.6.1.2.1.2.2.1.1'; my $ifDescr = '1.3.6.1.2.1.2.2.1.2'; + while ( my $ip = <IPFILE> ) { chomp $ip; + my ( $session, $error ) = Net::SNMP->session( -hostname => $ip, -community => $community, -port => 161 ); my $response; + if ( defined( $response = $session->get_table($ifIndex) ) ) { foreach my $index ( values %{$response} ) { my $this_desc = "$ifDescr.$index"; my $description; if ( defined( $description = $session->get_request($this_d +esc) ) ) { print values %{$description}, "\n"; } } + } + $session->close(); }

    Hope that helps

    /J\

      WOW thanks fpr all your comments. They really helped. I got the thing more or less because it has to do a lot more (redirect the output and filter it then rerun the prog with the new knot and so on because i need the Name of the Devive e.g Power Device and the coresponding serial no.) but i guess i figure that out myself. but here is the bigger problem: I can get all the results i want correctly as long as they are numeric, but if the answer is e.g SNI05638854 or 1300 watt supply AC i get this:

      Argument "SNI05638854" isn't numeric in numeric le (<=) at C:/Perl/lib/Net/SNMP/Message.pm line 998, <IPFILE> line 1 (#1) (W numeric) The indicated string was fed as an argument to an operator that expected a numeric value instead. If you're fortunate the message will identify which operator was so unfortunate.

      the IP file has only an IP in it. I based my prog on the one by gellyfish. (Tanks for that one). Any idea why this message comes?? I really must say i start to like perl but as i said before i am very new to it :-)

        I think your problem is either that you are misinterpreting your MIB and trying to use one of your returned values as part of an OID or your MIB is really strange - it would probably be useful for you to look at the output of 'snmpwalk' for the top level OID you are looking at (I'm not sure what the tools for this on windows are like however) - there is not much we can do from here because you are using a proprietary MIB.

        /J\

Re: Reading IP from a file and SNMP
by tachyon (Chancellor) on Aug 26, 2004 at 14:06 UTC

    Welcome, here is a hint. The more effort it appears you have put in the more help you will get. Now here is a short snippet to read a file in the hope you might develop good habits right from the get up and go.

    #!/usr/bin/perl use strict; use warnings; use diagnostics; # this will help you understand the error messages b +etter. my $file = "C:/path/to/some/file.txt"; open FILE, "<$file" or die "Can't read $file perl says error is $!\n"; while( my $line = <FILE> ) { chomp $line; print "Got: $line\n"; } close FILE;

    You may need to read up on split to split the line into bits. Then you would want to RTFM of Net::SNMP. A Guide to Installing Modules will help you install it, and a bit of reading will see you up and running in no time.

    cheers

    tachyon

Re: Reading IP from a file and SNMP
by dragonchild (Archbishop) on Aug 26, 2004 at 13:43 UTC
    You're going to want to use the various SNMP modules from CPAN. I'm not extremely familiar with them, but that's where we go to find modules to do what we don't want to have to figure out cause someone else already did. :-)

    Oh, and welcome aboard!

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      Well I like to run SNMP over tcp so i do this:
      sub get_my_oid { my ($host, $oid, undef) = @_; my $data = ''; my @errors = (); my $options = " -l authPriv -u $User -X $Pass". " -A $Pass -v 3 ". " -t $Timeout -r $Retries -Ouvq "; my $result = `snmpwalk $options TCP:${host} $oid`; if(defined $result && (($? >> 8) == 0)) { my @lines = split "\n", $result; foreach my $oid_line (@lines) { $oid_line = substr $oid_line, 1; #front quote chop $oid_line; #ending quote #unescape all of my quotes. \" => " $oid_line =~ s/\\\"/\"/og; #it is a part of our data. $data .= $oid_line; } } else { push @errors, "Error with the snmp walk command: $!\n"; return (undef, \@errors); } return ($data, undef); }

      Note that I actually use this code and it does work. BUT! Use at your own risk.

      --habit
      Try starting off with module Net::SNMP, to get single values from a remote IP, probably the method $session->get_request is your best bet.. it's pretty well documented in perldoc Net::SNMP.. However you probably have to put your community in the file.. if this is undesirable, you could use module Term::ReadKey to allow "safe" reading of the password from the command line..

      As far as getting the IP addresses out of a file, if they are listed one IP Address per line with nothing else included in the file itself: just read the file, put the contents in an array, then loop your SNMP get operations for each item in the array roughly something like:
      open IPFILE,'<',"/tmp/ipfile.txt"; my @ip_list = <IPFILE>; close IPFILE; foreach my $ip_in_list ( @ip_list ) { ... ($session, $error) = Net::SNMP->session( -hostname => $ip_in_list, ... => ..., .. all other options ...; ); $newval = $session->get_request( [-callback => sub {},] [-delay => $seconds,] [-contextengineid => $engine_id,] [-contextname => $name,] -varbindlist => \@oids, ); # now do something with the data found in $newval # use -callback to point to a subroutine where you put further operati +ons to be carried out on $newval }
      The above is more or less straight from the doc, and your situation is probably more complicated than that, but maybe this helps get started?

      There is still the question of the reading of the IPs in the file?? Thanks for wellcoming me and for the help already... I got some interseting piece of code :-) just got to understand it now.
        I highly suggest getting copies of Learning Perl, Programming Perl, and The Perl Cookbook.

        To get you started, you can read files like this:

        open FH, '<', $filename or die ("Can't open $filename"); #FH is a "filehandle", and the '<' means "open in read mode" #('>' would be write) while (<FH>) { #the angles around FH mean "read a line" work_with_the_line($_); # $_ holds the current line in this case # work_with_the_line would be a subroutine defined by you } close FH; #don't forget to close files!
        Much perl code is out there "in the wild", I highly suggest searching to see if someone has solved a similar problem, then reading and learning from their source.
        --
        $me = rand($hacker{perl});
        Well it depends on how they are stored in the file. If there is only one IP per line, this code will do:
        my @ip_array = (); if(open(F_IP,"<$filename")) { my %ip_hash = (); foreach my $ip (<F_IP>) { chomp($ip); #No duplicates! $ip_hash{$ip} = 1; } close(F_IP); @ip_array = keys(%ip_hash); } else { die "AHHHHH! Error Error go away!!"; } #Just keep doing your thing man...


        Note that I wrote this on the fly and have not tested it. It should give you a good start though. =)

        --habit
Re: Reading IP from a file and SNMP
by Anonymous Monk on Jan 07, 2005 at 14:59 UTC
    I have to do almost the same task, polling a single OID from a bunch of devices. I don't use net::snmp, but the snmpget from net-snmp. My problem is, that I have to poll aprox 8000 (8k) devices and each poll is aprox 1 sec => 8000 seconds. Do you think net::snmp module will increase the speed( I doubt). My next take will be forking and multithreading and here I need some help, please. Thanks in advance!
      yes, but use the SNMP module that comes with net-snmp. you can use the async interface to send out requests to multiple devices without waiting for each one to complete before sending out the next. i can get the sysDescr string from 1072 devices in around 20 seconds or so.
        That's good news! Could you be more specific or just show me some lines of code. I was reading the docs of net-snmp and tehre was only an exapmle of C async poll. Thanks!
      If you still need help I can send you the final prog as I use it
        It will be great ! Thanks! ibatch@gmail.com

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://386016]
Approved by been42
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (2)
As of 2022-05-21 07:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (76 votes). Check out past polls.

    Notices?