http://www.perlmonks.org?node_id=1055745


in reply to Re^3: Telnet File Handle isn't open on login
in thread Telnet File Handle isn't open on login

here is the script I'm trying to get to work. The main operational part is the subroutine called 'GetConfig'

#!/opt/SPECTRUM/bin/perl -w # This script will capture the startup configuration of a # Cisco BG OS device and print it to STDOUT. # # Error Codes: # 0 = Success # 255 = Usage error # 254 = Invalid timeout value # 252 = Connection error # 251 = Login error # 249 = Enable error # 244 = Error retrieving configuration # 253 = Unexpected output # use strict; use warnings; use Net::Telnet; ### Main ### if( $#ARGV != 4 && $#ARGV != 5 ) { print "Usage: capture_startup.pl <device IP> <user> <pass> <enable +_pass> <login_timeout_in_seconds> <capture_timeout_in_seconds>\n"; print STDERR "Usage: capture_startup.pl <deviceIP> <user> <pass> +<enable_pass> <login_timeout_in_seconds> <capture_timeout_in_seconds> +\n"; exit 255; } elsif( $ARGV[4] < 1 || $ARGV[4] > 600 ) { print "$ARGV[4] is the login timeout and must be an int between 1 +and 600 seconds\n"; print STDERR "$ARGV[4] is the login timeout and must be an int bet +ween 1 and 600 seconds\n"; exit 254; } elsif( $#ARGV == 5 && ( $ARGV[5] < 1 || $ARGV[5] > 600 ) ) { print "$ARGV[5] is the capture timeout and must be an int between +1 and 600 seconds\n"; print STDERR "$ARGV[5] is the capture timeout and must be an int b +etween 1 and 600 seconds\n"; exit 254; } else { my $capture_timeout = $ARGV[4]; if( $ARGV[5] ) { $capture_timeout = $ARGV[5]; } my $errorCode = 1; my @data; my $errorString = "\nHost $ARGV[0]: \n"; ($errorCode,@data) = GetConfig( $ARGV[0], $ARGV[1], $ARGV[2], $ARG +V[3], $ARGV[4], $capture_timeout ); if( $errorCode == 0 ) { # Success. The startup configuration # content is in the data variable for( @data ) { print }; # print the configuration to STDOUT exit 0; } else { print STDERR $errorString; if( $errorCode == 253 ) { print STDERR join " ", @data, "\nEnable password may be in +valid\n"; } else { print STDERR join " ", @data, "\n"; } exit $errorCode; } } exit 0; sub GetConfig { my $deviceIP=shift; my $user=shift; my $pass=shift; my $epass=shift; my $login_timeout=shift; my $capture_timeout=shift; my @config; my $msg; my $telnet=new Net::Telnet(); # $telnet->output_log; $telnet->timeout($login_timeout); $telnet->errmode('return'); $telnet->prompt('/[\$#>]/'); $telnet->open( $deviceIP ); if( $telnet->errmsg ) { $msg = "Error connecting to device: ".$telnet->errmsg; $telnet->close; return( 252, $msg ); } #first try login without username and just password $telnet->waitfor( Match => '/Password:/'); if( $telnet->errmsg ) { $telnet->login($user, $pass); if( $telnet->errmsg ) { $msg = $telnet->errmsg; $telnet->close; return( 251, $msg ); } } else { $telnet->cmd( $pass ); if( $telnet->errmsg ) { # can't use errmsg as it will give command timed-out # and we should really indicate bad password $msg = "login failed: bad password"; $telnet->close; return( 251, $msg ); } } $telnet->timeout( $capture_timeout); $telnet->print( "enable" ); # check for auto enable after logging in $telnet->waitfor( Match => '/#/i' ); if( $telnet->errmsg ) { $telnet->waitfor( Match => '/Password: $/i'); if( $telnet->errmsg ) { # can't use errmsg as it will be pattern match timed-out $msg = "No password prompt after 'enable' command"; $telnet->close( ); return( 249, $msg ); } $telnet->cmd( $epass ); if( $telnet->errmsg ) { # can't use errmsg as it will give command timed-out # and we should really indicate bad password $msg = "Enable failed: bad password"; $telnet->close( ); return( 249, $msg ); } } # disabe paging # different commands for different devices, if they don't # work then we will get messages about problems later # specifically the "No prompt after 'sh start'" error # errmsg doesn't get set when these error and if we use print # and getlines to read for errors it causes problems with print "s +h start" # later. #$telnet->cmd("term pager 0"); $telnet->cmd("term length 0"); $telnet->print( "sh start" ); if( $telnet->errmsg ) { $msg = "Device did not accept 'sh start' command: ".$telnet-> +errmsg; $telnet->close( ); return( 244, $msg ); } while( my $line = $telnet->getline() ) { # get configuration content if( $line !~ /sh start|Building configuration|Current configuration|^\s +*$/ ) { push @config, $line; } } $telnet->waitfor(Match => '/[\$#>]/'); if( $telnet->errmsg ) { $msg = "No prompt after 'sh start': ".$telnet->errmsg; $telnet->close( ); return( 244, $msg ); } if( @config <= 0 ) { $msg = "No data retrieved, the capture timeout may be too low. +"; $telnet->close(); return( 244, $msg ); } if( scalar grep {$_ =~ /^%/} @_ ) { # Ensure show start actually returned the config and not an er +ror message containing '%' return( 253, @config); } return( 0, @config); # everything was okay, return the captured da +ta }

Replies are listed 'Best First'.
Re^5: Telnet File Handle isn't open on login
by jbev2328 (Novice) on Sep 25, 2013 at 20:38 UTC

    Once I figure out how to post screenshots I'll provide the information you requested. I reran my script directing STDOUT and STDERR to a file. This is what I saw in SDTERR.

    Host 172.16.47.27: eof read waiting for login prompt: username:

      The above error message IS in Net::Telnet so that makes sense. However, when I run your script against a Cisco router (assuming Cisco based on the commands in your script) it works fine.

      I ran it with Net::Telnet versions 3.03 and 3.04 and against a router with Password only and User/Password prompts. Each of the 4 iterations produced the startup config printed to my screen.

      If you are connecting to a Cisco device, have a look at Net::Telnet::Cisco as that does the "heavy lifting" for you (waitfor, prompts, etc.) and makes connecting and issuing commands much easier.

      In fact, for a script using N::T::C that works, have a look at:

      Script: http://www.vinsworld.com/software/crapps.zip
      Perldoc: http://www.vinsworld.com/software/crapps.html

        I believe this particular class of Cisco Wireless routers are pretty old. They get classified as "CiscoBG" by my monitoring system. I suspect that I'm getting back some unrecognizable character that's causing the problem. In any case I'll give your suggestion and try and let you know what happened. Thanks for your help