Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
Hello,

I would like to connect from Windows XP to SSH2 server and from there establish a telnet connection to device. I would like to send a command to this device, wait expected prompt from the telnet session over SSH connection and read the result. So far best results have been with Net::SSH2. The problem is the telnet connection.

The problem is that after I issue 'telnet <IP Address>' command, I cannot read the data without breaking the command sending/reading. If I read the result once after telnet has been established, I get after that only the command that was sent. For example after sending the telnet command, I read the result to look for username prompt and send the username. After this I get only the username that was sent as a result, not the actual output. Seems like output and input are mixed after first read.

I can issue the commands over telnet session quite nicely if I do not read the results at all. But unfortunately, I need to parse the output and decide following actions based on collected data. This might be possible with several sequential sessions, but I am looking send command, wait expected data and read response type of solution on Windows machine. I am trying to compile this as executable with ActiveState tools and for this reason I don't think that Cygwin is an option.

Is there a way to do this on Windows machine? Is this somehow related to terminal settings that I should modify before establishing the telnet session? Newbie question, but I was not able to find the module where implementation of $channel->read() really is?

Thank You
#!/usr/bin/perl # Tested with ActiveState perl version 5.8.8 on Windows XP SP3. use strict; use warnings; use Net::SSH2; # Using version 0.28. use Data::Dumper; #Net::SSH2->debug(1); use constant NEWLINE => qq{\n}; my $g_ssh_server = '<10.10.10.10>'; # SSH server addresss my $g_username = '<username>'; my $g_password = '<password>'; my $g_prompt = '<ssh server prompt>'; my $g_telnet_cmd = 'telnet <10.10.10.10>'; # Command to telnet my $g_ssh = undef; my $g_channel = undef; # Connection opened with shell. SSH2Open(\$g_ssh, \$g_channel); # Separate commands are executed and read nicely. SSH2Send($g_ssh, $g_channel, "\n", $g_prompt); SSH2Send($g_ssh, $g_channel, 'ls -al', $g_prompt); SSH2Send($g_ssh, $g_channel, 'uname -a', $g_prompt); SSH2Send($g_ssh, $g_channel, 'ls -l', $g_prompt); # Starting telnet causes problems if command output is read SSH2Send($g_ssh, $g_channel, $g_telnet_cmd, '<expect username prom>'); SSH2Send($g_ssh, $g_channel, 'username', '<expect password prom>'); SSH2Send($g_ssh, $g_channel, 'passowrd', '<expect terminal prom>'); SSH2Send($g_ssh, $g_channel, 'ls -al', '<expect terminal prom>'); # Read to test commands without reading after each command. SSH2Read($g_ssh, $g_channel); sub SSH2Open{ my $ssh2 = shift; # OUT my $channel = shift; # OUT ${$ssh2} = Net::SSH2->new(); ${$ssh2}->connect($g_ssh_server) or die $!; ${$ssh2}->auth_password($g_username, $g_password) or die 'Auth. Fail +ed'; ${$channel} = ${$ssh2}->channel(); ${$channel}->pty('vt80'); # To get the prompt also. ${$channel}->shell(); return; } sub SSH2Send{ my $ssh = shift; # IN my $channel = shift; # IN - Created channel my $command = shift; # IN - Command to be sent my $waitfor = shift; # IN - String to be waited for. my $found = 0; my $string = q{}; my @result = (); print "===============================\n"; print "send command ($command)\n"; $channel->write(($command . NEWLINE)); if(0) { # Read response with method 1. This works randomly depending on # latency I quess. This may not read all of the data or last # command reads the data for every command. $string = q{}; while( <$channel> ) { $string = $string . $_; } } if(0) { # Read response with method 2. same as method 1. $string = q{}; my @result = readline($channel); $string = $string . join("\n", @result); } # Read response with method 3. Try polling until requested prompt # found. Based on http://search.cpan.org/~remi/Net-SSH2-Simple/. if(1) { my( $n, $buffer ); my @poll = ({handle => $channel, events => ['in', 'ext', 'err']}); $string = q{}; $channel->blocking(0); while(not $channel->eof and not $found) { $ssh->poll( 2000, [ @poll ] ); # 2 seconds print "poll" . Dumper \@poll; foreach my $poll ( @poll ) { foreach my $event ( qw( in ext ) ) { next unless $poll->{revents}{$event}; if($n = $channel->read( $buffer, 10_240, $event eq 'ext' )){ $string = $string . $buffer; #print "read string ($n) - $string\n"; } # Check if the requested data was read. $found = __test_waitfor($waitfor, $string); } } } } print "response: $string\n"; print "===============================\n"; return; } sub SSH2Read{ my $ssh = shift; # IN my $channel = shift; # IN my $string = q{}; if(0) { $string = q{}; while( <$channel> ) { $string = $string . $_; } print "string $string\n"; } return; } sub __test_waitfor{ my $waitfor = shift; # IN my $string = shift; # IN my $last_line = q{}; my $found = 0; # If user defined waitfor, it is checked from last line of the # string. Otherwise the string is just tested for couple of # characters. if( $waitfor ) { ($last_line) = $string =~ m/\n?(.*)\z/x; if( $last_line ) { print "last line ($last_line) wait ($waitfor)\n"; if( $last_line =~ m/$waitfor/ ) { $found = 1; } } } elsif( 5 < length $string ) { $found = 1; } return $found; }

In reply to Telnet over SSH2 from Windows by Hessu

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others perusing the Monastery: (7)
    As of 2015-07-07 03:13 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (86 votes), past polls