net-snmp2 0.3.0
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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +24 -0
- data/TODO.md +6 -0
- data/bin/mib2rb +129 -0
- data/bin/net-snmp2 +64 -0
- data/examples/agent.rb +104 -0
- data/examples/manager.rb +11 -0
- data/examples/trap_handler.rb +46 -0
- data/examples/v1_trap_session.rb +24 -0
- data/examples/v2_trap_session.rb +21 -0
- data/lib/net-snmp2.rb +85 -0
- data/lib/net/snmp.rb +27 -0
- data/lib/net/snmp/agent/agent.rb +48 -0
- data/lib/net/snmp/agent/provider.rb +51 -0
- data/lib/net/snmp/agent/provider_dsl.rb +124 -0
- data/lib/net/snmp/agent/request_dispatcher.rb +38 -0
- data/lib/net/snmp/constants.rb +287 -0
- data/lib/net/snmp/debug.rb +54 -0
- data/lib/net/snmp/dispatcher.rb +108 -0
- data/lib/net/snmp/error.rb +29 -0
- data/lib/net/snmp/listener.rb +76 -0
- data/lib/net/snmp/message.rb +142 -0
- data/lib/net/snmp/mib/mib.rb +67 -0
- data/lib/net/snmp/mib/module.rb +39 -0
- data/lib/net/snmp/mib/node.rb +122 -0
- data/lib/net/snmp/mib/templates.rb +48 -0
- data/lib/net/snmp/oid.rb +134 -0
- data/lib/net/snmp/pdu.rb +235 -0
- data/lib/net/snmp/repl/manager_repl.rb +243 -0
- data/lib/net/snmp/session.rb +560 -0
- data/lib/net/snmp/trap_handler/trap_handler.rb +42 -0
- data/lib/net/snmp/trap_handler/v1_trap_dsl.rb +44 -0
- data/lib/net/snmp/trap_handler/v2_trap_dsl.rb +38 -0
- data/lib/net/snmp/trap_session.rb +92 -0
- data/lib/net/snmp/utility.rb +10 -0
- data/lib/net/snmp/varbind.rb +57 -0
- data/lib/net/snmp/version.rb +5 -0
- data/lib/net/snmp/wrapper.rb +450 -0
- data/net-snmp2.gemspec +30 -0
- data/spec/README.md +105 -0
- data/spec/async_spec.rb +123 -0
- data/spec/em_spec.rb +23 -0
- data/spec/error_spec.rb +34 -0
- data/spec/fiber_spec.rb +41 -0
- data/spec/mib_spec.rb +68 -0
- data/spec/net-snmp_spec.rb +18 -0
- data/spec/oid_spec.rb +21 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/sync_spec.rb +132 -0
- data/spec/thread_spec.rb +19 -0
- data/spec/trap_spec.rb +45 -0
- data/spec/utility_spec.rb +10 -0
- data/spec/wrapper_spec.rb +69 -0
- metadata +166 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# Ruby api to the Wrapper::Module class (represents netsnmp's `struct module`)
|
2
|
+
|
3
|
+
module Net::SNMP
|
4
|
+
class Module
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators :struct, :modid, :no_imports
|
7
|
+
|
8
|
+
# Gets a module node by its id
|
9
|
+
def self.find(module_id)
|
10
|
+
if module_id < 0
|
11
|
+
nil
|
12
|
+
else
|
13
|
+
new(Wrapper.find_module(module_id))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(struct)
|
18
|
+
raise "Tried to initialize null module" if struct.null?
|
19
|
+
@struct = struct
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@struct.name.read_string
|
24
|
+
end
|
25
|
+
|
26
|
+
def file
|
27
|
+
@struct.file.read_string
|
28
|
+
end
|
29
|
+
|
30
|
+
def next
|
31
|
+
if @struct.next.null?
|
32
|
+
nil
|
33
|
+
else
|
34
|
+
self.class.new(@struct.next)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# Ruby api to the Wrapper::Tree class (represents netsnmp's `struct tree`)
|
2
|
+
|
3
|
+
module Net::SNMP
|
4
|
+
module MIB
|
5
|
+
class Node
|
6
|
+
include Debug
|
7
|
+
extend Forwardable
|
8
|
+
attr_accessor :struct, :is_in_mib
|
9
|
+
def_delegators :struct, :label, :type, :access, :status, :modid, :subid
|
10
|
+
|
11
|
+
class << self
|
12
|
+
include Debug
|
13
|
+
def get_node(oid)
|
14
|
+
if oid.kind_of?(String)
|
15
|
+
oid = OID.new(oid)
|
16
|
+
end
|
17
|
+
struct = Wrapper.get_tree(oid.pointer, oid.length_pointer.read_int, Wrapper.get_tree_head().pointer)
|
18
|
+
node = new(struct.pointer)
|
19
|
+
warn "OID #{oid.to_s} not found in MIB" unless node.in_mib?
|
20
|
+
node
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(arg)
|
25
|
+
@oid = nil
|
26
|
+
@module = nil
|
27
|
+
case arg
|
28
|
+
when Wrapper::Tree
|
29
|
+
@struct = arg
|
30
|
+
when FFI::Pointer
|
31
|
+
@struct = Wrapper::Tree.new(arg)
|
32
|
+
else
|
33
|
+
raise "invalid type"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def exists_in_mib?
|
38
|
+
# The structure can be created without the oid actually
|
39
|
+
# existing in the mib, but the parent will be null.
|
40
|
+
# Of course, the parent is null for the root node as well,
|
41
|
+
# so ignore that case.
|
42
|
+
(!@struct.parent.null?) || oid.to_s == '1'
|
43
|
+
end
|
44
|
+
alias in_mib? exists_in_mib?
|
45
|
+
|
46
|
+
def module
|
47
|
+
unless @module
|
48
|
+
@module = Module.find(modid)
|
49
|
+
end
|
50
|
+
@module
|
51
|
+
end
|
52
|
+
|
53
|
+
def description
|
54
|
+
if @struct.description.null?
|
55
|
+
nil
|
56
|
+
else
|
57
|
+
@struct.description.read_string
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def oid
|
62
|
+
return @oid if @oid
|
63
|
+
@oid = OID.new(label)
|
64
|
+
end
|
65
|
+
|
66
|
+
# actually seems like list is linked backward, so this will retrieve the previous oid numerically
|
67
|
+
def next
|
68
|
+
return nil if @struct.next.null?
|
69
|
+
self.class.new(@struct.next)
|
70
|
+
end
|
71
|
+
|
72
|
+
def next_peer
|
73
|
+
return nil if @struct.next_peer.null?
|
74
|
+
self.class.new(@struct.next_peer)
|
75
|
+
end
|
76
|
+
|
77
|
+
def parent
|
78
|
+
return nil if @struct.parent.null?
|
79
|
+
self.class.new(@struct.parent)
|
80
|
+
end
|
81
|
+
|
82
|
+
def children
|
83
|
+
return to_enum __method__ unless block_given?
|
84
|
+
return if @struct.child_list.null?
|
85
|
+
child = self.class.new(@struct.child_list)
|
86
|
+
yield child
|
87
|
+
while child = child.next_peer
|
88
|
+
yield child
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Depth-first traversal of all descendants
|
93
|
+
def descendants(&block)
|
94
|
+
return to_enum __method__ unless block_given?
|
95
|
+
return if @struct.child_list.null?
|
96
|
+
child = self.class.new(@struct.child_list)
|
97
|
+
block[child]
|
98
|
+
child.descendants(&block)
|
99
|
+
while child = child.next_peer
|
100
|
+
block[child]
|
101
|
+
child.descendants(&block)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def peers
|
106
|
+
return [] if oid.to_s == '1'
|
107
|
+
parent.children.reject { |n| n.oid.to_s == oid.to_s }
|
108
|
+
end
|
109
|
+
alias siblings peers
|
110
|
+
|
111
|
+
def enums
|
112
|
+
return to_enum __method__ unless block_given?
|
113
|
+
enum = struct.enums
|
114
|
+
while !enum.null?
|
115
|
+
yield({value: enum.value, label: enum.label.read_string})
|
116
|
+
enum = enum.next
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Net::SNMP::MIB
|
2
|
+
module Templates
|
3
|
+
DESCRIBE = '
|
4
|
+
<% nodes.each do |node| -%>
|
5
|
+
<%= node.module.nil? ? "" : "#{node.module.name}::" %><%= node.label %>
|
6
|
+
- oid: <%= node.oid %>
|
7
|
+
- type: <%= node.type %>
|
8
|
+
- file: <%= node.module.file unless node.module.nil? %>
|
9
|
+
- descr: <%= "\"#{node.description}\"" %>
|
10
|
+
- enums: <%=
|
11
|
+
if !(node.enums.count == 0)
|
12
|
+
node.enums.map { |e| "#{e[:label]}(#{e[:value]})" }.join(", ")
|
13
|
+
else
|
14
|
+
"NONE"
|
15
|
+
end
|
16
|
+
%>
|
17
|
+
- parent: <%= "#{node.parent.label}(#{node.parent.oid})" unless node.parent.nil? %>
|
18
|
+
- peers: <%= node.peers.map { |n| "#{n.label}(#{n.subid})"}.join(", ") %>
|
19
|
+
- next: <%= node.next.oid unless node.next.nil? %>
|
20
|
+
- next_peer: <%= node.next_peer.oid unless node.next_peer.nil? %>
|
21
|
+
- children: <%=
|
22
|
+
if node.children.count > 0
|
23
|
+
node.children.map { |n| "#{n.label}(#{n.subid})"}.join(", ")
|
24
|
+
else
|
25
|
+
"NONE"
|
26
|
+
end
|
27
|
+
%>
|
28
|
+
<% end -%>
|
29
|
+
'.sub!("\n", "") # Remove leading newline
|
30
|
+
|
31
|
+
JSON = json_template = '
|
32
|
+
[
|
33
|
+
<% nodes.each_with_index { |node, index| -%>
|
34
|
+
<%= ",\n" if index > 0 -%>
|
35
|
+
{
|
36
|
+
"name": "<%= node.module.nil? ? "" : "#{node.module.name}::" %><%= node.label %>",
|
37
|
+
"oid": "<%= node.oid %>",
|
38
|
+
"type": <%= node.type %>,
|
39
|
+
<% if node.enums && node.enums.count > 0 -%>
|
40
|
+
"enums": { <%= node.enums.map { |enum| "\"#{enum[:label]}\": #{enum[:value]}" }.join(", ") %> },
|
41
|
+
<% end -%>
|
42
|
+
"parent": <%= node.parent ? %Q["#{node.parent.oid}"] : "undefined" %>
|
43
|
+
}<% } -%>
|
44
|
+
|
45
|
+
]
|
46
|
+
'.sub!("\n", "")
|
47
|
+
end
|
48
|
+
end
|
data/lib/net/snmp/oid.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
module Net
|
2
|
+
module SNMP
|
3
|
+
class OID
|
4
|
+
extend Debug
|
5
|
+
include Debug
|
6
|
+
|
7
|
+
attr_reader :oid, :pointer, :length_pointer
|
8
|
+
@oid_size = nil
|
9
|
+
@sub_id_bit_width = nil
|
10
|
+
|
11
|
+
def self.from_pointer(ptr, sub_id_count)
|
12
|
+
OID.new(OID.read_pointer(ptr, sub_id_count))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.oid_size
|
16
|
+
unless @oid_size
|
17
|
+
determine_oid_size
|
18
|
+
end
|
19
|
+
@oid_size
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.determine_oid_size
|
23
|
+
if Net::SNMP.initialized?
|
24
|
+
oid_ptr = FFI::MemoryPointer.new(:ulong, 8)
|
25
|
+
length_ptr = FFI::MemoryPointer.new(:size_t, 1)
|
26
|
+
length_ptr.write_int(oid_ptr.total)
|
27
|
+
|
28
|
+
Wrapper.read_objid('1.1', oid_ptr, length_ptr)
|
29
|
+
oid_str = oid_ptr.read_array_of_uint8(oid_ptr.total).map{|byte| byte.to_s(2).rjust(8, '0') }.join('')
|
30
|
+
|
31
|
+
@oid_size = (oid_str[/10*1/].length - 1) / 8
|
32
|
+
else
|
33
|
+
@oid_size = FFI::MemoryPointer.new(:ulong).total
|
34
|
+
warn "SNMP not initialized\n" + <<-WARNING
|
35
|
+
Cannot determine OID sub-id size, assuming common case of sizeof(ulong)
|
36
|
+
On this platform, sizeof(ulong) = #{@oid_size} bytes
|
37
|
+
To avoid this warning, call `Net::SNMP.init`
|
38
|
+
WARNING
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.read_pointer(pointer, sub_id_count)
|
43
|
+
unless @sub_id_bit_width
|
44
|
+
@sub_id_bit_width = OID.oid_size * 8
|
45
|
+
end
|
46
|
+
pointer.send("read_array_of_uint#{@sub_id_bit_width}", sub_id_count).join('.')
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_to_buffer(buffer)
|
50
|
+
unless @sub_id_bit_width
|
51
|
+
@sub_id_bit_width = OID.oid_size * 8
|
52
|
+
end
|
53
|
+
buffer.send("write_array_of_uint#{@sub_id_bit_width}", self.to_s.split('.').map{ |subid| subid.to_i })
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize(oid)
|
57
|
+
@oid = oid
|
58
|
+
@pointer = FFI::MemoryPointer.new(Net::SNMP::OID.oid_size * Constants::MAX_OID_LEN)
|
59
|
+
@length_pointer = FFI::MemoryPointer.new(:size_t)
|
60
|
+
@length_pointer.write_int(Constants::MAX_OID_LEN)
|
61
|
+
if @oid =~ /^[\d\.]*$/
|
62
|
+
if Wrapper.read_objid(@oid, @pointer, @length_pointer) == 0
|
63
|
+
Wrapper.snmp_perror(@oid)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
if Wrapper.get_node(@oid, @pointer, @length_pointer) == 0
|
67
|
+
raise "No such node: #{oid}"
|
68
|
+
end
|
69
|
+
@oid = to_s
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def size
|
74
|
+
@length_pointer.read_int * Net::SNMP::OID.oid_size
|
75
|
+
end
|
76
|
+
|
77
|
+
def length
|
78
|
+
@length_pointer.read_int
|
79
|
+
end
|
80
|
+
|
81
|
+
def oid
|
82
|
+
@oid
|
83
|
+
end
|
84
|
+
|
85
|
+
def name
|
86
|
+
@oid
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_s
|
90
|
+
OID.read_pointer(@pointer, length)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Gets the MIB node corresponding to this OID.
|
94
|
+
# Note that if this OID represents a MIB node, like '1.3',
|
95
|
+
# then `oid.to_s == oid.node.oid.to_s`. However, if there
|
96
|
+
# are indices on this oid, then `oid.to_s.start_with?(oid.node.oid.to_s)`
|
97
|
+
def node
|
98
|
+
MIB::Node.get_node(oid)
|
99
|
+
end
|
100
|
+
|
101
|
+
# The instance index string
|
102
|
+
# Note that some MIB nodes specify the instance implicitly,
|
103
|
+
# like sysUpTimeInstance. So, this may be an empty string.
|
104
|
+
def index
|
105
|
+
# Strip the name
|
106
|
+
index = oid.sub(node.oid.name, '')
|
107
|
+
# Strip any leading dot
|
108
|
+
index.sub(/^\./, '')
|
109
|
+
end
|
110
|
+
|
111
|
+
# The label for the this OID. Includes any instance indexes.
|
112
|
+
def label
|
113
|
+
"#{node.label}#{index.length > 0 ? "." + index : ""}"
|
114
|
+
end
|
115
|
+
|
116
|
+
def <=>(o)
|
117
|
+
a = self._packed
|
118
|
+
b = o._packed
|
119
|
+
a <=> b
|
120
|
+
end
|
121
|
+
|
122
|
+
def _packed
|
123
|
+
i = self.to_s.dup
|
124
|
+
i.sub!(/^\./,'')
|
125
|
+
i.gsub!(/ /, '.0')
|
126
|
+
i.replace(i.split('.').map(&:to_i).pack('N*'))
|
127
|
+
end
|
128
|
+
|
129
|
+
def parent_of?(o)
|
130
|
+
o.to_s =~ /^#{self.to_s}\./
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/net/snmp/pdu.rb
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
module Net
|
2
|
+
module SNMP
|
3
|
+
# Wrapper around netsnmp_pdu.
|
4
|
+
class PDU
|
5
|
+
extend Forwardable
|
6
|
+
include Net::SNMP::Debug
|
7
|
+
attr_accessor :struct, :varbinds, :callback, :command
|
8
|
+
def_delegators :struct, :pointer
|
9
|
+
|
10
|
+
# Create a new PDU object.
|
11
|
+
# +pdu_type+ The type of the PDU. For example, Net::SNMP::SNMP_MSG_GET. See constants.rb
|
12
|
+
def initialize(pdu_type)
|
13
|
+
@varbinds = []
|
14
|
+
case pdu_type
|
15
|
+
when FFI::Pointer
|
16
|
+
@struct = Wrapper::SnmpPdu.new(pdu_type)
|
17
|
+
@command = @struct.command
|
18
|
+
v = @struct.variables
|
19
|
+
unless v.null?
|
20
|
+
@varbinds << Varbind.from_pointer(v)
|
21
|
+
while( !(v = v.next_variable).null? )
|
22
|
+
@varbinds << Varbind.from_pointer(v)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
when Fixnum
|
26
|
+
@struct = Wrapper.snmp_pdu_create(pdu_type)
|
27
|
+
@command = pdu_type
|
28
|
+
else
|
29
|
+
raise Error.new, "invalid pdu type"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Specifies the number of non-repeating, regular objects at the start of
|
34
|
+
# the variable list in the request.
|
35
|
+
# (For getbulk requests only, non-repeaters is stored in errstat location)
|
36
|
+
def non_repeaters
|
37
|
+
@struct.errstat
|
38
|
+
end
|
39
|
+
|
40
|
+
def non_repeaters=(nr)
|
41
|
+
@struct.errstat = nr
|
42
|
+
end
|
43
|
+
|
44
|
+
# The number of iterations in the table to be read for the repeating
|
45
|
+
# objects that follow the non-repeating objects.
|
46
|
+
# (For getbulk requests only, max-repititions are stored in errindex location)
|
47
|
+
def max_repetitions=(mr)
|
48
|
+
@struct.errindex = mr
|
49
|
+
end
|
50
|
+
|
51
|
+
def max_repetitions
|
52
|
+
@struct.errindex
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sets the enterprise OID of this PDU
|
56
|
+
# (Valid for SNMPv1 traps only)
|
57
|
+
def enterprise=(oid)
|
58
|
+
@i_own_enterprise = true
|
59
|
+
oid = OID.new(oid) if oid.kind_of?(String)
|
60
|
+
@struct.enterprise = FFI::LibC.calloc(oid.length, OID.oid_size)
|
61
|
+
oid.write_to_buffer(@struct.enterprise)
|
62
|
+
@struct.enterprise_length = oid.length
|
63
|
+
end
|
64
|
+
|
65
|
+
# The enterprise OID of this PDU
|
66
|
+
# (Valid for SNMPv1 traps only)
|
67
|
+
def enterprise
|
68
|
+
OID.from_pointer(@struct.enterprise, @struct.enterprise_length)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Sets the address of the agent that sent this PDU
|
72
|
+
# (Valid for SNMPv1 traps only)
|
73
|
+
def agent_addr=(addr)
|
74
|
+
# @struct.agent_addr is a binary array of 4 characters,
|
75
|
+
# so pack the provided string into four bytes and we can assign it
|
76
|
+
@struct.agent_addr = addr.split('.').map{ |octet| octet.to_i }.pack("CCCC")
|
77
|
+
end
|
78
|
+
|
79
|
+
# The address of the agent that sent this PDU
|
80
|
+
# (Valid for SNMPv1 traps only)
|
81
|
+
def agent_addr
|
82
|
+
# @struct.agent_addr is a binary array of 4 characters,
|
83
|
+
# to_a converts this to a ruby array of Integers, then join get's us
|
84
|
+
# back to the string form
|
85
|
+
@struct.agent_addr.to_a.join('.')
|
86
|
+
end
|
87
|
+
|
88
|
+
# The uptime for the PDU
|
89
|
+
# (Only valid for SNMPv1 traps)
|
90
|
+
def uptime
|
91
|
+
@struct.time
|
92
|
+
end
|
93
|
+
|
94
|
+
# The uptime for the PDU
|
95
|
+
# (Only valid for SNMPv1 traps)
|
96
|
+
def uptime=(value)
|
97
|
+
@struct.time = value.to_i
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns true if pdu is in error
|
101
|
+
def error?
|
102
|
+
self.errstat != 0
|
103
|
+
end
|
104
|
+
|
105
|
+
# Sets the pdu errstat
|
106
|
+
def error=(value)
|
107
|
+
@struct.errstat = value
|
108
|
+
end
|
109
|
+
alias errstat= error=
|
110
|
+
alias error_status= error=
|
111
|
+
|
112
|
+
# Sets the error index
|
113
|
+
def error_index=(index)
|
114
|
+
@struct.errindex = index
|
115
|
+
end
|
116
|
+
alias errindex= error_index=
|
117
|
+
|
118
|
+
# A descriptive error message
|
119
|
+
def error_message
|
120
|
+
Wrapper::snmp_errstring(self.errstat)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Tries to delegate missing methods to the underlying Wrapper::SnmpPdu object.
|
124
|
+
# If it does not respond to the method, calls super.
|
125
|
+
def method_missing(m, *args)
|
126
|
+
if @struct.respond_to?(m)
|
127
|
+
@struct.send(m, *args)
|
128
|
+
else
|
129
|
+
super
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Adds a variable binding to the pdu.
|
134
|
+
# Options:
|
135
|
+
# * +oid+ The SNMP OID
|
136
|
+
# * +type+ The data type. Possible values include Net::SNMP::ASN_OCTET_STR, Net::SNMP::ASN_COUNTER, etc. See constants.rb
|
137
|
+
# * +value+ The value of the varbind. default is nil.
|
138
|
+
def add_varbind(options)
|
139
|
+
options[:type] ||= case options[:value]
|
140
|
+
when String
|
141
|
+
Constants::ASN_OCTET_STR
|
142
|
+
when Fixnum
|
143
|
+
Constants::ASN_INTEGER
|
144
|
+
when Net::SNMP::OID
|
145
|
+
Constants::ASN_OBJECT_ID
|
146
|
+
when nil
|
147
|
+
Constants::ASN_NULL
|
148
|
+
else
|
149
|
+
raise "Unknown value type"
|
150
|
+
end
|
151
|
+
|
152
|
+
value = options[:value]
|
153
|
+
value_len = case options[:type]
|
154
|
+
when Constants::ASN_NULL,
|
155
|
+
Constants::SNMP_NOSUCHOBJECT,
|
156
|
+
Constants::SNMP_NOSUCHINSTANCE,
|
157
|
+
Constants::SNMP_ENDOFMIBVIEW
|
158
|
+
0
|
159
|
+
else
|
160
|
+
options[:value].size
|
161
|
+
end
|
162
|
+
|
163
|
+
value = case options[:type]
|
164
|
+
when Constants::ASN_INTEGER,
|
165
|
+
Constants::ASN_GAUGE,
|
166
|
+
Constants::ASN_COUNTER,
|
167
|
+
Constants::ASN_TIMETICKS,
|
168
|
+
Constants::ASN_UNSIGNED
|
169
|
+
new_val = FFI::MemoryPointer.new(:long)
|
170
|
+
new_val.write_long(value)
|
171
|
+
new_val
|
172
|
+
when Constants::ASN_OCTET_STR,
|
173
|
+
Constants::ASN_BIT_STR,
|
174
|
+
Constants::ASN_OPAQUE
|
175
|
+
value
|
176
|
+
when Constants::ASN_IPADDRESS
|
177
|
+
# TODO
|
178
|
+
when Constants::ASN_OBJECT_ID
|
179
|
+
value.pointer
|
180
|
+
when Constants::ASN_NULL,
|
181
|
+
Constants::SNMP_NOSUCHOBJECT,
|
182
|
+
Constants::SNMP_NOSUCHINSTANCE,
|
183
|
+
Constants::SNMP_ENDOFMIBVIEW
|
184
|
+
nil
|
185
|
+
else
|
186
|
+
if value.respond_to?(:pointer)
|
187
|
+
value.pointer
|
188
|
+
else
|
189
|
+
raise Net::SNMP::Error.new, "Unknown variable type #{options[:type]}"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
oid = options[:oid].kind_of?(OID) ? options[:oid] : OID.new(options[:oid])
|
194
|
+
var_ptr = Wrapper.snmp_pdu_add_variable(@struct.pointer, oid.pointer, oid.length_pointer.read_int, options[:type], value, value_len)
|
195
|
+
varbind = Varbind.new(var_ptr)
|
196
|
+
varbinds << varbind
|
197
|
+
end
|
198
|
+
|
199
|
+
def print_errors
|
200
|
+
puts "errstat = #{self.errstat}, index = #{self.errindex}, message = #{self.error_message}"
|
201
|
+
end
|
202
|
+
|
203
|
+
# Free the pdu
|
204
|
+
# Segfaults at the moment - most of the time, anyway.
|
205
|
+
# This is troublesome...
|
206
|
+
def free
|
207
|
+
# HACK
|
208
|
+
# snmp_free_pdu segfaults intermittently when freeing the enterprise
|
209
|
+
# oid if we've allocated it. Can't figure out why. For now, freeing it manually
|
210
|
+
# before calling snmp_free_pdu does the trick
|
211
|
+
if @i_own_enterprise
|
212
|
+
FFI::LibC.free(@struct.enterprise) unless @struct.enterprise.null?
|
213
|
+
@struct.enterprise = FFI::Pointer::NULL
|
214
|
+
end
|
215
|
+
Wrapper.snmp_free_pdu(@struct.pointer)
|
216
|
+
end
|
217
|
+
|
218
|
+
def print
|
219
|
+
puts "PDU"
|
220
|
+
if command == Constants::SNMP_MSG_TRAP
|
221
|
+
puts " - Enterprise: #{enterprise}"
|
222
|
+
puts " - Trap Type: #{trap_type}"
|
223
|
+
puts " - Specific Type: #{specific_type}"
|
224
|
+
puts " - Agent Addr: #{agent_addr}"
|
225
|
+
end
|
226
|
+
|
227
|
+
puts " - Varbinds:"
|
228
|
+
varbinds.each do |v|
|
229
|
+
puts " + #{MIB.translate(v.oid.to_s)}(#{v.oid}) = #{v.value}"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|