net-snmp 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -15,28 +15,28 @@ It provides classes for sessions, pdus, varbinds, and more.
15
15
 
16
16
  == USAGE
17
17
 
18
- You must have the net-snmp libraries installed and available on the system. Check to make sure
18
+ You must have the net-snmp libraries installed and available on the system. Check to make sure
19
19
  they are available in your library path. If necessary, add them to your shell like so:
20
20
 
21
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/local/lib/net-snmp
21
+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/local/lib/net-snmp
22
22
 
23
23
 
24
- You can use the library in two styles: synchronously or asynchronously. If you use the synchronous style,
24
+ You can use the library in two styles: synchronously or asynchronously. If you use the synchronous style,
25
25
  calls will block until a result is returned or the request times out. If you use the asynchronous style, you
26
26
  must provide a block to the client methods, which will be called when the data is ready.
27
27
 
28
- In order for your callbacks to fire, you must call Net::SNMP.dispatcher. You may pass a timeout argument to
28
+ In order for your callbacks to fire, you must call Net::SNMP.dispatcher. You may pass a timeout argument to
29
29
  the dispatcher. If you pass false, the call will block forever until data is ready. If you pass an integer, it will block for
30
30
  <timeout> seconds. If you pass nil (the default), it will do a poll and return immediately. In that case, you
31
31
  will have to arrange for the dispatcher to run periodically. This can be done in your main event loop or in a
32
32
  seperate thread.
33
33
 
34
- If you like eventmachine, it's very easy to set up the dispatcher to run periodically in the adaptor. If you're
34
+ If you like eventmachine, it's very easy to set up the dispatcher to run periodically in the adaptor. If you're
35
35
  using eventmachine with ruby 1.9, the library uses fibers behind the scenes to turn your synchronous calls into asynchronous
36
36
  calls, while allowing you to use a synchronous calling style. Examples of all these scenarios are below.
37
37
 
38
38
  == FFI
39
- This library uses ruby-ffi to access the net-snmp libraries. If you want to use the C library directly, the wrapper
39
+ This library uses ruby-ffi to access the net-snmp libraries. If you want to use the C library directly, the wrapper
40
40
  functions are defined in Net::SNMP::Wrapper. You can call them like so:
41
41
  Net::SNMP::Wrapper.snmp_perror("some_error")
42
42
 
@@ -111,6 +111,18 @@ background, control is passed back to the reactor fiber to process other request
111
111
  data is available. This is all seemless to you, the developer. Behold the power of fibers!
112
112
 
113
113
 
114
+ == MIBs
115
+
116
+ By default, net-snmp loads all of your system MIBS. You can add additional mibs by adding them to your MIBS environment variable.
117
+ You can also explicitly add MIBs using the MIB api. For example:
118
+
119
+ Net::SNMP::MIB.add_mibdir("/usr/local/share/mibs")
120
+ Net::SNMP::MIB.read_mib("RFC1213-MIB.txt")
121
+
122
+ Having the appropriate MIBs loaded will allow you to pass names instead of numeric oids to net-snmp methods. To translate a single oid,
123
+ you can call Net::SNMP.get_oid("sysDescr.0"). For more complex MIB parsing needs, see smi-ffi[http://github.com/mixtli/smi-ffi]
124
+
125
+
114
126
  == CAVEATS/DISCLAIMER
115
127
 
116
128
  THIS GEM COULD CRASH YOUR SYSTEM AND EAT YOUR CHILDREN!
@@ -129,7 +141,7 @@ break this gem. Please let me know if you find bugs or missing features. Or be
129
141
  * Better documentation
130
142
  * More tests
131
143
  * Cleanup cruft and unused code
132
-
144
+ * Implement SNMP traps/informs?
133
145
 
134
146
  == Note on Patches/Pull Requests
135
147
 
data/lib/net-snmp.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'forwardable'
2
2
  require 'nice-ffi'
3
3
  require 'fiber'
4
- %w(snmp snmp/constants snmp/oid snmp/error snmp/pdu snmp/wrapper snmp/session snmp/varbind snmp/mib snmp/mib/node).each do |f|
4
+ %w(snmp snmp/version snmp/constants snmp/oid snmp/error snmp/pdu snmp/wrapper snmp/session snmp/varbind snmp/mib snmp/mib/node).each do |f|
5
5
  require "#{File.dirname(__FILE__)}/net/#{f}"
6
6
  end
7
7
  Net::SNMP::MIB.init
@@ -2,13 +2,6 @@ module Net
2
2
  module SNMP
3
3
  module Inline
4
4
  extend Inliner
5
-
6
- #module LibC
7
- # extend FFI::Library
8
- # ffi_lib 'C'
9
- # attach_function :malloc, [ :uint ], :pointer
10
- # attach_function :free, [ :pointer ], :void
11
- #end
12
5
 
13
6
  inline do |builder|
14
7
  builder.include "sys/select.h"
@@ -31,9 +24,6 @@ module Net
31
24
  }
32
25
 
33
26
  end
34
-
35
-
36
-
37
27
  end
38
28
  end
39
29
  end
