netsnmp 0.6.0 → 0.6.3
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 +4 -4
- data/lib/netsnmp/client.rb +5 -2
- data/lib/netsnmp/encryption/aes.rb +3 -3
- data/lib/netsnmp/encryption/des.rb +4 -4
- data/lib/netsnmp/errors.rb +9 -4
- data/lib/netsnmp/extensions.rb +12 -1
- data/lib/netsnmp/loggable.rb +1 -2
- data/lib/netsnmp/message.rb +6 -6
- data/lib/netsnmp/mib/parser.rb +39 -39
- data/lib/netsnmp/mib.rb +17 -11
- data/lib/netsnmp/oid.rb +6 -3
- data/lib/netsnmp/pdu.rb +20 -23
- data/lib/netsnmp/scoped_pdu.rb +7 -6
- data/lib/netsnmp/security_parameters.rb +54 -54
- data/lib/netsnmp/session.rb +14 -12
- data/lib/netsnmp/timeticks.rb +1 -0
- data/lib/netsnmp/v3_session.rb +7 -7
- data/lib/netsnmp/varbind.rb +21 -11
- data/lib/netsnmp/version.rb +1 -1
- data/lib/netsnmp.rb +9 -9
- data/sig/client.rbs +8 -2
- data/sig/encryption/aes.rbs +23 -0
- data/sig/encryption/des.rbs +23 -0
- data/sig/errors.rbs +13 -0
- data/sig/extensions.rbs +12 -0
- data/sig/loggable.rbs +4 -7
- data/sig/message.rbs +10 -2
- data/sig/mib.rbs +20 -6
- data/sig/netsnmp.rbs +5 -5
- data/sig/oid.rbs +1 -0
- data/sig/pdu.rbs +14 -15
- data/sig/scoped_pdu.rbs +9 -4
- data/sig/security_parameters.rbs +29 -23
- data/sig/session.rbs +21 -6
- data/sig/timeticks.rbs +19 -0
- data/sig/v3_session.rbs +3 -2
- data/sig/varbind.rbs +13 -2
- data/spec/client_spec.rb +8 -8
- data/spec/pdu_spec.rb +2 -1
- metadata +8 -4
- data/sig/openssl.rbs +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff50c7291ee08e73da4c20435990ba7d4699a0489bbb454beb0577184988e865
|
4
|
+
data.tar.gz: 77e25540c9816c6c92e8c2783a276426149a468a9ea9c8f21130f260bbfcc1ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6b15908f819e3363ebb80d8bb556256025f8ef560abf796336b675cd22e487e5cc65f985ef993e771733dcc738d8b73625e124a2e3b42866bdb743fb9848e46
|
7
|
+
data.tar.gz: 9886d5aa5a0de7bbb8f71b1ef8a9eb9aacf29faa5363b09362b1ebb78ad6de8075a60251d2b0891d18fd7f1c6fa6d05a4ba20c91da55eeace0837f3d8a7d4437
|
data/lib/netsnmp/client.rb
CHANGED
@@ -28,12 +28,14 @@ module NETSNMP
|
|
28
28
|
when Integer then version # assume the use know what he's doing
|
29
29
|
when /v?1/ then 0
|
30
30
|
when /v?2c?/ then 1
|
31
|
-
when /v?3
|
31
|
+
when /v?3/ then 3
|
32
|
+
else 3 # rubocop:disable Lint/DuplicateBranch
|
32
33
|
end
|
33
34
|
|
34
|
-
@retries = options.fetch(:retries, RETRIES)
|
35
|
+
@retries = options.fetch(:retries, RETRIES).to_i
|
35
36
|
@session ||= version == 3 ? V3Session.new(**options) : Session.new(version: version, **options)
|
36
37
|
return unless block_given?
|
38
|
+
|
37
39
|
begin
|
38
40
|
yield self
|
39
41
|
ensure
|
@@ -155,6 +157,7 @@ module NETSNMP
|
|
155
157
|
yield
|
156
158
|
rescue Timeout::Error, IdNotInTimeWindowError => e
|
157
159
|
raise e if retries.zero?
|
160
|
+
|
158
161
|
retries -= 1
|
159
162
|
retry
|
160
163
|
end
|
@@ -9,7 +9,7 @@ module NETSNMP
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def encrypt(decrypted_data, engine_boots:, engine_time:)
|
12
|
-
cipher = OpenSSL::Cipher
|
12
|
+
cipher = OpenSSL::Cipher.new("aes-128-cfb")
|
13
13
|
|
14
14
|
iv, salt = generate_encryption_key(engine_boots, engine_time)
|
15
15
|
|
@@ -29,7 +29,7 @@ module NETSNMP
|
|
29
29
|
def decrypt(encrypted_data, salt:, engine_boots:, engine_time:)
|
30
30
|
raise Error, "invalid priv salt received" unless !salt.empty? && (salt.length % 8).zero?
|
31
31
|
|
32
|
-
cipher = OpenSSL::Cipher
|
32
|
+
cipher = OpenSSL::Cipher.new("aes-128-cfb")
|
33
33
|
cipher.padding = 0
|
34
34
|
|
35
35
|
iv = generate_decryption_key(engine_boots, engine_time, salt)
|
@@ -40,7 +40,7 @@ module NETSNMP
|
|
40
40
|
decrypted_data = cipher.update(encrypted_data) + cipher.final
|
41
41
|
|
42
42
|
hlen, bodylen = OpenSSL::ASN1.traverse(decrypted_data) { |_, _, x, y, *| break x, y }
|
43
|
-
decrypted_data.byteslice(0, hlen + bodylen)
|
43
|
+
decrypted_data.byteslice(0, hlen + bodylen) || "".b
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
@@ -11,7 +11,7 @@ module NETSNMP
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def encrypt(decrypted_data, engine_boots:, **)
|
14
|
-
cipher = OpenSSL::Cipher
|
14
|
+
cipher = OpenSSL::Cipher.new("des-cbc")
|
15
15
|
|
16
16
|
iv, salt = generate_encryption_key(engine_boots)
|
17
17
|
|
@@ -31,7 +31,7 @@ module NETSNMP
|
|
31
31
|
raise Error, "invalid priv salt received" unless (salt.length % 8).zero?
|
32
32
|
raise Error, "invalid encrypted PDU received" unless (encrypted_data.length % 8).zero?
|
33
33
|
|
34
|
-
cipher = OpenSSL::Cipher
|
34
|
+
cipher = OpenSSL::Cipher.new("des-cbc")
|
35
35
|
cipher.padding = 0
|
36
36
|
|
37
37
|
iv = generate_decryption_key(salt)
|
@@ -42,7 +42,7 @@ module NETSNMP
|
|
42
42
|
decrypted_data = cipher.update(encrypted_data) + cipher.final
|
43
43
|
|
44
44
|
hlen, bodylen = OpenSSL::ASN1.traverse(decrypted_data) { |_, _, x, y, *| break x, y }
|
45
|
-
decrypted_data.byteslice(0, hlen + bodylen)
|
45
|
+
decrypted_data.byteslice(0, hlen + bodylen) || "".b
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
@@ -70,7 +70,7 @@ module NETSNMP
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def des_key
|
73
|
-
@priv_key[0, 8]
|
73
|
+
@priv_key[0, 8] || "".b
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
data/lib/netsnmp/errors.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module NETSNMP
|
4
|
-
Error
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
class Error < StandardError; end
|
5
|
+
|
6
|
+
class ConnectionFailed < Error; end
|
7
|
+
|
8
|
+
class AuthenticationFailed < Error; end
|
9
|
+
|
10
|
+
class IdNotInTimeWindowError < Error; end
|
11
|
+
|
12
|
+
class OidNotFound < StandardError; end
|
8
13
|
end
|
data/lib/netsnmp/extensions.rb
CHANGED
@@ -14,6 +14,17 @@ module NETSNMP
|
|
14
14
|
|
15
15
|
module StringExtensions
|
16
16
|
refine(String) do
|
17
|
+
unless String.method_defined?(:delete_prefix)
|
18
|
+
def delete_prefix(prefix)
|
19
|
+
prefix = String(prefix)
|
20
|
+
if rindex(prefix, 0)
|
21
|
+
self[prefix.length..-1]
|
22
|
+
else
|
23
|
+
dup
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
17
28
|
unless String.method_defined?(:match?)
|
18
29
|
def match?(*args)
|
19
30
|
!match(*args).nil?
|
@@ -107,7 +118,7 @@ module NETSNMP
|
|
107
118
|
# Like a string, but it prints an hex-string version of itself
|
108
119
|
class HexString < String
|
109
120
|
def inspect
|
110
|
-
Hexdump.dump(
|
121
|
+
Hexdump.dump(to_s, in_groups_of: 2, separator: " ")
|
111
122
|
end
|
112
123
|
end
|
113
124
|
end
|
data/lib/netsnmp/loggable.rb
CHANGED
@@ -5,8 +5,7 @@ module NETSNMP
|
|
5
5
|
DEBUG = ENV.key?("NETSNMP_DEBUG") ? $stderr : nil
|
6
6
|
DEBUG_LEVEL = (ENV["NETSNMP_DEBUG"] || 1).to_i
|
7
7
|
|
8
|
-
def
|
9
|
-
super(**opts)
|
8
|
+
def initialize_logger(debug: DEBUG, debug_level: DEBUG_LEVEL, **)
|
10
9
|
@debug = debug
|
11
10
|
@debug_level = debug_level
|
12
11
|
end
|
data/lib/netsnmp/message.rb
CHANGED
@@ -5,7 +5,7 @@ module NETSNMP
|
|
5
5
|
class Message
|
6
6
|
using ASNExtensions
|
7
7
|
|
8
|
-
|
8
|
+
include Loggable
|
9
9
|
|
10
10
|
PRIVNONE = OpenSSL::ASN1::OctetString.new("")
|
11
11
|
MSG_MAX_SIZE = OpenSSL::ASN1::Integer.new(65507).with_label(:max_message_size)
|
@@ -13,7 +13,9 @@ module NETSNMP
|
|
13
13
|
MSG_VERSION = OpenSSL::ASN1::Integer.new(3).with_label(:message_version)
|
14
14
|
MSG_REPORTABLE = 4
|
15
15
|
|
16
|
-
def initialize(**)
|
16
|
+
def initialize(**args)
|
17
|
+
initialize_logger(**args)
|
18
|
+
end
|
17
19
|
|
18
20
|
def verify(stream, auth_param, security_level, security_parameters:)
|
19
21
|
security_parameters.verify(stream.sub(auth_param, authnone(security_parameters.auth_protocol).value), auth_param, security_level: security_level)
|
@@ -65,12 +67,10 @@ module NETSNMP
|
|
65
67
|
security_level: security_level)
|
66
68
|
|
67
69
|
log { "received response PDU" }
|
68
|
-
pdu = ScopedPDU.decode(encoded_pdu)
|
69
|
-
pdu.auth_param = auth_param
|
70
|
-
pdu.security_level = security_level
|
70
|
+
pdu = ScopedPDU.decode(encoded_pdu, auth_param: auth_param, security_level: security_level)
|
71
71
|
|
72
72
|
log(level: 2) { pdu.to_hex }
|
73
|
-
[pdu, engine_id.value, engine_boots, engine_time]
|
73
|
+
[pdu, engine_id.value.to_s, engine_boots, engine_time]
|
74
74
|
end
|
75
75
|
|
76
76
|
# @param [NETSNMP::ScopedPDU] the PDU to encode in the message
|
data/lib/netsnmp/mib/parser.rb
CHANGED
@@ -194,7 +194,7 @@ module NETSNMP::MIB
|
|
194
194
|
end
|
195
195
|
|
196
196
|
rule(:module_name_capabilities) do
|
197
|
-
spaced { uppercase_identifier } >> object_identifier | uppercase_identifier
|
197
|
+
(spaced { uppercase_identifier } >> object_identifier) | uppercase_identifier
|
198
198
|
end
|
199
199
|
|
200
200
|
rule(:capabilities_groups) do
|
@@ -368,7 +368,7 @@ module NETSNMP::MIB
|
|
368
368
|
end
|
369
369
|
|
370
370
|
rule(:category_id) do
|
371
|
-
spaced { lowercase_identifier } >> bracketed(number) | lowercase_identifier
|
371
|
+
(spaced { lowercase_identifier } >> bracketed(number)) | lowercase_identifier
|
372
372
|
end
|
373
373
|
|
374
374
|
rule(:notification_type_clause) do
|
@@ -407,8 +407,8 @@ module NETSNMP::MIB
|
|
407
407
|
end
|
408
408
|
|
409
409
|
rule(:enterprise_part) do
|
410
|
-
spaced("ENTERPRISE") >> object_identifier |
|
411
|
-
spaced("ENTERPRISE") >> curly(object_identifier)
|
410
|
+
(spaced("ENTERPRISE") >> object_identifier) |
|
411
|
+
(spaced("ENTERPRISE") >> curly(object_identifier))
|
412
412
|
end
|
413
413
|
|
414
414
|
rule(:var_part) do
|
@@ -454,7 +454,7 @@ module NETSNMP::MIB
|
|
454
454
|
end
|
455
455
|
|
456
456
|
rule(:max_access_part) do
|
457
|
-
spaced("MAX-ACCESS") >> access | spaced("ACCESS") >> access
|
457
|
+
(spaced("MAX-ACCESS") >> access) | (spaced("ACCESS") >> access)
|
458
458
|
end
|
459
459
|
|
460
460
|
rule(:access) { lowercase_identifier }
|
@@ -484,7 +484,7 @@ module NETSNMP::MIB
|
|
484
484
|
end
|
485
485
|
|
486
486
|
rule(:object_identifier_defval) do
|
487
|
-
spaced { lowercase_identifier } >> bracketed(number) |
|
487
|
+
(spaced { lowercase_identifier } >> bracketed(number)) |
|
488
488
|
number
|
489
489
|
end
|
490
490
|
|
@@ -493,7 +493,7 @@ module NETSNMP::MIB
|
|
493
493
|
end
|
494
494
|
|
495
495
|
rule(:index_type) do
|
496
|
-
spaced("IMPLIED") >> idx | idx
|
496
|
+
(spaced("IMPLIED") >> idx) | idx
|
497
497
|
end
|
498
498
|
|
499
499
|
rule(:idx) do
|
@@ -525,7 +525,7 @@ module NETSNMP::MIB
|
|
525
525
|
rule(:sub_identifier) do
|
526
526
|
fuzzy_lowercase_identifier |
|
527
527
|
number |
|
528
|
-
spaced { lowercase_identifier } >> bracketed(number)
|
528
|
+
(spaced { lowercase_identifier } >> bracketed(number))
|
529
529
|
end
|
530
530
|
|
531
531
|
rule(:type_declaration) do
|
@@ -542,12 +542,12 @@ module NETSNMP::MIB
|
|
542
542
|
|
543
543
|
rule(:type_declaration_rhs) do
|
544
544
|
spaced { choice_clause } |
|
545
|
-
spaced { str("TEXTUAL-CONVENTION") } >>
|
545
|
+
(spaced { str("TEXTUAL-CONVENTION") } >>
|
546
546
|
spaced { display_part }.maybe >>
|
547
547
|
spaced("STATUS") >> spaced { status } >>
|
548
548
|
spaced("DESCRIPTION") >> spaced { text } >>
|
549
549
|
spaced { refer_part }.maybe >>
|
550
|
-
spaced("SYNTAX") >> syntax |
|
550
|
+
spaced("SYNTAX") >> syntax) |
|
551
551
|
syntax
|
552
552
|
end
|
553
553
|
|
@@ -561,7 +561,7 @@ module NETSNMP::MIB
|
|
561
561
|
end
|
562
562
|
|
563
563
|
rule(:syntax) do
|
564
|
-
object_syntax | spaced("BITS").as(:type) >> curly(named_bits)
|
564
|
+
object_syntax | (spaced("BITS").as(:type) >> curly(named_bits))
|
565
565
|
end
|
566
566
|
|
567
567
|
rule(:display_part) do
|
@@ -581,27 +581,27 @@ module NETSNMP::MIB
|
|
581
581
|
entry_type |
|
582
582
|
simple_syntax |
|
583
583
|
application_syntax |
|
584
|
-
type_tag >> simple_syntax |
|
584
|
+
(type_tag >> simple_syntax) |
|
585
585
|
row.as(:value)
|
586
586
|
end
|
587
587
|
|
588
588
|
rule(:simple_syntax) do
|
589
|
-
spaced { str("INTEGER").as(:type) } >> (integer_subtype | enum_spec).maybe |
|
590
|
-
spaced { str("Integer32").as(:type) >> space } >> integer_subtype.maybe |
|
591
|
-
spaced { str("OCTET STRING").as(:type) } >> octetstring_subtype.maybe |
|
592
|
-
spaced { str("OBJECT IDENTIFIER").as(:type) } >> any_subtype |
|
593
|
-
spaced { uppercase_identifier.as(:type) } >> (integer_subtype | enum_spec | octetstring_subtype)
|
589
|
+
(spaced { str("INTEGER").as(:type) } >> (integer_subtype | enum_spec).maybe) |
|
590
|
+
(spaced { str("Integer32").as(:type) >> space } >> integer_subtype.maybe) |
|
591
|
+
(spaced { str("OCTET STRING").as(:type) } >> octetstring_subtype.maybe) |
|
592
|
+
(spaced { str("OBJECT IDENTIFIER").as(:type) } >> any_subtype) |
|
593
|
+
(spaced { uppercase_identifier.as(:type) } >> (integer_subtype | enum_spec | octetstring_subtype))
|
594
594
|
end
|
595
595
|
|
596
596
|
rule(:application_syntax) do
|
597
|
-
spaced { str("IpAddress").as(:type) >> space } >> any_subtype |
|
598
|
-
spaced { str("NetworkAddress").as(:type) >> space } >> any_subtype |
|
599
|
-
spaced { str("Counter32").as(:type) >> space } >> integer_subtype.maybe |
|
600
|
-
spaced { str("Gauge32").as(:type) >> space } >> integer_subtype.maybe |
|
601
|
-
spaced { str("Unsigned32").as(:type) >> space } >> integer_subtype.maybe |
|
602
|
-
spaced { str("TimeTicks").as(:type) >> space } >> any_subtype |
|
603
|
-
spaced { str("Opaque").as(:type) >> space } >> octetstring_subtype.maybe |
|
604
|
-
spaced { str("Counter64").as(:type) >> space } >> integer_subtype.maybe
|
597
|
+
(spaced { str("IpAddress").as(:type) >> space } >> any_subtype) |
|
598
|
+
(spaced { str("NetworkAddress").as(:type) >> space } >> any_subtype) |
|
599
|
+
(spaced { str("Counter32").as(:type) >> space } >> integer_subtype.maybe) |
|
600
|
+
(spaced { str("Gauge32").as(:type) >> space } >> integer_subtype.maybe) |
|
601
|
+
(spaced { str("Unsigned32").as(:type) >> space } >> integer_subtype.maybe) |
|
602
|
+
(spaced { str("TimeTicks").as(:type) >> space } >> any_subtype) |
|
603
|
+
(spaced { str("Opaque").as(:type) >> space } >> octetstring_subtype.maybe) |
|
604
|
+
(spaced { str("Counter64").as(:type) >> space } >> integer_subtype.maybe)
|
605
605
|
end
|
606
606
|
|
607
607
|
rule(:conceptual_table) do
|
@@ -613,8 +613,8 @@ module NETSNMP::MIB
|
|
613
613
|
end
|
614
614
|
|
615
615
|
rule(:type_tag) do
|
616
|
-
spaced { square_bracketed(spaced("APPLICATION") >> number.as(:application_type)) } >> spaced("IMPLICIT") |
|
617
|
-
spaced { square_bracketed(spaced("UNIVERSAL") >> number.as(:universal_type)) } >> spaced("IMPLICIT")
|
616
|
+
(spaced { square_bracketed(spaced("APPLICATION") >> number.as(:application_type)) } >> spaced("IMPLICIT")) |
|
617
|
+
(spaced { square_bracketed(spaced("UNIVERSAL") >> number.as(:universal_type)) } >> spaced("IMPLICIT"))
|
618
618
|
end
|
619
619
|
|
620
620
|
rule(:sequence_items) do
|
@@ -628,7 +628,7 @@ module NETSNMP::MIB
|
|
628
628
|
rule(:sequence_syntax) do
|
629
629
|
str("BITS") |
|
630
630
|
sequence_object_syntax |
|
631
|
-
spaced { uppercase_identifier } >> any_subtype
|
631
|
+
(spaced { uppercase_identifier } >> any_subtype)
|
632
632
|
end
|
633
633
|
|
634
634
|
rule(:sequence_object_syntax) do
|
@@ -636,20 +636,20 @@ module NETSNMP::MIB
|
|
636
636
|
end
|
637
637
|
|
638
638
|
rule(:sequence_simple_syntax) do
|
639
|
-
spaced("INTEGER") >> any_subtype |
|
640
|
-
spaced("Integer32") >> any_subtype |
|
641
|
-
spaced("OCTET STRING") >> any_subtype |
|
642
|
-
spaced("OBJECT IDENTIFIER") >> any_subtype
|
639
|
+
(spaced("INTEGER") >> any_subtype) |
|
640
|
+
(spaced("Integer32") >> any_subtype) |
|
641
|
+
(spaced("OCTET STRING") >> any_subtype) |
|
642
|
+
(spaced("OBJECT IDENTIFIER") >> any_subtype)
|
643
643
|
end
|
644
644
|
|
645
645
|
rule(:sequence_application_syntax) do
|
646
|
-
spaced { str("IpAddress") >> space } >> any_subtype |
|
647
|
-
spaced { str("COUNTER32") } >> any_subtype |
|
648
|
-
spaced { str("Gauge32") >> space } >> any_subtype |
|
649
|
-
spaced { str("Unsigned32") >> space } >> any_subtype |
|
650
|
-
spaced { str("TimeTicks") >> space } >> any_subtype |
|
646
|
+
(spaced { str("IpAddress") >> space } >> any_subtype) |
|
647
|
+
(spaced { str("COUNTER32") } >> any_subtype) |
|
648
|
+
(spaced { str("Gauge32") >> space } >> any_subtype) |
|
649
|
+
(spaced { str("Unsigned32") >> space } >> any_subtype) |
|
650
|
+
(spaced { str("TimeTicks") >> space } >> any_subtype) |
|
651
651
|
str("Opaque") |
|
652
|
-
spaced { str("Counter64") >> space } >> any_subtype
|
652
|
+
(spaced { str("Counter64") >> space } >> any_subtype)
|
653
653
|
end
|
654
654
|
|
655
655
|
rule(:row) { uppercase_identifier }
|
@@ -743,7 +743,7 @@ module NETSNMP::MIB
|
|
743
743
|
|
744
744
|
rule(:text) do
|
745
745
|
str('"') >> (
|
746
|
-
str(
|
746
|
+
(str("\\") >> any) | (str('"').absent? >> any)
|
747
747
|
).repeat >> str('"')
|
748
748
|
end
|
749
749
|
end
|
data/lib/netsnmp/mib.rb
CHANGED
@@ -6,11 +6,13 @@ module NETSNMP
|
|
6
6
|
module MIB
|
7
7
|
using IsNumericExtensions
|
8
8
|
|
9
|
-
OIDREGEX = /^[\d
|
9
|
+
OIDREGEX = /^[\d.]*$/.freeze
|
10
10
|
|
11
11
|
module_function
|
12
12
|
|
13
|
-
MIBDIRS = ENV.fetch("MIBDIRS", File.join("/usr", "share", "snmp", "mibs"))
|
13
|
+
MIBDIRS = ENV.fetch("MIBDIRS", File.join("/usr", "share", "snmp", "mibs"))
|
14
|
+
.split(":")
|
15
|
+
.flat_map { |dir| [dir, *Dir.glob(File.join(dir, "**", "*")).select(&File.method(:directory?))] }.uniq
|
14
16
|
PARSER = Parser.new
|
15
17
|
@parser_mutex = Mutex.new
|
16
18
|
@modules_loaded = []
|
@@ -20,11 +22,13 @@ module NETSNMP
|
|
20
22
|
def oid(identifier)
|
21
23
|
prefix, *suffix = case identifier
|
22
24
|
when Array
|
23
|
-
identifier
|
25
|
+
identifier.map(&:to_s)
|
24
26
|
else
|
25
|
-
identifier.split(".", 2)
|
27
|
+
identifier.split(".", 2).map(&:to_s)
|
26
28
|
end
|
27
29
|
|
30
|
+
return unless prefix
|
31
|
+
|
28
32
|
# early exit if it's an OID already
|
29
33
|
unless prefix.integer?
|
30
34
|
load_defaults
|
@@ -33,9 +37,7 @@ module NETSNMP
|
|
33
37
|
if idx
|
34
38
|
mod = prefix[0..(idx - 1)]
|
35
39
|
type = prefix[(idx + 2)..-1]
|
36
|
-
|
37
|
-
return unless load(mod)
|
38
|
-
end
|
40
|
+
return if mod && !module_loaded?(mod) && !load(mod)
|
39
41
|
else
|
40
42
|
type = prefix
|
41
43
|
end
|
@@ -53,7 +55,7 @@ module NETSNMP
|
|
53
55
|
def identifier(oid)
|
54
56
|
@object_identifiers.select do |_, ids_oid|
|
55
57
|
oid.start_with?(ids_oid)
|
56
|
-
end.
|
58
|
+
end.min_by(&:size)
|
57
59
|
end
|
58
60
|
|
59
61
|
#
|
@@ -78,9 +80,11 @@ module NETSNMP
|
|
78
80
|
end
|
79
81
|
end
|
80
82
|
return false unless moddir
|
83
|
+
|
81
84
|
mod = moddir
|
82
85
|
end
|
83
86
|
return true if @modules_loaded.include?(mod)
|
87
|
+
|
84
88
|
do_load(mod)
|
85
89
|
@modules_loaded << mod
|
86
90
|
true
|
@@ -129,9 +133,11 @@ module NETSNMP
|
|
129
133
|
@object_identifiers[cp]
|
130
134
|
else
|
131
135
|
STATIC_MIB_TO_OID[cp] || begin
|
132
|
-
imported_mod, = imports
|
133
|
-
|
134
|
-
|
136
|
+
imported_mod, = if imports
|
137
|
+
imports.find do |_, identifiers|
|
138
|
+
identifiers.include?(cp)
|
139
|
+
end
|
140
|
+
end
|
135
141
|
|
136
142
|
raise Error, "didn't find a module to import \"#{cp}\" from" unless imported_mod
|
137
143
|
|
data/lib/netsnmp/oid.rb
CHANGED
@@ -4,15 +4,18 @@ module NETSNMP
|
|
4
4
|
# Abstracts the OID structure
|
5
5
|
#
|
6
6
|
module OID
|
7
|
-
using StringExtensions
|
7
|
+
using StringExtensions
|
8
8
|
|
9
|
-
OIDREGEX = /^[\d
|
9
|
+
OIDREGEX = /^[\d.]*$/.freeze
|
10
10
|
|
11
11
|
module_function
|
12
12
|
|
13
13
|
def build(id)
|
14
14
|
oid = MIB.oid(id)
|
15
|
-
|
15
|
+
|
16
|
+
raise Error, "no OID found for #{id}" unless oid
|
17
|
+
|
18
|
+
oid = oid.delete_prefix(".") if oid.start_with?(".")
|
16
19
|
oid
|
17
20
|
end
|
18
21
|
|
data/lib/netsnmp/pdu.rb
CHANGED
@@ -11,17 +11,10 @@ module NETSNMP
|
|
11
11
|
|
12
12
|
using ASNExtensions
|
13
13
|
class << self
|
14
|
-
def decode(der)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
when OpenSSL::ASN1::ASN1Data
|
19
|
-
der
|
20
|
-
else
|
21
|
-
raise "#{der}: unexpected data"
|
22
|
-
end
|
23
|
-
|
24
|
-
*headers, request = asn_tree.value
|
14
|
+
def decode(der, **args)
|
15
|
+
der = OpenSSL::ASN1.decode(der) if der.is_a?(String)
|
16
|
+
|
17
|
+
*headers, request = der.value
|
25
18
|
|
26
19
|
version, community = headers.map(&:value)
|
27
20
|
|
@@ -37,11 +30,14 @@ module NETSNMP
|
|
37
30
|
{ oid: oid, value: val_asn }
|
38
31
|
end
|
39
32
|
|
40
|
-
new(type: type,
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
33
|
+
new(type: type,
|
34
|
+
version: version.to_i,
|
35
|
+
community: community,
|
36
|
+
error_status: error_status.to_i,
|
37
|
+
error_index: error_index.to_i,
|
38
|
+
request_id: request_id.to_i,
|
39
|
+
varbinds: varbs,
|
40
|
+
**args)
|
45
41
|
end
|
46
42
|
|
47
43
|
# factory method that abstracts initialization of the pdu types that the library supports.
|
@@ -64,19 +60,19 @@ module NETSNMP
|
|
64
60
|
end
|
65
61
|
end
|
66
62
|
|
67
|
-
attr_reader :varbinds, :type
|
68
|
-
|
69
|
-
attr_reader :version, :community, :request_id
|
63
|
+
attr_reader :varbinds, :type, :version, :community, :request_id
|
70
64
|
|
71
|
-
def initialize(type:,
|
65
|
+
def initialize(type:,
|
66
|
+
version:,
|
67
|
+
community:,
|
72
68
|
request_id: SecureRandom.random_number(MAXREQUESTID),
|
73
69
|
error_status: 0,
|
74
70
|
error_index: 0,
|
75
71
|
varbinds: [])
|
76
|
-
@version
|
77
|
-
@
|
72
|
+
@version = version.to_i
|
73
|
+
@community = community
|
78
74
|
@error_status = error_status
|
79
|
-
@error_index
|
75
|
+
@error_index = error_index
|
80
76
|
@type = type
|
81
77
|
@varbinds = []
|
82
78
|
varbinds.each do |varbind|
|
@@ -131,6 +127,7 @@ module NETSNMP
|
|
131
127
|
# http://www.tcpipguide.com/free/t_SNMPVersion2SNMPv2MessageFormats-5.htm#Table_219
|
132
128
|
def check_error_status(status)
|
133
129
|
return if status.zero?
|
130
|
+
|
134
131
|
message = case status
|
135
132
|
when 1 then "Response-PDU too big"
|
136
133
|
when 2 then "No such name"
|
data/lib/netsnmp/scoped_pdu.rb
CHANGED
@@ -4,13 +4,14 @@ module NETSNMP
|
|
4
4
|
class ScopedPDU < PDU
|
5
5
|
using ASNExtensions
|
6
6
|
|
7
|
-
attr_reader :engine_id
|
7
|
+
attr_reader :engine_id, :security_level, :auth_param
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@engine_id
|
13
|
-
|
9
|
+
def initialize(type:, auth_param: "", security_level: 3, engine_id: nil, context: nil, **options)
|
10
|
+
@auth_param = auth_param
|
11
|
+
@security_level = security_level
|
12
|
+
@engine_id = engine_id
|
13
|
+
@context = context
|
14
|
+
super(type: type, version: 3, community: nil, **options)
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|