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.