data/lib/net/snmp/mib.rb CHANGED
@@ -1,3 +1,4 @@
1
+ Net::SNMP::Wrapper.snmp_set_save_descriptions(1)
1
2
  module Net
2
3
  module SNMP
3
4
  module MIB
@@ -13,7 +14,16 @@ module Net
13
14
  Node.get_node(oid)
14
15
  end
15
16
 
17
+ def self.add_mibdir(dirname)
18
+ Wrapper.add_mibdir(dirname)
19
+ end
16
20
 
21
+ def self.read_mib(filename)
22
+ Wrapper.read_mib(filename)
23
+ end
24
+ def self.read_module(name)
25
+ Wrapper.read_module(name)
26
+ end
17
27
 
18
28
  end
19
29
  end
@@ -1,4 +1,3 @@
1
-
2
1
  module Net::SNMP
3
2
  module MIB
4
3
  class Node
@@ -8,8 +7,10 @@ module Net::SNMP
8
7
 
9
8
  class << self
10
9
  def get_node(oid)
11
- oid_ptr, oid_len_ptr = Net::SNMP._get_oid(oid)
12
- struct = Wrapper.get_tree(oid_ptr, oid_len_ptr.read_int, Wrapper.get_tree_head().pointer)
10
+ if oid.kind_of?(String)
11
+ oid = Net::SNMP::OID.new(oid)
12
+ end
13
+ struct = Wrapper.get_tree(oid.pointer, oid.length_pointer.read_int, Wrapper.get_tree_head().pointer)
13
14
  new(struct.pointer)
14
15
  end
15
16
  end
@@ -22,10 +23,14 @@ module Net::SNMP
22
23
  raise "invalid type"
23
24
  end
24
25
  end
25
-
26
+
27
+ def description
28
+ @struct.description.read_string
29
+ end
30
+
26
31
  def oid
27
32
  return @oid if @oid
28
- @oid = Net::SNMP.get_oid(label)
33
+ @oid = Net::SNMP::OID.new(label)
29
34
  end
30
35
 
31
36
  # actually seems like list is linked backward, so this will retrieve the previous oid numerically
@@ -46,6 +51,7 @@ module Net::SNMP
46
51
  while child = child.next
47
52
  children << child
48
53
  end
54
+ children.pop
49
55
  children.reverse # For some reason, net-snmp returns everything backwards
50
56
  end
51
57
 
data/lib/net/snmp/oid.rb CHANGED
@@ -1,20 +1,22 @@
1
1
  module Net
2
2
  module SNMP
3
3
  class OID
4
+ attr_reader :oid, :pointer, :length_pointer
4
5
  def initialize(oid)
5
6
  @oid = oid
6
- @oid_ptr = FFI::MemoryPointer.new(:ulong, Constants::MAX_OID_LEN)
7
- @oid_len_ptr = FFI::MemoryPointer.new(:size_t)
8
- @oid_len_ptr.write_int(Constants::MAX_OID_LEN)
7
+ @pointer = FFI::MemoryPointer.new(:ulong, Constants::MAX_OID_LEN)
8
+ @length_pointer = FFI::MemoryPointer.new(:size_t)
9
+ @length_pointer.write_int(Constants::MAX_OID_LEN)
9
10
 
10
11
  if @oid =~ /^[\d\.]*$/
11
- if Wrapper.read_objid(@oid, @oid_ptr, @oid_len_ptr) == 0
12
+ if Wrapper.read_objid(@oid, @pointer, @length_pointer) == 0
12
13
  Wrapper.snmp_perror(@oid)
13
14
  end
14
15
  else
15
- if Wrapper.get_node(@oid, @oid_ptr, @oid_len_ptr) == 0
16
+ if Wrapper.get_node(@oid, @pointer, @length_pointer) == 0
16
17
  Wrapper.snmp_perror(@oid)
17
18
  end
19
+ @oid = c_oid
18
20
  end
19
21
 
20
22
  end
@@ -23,17 +25,26 @@ module Net
23
25
  @oid
24
26
  end
25
27
 
28
+ def name
29
+ @oid
30
+ end
31
+
26
32
  def c_oid
27
- @oid_ptr.read_array_of_long(@oid_len_ptr.read_int).join(".")
33
+ @pointer.read_array_of_long(length_pointer.read_int).join(".")
28
34
  end
29
35
 
30
- def pointer
31
- @oid_ptr
36
+ def node
37
+ MIB::Node.get_node(oid)
32
38
  end
33
- def length_pointer
34
- @oid_len_ptr
39
+
40
+ def index
41
+ oid.sub(node.oid.name + ".","")
35
42
  end
36
43
 
44
+ def label
45
+ node.label + "." + index
46
+ end
47
+
37
48
  end
38
49
  end
39
50
  end
data/lib/net/snmp/pdu.rb CHANGED
@@ -25,19 +25,19 @@ module Net
25
25
  end
26
26
  end
27
27
 
