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
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.