net-snmp 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +19 -7
- data/lib/net-snmp.rb +1 -1
- data/lib/net/snmp/inline.rb +0 -10
- data/lib/net/snmp/mib.rb +10 -0
- data/lib/net/snmp/mib/node.rb +11 -5
- data/lib/net/snmp/oid.rb +21 -10
- data/lib/net/snmp/pdu.rb +13 -13
- data/lib/net/snmp/session.rb +48 -4
- data/lib/net/snmp/varbind.rb +10 -5
- data/lib/net/snmp/version.rb +2 -2
- data/lib/net/snmp/wrapper.rb +22 -35
- data/net-snmp.gemspec +1 -1
- data/spec/mib_spec.rb +8 -6
- data/spec/net-snmp_spec.rb +36 -20
- data/spec/wrapper_spec.rb +29 -38
- metadata +9 -20
- data/c/Makefile +0 -3
- data/c/test +0 -0
- data/c/test.c +0 -137
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/net/snmp/inline.rb
CHANGED
@@ -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
|
data/lib/net/snmp/mib/node.rb
CHANGED
@@ -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
|
-
|
12
|
-
|
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.
|
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
|
-
@
|
7
|
-
@
|
8
|
-
@
|
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, @
|
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, @
|
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
|
-
@
|
33
|
+
@pointer.read_array_of_long(length_pointer.read_int).join(".")
|
28
34
|
end
|
29
35
|
|
30
|
-
def
|
31
|
-
|
36
|
+
def node
|
37
|
+
MIB::Node.get_node(oid)
|
32
38
|
end
|
33
|
-
|
34
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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)
|
data/lib/net/snmp/session.rb
CHANGED
@@ -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
|
data/lib/net/snmp/varbind.rb
CHANGED
@@ -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
|
-
|
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,
|
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
|
data/lib/net/snmp/version.rb
CHANGED
data/lib/net/snmp/wrapper.rb
CHANGED
@@ -2,7 +2,7 @@ module Net
|
|
2
2
|
module SNMP
|
3
3
|
module Wrapper
|
4
4
|
extend NiceFFI::Library
|
5
|
-
ffi_lib "
|
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
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
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,
|
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
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
|
-
|
16
|
-
|
17
|
-
node
|
18
|
-
|
19
|
-
|
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
|
data/spec/net-snmp_spec.rb
CHANGED
@@ -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.
|
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(
|
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(
|
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
|
-
|
9
|
-
Net::SNMP::Wrapper.snmp_sess_init(
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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(
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
Net::SNMP::Wrapper.
|
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
|
-
|
39
|
-
sess = Net::SNMP::Wrapper.snmp_open(sess.pointer)
|
32
|
+
init_session
|
40
33
|
|
41
|
-
|
34
|
+
make_pdu
|
42
35
|
|
43
36
|
response_ptr = FFI::MemoryPointer.new(:pointer)
|
44
|
-
|
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
|
-
|
57
|
-
|
46
|
+
#pending
|
47
|
+
init_session
|
48
|
+
make_pdu
|
58
49
|
did_callback = 0
|
59
50
|
result = nil
|
60
|
-
|
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(
|
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:
|
5
|
-
|
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-
|
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.
|
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
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
|
-
}
|