28
- # For getbulk requests, repeaters and maxreps are stored in errstat and errindex
29
- def non_repeaters=(nr)
30
- @struct.errstat = nr
31
- end
32
- def non_repeaters
33
- @struct.errstat
34
- end
35
- def max_repetitions=(mr)
36
- @struct.errindex = mr
37
- end
38
- def max_repetitions
39
- @struct.errindex
40
- end
28
+ # For getbulk requests, repeaters and maxreps are stored in errstat and errindex
29
+ def non_repeaters=(nr)
30
+ @struct.errstat = nr
31
+ end
32
+ def non_repeaters
33
+ @struct.errstat
34
+ end
35
+ def max_repetitions=(mr)
36
+ @struct.errindex = mr
37
+ end
38
+ def max_repetitions
39
+ @struct.errindex
40
+ end
41
41
 
42
42
 
43
43
  def add_varbind(options)
@@ -55,7 +55,6 @@ module Net
55
55
  if @sess.version == Constants::SNMP_VERSION_3
56
56
  @sess.securityLevel = options[:security_level] || Constants::SNMP_SEC_LEVEL_NOAUTH
57
57
 
58
- oid = Net::SNMP::OID.new("1.3.6.1.6.3.10.1.1.2")
59
58
  @sess.securityAuthProto = case options[:auth_protocol]
60
59
  when :sha1
61
60
  Net::SNMP::OID.new("1.3.6.1.6.3.10.1.1.3").pointer
@@ -155,7 +154,48 @@ module Net
155
154
  end
156
155
 
157
156
 
158
-
157
+ # XXX This needs work. Need to use getbulk for speed, guess maxrepeaters, etc..
158
+ # Also need to figure out how we can tell column names from something like ifTable
159
+ # instead of ifEntry. Needs to handle errors, there are probably offset problems
160
+ # in cases of bad data, and various other problems. Also need to add async support.
161
+ # Maybe return a hash with index as key?
162
+ def get_table(table_name, options = {})
163
+ column_names = options[:columns] || Net::SNMP::MIB::Node.get_node(table_name).children.collect {|c| c.label }
164
+ puts "got column names #{column_names.inspect}"
165
+ results = []
166
+ oidlist = column_names
167
+ done = false
168
+ catch :break_outer_loop do
169
+ first_loop = true
170
+
171
+ while(result = get_next(oidlist))
172
+ puts "got result #{result.inspect}"
173
+ oidlist = []
174
+ row = {}
175
+ result.varbinds.each_with_index do |vb, idx|
176
+ puts "got vb #{vb.value.inspect}"
177
+ oid = vb.oid
178
+ row[column_names[idx]] = vb.value
179
+ oidlist << oid.label
180
+ if oid.label[0..column_names[idx].length - 1] != column_names[idx]
181
+ puts "breaking"
182
+ if first_loop
183
+ puts "deleting #{oid.label}"
184
+ oidlist.delete(oid.label)
185
+ column_names.delete_at(idx)
186
+ puts "columns now #{column_names.inspect}"
187
+ else
188
+ throw :break_outer_loop
189
+
190
+ end
191
+ end
192
+ end
193
+ results << row
194
+ first_loop = false
195
+ end
196
+ end
197
+ results
198
+ end
159
199
 
160
200
  def error(msg)
161
201
  Wrapper.snmp_perror("snmp_error")
@@ -185,14 +225,18 @@ module Net
185
225
 
186
226
  private
187
227
  def send_pdu(pdu, &block)
188
-
189
-
228
+ #puts "send_pdu #{Fiber.current.inspect}"
190
229
  if defined?(EM) && EM.reactor_running? && !block_given?
230
+ #puts "REACTORRUNNING"
191
231
  f = Fiber.current
192
232
 
193
233
  send_pdu pdu do | response |
194
234
  f.resume(response)
195
235
  end
236
+
237
+
238
+
239
+
196
240
  Fiber.yield
197
241
  else
198
242
  if block
@@ -16,19 +16,24 @@ module Net
16
16
  end
17
17
 
18
18
  def oid
19
- @struct.name.read_array_of_long(@struct.name_length).join(".")
19
+ @oid ||= Net::SNMP::OID.new(@struct.name.read_array_of_long(@struct.name_length).join("."))
20
20
  end
21
21
 
22
- def name
23
- oid
24
- end
22
+
25
23
 
26
24
  def value
27
25
  case object_type
28
26
  when Constants::ASN_OCTET_STR
29
27
  struct.val[:string].read_string(struct.val_len)
30
- when Constants::ASN_INTEGER, Net::SNMP::ASN_COUNTER
28
+ when Constants::ASN_INTEGER, Constants::ASN_COUNTER
31
29
  struct.val[:integer].read_int
30
+ when Constants::ASN_IPADDRESS
31
+ struct.val[:objid].read_string(struct.val_len).unpack('CCCC').join(".")
32
+ #puts "here #{arr.to_s}"
33
+ #puts arr[0]
34
+ #puts arr[1]
35
+ #puts arr[2]
36
+ #puts arr[3]
32
37
  end
33
38
  end
34
39
  end
@@ -1,5 +1,5 @@
1
1
  module Net
2
- module Snmp
3
- VERSION = "0.1.0"
2
+ module SNMP
3
+ VERSION = "0.1.2"
4
4
  end
5
5
  end
@@ -2,7 +2,7 @@ module Net
2
2
  module SNMP
