Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Telnet list of IP and get information stored to a file

by sanju7 (Acolyte)
on Jul 26, 2010 at 12:55 UTC ( [id://851364]=perlquestion: print w/replies, xml ) Need Help??

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

I have a list of ip addresses to telnet to a specific port and check about a specific application. If present it responds with a a line of output, no login is necessary. The list of IP i have is in this format below,

3.3.3.* 3.3.9.* 23.23.1.49

My code as below,

#! /usr/bin/perl -w # run telnet to port xx29 # read data use strict; use diagnostics; use Net::Telnet; my $file = 'iplist1.txt' ; #my $command = `/bin/ping` ; open (OUT,'>', "telnet.log"); open (IPS, '<', $file) or die('unable to open the file', $file ); while(<IPS>) { #ping($_) ; #print "$_ " ; my $telnet = Net::Telnet->new(Host=>"$_", Port=>'xx29', timeout=>4), e +rrmode=> (sub { open(OUT, ">>telnet.log"); print "Bad connection - Unable to connect to IP $_ at \r\n" ; print "-------------------\r\n"; next;})); } close OUT ; close IPS ;

I am getting error on this code as below

Use of uninitialized value $_ in concatenation (.) or string at run_te +lnet.pl line 22, <IPS> line 1 (#1) (W uninitialized) An undefined value was used as if it were alread +y defined. It was interpreted as a "" or a 0, but maybe it was a mi +stake. To suppress this warning assign a defined value to your variables. To help you figure out what was undefined, perl will try to tell y +ou the name of the variable (if any) that was undefined. In some cases it + cannot do this, so it also tells you what operation you used the undefine +d value in. Note, however, that perl optimizes your program and the opera +tion displayed in the warning may not necessarily appear literally in y +our program. For example, "that $foo" is usually optimized into "that + " . $foo, and the warning will refer to the concatenation (.) operat +or, even though there is no . in your program. Bad connection - Unable to connect to IP at ------------------- Exiting subroutine via next at run_telnet.pl line 24, <IPS> line 1 (#2 +) (W exiting) You are exiting a subroutine by unconventional means, +such as a goto, or a loop control statement. Use of uninitialized value $_ in concatenation (.) or string at run_te +lnet.pl line 22, <IPS> line 2 (#1) Bad connection - Unable to connect to IP at

The logic behind is to connect the IP address or the whole subnet (when its in xx.yy.zz.* ; asterisk in last quadrant) to a specific port, connect next if connection timeout or error, store the output to a file if connection successful, if not successful then move to next connection. I am yet to figure the code to connect complete subnet when asterisk, but the initial form is giving weird variable initialization error which i am not able to trace reason.Still looking at documentation of Net::Telnet. I am not very familiar with Net::Telnet and IP address and subnet iteration from a list, your opinion would be very useful to bring this code to action.

Replies are listed 'Best First'.
Re: Telnet list of IP and get information stored to a file
by afoken (Chancellor) on Jul 26, 2010 at 13:23 UTC

    Some problems I see without running the code:

    • You read from the IPS handle, but don't remove the line endings. Add a chomp as first command of the while loop.
    • 3.3.3.* is neither a valid IPv4 address nor a valid host name, thus Net::Telnet will never be able to connect. You need to expand * in your code.
    • The same applies to 3.3.9.*.
    • I don't see any method calls for the $telnet object (open, getline, close).
    • Confusing indent.
    • Missing error checks at least for open OUT
    • You are opening OUT more than once.
    • From the error messages, there seems to be a problem with your input file, but the error messages should not happen with the code you posted. Did you post the code that actually generated the error messages?

    Apart from that, I think that a simple nmap port scan should do the job, you don't need Perl for that.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      The list has some 300 IP address or network. It means so many thousands of IP address, I don't know how nmap would be useful here. The best logis i figured,

      (a) read the list

      (b) pick the ip address and process it

      (c) if ip address has asterisk(x.x.x.*) expand it to its all possible ip addresses (x.x.x.1/2/3..254) .

      (d) process it by script.

      (e) if telnet successful the app would throw its name etc .. record it on a file.

      (f) if fails go to next ip address.

      So the expansion is still a big deal here because 85% of the list is ip addresses like 3.3.3.* (yy.xxx.zz.*) format. I am thinking of Regex here.

      About error:

      Since my code woould fail to expand ip addresses which has last quadrant I tested the it with a IP list consisting of localhosts like below,

      127.0.0.1 127.0.0.1

      If you know any easier way to expand the list of IP which has asterisk at last quadrant to the whole network i can test that portion. And yes this code is the one that has generated the error, i haven't altered things except IP list etc.

        The list has some 300 IP address or network. It means so many thousands of IP address

        I wonder what reason one could have to try a port scan against such a large list. If you legally own (or use) that many systems, you should have a network management system making such strange scans unnecessary. I also wonder why you want to access machines owned by General Electrics (3.0.0.0/8) and the United States Department of Defense (22.0.0.0/8).

        I don't know how nmap would be useful here.

        Well, perhaps you should start reading the nmap documentation. nmap can be configured to scan entire net blocks. It can be configured to scan only one or a few selected ports. It can read a list of scan targets from a file. It can be configured to scan by establishing a TCP connection. It can scan in parallel. And it can be configured to do all this at once. And of course, nmap can write a report in various formats, like XML, HTML and plain text. nmap is the wheel you want to reinvent (and much more).

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Telnet list of IP and get information stored to a file
by morgon (Priest) on Jul 26, 2010 at 14:02 UTC
    What you get is a warning about an undefined $_.

    If you look closely you see that it complains about the errormode-sub.

    This is triggered because you fail to remove the newlines from the ips you read from the file (after <IPS> $_ contains not "1.2.3.4" but "1.2.3.4\n" - get rid of that with a chomp), so the ip you pass to Net::Telnet is not valid and so the errormode-sub is triggered.

    In this sub $_ is no longer the value you read from the file, probably because Net::Telnet localized $_.

    If you would use a lexical variable (rather than $_), e.g.

    while (my $ip = <IPS>) { chomp $ip; ...

    You could then refer to this $ip variable in your errmode-sub (which would then be a closure).

      Morgon:

      Your advice was good, it helped the code to run without error, that is good. Now since its running i can see the next issue --the successful output isn't going to "telnet.log" . I am still looking at the documentation to check what went wrong and where i need to change.

      Here is the changes i made

      #! /usr/bin/perl -w # run telnet to port xxx # read data use strict; use diagnostics; use Net::Telnet; my $file = 'iplist1.txt' ; #my $command = `/bin/ping` ; open (OUT,'>', "telnet.log"); open (IPS, '<', $file) or die('unable to open the file', $file ); while (my $ip = <IPS>) { chomp $ip; #ping($_) ; #print "$_ " ; my $telnet = Net::Telnet->new(Host=>"$ip", Port=>'xxx', timeout=>4, er +rmode=> (sub { open(OUT, ">>telnet.log"); print "Bad connection - Unable to connect to IP $ip at \r\n" ; print "-------------------\r\n"; next;})); } close OUT ; close IPS ;

        sanju7:

        To make the output go to the "telnet.log" file handle, you need to tell the print statement to use the file handle! For instance, change:

        print "Bad connection.\n";

        to

        print OUT "Bad connection.\n";

        ...roboticus

        A few more things:

        Use lexial filehandles, the 3 argument form of open and check for success, so rather than

        open(OUT, ">>telnet.log");
        Do it like this:

        open my $out, ">>", "telnet.log" or die $!;

        Then "$ip" is a useless interpolation - just use $ip.

        Your "next" in the error-sub is not needed.

        You open OUT both in the main-script as well as in the error-sub which won't hurt but does not achieve anything.
        Depending on what you want you could either open it once and re-use the filehandle for every error, or open it for every error. If you use lexial filehandles you can open it once in the main script and reference it in the error-sub (get rid of the open there and just do "print $out "Bad connection...".)

        On a more general note you should not hard-code filenames into your script as you loose a lot of flexibility (e.g. every time you run your script you overwrite the previous error-log - maybe you want to see how that changes over time).
        A better approach would be to pass in the input-filename on the commandline (using "iplist1.txt" as a default) and print the errors not to a file but to STDOUT.
        In this way the user of your script can decide where the error-log goes to (he could simply redirect the script-output to a file of his choosing).

        Lastly use better variable-names (e.g. $error_log rather than "OUT") - you'll be glad later.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2024-04-26 01:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found