Telnetting cisco routers/devices

Hi ruby telnet gurus,

I'm having difficulty telnetting properly cisco devices. I googled the net
and found http://nettelnetcisco.sourceforge.net/docs.html. But this is perl.
Any kind soul doing something like this in ruby and would love to share?

Thanks in advance -botp

Just a dumb question to begin with - what have you tried? Net::Telnet? Have you tried ruby's expect? (Had forgotten about this until I was flipping through pickaxe 2 today for something else).

J.

···

On 04/07/2005, at 1:45 PM, Peña, Botp wrote:

Hi ruby telnet gurus,

I'm having difficulty telnetting properly cisco devices. I googled the net
and found http://nettelnetcisco.sourceforge.net/docs.html\. But this is perl.
Any kind soul doing something like this in ruby and would love to share?

Thanks in advance -botp

Hi,

Here is what I did to access some information on a Cisco Access Point using telnet:

require 'net/telnet'

=begin rdoc
   This class consists of using a telnet connection to get some information
   from a Cisco Access Point.

   It has the ability to get some information about the STAs associations,
   some global statistics about the wireless interface of the AP, some
   statistics per QoS priority, and some statistics per STA.
=end
   class CiscoAP

     # The parameters of the AP about QoS: CWMin, CWMax, TXOP...
     attr_reader :qos_params

     # Create a new CiscoAP instance.
     def initialize(host, login, password)
       @host, @login, @password = host, login, password
       connect
       @qos_params = qos_information
     end

     # Close the connection to the telnet server.
     def close
       @connection.close
     end

     # Clear all the statistics.
     def clear_all_stats
       clear_global_stats
       clear_interface_stats
     end

     # Clear the global statistics about the Dot11Radio 0 interface.
     def clear_global_stats
       telnet_exec('clear dot11 statistics Dot11Radio 0')

       true
     end

     # Clear the interface statistics about the Dot11Radio 0 interface.
     def clear_interface_stats
       telnet_exec('clear interface Dot11Radio 0')

       true
     end

     # Get the global statistics about the Dot11Radio 0 interface.
     def global_stats
       telnet_exec('show interfaces Dot11Radio 0 statistics')
     end

=begin rdoc
     Get a Hash containing statistics for a particular STA knowing its MAC address.

     Output example:
       {
         :rts_retries => 0,
         :packets_in => 76274,
         :ip_address => "10.0.1.3",
         :packets_out => 157063,
         :state => "Assoc",
         :bytes_in => 24183047,
         :mac_address => "0040.96a6.802c",
         :supported_rates => [6.0, 9.0, 18.0, 24.0, 36.0],
         :bytes_out => 165501061,
         :data_retries => 7604,
         :signal_strength => -39,
         :current_rate => 36.0
       }
=end
     def information_about_sta(mac_address)
       result = telnet_exec(
         "show dot11 associations #{to_cisco_mac_address mac_address }")

       if result.size > 0
         output = Hash.new
         (md = result.match(/Address\s*:\s*(.{4}\..{4}\..{4})/)) &&
           (output[:mac_address] = md[1])
         (md = result.match(/IP Address\s*:\s*(\d+\.\d+\.\d+\.\d+)/)) &&
           (output[:ip_address] = md[1])
         (md = result.match(/State\s*:\s*(\w+)/)) && (output[:state] = md[1])
         (md = result.match(/Current Rate\s*:\s*(.*)?\s/)) &&
           (output[:current_rate] = md[1].to_f)
         (md = result.match(/Supported Rates\s*:\s*(.*)$/)) &&
           (output[:supported_rates] = md[1].split.collect { |elem| elem.to_f })
         (md = result.match(/Signal Strength\s*:\s*(-\d+)\s/)) &&
           (output[:signal_strength] = md[1].to_i)
         (md = result.match(/Packets Input\s*:\s*(\d+)\s/)) &&
           (output[:packets_in] = md[1].to_i)
         (md = result.match(/Packets Output\s*:\s*(\d+)\s/)) &&
           (output[:packets_out] = md[1].to_i)
         (md = result.match(/Bytes Input\s*:\s*(\d+)\s/)) &&
           (output[:bytes_in] = md[1].to_i)
         (md = result.match(/Bytes Output\s*:\s*(\d+)\s/)) &&
           (output[:bytes_out] = md[1].to_i)
         (md = result.match(/Data Retries\s*:\s*(\d+)\s/)) &&
           (output[:data_retries] = md[1].to_i)
         (md = result.match(/RTS Retries\s*:\s*(\d+)\s/)) &&
           (output[:rts_retries] = md[1].to_i)

         output
       end
     end

=begin rdoc
     Get QoS information about the AP: the values for CWmin, CWmax, AIFSn and TXOP.

     Output example:
       {
         :BACKGROUND => { :cwmin => 4,
                           :cwmax => 10,
                           :aifsn => 7,
                           :txop => 0 },
         :VIDEO => { :cwmin => 3,
                           :cwmax => 4,
                           :aifsn => 2,
                           :txop => 3008 },
         :BESTEFFORT => { :cwmin => 4,
                           :cwmax => 10,
                           :aifsn => 3,
                           :txop => 0 },
         :VOICE => { :cwmin => 2,
                           :cwmax => 3,
                           :aifsn => 2,
                           :txop => 1504 }
       }
=end
     def qos_information
       result = telnet_exec('show controllers | begin Configured Access Class Parameters')
       result = result.split("\n")[1..4].join("\n")

       if result.size > 0
         output = Hash.new
         result.each_line do |line|
           priority = line.match(/\s*(\w*)\s*:/)[1].upcase.to_sym
           output[priority] = {
             :cwmin => line.match(/cw-min\s+(\d+)/)[1].to_i,
             :cwmax => line.match(/cw-max\s+(\d+)/)[1].to_i,
             :aifsn => line.match(/fixed-slot\s+(\d+)/)[1].to_i,
             :txop => line.match(/txop\s+(\d+)/)[1].to_i
           }
         end
       end

       output
     end

     private

       # Connect to the telnet server.
       def connect
         @connection = Net::Telnet.new(
             "Host" => @host,
             "Timeout" => false,
             "Prompt" => /.*\#/
         ) #{ |str| print str }
         @connection.login({
           "Name" => @login,
           "Password" => @password,
           "LoginPrompt" => /Username:/
         }) #{ |str| print str }

         # Unset the terminal length.
         @connection.cmd('terminal length 0')
       end

       # Execute a set of telnet commands.
       def telnet_exec(commands)
         result = ''
         commands = [commands] if commands.class != Array

         # Execute each command.
         commands.each do |command|
           result += @connection.cmd(command)
         end

         # Clean the result a bit.
         result.gsub!(/^.*#/, '')
         commands.each do |command|
           result.gsub!(/#{command}/, '')
         end
         result.gsub!(/(\n)+/, "\n")
         result.gsub!(/\|\n/, '')
         result.strip!

         result
       end

       # Converts an ordinary MAC address to a Cisco MAC address.
       # XX:XX:XX:XX:XX:XX => XXXX.XXXX.XXXX
       def to_cisco_mac_address(mac_address)
         mac_address =~ /(\w\w):(\w\w):(\w\w):(\w\w):(\w\w):(\w\w)/
         "#$1#$2.#$3#$4.#$5#$6"
       end

   end

Hope that helps.

Regards,

Ghislain