3
3
  module Wrapper
4
4
  extend NiceFFI::Library
5
- ffi_lib "/opt/local/lib/libnetsnmp.dylib"
5
+ ffi_lib "libnetsnmp"
6
6
  #ffi_lib "netsnmp"
7
7
  typedef :u_long, :oid
8
8
 
@@ -214,40 +214,14 @@ module Wrapper
214
214
  :reported, :int,
215
215
  :defaultValue, :pointer
216
216
  )
217
- # struct tree *child_list; /* list of children of this node */
218
- # struct tree *next_peer; /* Next node in list of peers */
219
- # struct tree *next; /* Next node in hashed list of names */
220
- # struct tree *parent;
221
- # char *label; /* This node's textual name */
222
- # u_long subid; /* This node's integer subidentifier */
223
- # int modid; /* The module containing this node */
224
- # int number_modules;
225
- # int *module_list; /* To handle multiple modules */
226
- # int tc_index; /* index into tclist (-1 if NA) */
227
- # int type; /* This node's object type */
228
- # int access; /* This nodes access */
229
- # int status; /* This nodes status */
230
- # struct enum_list *enums; /* (optional) list of enumerated integers */
231
- # struct range_list *ranges;
232
- # struct index_list *indexes;
233
- # char *augments;
234
- # struct varbind_list *varbinds;
235
- # char *hint;
236
- # char *units;
237
- # int (*printomat) (u_char **, size_t *, size_t *, int,
238
- # const netsnmp_variable_list *,
239
- # const struct enum_list *, const char *,
240
- # const char *);
241
- # void (*printer) (char *, const netsnmp_variable_list *, const struct enum_list *, const char *, const char *); /* Value printing function */
242
- # char *description; /* description (a quoted string) */
243
- # char *reference; /* references (a quoted string) */
244
- # int reported; /* 1=report started in print_subtree... */
245
- # char *defaultValue;
246
217
  end
247
- attach_function :init_mib, [], :void
248
- attach_function :read_all_mibs, [], :void
249
- attach_function :get_tree_head, [], Tree.typed_pointer
250
- attach_function :get_tree, [:pointer, :int, :pointer], Tree.typed_pointer
218
+ class IndexList < NiceFFI::Struct
219
+ layout(
220
+ :next, :pointer,
221
+ :ilabel, :pointer,
222
+ :isimplied, :char
223
+ )
224
+ end
251
225
 
252
226
 
253
227
  # puts "snmp_session size = #{SnmpSession.size}"
@@ -354,7 +328,7 @@ module Wrapper
354
328
  attach_function :asn_parse_double, [ :pointer, :pointer, :pointer, :pointer, :uint ], :pointer
355
329
 
356
330
  attach_function :snmp_pdu_create, [:int], SnmpPdu.typed_pointer
357
- attach_function :get_node, [:pointer, :pointer, :pointer], :int
331
+ attach_function :get_node,[:string, :pointer, :pointer], :int
358
332
  attach_function :read_objid, [:string, :pointer, :pointer], :int
359
333
  attach_function :snmp_add_null_var, [:pointer, :pointer, :size_t], :pointer
360
334
  attach_function :snmp_sess_synch_response, [:pointer, :pointer, :pointer], :int
@@ -368,6 +342,19 @@ module Wrapper
368
342
  attach_function :select, [:int, :pointer, :pointer, :pointer, :pointer], :int
369
343
  attach_function :snmp_read, [:pointer], :void
370
344
  attach_function :generate_Ku, [:pointer, :int, :string, :int, :pointer, :pointer], :int
345
+
346
+
347
+ # MIB functions
348
+ attach_function :init_mib, [], :void
349
+ attach_function :read_all_mibs, [], :void
350
+ attach_function :add_mibdir, [:string], :int
351
+ attach_function :read_mib, [:string], Tree.typed_pointer
352
+ attach_function :read_module, [:string], Tree.typed_pointer
353
+ attach_function :snmp_set_save_descriptions, [:int], :void
354
+
355
+ attach_function :get_tree_head, [], Tree.typed_pointer
356
+ attach_function :get_tree, [:pointer, :int, :pointer], Tree.typed_pointer
357
+
371
358
  #attach_function :send_easy_trap, [:int, :int], :void
372
359
  #attach_function :send_trap_vars, [:int, :int, :pointer], :void
373
360
  #attach_function :send_v2trap, [:pointer], :void
data/net-snmp.gemspec CHANGED
@@ -4,7 +4,7 @@ require "net/snmp/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "net-snmp"
7
- s.version = Net::Snmp::VERSION
7
+ s.version = Net::SNMP::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Ron McClain"]
10
10
  s.email = ["mixtli@github.com"]
data/spec/mib_spec.rb CHANGED
@@ -12,12 +12,14 @@ describe Net::SNMP::MIB::Node do
12
12
  # puts node.parent.inspect
13
13
  end
14
14
 
15
- it "should get children" do
16
- node = Net::SNMP::MIB::Node.get_node("system")
17
- node.children.each do |c|
18
- # puts c.inspect
19
- end
15
+
16
+ it "should get node children" do
17
+ node = Net::SNMP::MIB::Node.get_node("ifTable")
18
+ if_entry = node.children.first
19
+ if_entry.label.should eql("ifEntry")
20
+ if_entry.children.first.label.should eql("ifIndex")
20
21
  end
