snmp 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ad322cefc232b70f0003fd1f3ed6180d8cddb9921c5819ad371b6d2af33399b
4
- data.tar.gz: f28bde102b1c66c5722b34feeff2a27ccfb846be7c1579ce5dbc12e5bbb364cf
3
+ metadata.gz: a7fcd45a1214475ca6b4994e449366998484949d4fbe46b580074fa7412a3d18
4
+ data.tar.gz: 4892233da93ed593ff4dad03eedf21d482c3bdc92ea586435452c085902077ff
5
5
  SHA512:
6
- metadata.gz: e7f74d10fad99debbc6a740753b467ed053790db7b5c3fa2286ab94f343f904720f1123cf49fcb25be008b931f4498f3480de7befc50320697426804d70e9988
7
- data.tar.gz: f7663d2514ce9a8fa43d75b1a32ad1cd485557d0206087a796a03109564e7e752135f68a38f86830202494e25cb4e62ee7f1a64b8c45e9385f38fe7a87fa5753
6
+ metadata.gz: 0d4589d39c3fc90acc39bdf5867961a55ce71922b59531ad734ef424876b2d973c65e387dc23a00f603504fbecf68edd43e0e00086f7ae49156c3b536ab5cb61
7
+ data.tar.gz: f92df29abd8eda6c7110444d46a2404a94f025903132ee4400255337cacfa67ed415a2f9a3135c3ce9045f007290b984f9cc5760838595f06c6e1948bb3bfc31
@@ -25,75 +25,13 @@ This release supports the following:
25
25
  See the SNMP::Manager, SNMP::TrapListener, and SNMP::MIB classes and the
26
26
  examples below for more details.
27
27
 
28
- == Changes
29
-
30
- Changes for version 1.3.0:
31
- * Cleaned up deprecation warnings
32
- * Fixed SNMP::Integer#<=> method for Ruby 2.3.0 and later
33
-
34
- Changes for version 1.2.0:
35
- * Removed support for Ruby 1.8
36
- * Changed license to MIT License
37
-
38
- Changes for version 1.1.1:
39
-
40
- * Incorporate various small pull requests
41
-
42
- Changes for version 1.1.0:
43
-
44
- * Added MIB support to ObjectId and Varbind, so that to_s can return symbolic information
45
- * Added to_str method to ObjectId to return a numeric OID string (old to_s behavior)
46
- * TrapListener can now support multiple community strings
47
-
48
- Changes for version 1.0.4:
49
-
50
- * New option handling and added lower-case versions of all options
51
- * Added SNMP::VERSION constant
52
- * Experimental support for IPv6
53
- * Removed support for installation with setup.rb
54
-
55
- Changes for version 1.0.3:
56
-
57
- * Minor changes to Manager class. The :Transport option may now be an
58
- object or a class. Explicity call Timeout.timeout so that a timeout
59
- method may be defined in subclasses. Thanks to Eric Monti.
60
-
61
- Changes for version 1.0.2:
62
-
63
- * Internal code changes to make this library compatible with both Ruby 1.8
64
- and Ruby 1.9. Note that an ord() method is now added to the Fixnum class
65
- for Ruby 1.8. See the ber.rb file for details.
66
-
67
- Changes for version 1.0.1:
68
-
69
- * Made the host configurable for the TrapListener. Previously defaulted
70
- to 'localhost'.
71
-
72
- Changes for version 1.0.0:
73
-
74
- * Added to_s method to TimeTicks. Displays time in human-readable form
75
- instead of just a number. The to_i method can still be used to get the
76
- number of ticks.
77
-
78
28
  == Installation
79
29
 
