snmp 1.0.4 → 1.1.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.
- data/README.rdoc +6 -0
- data/lib/snmp.rb +1 -0
- data/lib/snmp/manager.rb +118 -99
- data/lib/snmp/mib.rb +22 -0
- data/lib/snmp/options.rb +1 -1
- data/lib/snmp/pdu.rb +15 -15
- data/lib/snmp/varbind.rb +34 -8
- data/lib/snmp/version.rb +1 -1
- data/test/test_manager.rb +26 -8
- data/test/test_mib.rb +15 -0
- data/test/test_varbind.rb +20 -0
- data/test/test_walk.rb +6 -6
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -26,6 +26,12 @@ examples below for more details.
|
|
26
26
|
|
27
27
|
== Changes
|
28
28
|
|
29
|
+
Changes for version 1.1.0:
|
30
|
+
|
31
|
+
* Added MIB support to ObjectId and Varbind, so that to_s can return symbolic information
|
32
|
+
* Added to_str method to ObjectId to return a numeric OID string (old to_s behavior)
|
33
|
+
* TrapListener can now support multiple community strings
|
34
|
+
|
29
35
|
Changes for version 1.0.4:
|
30
36
|
|
31
37
|
* New option handling and added lower-case versions of all options
|
data/lib/snmp.rb
CHANGED
data/lib/snmp/manager.rb
CHANGED
@@ -16,7 +16,8 @@ require 'thread'
|
|
16
16
|
|
17
17
|
module SNMP
|
18
18
|
|
19
|
-
class RequestTimeout < RuntimeError;
|
19
|
+
class RequestTimeout < RuntimeError;
|
20
|
+
end
|
20
21
|
|
21
22
|
##
|
22
23
|
# Wrap socket so that it can be easily substituted for testing or for
|
@@ -55,7 +56,7 @@ module SNMP
|
|
55
56
|
@lock.synchronize do
|
56
57
|
@request_id += 1
|
57
58
|
@request_id = 1 if @request_id == MAX_REQUEST_ID
|
58
|
-
return
|
59
|
+
return @request_id
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
@@ -117,19 +118,19 @@ module SNMP
|
|
117
118
|
class Manager
|
118
119
|
|
119
120
|
class Config < Options
|
120
|
-
option :host,
|
121
|
-
option :port,
|
122
|
-
option :trap_port,
|
123
|
-
option :community,
|
124
|
-
option :write_community, :WriteCommunity,
|
125
|
-
option :version,
|
126
|
-
option :timeout,
|
127
|
-
option :retries,
|
128
|
-
option :transport,
|
129
|
-
option :max_recv_bytes,
|
130
|
-
option :mib_dir,
|
131
|
-
option :mib_modules,
|
132
|
-
option :use_IPv6,
|
121
|
+
option :host, :Host, 'localhost'
|
122
|
+
option :port, :Port, 161
|
123
|
+
option :trap_port, :TrapPort, 162
|
124
|
+
option :community, :Community, 'public'
|
125
|
+
option :write_community, :WriteCommunity, lambda { |c| c.community }
|
126
|
+
option :version, :Version, :SNMPv2c
|
127
|
+
option :timeout, :Timeout, 1
|
128
|
+
option :retries, :Retries, 5
|
129
|
+
option :transport, :Transport, UDPTransport
|
130
|
+
option :max_recv_bytes, :MaxReceiveBytes, 8000
|
131
|
+
option :mib_dir, :MibDir, MIB::DEFAULT_MIB_PATH
|
132
|
+
option :mib_modules, :MibModules, default_modules
|
133
|
+
option :use_IPv6, :use_IPv6, lambda { |c| ipv6_address?(c) }
|
133
134
|
|
134
135
|
def create_transport
|
135
136
|
transport.respond_to?(:new) ? transport.new(socket_address_family) : transport
|
@@ -274,10 +275,10 @@ module SNMP
|
|
274
275
|
def get_bulk(non_repeaters, max_repetitions, object_list)
|
275
276
|
varbind_list = @mib.varbind_list(object_list, :NullValue)
|
276
277
|
request = GetBulkRequest.new(
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
278
|
+
@@request_id.next,
|
279
|
+
varbind_list,
|
280
|
+
non_repeaters,
|
281
|
+
max_repetitions)
|
281
282
|
try_request(request)
|
282
283
|
end
|
283
284
|
|
@@ -417,7 +418,7 @@ module SNMP
|
|
417
418
|
vb_list = @mib.varbind_list(object_list, :NullValue)
|
418
419
|
raise ArgumentError, "index_column is past end of varbind list" if index_column >= vb_list.length
|
419
420
|
is_single_vb = object_list.respond_to?(:to_str) ||
|
420
|
-
|
421
|
+
object_list.respond_to?(:to_varbind)
|
421
422
|
start_list = vb_list
|
422
423
|
start_oid = vb_list[index_column].name
|
423
424
|
last_oid = start_oid
|
@@ -455,12 +456,13 @@ module SNMP
|
|
455
456
|
if i != index_column
|
456
457
|
expected_oid = start_list[i].name + row_index
|
457
458
|
if vb_list[i].name != expected_oid
|
458
|
-
vb_list[i] = VarBind.new(expected_oid, NoSuchInstance)
|
459
|
+
vb_list[i] = VarBind.new(expected_oid, NoSuchInstance).with_mib(@mib)
|
459
460
|
end
|
460
461
|
end
|
461
462
|
end
|
462
463
|
vb_list
|
463
464
|
end
|
465
|
+
|
464
466
|
private :validate_row
|
465
467
|
|
466
468
|
##
|
@@ -473,50 +475,50 @@ module SNMP
|
|
473
475
|
|
474
476
|
private
|
475
477
|
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
478
|
+
def warn(message)
|
479
|
+
trace = caller(2)
|
480
|
+
location = trace[0].sub(/:in.*/, '')
|
481
|
+
Kernel::warn "#{location}: warning: #{message}"
|
482
|
+
end
|
481
483
|
|
482
|
-
|
483
|
-
|
484
|
-
|
484
|
+
def load_modules(module_list, mib_dir)
|
485
|
+
module_list.each { |m| @mib.load_module(m, mib_dir) }
|
486
|
+
end
|
485
487
|
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
end
|
493
|
-
rescue Timeout::Error
|
494
|
-
# no action - try again
|
495
|
-
rescue => e
|
496
|
-
warn e.to_s
|
488
|
+
def try_request(request, community=@community, host=@host, port=@port)
|
489
|
+
(@retries + 1).times do |n|
|
490
|
+
send_request(request, community, host, port)
|
491
|
+
begin
|
492
|
+
Timeout.timeout(@timeout) do
|
493
|
+
return get_response(request)
|
497
494
|
end
|
495
|
+
rescue Timeout::Error
|
496
|
+
# no action - try again
|
497
|
+
rescue => e
|
498
|
+
warn e.to_s
|
498
499
|
end
|
499
|
-
raise RequestTimeout, "host #{config[:host]} not responding", caller
|
500
500
|
end
|
501
|
+
raise RequestTimeout, "host #{config[:host]} not responding", caller
|
502
|
+
end
|
501
503
|
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
504
|
+
def send_request(request, community, host, port)
|
505
|
+
message = Message.new(@snmp_version, community, request)
|
506
|
+
@transport.send(message.encode, host, port)
|
507
|
+
end
|
506
508
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
509
|
+
##
|
510
|
+
# Wait until response arrives. Ignore responses with mismatched IDs;
|
511
|
+
# these responses are typically from previous requests that timed out
|
512
|
+
# or almost timed out.
|
513
|
+
#
|
514
|
+
def get_response(request)
|
515
|
+
begin
|
516
|
+
data = @transport.recv(@max_bytes)
|
517
|
+
message = Message.decode(data, @mib)
|
518
|
+
response = message.pdu
|
519
|
+
end until request.request_id == response.request_id
|
520
|
+
response
|
521
|
+
end
|
520
522
|
end
|
521
523
|
|
522
524
|
class UDPServerTransport
|
@@ -559,14 +561,16 @@ module SNMP
|
|
559
561
|
class Config < Options
|
560
562
|
option :host, :Host, 'localhost'
|
561
563
|
option :port, :Port, 162
|
562
|
-
option :community, :Community,
|
564
|
+
option :community, :Community, nil
|
563
565
|
option :server_transport, :ServerTransport, UDPServerTransport
|
564
566
|
option :max_recv_bytes, :MaxReceiveBytes, 8000
|
567
|
+
option :mib_dir, :MibDir, MIB::DEFAULT_MIB_PATH
|
568
|
+
option :mib_modules, :MibModules, default_modules
|
565
569
|
option :use_IPv6, :use_IPv6, false
|
566
570
|
|
567
571
|
def create_transport
|
568
572
|
server_transport.respond_to?(:new) ?
|
569
|
-
|
573
|
+
server_transport.new(host, port, socket_address_family) : server_transport
|
570
574
|
end
|
571
575
|
end
|
572
576
|
|
@@ -591,11 +595,18 @@ module SNMP
|
|
591
595
|
# 2. handler for a specific SNMP version
|
592
596
|
# 3. default handler
|
593
597
|
#
|
598
|
+
# The default for the :community option is 'nil' allows traps with any
|
599
|
+
# community to be accepted. To only accept traps from a specific community,
|
600
|
+
# the community may also be set to a string (e.g. 'public') or a list of
|
601
|
+
# strings (e.g. ['public', 'my_private_community'] ).
|
602
|
+
#
|
594
603
|
def initialize(options={}, &block)
|
595
604
|
config = Config.new(options)
|
596
605
|
@transport = config.create_transport
|
597
606
|
@community = config.community
|
598
607
|
@max_bytes = config.max_recv_bytes
|
608
|
+
@mib = MIB.new
|
609
|
+
load_modules(config.mib_modules, config.mib_dir)
|
599
610
|
@config = config.applied_config
|
600
611
|
|
601
612
|
@handler_init = block
|
@@ -671,55 +682,63 @@ module SNMP
|
|
671
682
|
|
672
683
|
private
|
673
684
|
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
685
|
+
def load_modules(module_list, mib_dir)
|
686
|
+
module_list.each { |m| @mib.load_module(m, mib_dir) }
|
687
|
+
end
|
688
|
+
|
689
|
+
def process_traps(trap_listener)
|
690
|
+
@handler_init.call(trap_listener) if @handler_init
|
691
|
+
loop do
|
692
|
+
data, source_ip, source_port = @transport.recvfrom(@max_bytes)
|
693
|
+
begin
|
694
|
+
message = Message.decode(data, @mib)
|
695
|
+
if community_allowed? message.community
|
696
|
+
trap = message.pdu
|
697
|
+
if trap.kind_of?(InformRequest)
|
698
|
+
@transport.send(message.response.encode, source_ip, source_port)
|
687
699
|
end
|
688
|
-
|
689
|
-
|
690
|
-
puts e.backtrace.join("\n")
|
691
|
-
puts "Received data:"
|
692
|
-
p data
|
700
|
+
trap.source_ip = source_ip
|
701
|
+
select_handler(trap).call(trap)
|
693
702
|
end
|
703
|
+
rescue => e
|
704
|
+
puts "Error handling trap: #{e}"
|
705
|
+
puts e.backtrace.join("\n")
|
706
|
+
puts "Received data:"
|
707
|
+
p data
|
694
708
|
end
|
695
709
|
end
|
710
|
+
end
|
696
711
|
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
if @v1_handler
|
712
|
-
return @v1_handler
|
713
|
-
elsif @default_handler
|
714
|
-
return @default_handler
|
715
|
-
else
|
716
|
-
return NULL_HANDLER
|
717
|
-
end
|
712
|
+
def community_allowed?(msg_community)
|
713
|
+
@community.nil? || @community == msg_community || !(Array(@community) & Array(msg_community)).empty?
|
714
|
+
end
|
715
|
+
|
716
|
+
def select_handler(trap)
|
717
|
+
@lock.synchronize do
|
718
|
+
if trap.kind_of?(SNMPv2_Trap)
|
719
|
+
oid = trap.trap_oid
|
720
|
+
if @oid_handler[oid]
|
721
|
+
return @oid_handler[oid]
|
722
|
+
elsif @v2c_handler
|
723
|
+
return @v2c_handler
|
724
|
+
elsif @default_handler
|
725
|
+
return @default_handler
|
718
726
|
else
|
719
727
|
return NULL_HANDLER
|
720
728
|
end
|
729
|
+
elsif trap.kind_of?(SNMPv1_Trap)
|
730
|
+
if @v1_handler
|
731
|
+
return @v1_handler
|
732
|
+
elsif @default_handler
|
733
|
+
return @default_handler
|
734
|
+
else
|
735
|
+
return NULL_HANDLER
|
736
|
+
end
|
737
|
+
else
|
738
|
+
return NULL_HANDLER
|
721
739
|
end
|
722
740
|
end
|
741
|
+
end
|
723
742
|
end
|
724
743
|
|
725
744
|
end
|
data/lib/snmp/mib.rb
CHANGED
@@ -136,6 +136,7 @@ module SNMP
|
|
136
136
|
def initialize
|
137
137
|
@by_name = {}
|
138
138
|
@by_module_by_name = {}
|
139
|
+
@by_oid = {}
|
139
140
|
end
|
140
141
|
|
141
142
|
##
|
@@ -152,6 +153,9 @@ module SNMP
|
|
152
153
|
end
|
153
154
|
@by_module_by_name[module_name] = {}
|
154
155
|
@by_module_by_name[module_name].merge!(oid_hash)
|
156
|
+
|
157
|
+
name_hash = Hash[ oid_hash.invert.to_a.collect { |oid, name| [oid, "#{module_name}::#{name}"] } ]
|
158
|
+
@by_oid.merge!(name_hash)
|
155
159
|
end
|
156
160
|
|
157
161
|
##
|
@@ -234,6 +238,24 @@ module SNMP
|
|
234
238
|
end
|
235
239
|
end
|
236
240
|
|
241
|
+
##
|
242
|
+
# Returns the symbolic name of the given OID.
|
243
|
+
#
|
244
|
+
# e.g. OID "1.3.6.1.2.1.1.0" returns symbol "SNMPv2-MIB::system.0"
|
245
|
+
#
|
246
|
+
def name(oid)
|
247
|
+
current_oid = ObjectId.new(oid)
|
248
|
+
index = []
|
249
|
+
while current_oid.size > 1
|
250
|
+
name = @by_oid[current_oid.to_s]
|
251
|
+
if name
|
252
|
+
return index.empty? ? name : "#{name}.#{index.join('.')}"
|
253
|
+
end
|
254
|
+
index.unshift current_oid.slice!(-1)
|
255
|
+
end
|
256
|
+
ObjectId.new(oid).to_s
|
257
|
+
end
|
258
|
+
|
237
259
|
def parse_oid(node_hash, name)
|
238
260
|
oid_parts = name.split(".")
|
239
261
|
first_part = oid_parts.shift
|
data/lib/snmp/options.rb
CHANGED
@@ -18,7 +18,7 @@ module SNMP
|
|
18
18
|
attr_reader :alternates
|
19
19
|
|
20
20
|
def option(symbol, alternate, defaulter=nil)
|
21
|
-
@alternates
|
21
|
+
@alternates ||= {}
|
22
22
|
@alternates[symbol] = alternate
|
23
23
|
define_method(symbol) do
|
24
24
|
alternate_symbol = self.class.alternates[symbol]
|
data/lib/snmp/pdu.rb
CHANGED
@@ -32,12 +32,12 @@ module SNMP
|
|
32
32
|
attr_reader :pdu
|
33
33
|
|
34
34
|
class << self
|
35
|
-
def decode(data)
|
35
|
+
def decode(data, mib=nil)
|
36
36
|
message_data, remainder = decode_sequence(data)
|
37
37
|
assert_no_remainder(remainder)
|
38
38
|
version, remainder = decode_version(message_data)
|
39
39
|
community, remainder = decode_octet_string(remainder)
|
40
|
-
pdu, remainder = decode_pdu(version, remainder)
|
40
|
+
pdu, remainder = decode_pdu(version, remainder, mib)
|
41
41
|
assert_no_remainder(remainder)
|
42
42
|
Message.new(version, community, pdu)
|
43
43
|
end
|
@@ -54,29 +54,29 @@ module SNMP
|
|
54
54
|
return version, remainder
|
55
55
|
end
|
56
56
|
|
57
|
-
def decode_pdu(version, data)
|
57
|
+
def decode_pdu(version, data, mib=nil)
|
58
58
|
pdu_tag, pdu_data, remainder = decode_tlv(data)
|
59
59
|
case pdu_tag
|
60
60
|
when GetRequest_PDU_TAG
|
61
|
-
pdu = PDU.decode(GetRequest, pdu_data)
|
61
|
+
pdu = PDU.decode(GetRequest, pdu_data, mib)
|
62
62
|
when GetNextRequest_PDU_TAG
|
63
|
-
pdu = PDU.decode(GetNextRequest, pdu_data)
|
63
|
+
pdu = PDU.decode(GetNextRequest, pdu_data, mib)
|
64
64
|
when Response_PDU_TAG
|
65
|
-
pdu = PDU.decode(Response, pdu_data)
|
65
|
+
pdu = PDU.decode(Response, pdu_data, mib)
|
66
66
|
when SetRequest_PDU_TAG
|
67
|
-
pdu = PDU.decode(SetRequest, pdu_data)
|
67
|
+
pdu = PDU.decode(SetRequest, pdu_data, mib)
|
68
68
|
when SNMPv1_Trap_PDU_TAG
|
69
69
|
raise InvalidPduTag, "SNMPv1-trap not valid for #{version.to_s}" if version != :SNMPv1
|
70
|
-
pdu = SNMPv1_Trap.decode(pdu_data)
|
70
|
+
pdu = SNMPv1_Trap.decode(pdu_data, mib)
|
71
71
|
when GetBulkRequest_PDU_TAG
|
72
72
|
raise InvalidPduTag, "get-bulk not valid for #{version.to_s}" if version != :SNMPv2c
|
73
|
-
pdu = PDU.decode(GetBulkRequest, pdu_data)
|
73
|
+
pdu = PDU.decode(GetBulkRequest, pdu_data, mib)
|
74
74
|
when InformRequest_PDU_TAG
|
75
75
|
raise InvalidPduTag, "inform not valid for #{version.to_s}" if version != :SNMPv2c
|
76
|
-
pdu = PDU.decode(InformRequest, pdu_data)
|
76
|
+
pdu = PDU.decode(InformRequest, pdu_data, mib)
|
77
77
|
when SNMPv2_Trap_PDU_TAG
|
78
78
|
raise InvalidPduTag, "SNMPv2c-trap not valid for #{version.to_s}" if version != :SNMPv2c
|
79
|
-
pdu = PDU.decode(SNMPv2_Trap, pdu_data)
|
79
|
+
pdu = PDU.decode(SNMPv2_Trap, pdu_data, mib)
|
80
80
|
else
|
81
81
|
raise UnsupportedPduTag, pdu_tag.to_s
|
82
82
|
end
|
@@ -119,11 +119,11 @@ module SNMP
|
|
119
119
|
|
120
120
|
alias vb_list varbind_list
|
121
121
|
|
122
|
-
def self.decode(pdu_class, pdu_data)
|
122
|
+
def self.decode(pdu_class, pdu_data, mib=nil)
|
123
123
|
request_id, remainder = decode_integer(pdu_data)
|
124
124
|
error_status, remainder = decode_integer(remainder)
|
125
125
|
error_index, remainder = decode_integer(remainder)
|
126
|
-
varbind_list, remainder = VarBindList.decode(remainder)
|
126
|
+
varbind_list, remainder = VarBindList.decode(remainder, mib)
|
127
127
|
assert_no_remainder(remainder)
|
128
128
|
pdu_class.new(request_id, varbind_list, error_status, error_index)
|
129
129
|
end
|
@@ -310,7 +310,7 @@ module SNMP
|
|
310
310
|
|
311
311
|
alias :vb_list :varbind_list
|
312
312
|
|
313
|
-
def self.decode(pdu_data)
|
313
|
+
def self.decode(pdu_data, mib=nil)
|
314
314
|
oid_data, remainder = decode_object_id(pdu_data)
|
315
315
|
enterprise = ObjectId.new(oid_data)
|
316
316
|
ip_data, remainder = decode_ip_address(remainder)
|
@@ -319,7 +319,7 @@ module SNMP
|
|
319
319
|
specific_trap, remainder = decode_integer(remainder)
|
320
320
|
time_data, remainder = decode_timeticks(remainder)
|
321
321
|
timestamp = TimeTicks.new(time_data)
|
322
|
-
varbind_list, remainder = VarBindList.decode(remainder)
|
322
|
+
varbind_list, remainder = VarBindList.decode(remainder, mib)
|
323
323
|
assert_no_remainder(remainder)
|
324
324
|
SNMPv1_Trap.new(enterprise, agent_addr, generic_trap, specific_trap,
|
325
325
|
timestamp, varbind_list)
|
data/lib/snmp/varbind.rb
CHANGED
@@ -17,11 +17,11 @@ module SNMP
|
|
17
17
|
class InvalidIpAddress < ArgumentError; end
|
18
18
|
|
19
19
|
class VarBindList < Array
|
20
|
-
def self.decode(data)
|
20
|
+
def self.decode(data, mib=nil)
|
21
21
|
list = VarBindList.new
|
22
22
|
varbind_data, remainder = decode_sequence(data)
|
23
23
|
while varbind_data != ""
|
24
|
-
varbind, varbind_data = VarBind.decode(varbind_data)
|
24
|
+
varbind, varbind_data = VarBind.decode(varbind_data, mib)
|
25
25
|
list << varbind
|
26
26
|
end
|
27
27
|
return list, remainder
|
@@ -137,8 +137,8 @@ module SNMP
|
|
137
137
|
class ObjectId < Array
|
138
138
|
include Comparable
|
139
139
|
|
140
|
-
def self.decode(value_data)
|
141
|
-
ObjectId.new(decode_object_id_value(value_data))
|
140
|
+
def self.decode(value_data, mib=nil)
|
141
|
+
ObjectId.new(decode_object_id_value(value_data), mib)
|
142
142
|
end
|
143
143
|
|
144
144
|
def asn1_type
|
@@ -149,7 +149,7 @@ module SNMP
|
|
149
149
|
# Create an object id. The input is expected to be either a string
|
150
150
|
# in the format "n.n.n.n.n.n" or an array of integers.
|
151
151
|
#
|
152
|
-
def initialize(id=[])
|
152
|
+
def initialize(id=[], mib=nil)
|
153
153
|
if id.nil?
|
154
154
|
raise ArgumentError
|
155
155
|
elsif id.respond_to? :to_str
|
@@ -157,10 +157,19 @@ module SNMP
|
|
157
157
|
else
|
158
158
|
super(make_integers(id.to_ary))
|
159
159
|
end
|
160
|
+
@mib = mib
|
160
161
|
rescue ArgumentError
|
161
162
|
raise ArgumentError, "#{id.inspect}:#{id.class} not a valid object ID"
|
162
163
|
end
|
163
164
|
|
165
|
+
##
|
166
|
+
# Adds MIB information to this object_id for use with to_s.
|
167
|
+
#
|
168
|
+
def with_mib(mib)
|
169
|
+
@mib = mib
|
170
|
+
self
|
171
|
+
end
|
172
|
+
|
164
173
|
def to_varbind
|
165
174
|
VarBind.new(self, Null)
|
166
175
|
end
|
@@ -170,11 +179,19 @@ module SNMP
|
|
170
179
|
end
|
171
180
|
|
172
181
|
def to_s
|
182
|
+
if @mib
|
183
|
+
@mib.name(self)
|
184
|
+
else
|
185
|
+
to_str
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def to_str
|
173
190
|
self.join('.')
|
174
191
|
end
|
175
192
|
|
176
193
|
def inspect
|
177
|
-
"[#{
|
194
|
+
"[#{to_str}]"
|
178
195
|
end
|
179
196
|
|
180
197
|
def encode
|
@@ -507,12 +524,12 @@ module SNMP
|
|
507
524
|
alias :oid :name
|
508
525
|
|
509
526
|
class << self
|
510
|
-
def decode(data)
|
527
|
+
def decode(data, mib=nil)
|
511
528
|
varbind_data, remaining_varbind_data = decode_sequence(data)
|
512
529
|
name, remainder = decode_object_id(varbind_data)
|
513
530
|
value, remainder = decode_value(remainder)
|
514
531
|
assert_no_remainder(remainder)
|
515
|
-
return VarBind.new(name, value), remaining_varbind_data
|
532
|
+
return VarBind.new(name, value).with_mib(mib), remaining_varbind_data
|
516
533
|
end
|
517
534
|
|
518
535
|
ValueDecoderMap = {
|
@@ -553,6 +570,15 @@ module SNMP
|
|
553
570
|
@value = value
|
554
571
|
end
|
555
572
|
|
573
|
+
##
|
574
|
+
# Adds MIB information to this varbind for use with to_s.
|
575
|
+
#
|
576
|
+
def with_mib(mib)
|
577
|
+
@name.with_mib(mib) if @name
|
578
|
+
@value.with_mib(mib) if @value.respond_to? :with_mib
|
579
|
+
self
|
580
|
+
end
|
581
|
+
|
556
582
|
def asn1_type
|
557
583
|
"VarBind"
|
558
584
|
end
|
data/lib/snmp/version.rb
CHANGED
data/test/test_manager.rb
CHANGED
@@ -143,8 +143,8 @@ class TestManager < Test::Unit::TestCase
|
|
143
143
|
assert_equal(:noError, response.error_status)
|
144
144
|
assert_equal(0, response.error_index)
|
145
145
|
assert_equal(2, response.varbind_list.length)
|
146
|
-
assert_equal("
|
147
|
-
assert_equal("
|
146
|
+
assert_equal("SNMPv2-SMI::experimental.1.1.1.0", response.varbind_list[0].name.to_s)
|
147
|
+
assert_equal("SNMPv2-SMI::experimental.1.1.2.0", response.varbind_list[1].name.to_s)
|
148
148
|
end
|
149
149
|
|
150
150
|
def test_walk
|
@@ -206,12 +206,12 @@ class TestManager < Test::Unit::TestCase
|
|
206
206
|
def test_inform
|
207
207
|
response = @manager.inform(1234, "1.3.6.1.2.3.4")
|
208
208
|
assert_equal(1234, response.vb_list[0].value)
|
209
|
-
assert_equal("
|
209
|
+
assert_equal("SNMPv2-SMI::mgmt.3.4", response.vb_list[1].value.to_s)
|
210
210
|
assert_equal(2, response.vb_list.length)
|
211
211
|
|
212
212
|
response = @manager.inform(1234, "1.3.6.1.2.3.4", ["1.2.3", "1.4.5.6"])
|
213
213
|
assert_equal(1234, response.vb_list[0].value)
|
214
|
-
assert_equal("
|
214
|
+
assert_equal("SNMPv2-SMI::mgmt.3.4", response.vb_list[1].value.to_s)
|
215
215
|
assert_equal(4, response.vb_list.length)
|
216
216
|
end
|
217
217
|
end
|
@@ -289,15 +289,33 @@ class TestTrapListener < Test::Unit::TestCase
|
|
289
289
|
assert(oid_called)
|
290
290
|
end
|
291
291
|
|
292
|
-
|
292
|
+
##
|
293
|
+
# Should filter traps with a 'public' community if that community is not accepted
|
294
|
+
#
|
295
|
+
def test_reject_community
|
296
|
+
assert !public_trap_passes?("test")
|
297
|
+
assert !public_trap_passes?(["foo", "bar"])
|
298
|
+
assert !public_trap_passes?([])
|
299
|
+
end
|
300
|
+
|
301
|
+
##
|
302
|
+
# Should accept traps with a 'public' community if that community is allowed.
|
303
|
+
#
|
304
|
+
def test_accept_community
|
305
|
+
assert public_trap_passes? "public"
|
306
|
+
assert public_trap_passes? ["test", "public"]
|
307
|
+
assert public_trap_passes? nil
|
308
|
+
end
|
309
|
+
|
310
|
+
def public_trap_passes?(community_filter)
|
293
311
|
default_called = false
|
294
312
|
m = TrapListener.new(
|
295
|
-
|
296
|
-
|
313
|
+
:community => community_filter,
|
314
|
+
:server_transport => TrapTestTransport.new) do |manager|
|
297
315
|
manager.on_trap_default { default_called = true }
|
298
316
|
end
|
299
317
|
m.join
|
300
|
-
|
318
|
+
default_called
|
301
319
|
end
|
302
320
|
|
303
321
|
end
|
data/test/test_mib.rb
CHANGED
@@ -7,6 +7,7 @@ module SNMP
|
|
7
7
|
|
8
8
|
def setup
|
9
9
|
@mib = MIB.new
|
10
|
+
@mib.load_module("SNMPv2-SMI")
|
10
11
|
@mib.load_module("SNMPv2-MIB")
|
11
12
|
@mib.load_module("IF-MIB")
|
12
13
|
end
|
@@ -71,6 +72,20 @@ module SNMP
|
|
71
72
|
assert_equal(4, list.length)
|
72
73
|
end
|
73
74
|
|
75
|
+
def test_name
|
76
|
+
cases = [["1.3.6.1.2.1.2.2.3.45", "IF-MIB::ifTable.3.45"],
|
77
|
+
["1.3.6.1.2.1.1.0", "SNMPv2-MIB::system.0"],
|
78
|
+
["1.2.3.4", "1.2.3.4"],
|
79
|
+
["1.3", "SNMPv2-SMI::org"],
|
80
|
+
["1.2", "1.2"],
|
81
|
+
["1", "1"],
|
82
|
+
["", ""]]
|
83
|
+
cases.each do |oid, expected_name|
|
84
|
+
name = @mib.name(oid)
|
85
|
+
assert_equal(expected_name, name)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
74
89
|
# def test_import
|
75
90
|
# module_name = MIB.import_module('SNMPv2-MIB')
|
76
91
|
# assert_equal('SNMPv2-MIB', module_name)
|
data/test/test_varbind.rb
CHANGED
@@ -22,6 +22,17 @@ class TestVarBind < Test::Unit::TestCase
|
|
22
22
|
assert_equal("0\f\006\010+\006\001\002\001\001\002\000\005\000", remainder)
|
23
23
|
end
|
24
24
|
|
25
|
+
def test_varbind_to_s
|
26
|
+
mib = MIB.new
|
27
|
+
mib.load_module("IF-MIB")
|
28
|
+
|
29
|
+
vb = VarBind.new("1.3.6.1.2.1.2.2.1.2.1.1", OctetString.new("description")).with_mib(mib)
|
30
|
+
assert_equal "[name=IF-MIB::ifDescr.1.1, value=description (OCTET STRING)]", vb.to_s
|
31
|
+
|
32
|
+
vb = VarBind.new("1.3.6.1.2.1.2.2.1.2.1.1", ObjectId.new("1.3.6.1.2.1.2.2.1.2.1.1")).with_mib(mib)
|
33
|
+
assert_equal "[name=IF-MIB::ifDescr.1.1, value=IF-MIB::ifDescr.1.1 (OBJECT IDENTIFIER)]", vb.to_s
|
34
|
+
end
|
35
|
+
|
25
36
|
def test_varbind_name_alias_oid
|
26
37
|
vb = VarBind.new("1.2.3.4", OctetString.new("blah"))
|
27
38
|
assert_equal(ObjectId.new("1.2.3.4"), vb.name)
|
@@ -124,6 +135,15 @@ class TestVarBind < Test::Unit::TestCase
|
|
124
135
|
assert_equal("", ObjectId.new.to_s)
|
125
136
|
end
|
126
137
|
|
138
|
+
def test_object_id_to_s_with_mib
|
139
|
+
mib = MIB.new
|
140
|
+
mib.load_module("IF-MIB")
|
141
|
+
id = ObjectId.new("1.3.6.1.2.1.2.2.1.2.1.1", mib)
|
142
|
+
assert_equal("IF-MIB::ifDescr.1.1", id.to_s)
|
143
|
+
assert_equal("1.3.6.1.2.1.2.2.1.2.1.1", id.to_str)
|
144
|
+
assert_equal("[1.3.6.1.2.1.2.2.1.2.1.1]", id.inspect)
|
145
|
+
end
|
146
|
+
|
127
147
|
def test_object_id_create
|
128
148
|
assert_equal("1.3.6.1", ObjectId.new("1.3.6.1").to_s)
|
129
149
|
assert_equal("1.3.6.1", ObjectId.new([1,3,6,1]).to_s)
|
data/test/test_walk.rb
CHANGED
@@ -116,7 +116,7 @@ class TestWalk < Test::Unit::TestCase
|
|
116
116
|
ifTable6_manager.walk(["1.3.6.1.2.1.2.2.1.2"]) do |vb_list|
|
117
117
|
executed_block = true
|
118
118
|
assert_equal(1, vb_list.length)
|
119
|
-
assert_equal("
|
119
|
+
assert_equal("IF-MIB::ifDescr.1", vb_list.first.name.to_s)
|
120
120
|
break
|
121
121
|
end
|
122
122
|
assert(executed_block, "Did not execute block")
|
@@ -155,8 +155,8 @@ class TestWalk < Test::Unit::TestCase
|
|
155
155
|
def test_one
|
156
156
|
list = []
|
157
157
|
ifTable1_manager.walk(["1.3.6.1.2.1.2.2.1.1", "1.3.6.1.2.1.2.2.1.2"]) do |vb|
|
158
|
-
assert_equal("
|
159
|
-
assert_equal("
|
158
|
+
assert_equal("IF-MIB::ifIndex.1", vb[0].name.to_s)
|
159
|
+
assert_equal("IF-MIB::ifDescr.1", vb[1].name.to_s)
|
160
160
|
list << vb
|
161
161
|
end
|
162
162
|
assert_equal(1, list.length)
|
@@ -165,11 +165,11 @@ class TestWalk < Test::Unit::TestCase
|
|
165
165
|
def test_hole_in_one
|
166
166
|
list = []
|
167
167
|
ifTable1_manager.walk(["ifIndex", "ifDescr", "ifType"]) do |vb|
|
168
|
-
assert_equal("
|
168
|
+
assert_equal("IF-MIB::ifIndex.1", vb[0].name.to_s)
|
169
169
|
assert_equal(1, vb[0].value)
|
170
|
-
assert_equal("
|
170
|
+
assert_equal("IF-MIB::ifDescr.1", vb[1].name.to_s)
|
171
171
|
assert_equal("lo0", vb[1].value)
|
172
|
-
assert_equal("
|
172
|
+
assert_equal("IF-MIB::ifType.1", vb[2].name.to_s)
|
173
173
|
assert_equal(NoSuchInstance, vb[2].value)
|
174
174
|
list << vb
|
175
175
|
break
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-22 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: A Ruby implementation of SNMP (the Simple Network Management Protocol).
|
15
15
|
email: hallidave@gmail.com
|