22
+
21
23
 
22
24
  it "should get siblings" do
23
25
  node = Net::SNMP::MIB::Node.get_node("sysDescr")
@@ -28,7 +30,7 @@ describe Net::SNMP::MIB::Node do
28
30
  it "should get oid" do
29
31
  node = Net::SNMP::MIB::Node.get_node("sysDescr")
30
32
  puts node.struct.inspect
31
- node.oid.should eq("1.3.6.1.2.1.1.1")
33
+ node.oid.name.should eq("1.3.6.1.2.1.1.1")
32
34
  end
33
35
 
34
36
  it "should get by oid" do
@@ -20,7 +20,6 @@ describe "NetSnmp" do
20
20
  did_callback = false
21
21
  session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |s|
22
22
  s.get(["sysDescr.0", "sysContact.0"]) do |result|
23
- puts "in callback"
24
23
  did_callback = true
25
24
  result.varbinds[0].value.should eql("test.net-snmp.org")
26
25
  result.varbinds[1].value.should match(/Coders/)
@@ -31,13 +30,10 @@ describe "NetSnmp" do
31
30
  end
32
31
 
33
32
 
34
-
35
-
36
33
  it "should get an oid asynchronously in a thread" do
37
34
  did_callback = false
38
35
  session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |s|
39
36
  s.get(["sysDescr.0", "sysContact.0"]) do |result|
40
- puts "in callback"
41
37
  did_callback = true
42
38
  result.varbinds[0].value.should eql("test.net-snmp.org")
43
39
  result.varbinds[1].value.should match(/Coders/)
@@ -102,7 +98,7 @@ describe "NetSnmp" do
102
98
  it "should get next an array of oids" do
103
99
  Net::SNMP::Session.open(:peername => "test.net-snmp.org", :community => "demopublic" ) do |sess|
104
100
  result = sess.get_next(["sysUpTimeInstance.0"])
105
- result.varbinds.first.name.should eql("1.3.6.1.2.1.1.4.0")
101
+ result.varbinds.first.oid.oid.should eql("1.3.6.1.2.1.1.4.0")
106
102
  result.varbinds.first.value.should match(/Net-SNMP Coders/)
107
103
  end
108
104
  end
@@ -111,13 +107,44 @@ describe "NetSnmp" do
111
107
  it "should get_bulk_request" do
112
108
  Net::SNMP::Session.open(:peername => "test.net-snmp.org" , :version => '2c', :community => 'demopublic') do |sess|
113
109
  result = sess.get_bulk(["sysContact.0"], :max_repetitions => 10)
114
- result.varbinds.first.oid.should eql("1.3.6.1.2.1.1.5.0")
110
+ result.varbinds.first.oid.name.should eql("1.3.6.1.2.1.1.5.0")
115
111
  result.varbinds.first.value.should eql("test.net-snmp.org")
116
112
  end
117
113
  end
118
114
 
119
- it "should get a table of values"
115
+ it "should get a table of values with explicit columns" do
116
+ session = Net::SNMP::Session.open(:peername => "localhost", :version => '2c')
117
+ table = session.get_table("ifTable", :columns => ["ifIndex", "ifDescr", "ifName"])
118
+ table[0]['ifName'].should eql("lo0")
119
+ table[1]['ifName'].should eql("gif0")
120
+ end
121
+
122
+ it "should get a table of values" do
123
+ session = Net::SNMP::Session.open(:peername => "localhost", :version => '2c')
124
+ table = session.get_table("ifEntry")
125
+ table[0]['ifIndex'].should eql(1)
126
+ table[1]['ifIndex'].should eql(2)
127
+ end
128
+
129
+ it "should get a table of values ipAddrEntry" do
130
+ puts Net::SNMP::Constants::ASN_IPADDRESS
131
+ session = Net::SNMP::Session.open(:peername => "localhost", :version => '2c')
132
+ table = session.get_table("ipAddrEntry")
133
+ puts table.inspect
134
+ table[0]['ipAdEntAddr'].should eql('127.0.0.1')
135
+ table[1]['ipAdEntNetMask'].should eql('255.255.255.0')
136
+ end
120
137
 
138
+ it "should translate an oid" do
139
+
140
+ oid = Net::SNMP::OID.new("ifDescr.1")
141
+ oid.node.label.should eql("ifDescr")
142
+ oid.label.should eql("ifDescr.1")
143
+ oid.index.should eql("1")
144
+ end
145
+
146
+
147
+
121
148
  it "should work in event_machine" do
122
149
  require 'eventmachine'
123
150
  did_callback = false
@@ -134,8 +161,7 @@ describe "NetSnmp" do
134
161
 
135
162
  end
136
163
 
137
- EM.add_timer(2) do
138
- puts "in timer"
164
+ EM.add_timer(3) do
139
165
  did_callback.should be_true
140
166
  EM.stop
141
167
  end
@@ -154,15 +180,12 @@ describe "NetSnmp" do
154
180
  session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |s|
