Reputation: 199
I am experiencing some funny behaviour with telnet. Below is my code:
#!/usr/bin/env ruby
require 'net/telnet'
ipaddress = "182.201.120.218"
j = Net::Telnet::new("Host" => '127.0.0.1',
"Port" => 2605,
"Output_log" => "output.log",
"Dump_log" => "dump.log",
"Prompt" => /[#>]/ ,
"Telnetmode" => true,
"Timeout" => 10,
)
response = j.cmd("show ip bgp 182.201.120.218\n")
puts response
This is the output I get trying to run it a few times (dont worry no sensitive info there, all sanitized):
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au> show ip bgp 182.255.120.248
BGP routing table entry for 182.235.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
As you can see above, telnet refuses to run the command show ip bgp 182.201.120.218\n
even though the telnet session was established/connected. It finally succeeded in the 6th run but 7th failed etc. If I run it another random times it works again, only to fail. Manual telnet is always successful, aka :
[root@dummyserver]# telnet 127.0.0.1 2605
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
dummyserver.com.au>show ip bgp 182.255.120.248
BGP routing table entry for 182.255.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
dummyserver.com.au>
Output log shows the following:
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> show ip bgp 182.255.120.248
BGP routing table entry for 182.255.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
dummyserver.com.au>
dummyserver.com.au>
dummyserver.com.au>
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au>
I'm scratching my head trying to understand why telnet is behaving this way when normal telnet has got no issues.
Rvm version :
# rvm version rvm 1.29.10 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
Running on Redhat 7.8
If anyone have any idea or would like to provide more details, let me know. I'm stumped :( (If you are curious - I'm trying to query BGP route info from Quagga/zebra using telnet to run the commands with no credentials required. I could do this easily and with no issue with Perl, but we have to port the scripts to Ruby for internal reasons).
Upvotes: 1
Views: 109
Reputation: 199
OK, not sure if this is the best way, but I appear to have resolved it by the adding waitfor
. Complete code :
#!/usr/bin/env ruby
require 'net/telnet'
ipaddress = "182.255.120.248"
j = Net::Telnet::new("Host" => '127.0.0.1',
"Port" => 2605,
"Output_log" => "output.log", # default: nil (no output)
"Dump_log" => "dump.log", # default: nil (no output)
"Prompt" => /[$%#>] \z/n ,
"Telnetmode" => true, # default: true
"Timeout" => 10, # default: 10
)
j.waitfor(/[\>\# ]$/) {
response = j.cmd("show ip bgp 182.255.120.248")
puts response
}
Upvotes: 0
Reputation: 55778
With your :Prompt
specification, you tell the telnet client that the telnet prompt of the server is any line which contains a #
or >
character.
The telnet client reads all received output of the server until it has observed a line looking like a prompt. Now in your case, your first line of the show ip bgp
command output already contains a #
character, matching your prompt specification.
With that, you are now running into a race-condition. You will see some output if the server send more than the first line in the first TCP packet of its response, which results in the telnet client to read all of this sent output. If the server sends each line separately in one packet, the telnet client bails out quicker since it already sees the designated prompt.
To fix this, it might already be sufficient to specify a stricter :Prompt
, e.g. /[$%#>] \z/n
as shown in the example at https://github.com/ruby/net-telnet#usage
Upvotes: 2