net-snmp is a Ruby object oriented wrapper around the C netsnmp libraries. It provides classes for sessions, pdus, varbinds, and more.
-
Supports SNMP versions 1, 2c, and 3
-
Supports both synchronous and asynchronous calls
-
Supports sending of snmpv1 traps and snmpv2 traps/informs using TrapSession
-
Integrates well with eventmachine, or can be used standalone.
-
In Ruby 1.9, uses fibers behind the scenes to emulate synchronous calls asynchronously
-
MIB support
-
Convenience methods such as session.walk, session.get_columns, and session.table
You must have the net-snmp libraries installed and available on the system. Check to make sure they are available in your library path. If necessary, add them to your shell like so:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/local/lib/net-snmp
You can use the library in two styles: synchronously or asynchronously. If you use the synchronous style, calls will block until a result is returned or the request times out. If you use the asynchronous style, you must provide a block to the client methods, which will be called when the data is ready.
In order for your callbacks to fire, you must call Net::SNMP::Dispatcher.poll You may pass a timeout argument to the dispatcher. If you pass false, the call will block forever until data is ready. If you pass an integer, it will block for <timeout> seconds. If you pass nil (the default), it will do a poll and return immediately. In that case, you will have to arrange for the dispatcher to run periodically. This can be done in your main event loop or in a seperate thread. There are convenience class methods in Net::SNMP::Dispatcher called run_loop, fiber_loop, em_loop, thread_loop and so on for setting up various polling loops. Or, you can roll your own loop.
If you like eventmachine, it’s very easy to set up the dispatcher to run periodically in the adaptor. If you’re using eventmachine with ruby 1.9, the library uses fibers behind the scenes to turn your synchronous calls into asynchronous calls, while allowing you to use a synchronous calling style. Examples of all these scenarios are below.
This library uses ruby-ffi to access the net-snmp libraries. If you want to use the C library directly, the wrapper functions are defined in Net::SNMP::Wrapper. You can call them like so:
Net::SNMP::Wrapper.snmp_perror("some_error")
You must call Session.close when you’re done with a session to avoid leaking memory
In the synchronous versions, all session methods raise Net::SNMP:Error on any error. Timeouts raise Net::SNMP::TimeoutError. In the asynchronous versions, the first argument to your callback will be the return status. Possible values include :success, :timeout, and :send_error. If you need the underlying net-snmp session errors, you can call session.errno, session.snmp_err, and session.error_message. PDU errors can be retreived with pdu.errstat, pdu.errindex giving the index of the offending varbind. See constants.rb for possible errors.
A simple synchronous SNMP-GET
session = Net::SNMP::Session.open(:peername => "test.net-snmp.org", :community => "demopublic" ) begin pdu = session.get("sysDescr.0") puts pdu.varbinds.first.value rescue Net::SNMP::Error => e puts e.message end session.close
An asynchronous SNMP-GET
session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |session| session.get(["sysDescr.0", "sysContact.0"]) do |status, pdu| if status == :success puts pdu.varbinds[0].value else puts "something went wrong. status is #{status}" end end end Net::SNMP::Dispatcher.select(false) #Setting timeout to false causes dispatcher to block until data is ready session.close
An SNMPv3 synchronous AuthPriv (encrypted) SNMP-GET
Net::SNMP::Session.open(:peername => "test.net-snmp.org",
:community => “demopublic”, :version => “3”, :security_level => Net::SNMP::Constants::SNMP_SEC_LEVEL_AUTHPRIV, :auth_protocol => :sha1, :priv_protocol => :des, :username => “myuser”, :auth_password => “mypassword”,
:priv_password => "myprivpasswd"
) {|session|
begin pdu = session.get("sysDescr.0") puts pdu.varbinds.first.value rescue Net::SNMP::Error => e puts e.message end
end
Running the dispatcher from eventmachine
EM.run do Net::SNMP::Dispatcher.em_loop session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |session| session.get("sysDescr.0") do |status, pdu| if status == :success puts pdu.varbinds[0].value else puts "something went wrong. status is #{status}" end end end EM.add_timer(2) do session.close EM.stop end end
Using synchronous style with eventmachine in ruby 1.9
EM.run do Net::SNMP::Dispatcher.fiber_loop Fiber.new { session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') begin pdu = session.get("sysDescr.0") puts pdu.varbinds[0].value rescue Net::SNMP::Error => e puts e.message end session.close EM.stop }.resume end
In the last example, note that you must wrap your code in Fiber.new {}.resume. You could instead use the em-synchrony gem, and wrap your loop with EM.synchrony{}. Note that even though it appears you are making a blocking call, waiting for a return value, actually in the background, control is passed back to the reactor fiber to process other requests. get() will return once the data is available. This is all seemless to you, the developer. Behold the power of fibers!
By default, net-snmp loads all of your system MIBS. You can add additional mibs by adding them to your MIBS environment variable. You can also explicitly add MIBs using the MIB api. For example:
Net::SNMP::MIB.add_mibdir("/usr/local/share/mibs") Net::SNMP::MIB.read_mib("RFC1213-MIB.txt")
Having the appropriate MIBs loaded will allow you to pass names instead of numeric oids to net-snmp methods. You can also pass Net::SNMP::OID objects. For example
oid = Net::SNMP::OID.new('sysDescr.0') # or Net::SNMP::OID.new("1.3.6.1.2.1.1.1.0") puts oid.to_s --> '1.3.6.1.2.1.1.1.0' puts oid.label --> 'sysDescr.0' pdu = session.get([oid])
For more complex MIB parsing needs, see smi-ffi
If you intent to use threads, you should set:
Net::SNMP.thread_safe = true
Thread support is experimental and may be dropped. Let me know if you’re using this feature.
THIS GEM COULD CRASH YOUR SYSTEM AND EAT YOUR CHILDREN!
You have been warned.
The API is subject to change.
This is very much alpha software. For more information on usage, take a look at the specs. Currently it’s only tested against net-snmp 5.5. The net-snmp api seems pretty stable, but if anything changes, it could break this gem. Please let me know if you find bugs or missing features. Or better yet, send a pull request.
-
Implement walk and get_table convenience methods.
-
SNMPv3 support needs testing for various security models
-
Better documentation
-
More tests
-
Fork the project.
-
Make your feature addition or bug fix.
-
Add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-
Send me a pull request. Bonus points for topic branches.
-
Bug reports including a failing rspec get priority treatment
== Copyright
Copyright © 2010 mixtli. See LICENSE for details.