155
181
  s.get("sysDescr.0") do |result|
156
182
  did_callback = true
157
- puts "INHERERERERERERE"
158
- puts result.inspect
159
183
  result.varbinds[0].value.should eql("test.net-snmp.org")
160
184
  end
161
185
 
162
186
  end
163
187
 
164
- EM.add_timer(2) do
165
- puts "in timer"
188
+ EM.add_timer(3) do
166
189
  did_callback.should eql(true)
167
190
  EM.stop
168
191
  end
@@ -176,26 +199,19 @@ describe "NetSnmp" do
176
199
  require 'eventmachine'
177
200
  did_callback = false
178
201
  EM.run do
179
- puts "em fiber = #{Fiber.current.inspect}"
180
202
  Fiber.new {
181
- puts "inner fiber = #{Fiber.current.inspect}"
182
203
 
183
204
  EM.tick_loop do
184
- #puts "tick_fiber = #{Fiber.current.inspect}"
185
205
 
186
206
  Net::SNMP.dispatcher
187
207
  end
188
208
  sleep 1
189
209
  session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic')
190
- puts "calling aget"
191
210
  result = session.get("sysDescr.0")
192
211
  result.varbinds[0].value.should eql("test.net-snmp.org")
193
-
194
-
195
212
  }.resume
196
213
  EM.stop
197
214
  end
198
-
199
215
  end
200
216
 
201
217
 
data/spec/wrapper_spec.rb CHANGED
@@ -5,68 +5,59 @@ describe "Net::SNMP::Wrapper" do
5
5
  community = "demopublic"
6
6
  peername = "test.net-snmp.org"
7
7
 
8
- sess = Net::SNMP::Wrapper::SnmpSession.new
9
- Net::SNMP::Wrapper.snmp_sess_init(sess.pointer)
10
- sess.community = FFI::MemoryPointer.new(:pointer, community.length + 1)
11
- #sess.community.autorelease = false
12
- sess.community.write_string(community)
13
- sess.community_len = community.length
14
- sess.peername = FFI::MemoryPointer.new(:pointer, peername.length + 1)
15
- #sess.peername.autorelease = false
16
- sess.peername.write_string(peername)
17
- sess.version = Net::SNMP::SNMP_VERSION_1
8
+ @session = Net::SNMP::Wrapper::SnmpSession.new(nil)
9
+ Net::SNMP::Wrapper.snmp_sess_init(@session.pointer)
10
+ @session.community = FFI::MemoryPointer.from_string(community)
11
+ @session.community_len = community.length
12
+ @session.peername = FFI::MemoryPointer.from_string(peername)
13
+ @session.version = Net::SNMP::Constants::SNMP_VERSION_1
18
14
 
19
- @handle = Net::SNMP::Wrapper.snmp_sess_open(sess.pointer)
20
- Net::SNMP::Wrapper.snmp_sess_session(@handle)
21
-
22
- sess
15
+ @handle = Net::SNMP::Wrapper.snmp_sess_open(@session.pointer)
16
+ @session_struct = Net::SNMP::Wrapper.snmp_sess_session(@handle)
23
17
  end
24
18
 
25
19
  def make_pdu
26
- pdu_ptr = Net::SNMP::Wrapper.snmp_pdu_create(Net::SNMP::SNMP_MSG_GET)
27
- pdu = Net::SNMP::Wrapper::SnmpPdu.new(pdu_ptr)
28
- anOID = FFI::MemoryPointer.new(:ulong, Net::SNMP::MAX_OID_LEN)
29
- anOIDLen = FFI::MemoryPointer.new(:size_t)
30
- anOIDLen.write_int(Net::SNMP::MAX_OID_LEN)
31
- Net::SNMP::Wrapper.snmp_parse_oid("sysDescr.0", anOID, anOIDLen)
32
- Net::SNMP::Wrapper.snmp_add_null_var(pdu.pointer, anOID, anOIDLen.read_int)
33
- pdu
20
+ @pdu = Net::SNMP::Wrapper.snmp_pdu_create(Net::SNMP::Constants::SNMP_MSG_GET)
21
+ @oid_ptr = FFI::MemoryPointer.new(:ulong, Net::SNMP::Constants::MAX_OID_LEN)
22
+ @oid_len_ptr = FFI::MemoryPointer.new(:size_t)
23
+ @oid_len_ptr.write_int(Net::SNMP::Constants::MAX_OID_LEN)
24
+ puts @pdu.inspect
25
+
26
+ Net::SNMP::Wrapper.get_node("sysDescr.0", @oid_ptr, @oid_len_ptr)
27
+ Net::SNMP::Wrapper.snmp_pdu_add_variable(@pdu.pointer, @oid_ptr, @oid_len_ptr.read_int, Net::SNMP::Constants::ASN_NULL, nil, 0)
34
28
  end
35
29
 
36
30
  it "wrapper should snmpget synchronously" do
37
31
  #pending
38
- sess = init_session
39
- sess = Net::SNMP::Wrapper.snmp_open(sess.pointer)
32
+ init_session
40
33
 
41
- pdu = make_pdu
34
+ make_pdu
42
35
 