80
- You can use RubyGems [http://rubygems.org/] to
30
+ You can use RubyGems[http://rubygems.org/] to
81
31
  install the latest version of the SNMP library.
82
32
 
83
33
  gem install snmp
84
34
 
85
- == Testing
86
-
87
- This library has received limited testing:
88
- * The unit tests have been executed with both Ruby 1.9.3 and Ruby 2.1.2 on
89
- Mac OS X 10.9.
90
- * Basic interoperability testing has been done with the
91
- net-snmp[http://www.net-snmp.org/] tools.
92
-
93
- I'm very interested in hearing about successes or failures on other platforms.
94
-
95
- Send me an email at hallidave at gmail.com.
96
-
97
35
  == Examples
98
36
 
99
37
  === Get Request
@@ -187,7 +125,59 @@ Log traps to STDOUT.
187
125
  end
188
126
  end
189
127
  m.join
190
-
128
+
129
+ == Changes
130
+
131
+ Changes for version 1.3.1:
132
+ * Cleaned up deprecation warnings
133
+ * Fixed SNMP::Integer#<=> method for Ruby 2.3.0 and later
134
+ * Removed artificial limit on number of non-repeaters for GetBulkRequest
135
+ * SNMP::BER module no longer pollutes global namespace
136
+
137
+ Changes for version 1.2.0:
138
+ * Removed support for Ruby 1.8
139
+ * Changed license to MIT License
140
+
141
+ Changes for version 1.1.1:
142
+
143
+ * Incorporate various small pull requests
144
+
145
+ Changes for version 1.1.0:
146
+
147
+ * Added MIB support to ObjectId and Varbind, so that to_s can return symbolic information
148
+ * Added to_str method to ObjectId to return a numeric OID string (old to_s behavior)
149
+ * TrapListener can now support multiple community strings
150
+
151
+ Changes for version 1.0.4:
152
+
153
+ * New option handling and added lower-case versions of all options
154
+ * Added SNMP::VERSION constant
155
+ * Experimental support for IPv6
156
+ * Removed support for installation with setup.rb
157
+
158
+ Changes for version 1.0.3:
159
+
160
+ * Minor changes to Manager class. The :Transport option may now be an
161
+ object or a class. Explicity call Timeout.timeout so that a timeout
162
+ method may be defined in subclasses. Thanks to Eric Monti.
163
+
164
+ Changes for version 1.0.2:
165
+
166
+ * Internal code changes to make this library compatible with both Ruby 1.8
167
+ and Ruby 1.9. Note that an ord() method is now added to the Fixnum class
168
+ for Ruby 1.8. See the ber.rb file for details.
169
+
170
+ Changes for version 1.0.1:
171
+
172
+ * Made the host configurable for the TrapListener. Previously defaulted
173
+ to 'localhost'.
174
+
175
+ Changes for version 1.0.0:
176
+
177
+ * Added to_s method to TimeTicks. Displays time in human-readable form
178
+ instead of just a number. The to_i method can still be used to get the
179
+ number of ticks.
180
+
191
181
  == License
192
182
 
193
183
  This SNMP Library is released under the MIT License.
@@ -211,4 +201,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
211
201
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
212
202
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
213
203
  THE SOFTWARE.
214
-
@@ -78,278 +78,285 @@ module SNMP
78
78
  class InvalidObjectId < RuntimeError; end
79
79
  class InvalidLength < RuntimeError; end
80
80
 
81
- def assert_no_remainder(remainder)
82
- raise ParseError, remainder.inspect if remainder != ""
83
- end
81
+ module Decode
84
82
 
85
- #
86
- # Decode tag-length-value data. The data is assumed to be a string of
87
- # bytes in network byte order. This format is returned by Socket#recv.
88
- #
89
- # Returns a tuple containing the tag, the value, and any remaining
90
- # unprocessed data.
91
- #
92
- # The data is not interpretted by this method. Use one of the other
93
- # decoding methods to interpret the data.
94
- #
95
- # Note that ASN.1 supports an indefinite length format where the end of
96
- # content is marked by a pair of 0 octets. SNMP does not support this
97
- # format, so only the two definite forms are implemented (single byte and
98
- # multi-byte).
99
- #
100
- def decode_tlv(data)
101
- raise OutOfData if (data.length == 2 && data[1].ord != 0) || data.length < 2
102
- tag = data[0].ord
103
- length = data[1].ord
104
- if length < 0x80
105
- value = data[2, length]
106
- remainder = data[length+2..-1]
107
- else
108
- # ASN.1 says this octet can't be 0xff
109
- raise InvalidLength, length.to_s if length == 0xff
110
- num_octets = length & 0x7f
111
- length = build_integer(data, 2, num_octets)
112
- value = data[num_octets+2, length]
113
- remainder = data[num_octets+2+length..-1]
83
+ def assert_no_remainder(remainder)
84
+ raise ParseError, remainder.inspect if remainder != ""
114
85
  end
115
- return tag, value, remainder
116
- end
117
86
 
118
- #
119
- # Decode TLV data for an ASN.1 integer.
120
- #
121
- # Throws an InvalidTag exception if the tag is incorrect.
122
- #
123
- # Returns a tuple containing an integer and any remaining unprocessed data.
124
- #
125
- def decode_integer(data)
126
- tag, value, remainder = decode_tlv(data)
127
- raise InvalidTag, tag.to_s if tag != INTEGER_TAG
128
- return decode_integer_value(value), remainder
129
- end
87
+ #
88
+ # Decode tag-length-value data. The data is assumed to be a string of
89
+ # bytes in network byte order. This format is returned by Socket#recv.
90
+ #
91
+ # Returns a tuple containing the tag, the value, and any remaining
92
+ # unprocessed data.
93
+ #
94
+ # The data is not interpretted by this method. Use one of the other
95
+ # decoding methods to interpret the data.
96
+ #
97
+ # Note that ASN.1 supports an indefinite length format where the end of
98
+ # content is marked by a pair of 0 octets. SNMP does not support this
99
+ # format, so only the two definite forms are implemented (single byte and
100
+ # multi-byte).
101
+ #
102
+ def decode_tlv(data)
103
+ raise OutOfData if (data.length == 2 && data[1].ord != 0) || data.length < 2
104
+ tag = data[0].ord
105
+ length = data[1].ord
106
+ if length < 0x80
107
+ value = data[2, length]
108
+ remainder = data[length+2..-1]
109
+ else
110
+ # ASN.1 says this octet can't be 0xff
111
+ raise InvalidLength, length.to_s if length == 0xff
112
+ num_octets = length & 0x7f
113
+ length = build_integer(data, 2, num_octets)
114
+ value = data[num_octets+2, length]
115
+ remainder = data[num_octets+2+length..-1]
116
+ end
117
+ return tag, value, remainder
118
+ end
130
119
 
131
- def decode_timeticks(data)
132
- tag, value, remainder = decode_tlv(data)
133
- raise InvalidTag, tag.to_s if tag != TimeTicks_TAG
134
- return decode_uinteger_value(value), remainder
135
- end
120
+ #
121
+ # Decode TLV data for an ASN.1 integer.
122
+ #
123
+ # Throws an InvalidTag exception if the tag is incorrect.
124
+ #
125
+ # Returns a tuple containing an integer and any remaining unprocessed data.
126
+ #
127
+ def decode_integer(data)
128
+ tag, value, remainder = decode_tlv(data)
129
+ raise InvalidTag, tag.to_s if tag != INTEGER_TAG
130
+ return decode_integer_value(value), remainder
131
+ end
136
132
 
137
- def decode_integer_value(value)
138
- result = build_integer(value, 0, value.length)
139
- if value[0].ord[7] == 1
140
- result -= (1 << (8 * value.length))
133
+ def decode_timeticks(data)
134
+ tag, value, remainder = decode_tlv(data)
135
+ raise InvalidTag, tag.to_s if tag != TimeTicks_TAG
136
+ return decode_uinteger_value(value), remainder
141
137
  end
142
- result
143
- end
144
138
 
145
- ##
146
- # Decode an integer, ignoring the sign bit. Some agents insist on
147
- # encoding 32 bit unsigned integers with four bytes even though it
148
- # should be 5 bytes (at least the way I read it).
149
- #
150
- def decode_uinteger_value(value)
151
- build_integer(value, 0, value.length)
152
- end
139
+ def decode_integer_value(value)
140
+ result = build_integer(value, 0, value.length)
141
+ if value[0].ord[7] == 1
142
+ result -= (1 << (8 * value.length))
143
+ end
144
+ result
145
+ end
153
146
 
154
- def build_integer(data, start, num_octets)
155
- number = 0
156
- num_octets.times { |i| number = number<<8 | data[start+i].ord }
157
- return number
158
- end
147
+ ##
148
+ # Decode an integer, ignoring the sign bit. Some agents insist on
149
+ # encoding 32 bit unsigned integers with four bytes even though it
150
+ # should be 5 bytes (at least the way I read it).
151
+ #
152
+ def decode_uinteger_value(value)
153
+ build_integer(value, 0, value.length)
154
+ end
159
155
 
160
- #
161
- # Decode TLV data for an ASN.1 octet string.
162
- #
163
- # Throws an InvalidTag exception if the tag is incorrect.
164
- #
165
- # Returns a tuple containing a string and any remaining unprocessed data.
166
- #
167
- def decode_octet_string(data)
168
- tag, value, remainder = decode_tlv(data)
169
- raise InvalidTag, tag.to_s if tag != OCTET_STRING_TAG
170
- return value, remainder
171
- end
156
+ def build_integer(data, start, num_octets)
157
+ number = 0
158
+ num_octets.times { |i| number = number<<8 | data[start+i].ord }
159
+ return number
160
+ end
172
161
 
173
- def decode_ip_address(data)
174
- tag, value, remainder = decode_tlv(data)
175
- raise InvalidTag, tag.to_s if tag != IpAddress_TAG
176
- raise InvalidLength, tag.to_s if value.length != 4
177
- return value, remainder
178
- end
162
+ #
163
+ # Decode TLV data for an ASN.1 octet string.
164
+ #
165
+ # Throws an InvalidTag exception if the tag is incorrect.
166
+ #
167
+ # Returns a tuple containing a string and any remaining unprocessed data.
168
+ #
169
+ def decode_octet_string(data)
170
+ tag, value, remainder = decode_tlv(data)
171
+ raise InvalidTag, tag.to_s if tag != OCTET_STRING_TAG
172
+ return value, remainder
173
+ end
179
174
 
180
- #
181
- # Decode TLV data for an ASN.1 sequence.
182
- #
183
- # Throws an InvalidTag exception if the tag is incorrect.
184
- #
185
- # Returns a tuple containing the sequence data and any remaining
186
- # unprocessed data that follows the sequence.
187
- #
188
- def decode_sequence(data)
189
- tag, value, remainder = decode_tlv(data)
190
- raise InvalidTag, tag.to_s if tag != SEQUENCE_TAG
191
- return value, remainder
192
- end
175
+ def decode_ip_address(data)
176
+ tag, value, remainder = decode_tlv(data)
177
+ raise InvalidTag, tag.to_s if tag != IpAddress_TAG
178
+ raise InvalidLength, tag.to_s if value.length != 4
179
+ return value, remainder
180
+ end
193
181
 
194
- #
195
- # Unwrap TLV data for an ASN.1 object identifier. This method extracts
196
- # the OID value as a character string but does not decode it further.
197
- #
198
- # Throws an InvalidTag exception if the tag is incorrect.
199
- #
200
- # Returns a tuple containing the object identifier (OID) and any
201
- # remaining unprocessed data. The OID is represented as an array
202
- # of integers.
203
- #
204
- def decode_object_id(data)
205
- tag, value, remainder = decode_tlv(data)
206
- raise InvalidTag, tag.to_s if tag != OBJECT_IDENTIFIER_TAG
207
- return decode_object_id_value(value), remainder
208
- end
182
+ #
183
+ # Decode TLV data for an ASN.1 sequence.
184
+ #
185
+ # Throws an InvalidTag exception if the tag is incorrect.
186
+ #
187
+ # Returns a tuple containing the sequence data and any remaining
188
+ # unprocessed data that follows the sequence.
189
+ #
190
+ def decode_sequence(data)
191
+ tag, value, remainder = decode_tlv(data)
192
+ raise InvalidTag, tag.to_s if tag != SEQUENCE_TAG
193
+ return value, remainder
194
+ end
195
+
196
+ #
197
+ # Unwrap TLV data for an ASN.1 object identifier. This method extracts
198
+ # the OID value as a character string but does not decode it further.
199
+ #
200
+ # Throws an InvalidTag exception if the tag is incorrect.
201
+ #
202
+ # Returns a tuple containing the object identifier (OID) and any
203
+ # remaining unprocessed data. The OID is represented as an array
204
+ # of integers.
205
+ #
206
+ def decode_object_id(data)
207
+ tag, value, remainder = decode_tlv(data)
208
+ raise InvalidTag, tag.to_s if tag != OBJECT_IDENTIFIER_TAG
209
+ return decode_object_id_value(value), remainder
210
+ end
209
211
 
210
- def decode_object_id_value(value)
211
- if value.length == 0
212
- object_id = []
213
- else
214
- value0 = value[0].ord
215
- if value0 == 0x2b
216
- object_id = [1,3]
212
+ def decode_object_id_value(value)
213
+ if value.length == 0
214
+ object_id = []
217
215
  else
218
- second = value0 % 40
219
- first = (value0 - second) / 40
220
- raise InvalidObjectId, value.to_s if first > 2
221
- object_id = [first, second]
222
- end
223
- n = 0
224
- for i in 1...value.length
225
- n = (n<<7) + (value[i].ord & 0x7f)
226
- if value[i].ord < 0x80
227
- object_id << n
228
- n = 0
216
+ value0 = value[0].ord
217
+ if value0 == 0x2b
218
+ object_id = [1,3]
219
+ else
220
+ second = value0 % 40
221
+ first = (value0 - second) / 40
222
+ raise InvalidObjectId, value.to_s if first > 2
223
+ object_id = [first, second]
224
+ end
225
+ n = 0
226
+ for i in 1...value.length
227
+ n = (n<<7) + (value[i].ord & 0x7f)
228
+ if value[i].ord < 0x80
229
+ object_id << n
230
+ n = 0
231
+ end
229
232
  end
230
233
  end
234
+ return object_id
231
235
  end
232
- return object_id
236
+
233
237
  end
234
238
 
235
- #
236
- # Encode the length field for TLV data. Returns the length octets
237
- # as a string.
238
- #
239
- def encode_length(length)
240
- raise InvalidLength, length.to_s if length < 0
241
- if length < 0x80
242
- length.chr
243
- else
244
- data = integer_to_octets(length)
245
- (data.size | 0x80).chr << data
239
+ module Encode
240
+
241
+ #
242
+ # Encode the length field for TLV data. Returns the length octets
243
+ # as a string.
244
+ #
245
+ def encode_length(length)
246
+ raise InvalidLength, length.to_s if length < 0
247
+ if length < 0x80
248
+ length.chr
249
+ else
250
+ data = integer_to_octets(length)
251
+ (data.size | 0x80).chr << data
252
+ end
246
253
  end
247
- end
248
254
 
249
- #
250
- # Encode integer
251
- #
252
- def encode_integer(value)
253
- encode_tagged_integer(INTEGER_TAG, value)
254
- end
255
+ #
256
+ # Encode integer
257
+ #
258
+ def encode_integer(value)
259
+ encode_tagged_integer(INTEGER_TAG, value)
260
+ end
255
261
 
256
- def encode_tagged_integer(tag, value)
257
- if value > 0 && value < 0x80
258
- data = value.chr
259
- else
260
- data = integer_to_octets(value)
261
- if value > 0 && data[0].ord > 0x7f
262
- data = "\000" << data
263
- elsif value < 0 && data[0].ord < 0x80
264
- data = "\377" << data
262
+ def encode_tagged_integer(tag, value)
263
+ if value > 0 && value < 0x80
264
+ data = value.chr
265
+ else
266
+ data = integer_to_octets(value)
267
+ if value > 0 && data[0].ord > 0x7f
268
+ data = "\000" << data
269
+ elsif value < 0 && data[0].ord < 0x80
270
+ data = "\377" << data
271
+ end
265
272
  end
273
+ encode_tlv(tag, data)
266
274
  end
267
- encode_tlv(tag, data)
268
- end
269
275
 
270
- #
271
- # Helper method for encoding integer-like things.
272
- #
273
- def integer_to_octets(i)
274
- if i >= 0
275
- done = 0
276
- else
277
- done = -1
276
+ #
277
+ # Helper method for encoding integer-like things.
278
+ #
279
+ def integer_to_octets(i)
280
+ if i >= 0
281
+ done = 0
282
+ else
283
+ done = -1
284
+ end
285
+ octets = ""
286
+ begin
287
+ octets = (i & 0xff).chr << octets
288
+ i = i >> 8
289
+ end until i == done
290
+ octets
278
291
  end
279
- octets = ""
280
- begin
281
- octets = (i & 0xff).chr << octets
282
- i = i >> 8
283
- end until i == done
284
- octets
285
- end
286
292
 
287
- def encode_null
288
- NULL_TAG.chr << "\000"
289
- end
293
+ def encode_null
294
+ NULL_TAG.chr << "\000"
295
+ end
290
296
 
291
- #
292
- # Encode an exception. The encoding is simply the exception tag with
293
- # no data, similar to NULL.
294
- #
295
- def encode_exception(tag)
296
- tag.chr << "\000"
297
- end
297
+ #
298
+ # Encode an exception. The encoding is simply the exception tag with
299
+ # no data, similar to NULL.
300
+ #
301
+ def encode_exception(tag)
302
+ tag.chr << "\000"
303
+ end
298
304
 
299
- #
300
- # Wraps value in a tag and length. This method expects an
301
- # integer tag and a string value.
302
- #
303
- def encode_tlv(tag, value)
304
- data = tag.chr << encode_length(value.length)
305
- data = data << value if value.length > 0
306
- data
307
- end
305
+ #
306
+ # Wraps value in a tag and length. This method expects an
307
+ # integer tag and a string value.
308
+ #
309
+ def encode_tlv(tag, value)
310
+ data = tag.chr << encode_length(value.length)
311
+ data = data << value if value.length > 0
312
+ data
313
+ end
308
314
 
309
- #
310
- # Wrap string in a octet string tag and length.
311
- #
312
- def encode_octet_string(value)
313
- encode_tlv(OCTET_STRING_TAG, value)
314
- end
315
+ #
316
+ # Wrap string in a octet string tag and length.
317
+ #
318
+ def encode_octet_string(value)
319
+ encode_tlv(OCTET_STRING_TAG, value)
320
+ end
315
321
 
316
- #
317
- # Wrap value in a sequence tag and length.
318
- #
319
- def encode_sequence(value)
320
- encode_tlv(SEQUENCE_TAG, value)
321
- end
322
+ #
323
+ # Wrap value in a sequence tag and length.
324
+ #
325
+ def encode_sequence(value)
326
+ encode_tlv(SEQUENCE_TAG, value)
327
+ end
322
328
 
323
- #
324
- # Encode an object id. The input is assumed to be an array of integers
325
- # representing the object id.
326
- #
327
- def encode_object_id(value)
328
- raise InvalidObjectId, value.to_s if value.length < 1
329
- raise InvalidObjectId, value.to_s if value[0] > 2
330
- data = ""
331
- if (value.length > 1)
332
- raise InvalidObjectId if value[0] < 2 && value[1] > 40
333
- data << (40 * value[0] + value[1]).chr
334
- for i in 2...value.length
335
- if value[i] < 0x80
336
- data << value[i].chr
337
- else
338
- octets = ""
339
- n = value[i]
340
- begin
341
- octets = (n & 0x7f | 0x80).chr << octets
342
- n = n >> 7
343
- end until n == 0
344
- octets[-1] = (octets[-1].ord & 0x7f).chr
345
- data << octets
329
+ #
330
+ # Encode an object id. The input is assumed to be an array of integers
331
+ # representing the object id.
332
+ #
333
+ def encode_object_id(value)
334
+ raise InvalidObjectId, value.to_s if value.length < 1
335
+ raise InvalidObjectId, value.to_s if value[0] > 2
336
+ data = ""
337
+ if (value.length > 1)
338
+ raise InvalidObjectId if value[0] < 2 && value[1] > 40
339
+ data << (40 * value[0] + value[1]).chr
340
+ for i in 2...value.length
341
+ if value[i] < 0x80
342
+ data << value[i].chr
343
+ else
344
+ octets = ""
345
+ n = value[i]
346
+ begin
347
+ octets = (n & 0x7f | 0x80).chr << octets
348
+ n = n >> 7
349
+ end until n == 0
350
+ octets[-1] = (octets[-1].ord & 0x7f).chr
351
+ data << octets
352
+ end
346
353
  end
354
+ elsif (value.length == 1)
355
+ data << (40 * value[0]).chr
347
356
  end
348
- elsif (value.length == 1)
349
- data << (40 * value[0]).chr
357
+ encode_tlv(OBJECT_IDENTIFIER_TAG, data)
350
358
  end
351
- encode_tlv(OBJECT_IDENTIFIER_TAG, data)
352
- end
353
359
 
360
+ end
354
361
  end
355
362
  end
@@ -23,8 +23,6 @@
23
23
  require 'snmp/ber'
24
24
  require 'snmp/varbind'
25
25
 
26
- include SNMP::BER
27
-
28
26
  module SNMP
29
27
 
30
28
  # Exceptions thrown during message/pdu decoding
@@ -40,6 +38,9 @@ module SNMP
40
38
  SNMP_TRAP_OID_OID = ObjectId.new("1.3.6.1.6.3.1.1.4.1.0")
41
39
 
42
40
  class Message
41
+ include SNMP::BER::Encode
42
+ extend SNMP::BER::Decode
43
+
43
44
  attr_reader :version
44
45
  attr_reader :community
45
46
  attr_reader :pdu
@@ -57,9 +58,9 @@ module SNMP
57
58
 
58
59
  def decode_version(data)
59
60
  version_data, remainder = decode_integer(data)
60
- if version_data == SNMP_V1
61
+ if version_data == BER::SNMP_V1
61
62
  version = :SNMPv1
62
- elsif version_data == SNMP_V2C
63
+ elsif version_data == BER::SNMP_V2C
63
64
  version = :SNMPv2c
64
65
  else
65
66
  raise UnsupportedVersion, version_data.to_s
@@ -70,24 +71,24 @@ module SNMP
70
71
  def decode_pdu(version, data, mib=nil)
71
72
  pdu_tag, pdu_data, remainder = decode_tlv(data)
72
73
  case pdu_tag
73
- when GetRequest_PDU_TAG
74
+ when BER::GetRequest_PDU_TAG
74
75
  pdu = PDU.decode(GetRequest, pdu_data, mib)
75
- when GetNextRequest_PDU_TAG
76
+ when BER::GetNextRequest_PDU_TAG
76
77
  pdu = PDU.decode(GetNextRequest, pdu_data, mib)
77
- when Response_PDU_TAG
78
+ when BER::Response_PDU_TAG
78
79
  pdu = PDU.decode(Response, pdu_data, mib)
79
- when SetRequest_PDU_TAG
80
+ when BER::SetRequest_PDU_TAG
80
81
  pdu = PDU.decode(SetRequest, pdu_data, mib)
81
- when SNMPv1_Trap_PDU_TAG
82
+ when BER::SNMPv1_Trap_PDU_TAG
82
83
  raise InvalidPduTag, "SNMPv1-trap not valid for #{version.to_s}" if version != :SNMPv1
83
84
  pdu = SNMPv1_Trap.decode(pdu_data, mib)
84
- when GetBulkRequest_PDU_TAG
85
+ when BER::GetBulkRequest_PDU_TAG
85
86
  raise InvalidPduTag, "get-bulk not valid for #{version.to_s}" if version != :SNMPv2c
86
87
  pdu = PDU.decode(GetBulkRequest, pdu_data, mib)
87
- when InformRequest_PDU_TAG
88
+ when BER::InformRequest_PDU_TAG
88
89
  raise InvalidPduTag, "inform not valid for #{version.to_s}" if version != :SNMPv2c
89
90
  pdu = PDU.decode(InformRequest, pdu_data, mib)
90
- when SNMPv2_Trap_PDU_TAG
91
+ when BER::SNMPv2_Trap_PDU_TAG
91
92
  raise InvalidPduTag, "SNMPv2c-trap not valid for #{version.to_s}" if version != :SNMPv2c
92
93
  pdu = PDU.decode(SNMPv2_Trap, pdu_data, mib)
93
94
  else
@@ -109,9 +110,9 @@ module SNMP
109
110
 
110
111
  def encode_version(version)
111
112
  if version == :SNMPv1
112
- encode_integer(SNMP_V1)
113
+ encode_integer(BER::SNMP_V1)
113
114
  elsif version == :SNMPv2c
114
- encode_integer(SNMP_V2C)
115
+ encode_integer(BER::SNMP_V2C)
115
116
  else
116
117
  raise UnsupportedVersion, version.to_s
117
118
  end
@@ -126,6 +127,9 @@ module SNMP
126
127
  end
127
128
 
128
129
  class PDU
130
+ include SNMP::BER::Encode
131
+ extend SNMP::BER::Decode
132
+
129
133
  attr_accessor :request_id
130
134
  attr_accessor :error_index
131
135
  attr_accessor :varbind_list
@@ -202,19 +206,19 @@ module SNMP
202
206
 
203
207
  class GetRequest < PDU
204
208
  def encode
205
- encode_pdu(GetRequest_PDU_TAG)
209
+ encode_pdu(BER::GetRequest_PDU_TAG)
206
210
  end
207
211
  end
208
212
 
209
213
  class GetNextRequest < PDU
210
214
  def encode
211
- encode_pdu(GetNextRequest_PDU_TAG)
215
+ encode_pdu(BER::GetNextRequest_PDU_TAG)
212
216
  end
213
217
  end
214
218
 
215
219
  class SetRequest < PDU
216
220
  def encode
217
- encode_pdu(SetRequest_PDU_TAG)
221
+ encode_pdu(BER::SetRequest_PDU_TAG)
218
222
  end
219
223
  end
220
224
 
@@ -222,8 +226,15 @@ module SNMP
222
226
  alias max_repetitions error_index
223
227
  alias max_repetitions= error_index=
224
228
 
229
+ def initialize(request_id, varbind_list, non_repeaters, max_repetitions)
230
+ super(request_id, varbind_list)
231
+ # Reuse attributes of superclass - same encoding
232
+ @error_status = non_repeaters
233
+ @error_index = max_repetitions
234
+ end
235
+
225
236
  def encode
226
- encode_pdu(GetBulkRequest_PDU_TAG)
237
+ encode_pdu(BER::GetBulkRequest_PDU_TAG)
227
238
  end
228
239
 
229
240
  def non_repeaters=(number)
@@ -244,7 +255,7 @@ module SNMP
244
255
  end
245
256
 
246
257
  def encode
247
- encode_pdu(Response_PDU_TAG)
258
+ encode_pdu(BER::Response_PDU_TAG)
248
259
  end
249
260
  end
250
261
 
@@ -257,7 +268,7 @@ module SNMP
257
268
  #
258
269
  class SNMPv2_Trap < PDU
259
270
  def encode
260
- encode_pdu(SNMPv2_Trap_PDU_TAG)
271
+ encode_pdu(BER::SNMPv2_Trap_PDU_TAG)
261
272
  end
262
273
 
263
274
  ##
@@ -301,7 +312,7 @@ module SNMP
301
312
  #
302
313
  class InformRequest < SNMPv2_Trap
303
314
  def encode
304
- encode_pdu(InformRequest_PDU_TAG)
315
+ encode_pdu(BER::InformRequest_PDU_TAG)
305
316
  end
306
317
  end
307
318
 
@@ -309,6 +320,9 @@ module SNMP
309
320
  # The PDU class for traps in SNMPv1.
310
321
  #
311
322
  class SNMPv1_Trap
323
+ include SNMP::BER::Encode
324
+ extend SNMP::BER::Decode
325
+
312
326
  ##
313
327
  # Returns the source IP address for the trap, usually derived from the
314
328
  # source IP address of the packet that delivered the trap.
@@ -383,7 +397,7 @@ module SNMP
383
397
  encode_integer(@specific_trap) <<
384
398
  @timestamp.encode <<
385
399
  @varbind_list.encode
386
- encode_tlv(SNMPv1_Trap_PDU_TAG, pdu_data)
400
+ encode_tlv(BER::SNMPv1_Trap_PDU_TAG, pdu_data)
387
401
  end
388
402
 
389
403
  def each_varbind(&block)
@@ -22,14 +22,15 @@
22
22
 
23
23
  require 'snmp/ber'
24
24
 
25
- include SNMP::BER
26
-
27
25
  module SNMP
28
26
 
29
27
  class UnsupportedValueTag < RuntimeError; end
30
28
  class InvalidIpAddress < ArgumentError; end
31
29
 
32
30
  class VarBindList < Array
31
+ include SNMP::BER::Encode
32
+ extend SNMP::BER::Decode
33
+
33
34
  def self.decode(data, mib=nil)
34
35
  list = VarBindList.new
35
36
  varbind_data, remainder = decode_sequence(data)
@@ -71,6 +72,8 @@ module SNMP
71
72
  end
72
73
 
73
74
  class Integer
75
+ include SNMP::BER::Encode
76
+ extend SNMP::BER::Decode
74
77
  include Comparable
75
78
 
76
79
  def self.decode(value_data)
@@ -129,6 +132,7 @@ module SNMP
129
132
  end
130
133
 
131
134
  class OctetString < String
135
+ include SNMP::BER::Encode
132
136
  def self.decode(value_data)
133
137
  OctetString.new(value_data)
134
138
  end
@@ -149,6 +153,8 @@ module SNMP
149
153
  end
150
154
 
151
155
  class ObjectId < Array
156
+ include SNMP::BER::Encode
157
+ extend SNMP::BER::Decode
152
158
  include Comparable
153
159
 
154
160
  def self.decode(value_data, mib=nil)
@@ -259,6 +265,8 @@ module SNMP
259
265
  end
260
266
 
261
267
  class IpAddress
268
+ include SNMP::BER::Encode
269
+
262
270
  class << self
263
271
  def decode(value_data)
264
272
  IpAddress.new(value_data, false)
@@ -326,7 +334,7 @@ module SNMP
326
334
  end
327
335
 
328
336
  def encode
329
- encode_tlv(IpAddress_TAG, @value)
337
+ encode_tlv(BER::IpAddress_TAG, @value)
330
338
  end
331
339
 
332
340
  private
@@ -365,7 +373,7 @@ module SNMP
365
373
  end
366
374
 
367
375
  def encode
368
- encode_tagged_integer(Counter32_TAG, @value)
376
+ encode_tagged_integer(BER::Counter32_TAG, @value)
369
377
  end
370
378
  end
371
379
 
@@ -375,7 +383,7 @@ module SNMP
375
383
  end
376
384
 
377
385
  def encode
378
- encode_tagged_integer(Gauge32_TAG, @value)
386
+ encode_tagged_integer(BER::Gauge32_TAG, @value)
379
387
  end
380
388
  end
381
389
 
@@ -385,7 +393,7 @@ module SNMP
385
393
  end
386
394
 
387
395
  def encode
388
- encode_tagged_integer(Unsigned32_TAG, @value)
396
+ encode_tagged_integer(BER::Unsigned32_TAG, @value)
389
397
  end
390
398
  end
391
399
 
@@ -395,7 +403,7 @@ module SNMP
395
403
  end
396
404
 
397
405
  def encode
398
- encode_tagged_integer(TimeTicks_TAG, @value)
406
+ encode_tagged_integer(BER::TimeTicks_TAG, @value)
399
407
  end
400
408
 
401
409
  def to_s
@@ -427,7 +435,7 @@ module SNMP
427
435
  end
428
436
 
429
437
  def encode
430
- encode_tlv(Opaque_TAG, self)
438
+ encode_tlv(BER::Opaque_TAG, self)
431
439
  end
432
440
  end
433
441
 
@@ -447,11 +455,13 @@ module SNMP
447
455
  end
448
456
 
449
457
  def encode
450
- encode_tagged_integer(Counter64_TAG, @value)
458
+ encode_tagged_integer(BER::Counter64_TAG, @value)
451
459
  end
452
460
  end
453
461
 
454
462
  class Null
463
+ extend SNMP::BER::Encode
464
+
455
465
  class << self
456
466
  def decode(value_data)
457
467
  Null
@@ -472,13 +482,15 @@ module SNMP
472
482
  end
473
483
 
474
484
  class NoSuchObject
485
+ extend SNMP::BER::Encode
486
+
475
487
  class << self
476
488
  def decode(value_data)
477
489
  NoSuchObject
478
490
  end
479
491
 
480
492
  def encode
481
- encode_exception(NoSuchObject_TAG)
493
+ encode_exception(BER::NoSuchObject_TAG)
482
494
  end
483
495
 
484
496
  def asn1_type
@@ -492,13 +504,15 @@ module SNMP
492
504
  end
493
505
 
494
506
  class NoSuchInstance
507
+ extend SNMP::BER::Encode
508
+
495
509
  class << self
496
510
  def decode(value_data)
497
511
  NoSuchInstance
498
512
  end
499
513
 
500
514
  def encode
501
- encode_exception(NoSuchInstance_TAG)
515
+ encode_exception(BER::NoSuchInstance_TAG)
502
516
  end
503
517
 
504
518
  def asn1_type
@@ -512,13 +526,15 @@ module SNMP
512
526
  end
513
527
 
514
528
  class EndOfMibView
529
+ extend SNMP::BER::Encode
530
+
515
531
  class << self
516
532
  def decode(value_data)
517
533
  EndOfMibView
518
534
  end
519
535
 
520
536
  def encode
521
- encode_exception(EndOfMibView_TAG)
537
+ encode_exception(BER::EndOfMibView_TAG)
522
538
  end
523
539
 
524
540
  def asn1_type
@@ -532,6 +548,9 @@ module SNMP
532
548
  end
533
549
 
534
550
  class VarBind
551
+ include SNMP::BER::Encode
552
+ extend SNMP::BER::Decode
553
+
535
554
  attr_accessor :name
536
555
  attr_accessor :value
537
556
 
@@ -547,20 +566,20 @@ module SNMP
547
566
  end
548
567
 
549
568
  ValueDecoderMap = {
550
- INTEGER_TAG => Integer,
551
- OCTET_STRING_TAG => OctetString,
552
- NULL_TAG => Null,
553
- OBJECT_IDENTIFIER_TAG => ObjectId,
554
- IpAddress_TAG => IpAddress,
555
- Counter32_TAG => Counter32,
556
- Gauge32_TAG => Gauge32,
569
+ BER::INTEGER_TAG => Integer,
570
+ BER::OCTET_STRING_TAG => OctetString,
571
+ BER::NULL_TAG => Null,
572
+ BER::OBJECT_IDENTIFIER_TAG => ObjectId,
573
+ BER::IpAddress_TAG => IpAddress,
574
+ BER::Counter32_TAG => Counter32,
575
+ BER::Gauge32_TAG => Gauge32,
557
576
  # note Gauge32 tag same as Unsigned32
558
- TimeTicks_TAG => TimeTicks,
559
- Opaque_TAG => Opaque,
560
- Counter64_TAG => Counter64,
561
- NoSuchObject_TAG => NoSuchObject,
562
- NoSuchInstance_TAG => NoSuchInstance,
563
- EndOfMibView_TAG => EndOfMibView
577
+ BER::TimeTicks_TAG => TimeTicks,
578
+ BER::Opaque_TAG => Opaque,
579
+ BER::Counter64_TAG => Counter64,
580
+ BER::NoSuchObject_TAG => NoSuchObject,
581
+ BER::NoSuchInstance_TAG => NoSuchInstance,
582
+ BER::EndOfMibView_TAG => EndOfMibView
564
583
  }
565
584
 
566
585
  def decode_value(data)
@@ -1,3 +1,3 @@
1
1
  module SNMP
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.1"
3
3
  end
@@ -6,7 +6,8 @@ require 'snmp/ber'
6
6
 
7
7
  class ASN1_Test < Minitest::Test
8
8
 
9
- include SNMP::BER
9
+ include SNMP::BER::Encode
10
+ include SNMP::BER::Decode
10
11
 
11
12
  def test_decode_tlv_empty
12
13
  tag, value, data = decode_tlv("\001\000")
@@ -56,20 +57,20 @@ class ASN1_Test < Minitest::Test
56
57
 
57
58
  # Check invalid length - ASN.1 says that first length octet can't be 255.
58
59
  def test_bad_length
59
- assert_raises(InvalidLength) {
60
+ assert_raises(BER::InvalidLength) {
60
61
  decode_tlv("\001\377\001")
61
62
  }
62
63
  end
63
64
 
64
65
  # Check if input data is too short
65
66
  def test_out_of_data
66
- assert_raises(OutOfData) {
67
+ assert_raises(BER::OutOfData) {
67
68
  decode_tlv("\001\001")
68
69
  }
69
- assert_raises(OutOfData) {
70
+ assert_raises(BER::OutOfData) {
70
71
  decode_tlv("\001")
71
72
  }
72
- assert_raises(OutOfData) {
73
+ assert_raises(BER::OutOfData) {
73
74
  decode_tlv("")
74
75
  }
75
76
  end
@@ -103,7 +104,7 @@ class ASN1_Test < Minitest::Test
103
104
  assert_equal(255, i)
104
105
  assert_equal("", data)
105
106
 
106
- assert_raises(InvalidTag) {
107
+ assert_raises(BER::InvalidTag) {
107
108
  decode_integer("\001\004\001\002\003\004")
108
109
  }
109
110
  end
@@ -113,7 +114,7 @@ class ASN1_Test < Minitest::Test
113
114
  assert_equal(16909060, i)
114
115
  assert_equal("", data)
115
116
 
116
- assert_raises(InvalidTag) {
117
+ assert_raises(BER::InvalidTag) {
117
118
  decode_timeticks("\002\004\001\002\003\004")
118
119
  }
119
120
  end
@@ -122,7 +123,7 @@ class ASN1_Test < Minitest::Test
122
123
  def test_decode_octet_string
123
124
  s, _ = decode_octet_string("\004\202\000\005hello")
124
125
  assert_equal("hello",s)
125
- assert_raises(InvalidTag) {
126
+ assert_raises(BER::InvalidTag) {
126
127
  decode_octet_string("\005\202\000\005hello")
127
128
  }
128
129
  end
@@ -130,10 +131,10 @@ class ASN1_Test < Minitest::Test
130
131
  def test_decode_ip_address
131
132
  ip, _ = decode_ip_address("@\004\001\002\003\004")
132
133
  assert_equal(ip, "\001\002\003\004")
133
- assert_raises(InvalidTag) {
134
+ assert_raises(BER::InvalidTag) {
134
135
  decode_ip_address("\004\004\001\002\003\004")
135
136
  }
136
- assert_raises(InvalidLength) {
137
+ assert_raises(BER::InvalidLength) {
137
138
  decode_ip_address("@\005\001\002\003\004\005")
138
139
  }
139
140
  end
@@ -148,7 +149,7 @@ class ASN1_Test < Minitest::Test
148
149
  assert_equal("\002\001\077", seq)
149
150
  assert_equal("\002\001\001", data)
150
151
 
151
- assert_raises(InvalidTag) {
152
+ assert_raises(BER::InvalidTag) {
152
153
  decode_sequence("\061\003\002\001\077")
153
154
  }
154
155
  end
@@ -180,7 +181,7 @@ class ASN1_Test < Minitest::Test
180
181
  assert_equal([0,0], object_id);
181
182
  assert_equal("", remainder)
182
183
 
183
- assert_raises(InvalidTag) do
184
+ assert_raises(BER::InvalidTag) do
184
185
  decode_object_id("\007\001+")
185
186
  end
186
187
  end
@@ -191,7 +192,7 @@ class ASN1_Test < Minitest::Test
191
192
  assert_equal("\177", encode_length(127))
192
193
  assert_equal("\201\200", encode_length(128))
193
194
  assert_equal("\202\002\001", encode_length(513))
194
- assert_raises(InvalidLength) { encode_length(-1) }
195
+ assert_raises(BER::InvalidLength) { encode_length(-1) }
195
196
  end
196
197
 
197
198
  def test_encode_integer
@@ -232,8 +233,8 @@ class ASN1_Test < Minitest::Test
232
233
  assert_equal("\006\002+\006", encode_object_id([1,3,6]))
233
234
  assert_equal("\006\003+\202\001", encode_object_id([1,3,257]))
234
235
  assert_equal("\006\003" << 82.chr << "\202\001", encode_object_id([2,2,257]))
235
- assert_raises(InvalidObjectId) { encode_object_id([3,2,257]) }
236
- assert_raises(InvalidObjectId) { encode_object_id([]) }
236
+ assert_raises(BER::InvalidObjectId) { encode_object_id([3,2,257]) }
237
+ assert_raises(BER::InvalidObjectId) { encode_object_id([]) }
237
238
 
238
239
  assert_equal("\006\a+\203\377\177\203\377\177",
239
240
  encode_object_id(SNMP::ObjectId.new("1.3.65535.65535")))
@@ -94,9 +94,9 @@ class TestProtocol < Minitest::Test
94
94
  end
95
95
 
96
96
  def test_get_bulk_create
97
- request = SNMP::GetBulkRequest.new(1234, VarBindList.new("1.3.6.2"), 0, 10)
97
+ request = SNMP::GetBulkRequest.new(1234, VarBindList.new("1.3.6.2"), 20, 10)
98
98
  assert_equal(1234, request.request_id)
99
- assert_equal(0, request.non_repeaters)
99
+ assert_equal(20, request.non_repeaters)
100
100
  assert_equal(10, request.max_repetitions)
101
101
  assert_equal(1, request.varbind_list.length)
102
102
  assert_equal("1.3.6.2", request.varbind_list.first.name.to_s)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Halliday
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-31 00:00:00.000000000 Z
11
+ date: 2018-09-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Ruby implementation of SNMP (the Simple Network Management Protocol).
14
14
  email: hallidave@gmail.com