snmp 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|