Custom Class Problem

I’m a novice Ruby programmer and I’ve come up against a problem which I
really have no idea as to how to fix. I’m making a small Ruby/RoR web
application to poll and display information from SNMP devices. The
problem I’m having is trying to poll an IP range for SNMP enabled
devices. I hacked together a small method to do this using the
SNMP Scanner gem/command line app as a basis
(http://snmpscan.rubyforge.org). I just modified it by throwing it into
a method and have
it return an array of “live” IP addresses.

In application.rb

class IPAddr

The broadcast method calculate the broadcast

address of the range (if any)

def broadcast
return @addr + (IPAddr::IN4MASK - @mask_addr)
end
# The each_address method iterates over each address
# of the ip range
def each_address
(@addr…broadcast).each do |addr|
yield _to_string(addr)
end
end
end
[/code]

#In network_controller.rb
  def poll(inc_ip)
    # Default Settings
    timeout = 200
    mib = "sysDescr.0"
    protocol = "2c"
    comunity = "public"
    verbose = false

    args = [timeout,mib,protocol,comunity]
    live = []

    iprange = IPAddr.new(inc_ip)
    threads = []

    iprange.each_address do |ip|
      begin
        threads << Thread.new(ip,args) do |ip,args|
          timeout,mib,protocol,comunity = args
          begin
            SNMP::Manager.open(:Host => ip,
                               :Community => comunity,
                               :Port => 161,
                               :Timeout => (timeout/1000.0)) do |man|
              res = man.get([mib])
              answer = res.varbind_list[0].value
              live << "#{ip}"
              print "#{ip}:\t#{answer}\n"
            end

          end
        end
      rescue
        next
      end
    end

    ThreadsWait.all_waits(threads)

    return live
  end

To test, I just an action to poll a range (10.1.1.1-10.1.1.254) and
flash the first result to me:

#In network_controller.rb
  def live_devices
    live = Array.new(poll("10.1.1.1/24"))
    flash[:notice] = live[0]
    redirect_to :action => 'list'
  end

This works fine and reveals the IP addresses of two SNMP devices on my
network just fine. However, if I try to poll 192.168.1.1/24, the
application hangs and seems to spawn hundreds of threads, most of which
never complete. In the command line window I can see it returning the
first and only SNMP device within that range, the router at 192.168.1.1.
My knowledge of CIDR notation is cursory but 192.168.1.1/24 should scan
between 192.168.1.1 and 192.168.1.254 unless I’m mistaken. I’m stumped
as to what the problem is. Either there’s a serious problem with the
threading somewhere or something else. Another thing I noted is that
using the SNMP scanner gem from the command line to scan a single IP
address works fine, but using the code above to scan single IP returns
nothing.

This is all very confusing :frowning:

Edit: I don’t think I’m initialising the IPAddr object I want
correctly as calling “iprange = IPTest.new(inc_ip)” after renaming the
IPAddr class in application.rb to IPTest throws an error. I think this
is where my problem lies.

I’ve moved the code from application.rb to iptest.rb in /lib and use
require ‘iptest’ in environment.rb but now calling the live_devices
action just yields a “wrong number of arguments (1 for 0)” error.
Perhaps it’s not loaded correctly?

Hi Jason,

On 2/11/07, Jason M. [email protected] wrote:

it return an array of “live” IP addresses.
# of the ip range
def poll(inc_ip)
iprange = IPAddr.new(inc_ip)
:Timeout => (timeout/1000.0)) do |man|
end

network just fine. However, if I try to poll 192.168.1.1/24, the

This is all very confusing :frowning:

You may have better luck with an answer on RubyTalk instead of RailsTalk
as
the focus here is on Rails and this is more of a generic Ruby problem.

Edit: I don’t think I’m initialising the IPAddr object I want

Posted via http://www.ruby-forum.com/.


Michael G.