Custom Class Problem

Hi Jason,

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](http://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:

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.