Forum: Ruby on Rails Custom Class Problem

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jason M. (Guest)
on 2007-02-11 17:31
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]

[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
[/code]

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:

[code]
#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
[/code]

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 :(

[b]Edit:[/b] 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?
Michael G. (Guest)
on 2007-02-12 06:54
(Received via mailing list)
Hi Jason,

On 2/11/07, Jason M. <removed_email_address@domain.invalid> 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 :(


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.

[b]Edit:[/b] I don't think I'm initialising the IPAddr object I want
> Posted via http://www.ruby-forum.com/.
>
> >
>


--
Michael G.
This topic is locked and can not be replied to.