README.rdoc
March 16, 2012 ยท View on GitHub
= net-snmp
== DESCRIPTION
net-snmp is a Ruby object oriented wrapper around the C netsnmp[http://www.net-snmp.org] libraries. It provides classes for sessions, pdus, varbinds, and more.
== FEATURES
- 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
== USAGE
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
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.
== FFI 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")
== NOTES You must call Session.close when you're done with a session to avoid leaking memory
== ERROR HANDLING 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.
== EXAMPLES
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[https://github.com/igrigorik/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!
== MIBs
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[http://github.com/mixtli/smi-ffi]
== EXPERIMENTAL THREAD SUPPORT 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.
== CAVEATS/DISCLAIMER
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.
== TODO
- Implement walk and get_table convenience methods.
- SNMPv3 support needs testing for various security models
- Better documentation
- More tests
== Note on Patches/Pull Requests
- 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 (c) 2010 mixtli. See LICENSE for details.