43
36
  response_ptr = FFI::MemoryPointer.new(:pointer)
44
- #response_ptr.autorelease = false
45
- status = Net::SNMP::Wrapper.snmp_sess_synch_response(@handle, pdu.pointer, response_ptr)
37
+ status = Net::SNMP::Wrapper.snmp_sess_synch_response(@handle, @pdu.pointer, response_ptr)
46
38
  status.should eql(0)
47
-
39
+
48
40
  response = Net::SNMP::Wrapper::SnmpPdu.new(response_ptr.read_pointer)
49
- value = response.variables.val[:string].read_string
50
- puts "val_len = #{response.variables.val_len}"
41
+ value = response.variables.val[:string].read_string(response.variables.val_len)
51
42
  value.should eql('test.net-snmp.org')
52
43
  end
53
44
 
54
45
  it "wrapper should snmpget asynchronously" do
55
- pending
56
- sess = init_session
57
- pdu = make_pdu
46
+ #pending
47
+ init_session
48
+ make_pdu
58
49
  did_callback = 0
59
50
  result = nil
60
- sess.callback = lambda do |operation, session, reqid, pdu_ptr, magic|
51
+ @session.callback = lambda do |operation, session, reqid, pdu_ptr, magic|
61
52
  did_callback = 1
62
53
  pdu = Net::SNMP::Wrapper::SnmpPdu.new(pdu_ptr)
63
54
  variables = Net::SNMP::Wrapper::VariableList.new(pdu.variables)
64
- result = variables.val[:string].read_string
55
+ result = variables.val[:string].read_string(variables.val_len)
65
56
  0
66
57
  end
67
- sess = Net::SNMP::Wrapper.snmp_open(sess.pointer)
68
- Net::SNMP::Wrapper.snmp_send(sess.pointer, pdu)
69
-
58
+ sess = Net::SNMP::Wrapper.snmp_open(@session.pointer)
59
+ Net::SNMP::Wrapper.snmp_send(sess.pointer, @pdu)
60
+ sleep 1
70
61
  fdset = Net::SNMP::Wrapper.get_fd_set
71
62
  fds = FFI::MemoryPointer.new(:int)
72
63
  #fds.autorelease = false
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-snmp
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 0
9
- version: 0.1.0
4
+ prerelease:
5
+ version: 0.1.2
10
6
  platform: ruby
11
7
  authors:
12
8
  - Ron McClain
@@ -14,47 +10,41 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2011-03-24 00:00:00 -05:00
13
+ date: 2011-03-28 00:00:00 -05:00
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
21
17
  name: rspec
22
- prerelease: false
23
18
  requirement: &id001 !ruby/object:Gem::Requirement
24
19
  none: false
25
20
  requirements:
26
21
  - - ">="
27
22
  - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
23
  version: "0"
31
24
  type: :development
25
+ prerelease: false
32
26
  version_requirements: *id001
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: eventmachine
35
- prerelease: false
36
29
  requirement: &id002 !ruby/object:Gem::Requirement
37
30
  none: false
38
31
  requirements:
39
32
  - - ">="
40
33
  - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
34
  version: "0"
44
35
  type: :development
36
+ prerelease: false
45
37
  version_requirements: *id002
46
38
  - !ruby/object:Gem::Dependency
47
39
  name: nice-ffi
48
- prerelease: false
49
40
  requirement: &id003 !ruby/object:Gem::Requirement
50
41
  none: false
51
42
  requirements:
52
43
  - - ">="
53
44
  - !ruby/object:Gem::Version
54
- segments:
55
- - 0
56
45
  version: "0"
57
46
  type: :runtime
47
+ prerelease: false
58
48
  version_requirements: *id003
59
49
  description: Uses ffi to create an object oriented wrapper around C net-snmp libraries
60
50
  email:
@@ -75,9 +65,6 @@ files:
75
65
  - Rakefile
76
66
  - VERSION
77
67
  - bin/snmpget.rb
78
- - c/Makefile
79
- - c/test
80
- - c/test.c
81
68
  - interface/snmp_api.h
82
69
  - interface/snmp_api.i
83
70
  - interface/snmp_api_wrap.xml
@@ -113,6 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
100
  requirements:
114
101
  - - ">="
115
102
  - !ruby/object:Gem::Version
103
+ hash: -4066083609341364486
116
104
  segments:
117
105
  - 0
118
106
  version: "0"
@@ -121,13 +109,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
109
  requirements:
122
110
  - - ">="
123
111
  - !ruby/object:Gem::Version
112
+ hash: -4066083609341364486
124
113
  segments:
125
114
  - 0
126
115
  version: "0"
127
116
  requirements: []
128
117
 
129
118
  rubyforge_project: net-snmp
130
- rubygems_version: 1.3.7
119
+ rubygems_version: 1.6.2
131
120
  signing_key:
132
121
  specification_version: 3
133
122
  summary: Object oriented wrapper around C net-snmp libraries
data/c/Makefile DELETED
@@ -1,3 +0,0 @@
1
- all:
2
- gcc -o test -L/opt/local/lib -I/opt/local/include -lnetsnmp test.c
3
-
data/c/test DELETED
Binary file
data/c/test.c DELETED
@@ -1,137 +0,0 @@
1
- #include <stdio.h>
2
- #include "string.h"
3
- #include <net-snmp/net-snmp-config.h>
4
- #include <net-snmp/types.h>
5
- #include <net-snmp/library/parse.h>
6
-
7
- struct oid {
8
- char *Name;
9
- oid Oid[MAX_OID_LEN];
10
- size_t OidLen;
11
- } oids[] = {
12
- { "system.sysDescr.0" },
13
- { "ifDescr.1" },
14
- { "ifIndex.1" },
15
- { NULL }
16
- };
17
-
18
- int main() {
19
- struct oid *op = oids;
20
- init_snmp("snmpdemoapp");
21
- init_mib();
22
- test_mib();
23
- while (op->Name) {
24
- op->OidLen = sizeof(op->Oid)/sizeof(op->Oid[0]);
25
-
26
- get_node(op->Name, op->Oid, &op->OidLen);
27
-
28
- op++;
29
- }
30
-
31
- test_synch();
32
-
33
-
34
- }
35
-
36
- int test_mib() {
37
- struct tree *mytree;
38
- size_t oidlen;
39
- int i = 0;
40
- oid myoid[MAX_OID_LEN];
41
- snmp_set_save_descriptions(1);
42
-
43
- printf("sizeof(netsnmp_vardata) = %lu\n", sizeof(netsnmp_vardata));
44
- printf("sizeof(netsnmp_variable_list) = %lu\n", sizeof(netsnmp_variable_list));
45
- printf("sizeof(netsnmp_session) = %lu\n", sizeof(netsnmp_session));
46
- printf("sizeof(netsnmp_pdu) = %lu\n", sizeof(netsnmp_pdu));
47
- oidlen = 100;
48
- get_node("interfaces.ifNumber.2", myoid, &oidlen);
49
- printf("oidlen = %lu\n", oidlen);
50
- for(i=0;i < oidlen; i++) {
51
- printf("%lu\n", myoid[i]);
52
- }
53
- mytree = get_tree(myoid, oidlen, get_tree_head());
54
- printf("label = %s\n", mytree->label);
55
- printf("description = %s\n", mytree->description);
56
- print_description(myoid, oidlen, 200);
57
-
58
- print_mib_tree(stdout, mytree, 1000);
59
- }
60
-
61
-
62
- int test_synch() {
63
- struct snmp_session ss, *sp;
64
- struct oid *op;
65
-
66
- snmp_sess_init(&ss); /* initialize session */
67
- ss.version = SNMP_VERSION_2c;
68
- ss.peername = "127.0.0.1";
69
- ss.community = "public";
70
- ss.community_len = strlen(ss.community);
71
- printf("here\n");
72
- snmp_synch_setup(&ss);
73
- if (!(sp = snmp_open(&ss))) {
74
- snmp_perror("snmp_open");
75
- return;
76
- }
77
- printf("and here\n");
78
- for (op = oids; op->Name; op++) {
79
- struct snmp_pdu *req, *resp;
80
- int status;
81
- req = snmp_pdu_create(SNMP_MSG_GET);
82
- snmp_add_null_var(req, op->Oid, op->OidLen);
83
- status = snmp_synch_response(sp, req, &resp);
84
- printf("got status %d\n", status);
85
- printf("oid %s\n", op->Name);
86
- if (!print_result(status, sp, resp)) break;
87
- snmp_free_pdu(resp);
88
- }
89
- snmp_close(sp);
90
- }
91
-
92
-
93
-
94
- /*
95
- * simple printing of returned data
96
- */
97
- int print_result (int status, struct snmp_session *sp, struct snmp_pdu *pdu)
98
- {
99
- char buf[1024];
100
- struct variable_list *vp;
101
- int ix;
102
- struct timeval now;
103
- struct timezone tz;
104
- struct tm *tm;
105
-
106
- gettimeofday(&now, &tz);
107
- tm = localtime(&now.tv_sec);
108
- fprintf(stdout, "%.2d:%.2d:%.2d.%.6d ", tm->tm_hour, tm->tm_min, tm->tm_sec,
109
- now.tv_usec);
110
- switch (status) {
111
- case STAT_SUCCESS:
112
- vp = pdu->variables;
113
- if (pdu->errstat == SNMP_ERR_NOERROR) {
114
- while (vp) {
115
- snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
116
- fprintf(stdout, "%s: %s\n", sp->peername, buf);
117
- vp = vp->next_variable;
118
- }
119
- }
120
- else {
121
- for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++)
122
- ;
123
- if (vp) snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
124
- else strcpy(buf, "(none)");
125
- fprintf(stdout, "%s: %s: %s\n",
126
- sp->peername, buf, snmp_errstring(pdu->errstat));
127
- }
128
- return 1;
129
- case STAT_TIMEOUT:
130
- fprintf(stdout, "%s: Timeout\n", sp->peername);
131
- return 0;
132
- case STAT_ERROR:
133
- snmp_perror(sp->peername);
134
- return 0;
135
- }
136
- return 0;
137
- }