net-snmp 1.2.4 → 1.2.5
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.
- package/README.md +1296 -1296
- package/example/cisco-device-inventory.js +140 -140
- package/example/snmp-get-bulk.js +53 -53
- package/example/snmp-get-next.js +30 -30
- package/example/snmp-get.js +30 -30
- package/example/snmp-inform.js +32 -32
- package/example/snmp-set.js +31 -31
- package/example/snmp-subtree.js +37 -37
- package/example/snmp-table-columns.js +61 -61
- package/example/snmp-table.js +56 -56
- package/example/snmp-tail.js +34 -34
- package/example/snmp-trap.js +32 -32
- package/example/snmp-walk.js +37 -37
- package/example/specify-source-address-and-port.js +41 -41
- package/example/specify-sysuptime-to-inform.js +34 -34
- package/example/specify-sysuptime-to-trap.js +35 -35
- package/index.js +1464 -1464
- package/package.json +43 -39
- package/ref/rfc/v1/rfc1065.txt +1178 -1178
- package/ref/rfc/v1/rfc1066.txt +5042 -5042
- package/ref/rfc/v1/rfc1067.txt +1850 -1850
- package/ref/rfc/v1/rfc1098.txt +1906 -1906
- package/ref/rfc/v1/rfc1155.txt +1234 -1234
- package/ref/rfc/v2c/rfc1908.txt +563 -563
- package/ref/rfc/v2c/rfc2578.txt +2541 -2541
- package/ref/rfc/v2c/rfc3416.txt +1739 -1739
- package/test/varbinds.js +42 -42
package/index.js
CHANGED
@@ -1,1464 +1,1464 @@
|
|
1
|
-
|
2
|
-
// Copyright 2013 Stephen Vickers <stephen.vickers.sv@gmail.com>
|
3
|
-
|
4
|
-
var ber = require ("asn1-ber").Ber;
|
5
|
-
var dgram = require ("dgram");
|
6
|
-
var events = require ("events");
|
7
|
-
var util = require ("util");
|
8
|
-
|
9
|
-
/*****************************************************************************
|
10
|
-
** Constants
|
11
|
-
**/
|
12
|
-
|
13
|
-
function _expandConstantObject (object) {
|
14
|
-
var keys = [];
|
15
|
-
for (var key in object)
|
16
|
-
keys.push (key);
|
17
|
-
for (var i = 0; i < keys.length; i++)
|
18
|
-
object[object[keys[i]]] = parseInt (keys[i]);
|
19
|
-
}
|
20
|
-
|
21
|
-
var ErrorStatus = {
|
22
|
-
0: "NoError",
|
23
|
-
1: "TooBig",
|
24
|
-
2: "NoSuchName",
|
25
|
-
3: "BadValue",
|
26
|
-
4: "ReadOnly",
|
27
|
-
5: "GeneralError",
|
28
|
-
6: "NoAccess",
|
29
|
-
7: "WrongType",
|
30
|
-
8: "WrongLength",
|
31
|
-
9: "WrongEncoding",
|
32
|
-
10: "WrongValue",
|
33
|
-
11: "NoCreation",
|
34
|
-
12: "InconsistentValue",
|
35
|
-
13: "ResourceUnavailable",
|
36
|
-
14: "CommitFailed",
|
37
|
-
15: "UndoFailed",
|
38
|
-
16: "AuthorizationError",
|
39
|
-
17: "NotWritable",
|
40
|
-
18: "InconsistentName"
|
41
|
-
};
|
42
|
-
|
43
|
-
_expandConstantObject (ErrorStatus);
|
44
|
-
|
45
|
-
var ObjectType = {
|
46
|
-
1: "Boolean",
|
47
|
-
2: "Integer",
|
48
|
-
4: "OctetString",
|
49
|
-
5: "Null",
|
50
|
-
6: "OID",
|
51
|
-
64: "IpAddress",
|
52
|
-
65: "Counter",
|
53
|
-
66: "Gauge",
|
54
|
-
67: "TimeTicks",
|
55
|
-
68: "Opaque",
|
56
|
-
70: "Counter64",
|
57
|
-
128: "NoSuchObject",
|
58
|
-
129: "NoSuchInstance",
|
59
|
-
130: "EndOfMibView"
|
60
|
-
};
|
61
|
-
|
62
|
-
_expandConstantObject (ObjectType);
|
63
|
-
|
64
|
-
ObjectType.Integer32 = ObjectType.Integer;
|
65
|
-
ObjectType.Counter32 = ObjectType.Counter;
|
66
|
-
ObjectType.Gauge32 = ObjectType.Gauge;
|
67
|
-
ObjectType.Unsigned32 = ObjectType.Gauge32;
|
68
|
-
|
69
|
-
var PduType = {
|
70
|
-
160: "GetRequest",
|
71
|
-
161: "GetNextRequest",
|
72
|
-
162: "GetResponse",
|
73
|
-
163: "SetRequest",
|
74
|
-
164: "Trap",
|
75
|
-
165: "GetBulkRequest",
|
76
|
-
166: "InformRequest",
|
77
|
-
167: "TrapV2",
|
78
|
-
168: "Report"
|
79
|
-
};
|
80
|
-
|
81
|
-
_expandConstantObject (PduType);
|
82
|
-
|
83
|
-
var TrapType = {
|
84
|
-
0: "ColdStart",
|
85
|
-
1: "WarmStart",
|
86
|
-
2: "LinkDown",
|
87
|
-
3: "LinkUp",
|
88
|
-
4: "AuthenticationFailure",
|
89
|
-
5: "EgpNeighborLoss",
|
90
|
-
6: "EnterpriseSpecific"
|
91
|
-
};
|
92
|
-
|
93
|
-
_expandConstantObject (TrapType);
|
94
|
-
|
95
|
-
var Version1 = 0;
|
96
|
-
var Version2c = 1;
|
97
|
-
|
98
|
-
/*****************************************************************************
|
99
|
-
** Exception class definitions
|
100
|
-
**/
|
101
|
-
|
102
|
-
function ResponseInvalidError (message) {
|
103
|
-
this.name = "ResponseInvalidError";
|
104
|
-
this.message = message;
|
105
|
-
Error.captureStackTrace(this, ResponseInvalidError);
|
106
|
-
}
|
107
|
-
util.inherits (ResponseInvalidError, Error);
|
108
|
-
|
109
|
-
function RequestInvalidError (message) {
|
110
|
-
this.name = "RequestInvalidError";
|
111
|
-
this.message = message;
|
112
|
-
Error.captureStackTrace(this, RequestInvalidError);
|
113
|
-
}
|
114
|
-
util.inherits (RequestInvalidError, Error);
|
115
|
-
|
116
|
-
function RequestFailedError (message, status) {
|
117
|
-
this.name = "RequestFailedError";
|
118
|
-
this.message = message;
|
119
|
-
this.status = status;
|
120
|
-
Error.captureStackTrace(this, RequestFailedError);
|
121
|
-
}
|
122
|
-
util.inherits (RequestFailedError, Error);
|
123
|
-
|
124
|
-
function RequestTimedOutError (message) {
|
125
|
-
this.name = "RequestTimedOutError";
|
126
|
-
this.message = message;
|
127
|
-
Error.captureStackTrace(this, RequestTimedOutError);
|
128
|
-
}
|
129
|
-
util.inherits (RequestTimedOutError, Error);
|
130
|
-
|
131
|
-
/*****************************************************************************
|
132
|
-
** OID and varbind helper functions
|
133
|
-
**/
|
134
|
-
|
135
|
-
function isVarbindError (varbind) {
|
136
|
-
return !!(varbind.type == ObjectType.NoSuchObject
|
137
|
-
|| varbind.type == ObjectType.NoSuchInstance
|
138
|
-
|| varbind.type == ObjectType.EndOfMibView);
|
139
|
-
}
|
140
|
-
|
141
|
-
function varbindError (varbind) {
|
142
|
-
return (ObjectType[varbind.type] || "NotAnError") + ": " + varbind.oid;
|
143
|
-
}
|
144
|
-
|
145
|
-
function oidFollowsOid (oidString, nextString) {
|
146
|
-
var oid = {str: oidString, len: oidString.length, idx: 0};
|
147
|
-
var next = {str: nextString, len: nextString.length, idx: 0};
|
148
|
-
var dotCharCode = ".".charCodeAt (0);
|
149
|
-
|
150
|
-
function getNumber (item) {
|
151
|
-
var n = 0;
|
152
|
-
if (item.idx >= item.len)
|
153
|
-
return null;
|
154
|
-
while (item.idx < item.len) {
|
155
|
-
var charCode = item.str.charCodeAt (item.idx++);
|
156
|
-
if (charCode == dotCharCode)
|
157
|
-
return n;
|
158
|
-
n = (n ? (n * 10) : n) + (charCode - 48);
|
159
|
-
}
|
160
|
-
return n;
|
161
|
-
}
|
162
|
-
|
163
|
-
while (1) {
|
164
|
-
var oidNumber = getNumber (oid);
|
165
|
-
var nextNumber = getNumber (next);
|
166
|
-
|
167
|
-
if (oidNumber !== null) {
|
168
|
-
if (nextNumber !== null) {
|
169
|
-
if (nextNumber > oidNumber) {
|
170
|
-
return true;
|
171
|
-
} else if (nextNumber < oidNumber) {
|
172
|
-
return false;
|
173
|
-
}
|
174
|
-
} else {
|
175
|
-
return true;
|
176
|
-
}
|
177
|
-
} else {
|
178
|
-
return true;
|
179
|
-
}
|
180
|
-
}
|
181
|
-
}
|
182
|
-
|
183
|
-
function oidInSubtree (oidString, nextString) {
|
184
|
-
var oid = oidString.split (".");
|
185
|
-
var next = nextString.split (".");
|
186
|
-
|
187
|
-
if (oid.length > next.length)
|
188
|
-
return false;
|
189
|
-
|
190
|
-
for (var i = 0; i < oid.length; i++) {
|
191
|
-
if (next[i] != oid[i])
|
192
|
-
return false;
|
193
|
-
}
|
194
|
-
|
195
|
-
return true;
|
196
|
-
}
|
197
|
-
|
198
|
-
/**
|
199
|
-
** Some SNMP agents produce integers on the wire such as 00 ff ff ff ff.
|
200
|
-
** The ASN.1 BER parser we use throws an error when parsing this, which we
|
201
|
-
** believe is correct. So, we decided not to bother the "asn1" developer(s)
|
202
|
-
** with this, instead opting to work around it here.
|
203
|
-
**
|
204
|
-
** If an integer is 5 bytes in length we check if the first byte is 0, and if so
|
205
|
-
** simply drop it and parse it like it was a 4 byte integer, otherwise throw
|
206
|
-
** an error since the integer is too large.
|
207
|
-
**/
|
208
|
-
|
209
|
-
function readInt (buffer) {
|
210
|
-
return readUint (buffer, true);
|
211
|
-
}
|
212
|
-
|
213
|
-
function readUint (buffer, isSigned) {
|
214
|
-
buffer.readByte ();
|
215
|
-
var length = buffer.readByte ();
|
216
|
-
var value = 0;
|
217
|
-
var signedBitSet = false;
|
218
|
-
|
219
|
-
if (length > 5) {
|
220
|
-
throw new RangeError ("Integer too long '" + length + "'");
|
221
|
-
} else if (length == 5) {
|
222
|
-
if (buffer.readByte () !== 0)
|
223
|
-
throw new RangeError ("Integer too long '" + length + "'");
|
224
|
-
length = 4;
|
225
|
-
}
|
226
|
-
|
227
|
-
for (var i = 0; i < length; i++) {
|
228
|
-
value *= 256;
|
229
|
-
value += buffer.readByte ();
|
230
|
-
|
231
|
-
if (isSigned && i <= 0) {
|
232
|
-
if ((value & 0x80) == 0x80)
|
233
|
-
signedBitSet = true;
|
234
|
-
}
|
235
|
-
}
|
236
|
-
|
237
|
-
if (signedBitSet)
|
238
|
-
value -= (1 << (i * 8));
|
239
|
-
|
240
|
-
return value;
|
241
|
-
}
|
242
|
-
|
243
|
-
function readUint64 (buffer) {
|
244
|
-
var value = buffer.readString (ObjectType.Counter64, true);
|
245
|
-
|
246
|
-
return value;
|
247
|
-
}
|
248
|
-
|
249
|
-
function readVarbinds (buffer, varbinds) {
|
250
|
-
buffer.readSequence ();
|
251
|
-
|
252
|
-
while (1) {
|
253
|
-
buffer.readSequence ();
|
254
|
-
var oid = buffer.readOID ();
|
255
|
-
var type = buffer.peek ();
|
256
|
-
|
257
|
-
if (type == null)
|
258
|
-
break;
|
259
|
-
|
260
|
-
var value;
|
261
|
-
|
262
|
-
if (type == ObjectType.Boolean) {
|
263
|
-
value = buffer.readBoolean ();
|
264
|
-
} else if (type == ObjectType.Integer) {
|
265
|
-
value = readInt (buffer);
|
266
|
-
} else if (type == ObjectType.OctetString) {
|
267
|
-
value = buffer.readString (null, true);
|
268
|
-
} else if (type == ObjectType.Null) {
|
269
|
-
buffer.readByte ();
|
270
|
-
buffer.readByte ();
|
271
|
-
value = null;
|
272
|
-
} else if (type == ObjectType.OID) {
|
273
|
-
value = buffer.readOID ();
|
274
|
-
} else if (type == ObjectType.IpAddress) {
|
275
|
-
var bytes = buffer.readString (ObjectType.IpAddress, true);
|
276
|
-
if (bytes.length != 4)
|
277
|
-
throw new ResponseInvalidError ("Length '" + bytes.length
|
278
|
-
+ "' of IP address '" + bytes.toString ("hex")
|
279
|
-
+ "' is not 4");
|
280
|
-
value = bytes[0] + "." + bytes[1] + "." + bytes[2] + "." + bytes[3];
|
281
|
-
} else if (type == ObjectType.Counter) {
|
282
|
-
value = readUint (buffer);
|
283
|
-
} else if (type == ObjectType.Gauge) {
|
284
|
-
value = readUint (buffer);
|
285
|
-
} else if (type == ObjectType.TimeTicks) {
|
286
|
-
value = readUint (buffer);
|
287
|
-
} else if (type == ObjectType.Opaque) {
|
288
|
-
value = buffer.readString (ObjectType.Opaque, true);
|
289
|
-
} else if (type == ObjectType.Counter64) {
|
290
|
-
value = readUint64 (buffer);
|
291
|
-
} else if (type == ObjectType.NoSuchObject) {
|
292
|
-
buffer.readByte ();
|
293
|
-
buffer.readByte ();
|
294
|
-
value = null;
|
295
|
-
} else if (type == ObjectType.NoSuchInstance) {
|
296
|
-
buffer.readByte ();
|
297
|
-
buffer.readByte ();
|
298
|
-
value = null;
|
299
|
-
} else if (type == ObjectType.EndOfMibView) {
|
300
|
-
buffer.readByte ();
|
301
|
-
buffer.readByte ();
|
302
|
-
value = null;
|
303
|
-
} else {
|
304
|
-
throw new ResponseInvalidError ("Unknown type '" + type
|
305
|
-
+ "' in response");
|
306
|
-
}
|
307
|
-
|
308
|
-
varbinds.push ({
|
309
|
-
oid: oid,
|
310
|
-
type: type,
|
311
|
-
value: value
|
312
|
-
});
|
313
|
-
}
|
314
|
-
}
|
315
|
-
|
316
|
-
function writeUint (buffer, type, value) {
|
317
|
-
var b = new Buffer (4);
|
318
|
-
b.writeUInt32BE (value, 0);
|
319
|
-
buffer.writeBuffer (b, type);
|
320
|
-
}
|
321
|
-
|
322
|
-
function writeUint64 (buffer, value) {
|
323
|
-
buffer.writeBuffer (value, ObjectType.Counter64);
|
324
|
-
}
|
325
|
-
|
326
|
-
function writeVarbinds (buffer, varbinds) {
|
327
|
-
buffer.startSequence ();
|
328
|
-
for (var i = 0; i < varbinds.length; i++) {
|
329
|
-
buffer.startSequence ();
|
330
|
-
buffer.writeOID (varbinds[i].oid);
|
331
|
-
|
332
|
-
if (varbinds[i].type && varbinds[i].hasOwnProperty("value")) {
|
333
|
-
var type = varbinds[i].type;
|
334
|
-
var value = varbinds[i].value;
|
335
|
-
|
336
|
-
if (type == ObjectType.Boolean) {
|
337
|
-
buffer.writeBoolean (value ? true : false);
|
338
|
-
} else if (type == ObjectType.Integer) { // also Integer32
|
339
|
-
buffer.writeInt (value);
|
340
|
-
} else if (type == ObjectType.OctetString) {
|
341
|
-
if (typeof value == "string")
|
342
|
-
buffer.writeString (value);
|
343
|
-
else
|
344
|
-
buffer.writeBuffer (value, ObjectType.OctetString);
|
345
|
-
} else if (type == ObjectType.Null) {
|
346
|
-
buffer.writeNull ();
|
347
|
-
} else if (type == ObjectType.OID) {
|
348
|
-
buffer.writeOID (value);
|
349
|
-
} else if (type == ObjectType.IpAddress) {
|
350
|
-
var bytes = value.split (".");
|
351
|
-
if (bytes.length != 4)
|
352
|
-
throw new RequestInvalidError ("Invalid IP address '"
|
353
|
-
+ value + "'");
|
354
|
-
buffer.writeBuffer (new Buffer (bytes), 64);
|
355
|
-
} else if (type == ObjectType.Counter) { // also Counter32
|
356
|
-
writeUint (buffer, ObjectType.Counter, value);
|
357
|
-
} else if (type == ObjectType.Gauge) { // also Gauge32 & Unsigned32
|
358
|
-
writeUint (buffer, ObjectType.Gauge, value);
|
359
|
-
} else if (type == ObjectType.TimeTicks) {
|
360
|
-
writeUint (buffer, ObjectType.TimeTicks, value);
|
361
|
-
} else if (type == ObjectType.Opaque) {
|
362
|
-
buffer.writeBuffer (value, ObjectType.Opaque);
|
363
|
-
} else if (type == ObjectType.Counter64) {
|
364
|
-
writeUint64 (buffer, value);
|
365
|
-
} else {
|
366
|
-
throw new RequestInvalidError ("Unknown type '" + type
|
367
|
-
+ "' in request");
|
368
|
-
}
|
369
|
-
} else {
|
370
|
-
buffer.writeNull ();
|
371
|
-
}
|
372
|
-
|
373
|
-
buffer.endSequence ();
|
374
|
-
}
|
375
|
-
buffer.endSequence ();
|
376
|
-
}
|
377
|
-
|
378
|
-
/*****************************************************************************
|
379
|
-
** PDU class definitions
|
380
|
-
**/
|
381
|
-
|
382
|
-
var SimplePdu = function (id, varbinds, options) {
|
383
|
-
this.id = id;
|
384
|
-
this.varbinds = varbinds;
|
385
|
-
this.options = options || {};
|
386
|
-
};
|
387
|
-
|
388
|
-
SimplePdu.prototype.toBuffer = function (buffer) {
|
389
|
-
buffer.startSequence (this.type);
|
390
|
-
|
391
|
-
buffer.writeInt (this.id);
|
392
|
-
buffer.writeInt ((this.type == PduType.GetBulkRequest)
|
393
|
-
? (this.options.nonRepeaters || 0)
|
394
|
-
: 0);
|
395
|
-
buffer.writeInt ((this.type == PduType.GetBulkRequest)
|
396
|
-
? (this.options.maxRepetitions || 0)
|
397
|
-
: 0);
|
398
|
-
|
399
|
-
writeVarbinds (buffer, this.varbinds);
|
400
|
-
|
401
|
-
buffer.endSequence ();
|
402
|
-
};
|
403
|
-
|
404
|
-
var GetBulkRequestPdu = function () {
|
405
|
-
this.type = PduType.GetBulkRequest;
|
406
|
-
GetBulkRequestPdu.super_.apply (this, arguments);
|
407
|
-
};
|
408
|
-
|
409
|
-
util.inherits (GetBulkRequestPdu, SimplePdu);
|
410
|
-
|
411
|
-
var GetNextRequestPdu = function () {
|
412
|
-
this.type = PduType.GetNextRequest;
|
413
|
-
GetNextRequestPdu.super_.apply (this, arguments);
|
414
|
-
};
|
415
|
-
|
416
|
-
util.inherits (GetNextRequestPdu, SimplePdu);
|
417
|
-
|
418
|
-
var GetResponsePdu = function (buffer) {
|
419
|
-
this.type = PduType.GetResponse;
|
420
|
-
|
421
|
-
buffer.readSequence (this.type);
|
422
|
-
|
423
|
-
this.id = buffer.readInt ();
|
424
|
-
|
425
|
-
this.errorStatus = buffer.readInt ();
|
426
|
-
this.errorIndex = buffer.readInt ();
|
427
|
-
|
428
|
-
this.varbinds = [];
|
429
|
-
|
430
|
-
readVarbinds (buffer, this.varbinds);
|
431
|
-
};
|
432
|
-
|
433
|
-
var GetRequestPdu = function () {
|
434
|
-
this.type = PduType.GetRequest;
|
435
|
-
GetRequestPdu.super_.apply (this, arguments);
|
436
|
-
};
|
437
|
-
|
438
|
-
util.inherits (GetRequestPdu, SimplePdu);
|
439
|
-
|
440
|
-
var InformRequestPdu = function () {
|
441
|
-
this.type = PduType.InformRequest;
|
442
|
-
InformRequestPdu.super_.apply (this, arguments);
|
443
|
-
};
|
444
|
-
|
445
|
-
util.inherits (InformRequestPdu, SimplePdu);
|
446
|
-
|
447
|
-
var SetRequestPdu = function () {
|
448
|
-
this.type = PduType.SetRequest;
|
449
|
-
SetRequestPdu.super_.apply (this, arguments);
|
450
|
-
};
|
451
|
-
|
452
|
-
util.inherits (SetRequestPdu, SimplePdu);
|
453
|
-
|
454
|
-
var TrapPdu = function (typeOrOid, varbinds, options) {
|
455
|
-
this.type = PduType.Trap;
|
456
|
-
|
457
|
-
this.agentAddr = options.agentAddr || "127.0.0.1";
|
458
|
-
this.upTime = options.upTime;
|
459
|
-
|
460
|
-
if (typeof typeOrOid == "string") {
|
461
|
-
this.generic = TrapType.EnterpriseSpecific;
|
462
|
-
this.specific = parseInt (typeOrOid.match (/\.(\d+)$/)[1]);
|
463
|
-
this.enterprise = typeOrOid.replace (/\.(\d+)$/, "");
|
464
|
-
} else {
|
465
|
-
this.generic = typeOrOid;
|
466
|
-
this.specific = 0;
|
467
|
-
this.enterprise = "1.3.6.1.4.1";
|
468
|
-
}
|
469
|
-
|
470
|
-
this.varbinds = varbinds;
|
471
|
-
};
|
472
|
-
|
473
|
-
TrapPdu.prototype.toBuffer = function (buffer) {
|
474
|
-
buffer.startSequence (this.type);
|
475
|
-
|
476
|
-
buffer.writeOID (this.enterprise);
|
477
|
-
buffer.writeBuffer (new Buffer (this.agentAddr.split (".")),
|
478
|
-
ObjectType.IpAddress);
|
479
|
-
buffer.writeInt (this.generic);
|
480
|
-
buffer.writeInt (this.specific);
|
481
|
-
writeUint (buffer, ObjectType.TimeTicks,
|
482
|
-
this.upTime || Math.floor (process.uptime () * 100));
|
483
|
-
|
484
|
-
writeVarbinds (buffer, this.varbinds);
|
485
|
-
|
486
|
-
buffer.endSequence ();
|
487
|
-
};
|
488
|
-
|
489
|
-
var TrapV2Pdu = function () {
|
490
|
-
this.type = PduType.TrapV2;
|
491
|
-
TrapV2Pdu.super_.apply (this, arguments);
|
492
|
-
};
|
493
|
-
|
494
|
-
util.inherits (TrapV2Pdu, SimplePdu);
|
495
|
-
|
496
|
-
/*****************************************************************************
|
497
|
-
** Message class definitions
|
498
|
-
**/
|
499
|
-
|
500
|
-
var RequestMessage = function (version, community, pdu) {
|
501
|
-
this.version = version;
|
502
|
-
this.community = community;
|
503
|
-
this.pdu = pdu;
|
504
|
-
};
|
505
|
-
|
506
|
-
RequestMessage.prototype.toBuffer = function () {
|
507
|
-
if (this.buffer)
|
508
|
-
return this.buffer;
|
509
|
-
|
510
|
-
var writer = new ber.Writer ();
|
511
|
-
|
512
|
-
writer.startSequence ();
|
513
|
-
|
514
|
-
writer.writeInt (this.version);
|
515
|
-
writer.writeString (this.community);
|
516
|
-
|
517
|
-
this.pdu.toBuffer (writer);
|
518
|
-
|
519
|
-
writer.endSequence ();
|
520
|
-
|
521
|
-
this.buffer = writer.buffer;
|
522
|
-
|
523
|
-
return this.buffer;
|
524
|
-
};
|
525
|
-
|
526
|
-
var ResponseMessage = function (buffer) {
|
527
|
-
var reader = new ber.Reader (buffer);
|
528
|
-
|
529
|
-
reader.readSequence ();
|
530
|
-
|
531
|
-
this.version = reader.readInt ();
|
532
|
-
this.community = reader.readString ();
|
533
|
-
|
534
|
-
var type = reader.peek ();
|
535
|
-
|
536
|
-
if (type == PduType.GetResponse) {
|
537
|
-
this.pdu = new GetResponsePdu (reader);
|
538
|
-
} else {
|
539
|
-
throw new ResponseInvalidError ("Unknown PDU type '" + type
|
540
|
-
+ "' in response");
|
541
|
-
}
|
542
|
-
};
|
543
|
-
|
544
|
-
/*****************************************************************************
|
545
|
-
** Session class definition
|
546
|
-
**/
|
547
|
-
|
548
|
-
var Session = function (target, community, options) {
|
549
|
-
this.target = target || "127.0.0.1";
|
550
|
-
this.community = community || "public";
|
551
|
-
|
552
|
-
this.version = (options && options.version)
|
553
|
-
? options.version
|
554
|
-
: Version1;
|
555
|
-
|
556
|
-
this.transport = (options && options.transport)
|
557
|
-
? options.transport
|
558
|
-
: "udp4";
|
559
|
-
this.port = (options && options.port )
|
560
|
-
? options.port
|
561
|
-
: 161;
|
562
|
-
this.trapPort = (options && options.trapPort )
|
563
|
-
? options.trapPort
|
564
|
-
: 162;
|
565
|
-
|
566
|
-
this.retries = (options && (options.retries || options.retries == 0))
|
567
|
-
? options.retries
|
568
|
-
: 1;
|
569
|
-
this.timeout = (options && options.timeout)
|
570
|
-
? options.timeout
|
571
|
-
: 5000;
|
572
|
-
|
573
|
-
this.sourceAddress = (options && options.sourceAddress )
|
574
|
-
? options.sourceAddress
|
575
|
-
: undefined;
|
576
|
-
this.sourcePort = (options && options.sourcePort )
|
577
|
-
? parseInt(options.sourcePort)
|
578
|
-
: undefined;
|
579
|
-
|
580
|
-
this.idBitsSize = (options && options.idBitsSize)
|
581
|
-
? parseInt(options.idBitsSize)
|
582
|
-
: 32;
|
583
|
-
|
584
|
-
this.reqs = {};
|
585
|
-
this.reqCount = 0;
|
586
|
-
|
587
|
-
this.dgram = dgram.createSocket (this.transport);
|
588
|
-
this.dgram.unref();
|
589
|
-
|
590
|
-
var me = this;
|
591
|
-
this.dgram.on ("message", me.onMsg.bind (me));
|
592
|
-
this.dgram.on ("close", me.onClose.bind (me));
|
593
|
-
this.dgram.on ("error", me.onError.bind (me));
|
594
|
-
|
595
|
-
if (this.sourceAddress || this.sourcePort)
|
596
|
-
this.dgram.bind (this.sourcePort, this.sourceAddress);
|
597
|
-
};
|
598
|
-
|
599
|
-
util.inherits (Session, events.EventEmitter);
|
600
|
-
|
601
|
-
Session.prototype.close = function () {
|
602
|
-
this.dgram.close ();
|
603
|
-
return this;
|
604
|
-
};
|
605
|
-
|
606
|
-
Session.prototype.cancelRequests = function (error) {
|
607
|
-
var id;
|
608
|
-
for (id in this.reqs) {
|
609
|
-
var req = this.reqs[id];
|
610
|
-
this.unregisterRequest (req.id);
|
611
|
-
req.responseCb (error);
|
612
|
-
}
|
613
|
-
};
|
614
|
-
|
615
|
-
function _generateId (bitSize) {
|
616
|
-
if (bitSize === 16) {
|
617
|
-
return Math.floor(Math.random() * 10000) % 65535;
|
618
|
-
}
|
619
|
-
return Math.floor(Math.random() * 100000000) % 4294967295;
|
620
|
-
}
|
621
|
-
|
622
|
-
Session.prototype.get = function (oids, responseCb) {
|
623
|
-
function feedCb (req, message) {
|
624
|
-
var pdu = message.pdu;
|
625
|
-
var varbinds = [];
|
626
|
-
|
627
|
-
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
628
|
-
req.responseCb (new ResponseInvalidError ("Requested OIDs do not "
|
629
|
-
+ "match response OIDs"));
|
630
|
-
} else {
|
631
|
-
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
632
|
-
if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) {
|
633
|
-
req.responseCb (new ResponseInvalidError ("OID '"
|
634
|
-
+ req.message.pdu.varbinds[i].oid
|
635
|
-
+ "' in request at positiion '" + i + "' does not "
|
636
|
-
+ "match OID '" + pdu.varbinds[i].oid + "' in response "
|
637
|
-
+ "at position '" + i + "'"));
|
638
|
-
return;
|
639
|
-
} else {
|
640
|
-
varbinds.push (pdu.varbinds[i]);
|
641
|
-
}
|
642
|
-
}
|
643
|
-
|
644
|
-
req.responseCb (null, varbinds);
|
645
|
-
}
|
646
|
-
}
|
647
|
-
|
648
|
-
var pduVarbinds = [];
|
649
|
-
|
650
|
-
for (var i = 0; i < oids.length; i++) {
|
651
|
-
var varbind = {
|
652
|
-
oid: oids[i]
|
653
|
-
};
|
654
|
-
pduVarbinds.push (varbind);
|
655
|
-
}
|
656
|
-
|
657
|
-
this.simpleGet (GetRequestPdu, feedCb, pduVarbinds, responseCb);
|
658
|
-
|
659
|
-
return this;
|
660
|
-
};
|
661
|
-
|
662
|
-
Session.prototype.getBulk = function () {
|
663
|
-
var oids, nonRepeaters, maxRepetitions, responseCb;
|
664
|
-
|
665
|
-
if (arguments.length >= 4) {
|
666
|
-
oids = arguments[0];
|
667
|
-
nonRepeaters = arguments[1];
|
668
|
-
maxRepetitions = arguments[2];
|
669
|
-
responseCb = arguments[3];
|
670
|
-
} else if (arguments.length >= 3) {
|
671
|
-
oids = arguments[0];
|
672
|
-
nonRepeaters = arguments[1];
|
673
|
-
maxRepetitions = 10;
|
674
|
-
responseCb = arguments[2];
|
675
|
-
} else {
|
676
|
-
oids = arguments[0];
|
677
|
-
nonRepeaters = 0;
|
678
|
-
maxRepetitions = 10;
|
679
|
-
responseCb = arguments[1];
|
680
|
-
}
|
681
|
-
|
682
|
-
function feedCb (req, message) {
|
683
|
-
var pdu = message.pdu;
|
684
|
-
var varbinds = [];
|
685
|
-
var i = 0;
|
686
|
-
|
687
|
-
// first walk through and grab non-repeaters
|
688
|
-
if (pdu.varbinds.length < nonRepeaters) {
|
689
|
-
req.responseCb (new ResponseInvalidError ("Varbind count in "
|
690
|
-
+ "response '" + pdu.varbinds.length + "' is less than "
|
691
|
-
+ "non-repeaters '" + nonRepeaters + "' in request"));
|
692
|
-
} else {
|
693
|
-
for ( ; i < nonRepeaters; i++) {
|
694
|
-
if (isVarbindError (pdu.varbinds[i])) {
|
695
|
-
varbinds.push (pdu.varbinds[i]);
|
696
|
-
} else if (! oidFollowsOid (req.message.pdu.varbinds[i].oid,
|
697
|
-
pdu.varbinds[i].oid)) {
|
698
|
-
req.responseCb (new ResponseInvalidError ("OID '"
|
699
|
-
+ req.message.pdu.varbinds[i].oid + "' in request at "
|
700
|
-
+ "positiion '" + i + "' does not precede "
|
701
|
-
+ "OID '" + pdu.varbinds[i].oid + "' in response "
|
702
|
-
+ "at position '" + i + "'"));
|
703
|
-
return;
|
704
|
-
} else {
|
705
|
-
varbinds.push (pdu.varbinds[i]);
|
706
|
-
}
|
707
|
-
}
|
708
|
-
}
|
709
|
-
|
710
|
-
var repeaters = req.message.pdu.varbinds.length - nonRepeaters;
|
711
|
-
|
712
|
-
// secondly walk through and grab repeaters
|
713
|
-
if (pdu.varbinds.length % (repeaters)) {
|
714
|
-
req.responseCb (new ResponseInvalidError ("Varbind count in "
|
715
|
-
+ "response '" + pdu.varbinds.length + "' is not a "
|
716
|
-
+ "multiple of repeaters '" + repeaters
|
717
|
-
+ "' plus non-repeaters '" + nonRepeaters + "' in request"));
|
718
|
-
} else {
|
719
|
-
while (i < pdu.varbinds.length) {
|
720
|
-
for (var j = 0; j < repeaters; j++, i++) {
|
721
|
-
var reqIndex = nonRepeaters + j;
|
722
|
-
var respIndex = i;
|
723
|
-
|
724
|
-
if (isVarbindError (pdu.varbinds[respIndex])) {
|
725
|
-
if (! varbinds[reqIndex])
|
726
|
-
varbinds[reqIndex] = [];
|
727
|
-
varbinds[reqIndex].push (pdu.varbinds[respIndex]);
|
728
|
-
} else if (! oidFollowsOid (
|
729
|
-
req.message.pdu.varbinds[reqIndex].oid,
|
730
|
-
pdu.varbinds[respIndex].oid)) {
|
731
|
-
req.responseCb (new ResponseInvalidError ("OID '"
|
732
|
-
+ req.message.pdu.varbinds[reqIndex].oid
|
733
|
-
+ "' in request at positiion '" + (reqIndex)
|
734
|
-
+ "' does not precede OID '"
|
735
|
-
+ pdu.varbinds[respIndex].oid
|
736
|
-
+ "' in response at position '" + (respIndex) + "'"));
|
737
|
-
return;
|
738
|
-
} else {
|
739
|
-
if (! varbinds[reqIndex])
|
740
|
-
varbinds[reqIndex] = [];
|
741
|
-
varbinds[reqIndex].push (pdu.varbinds[respIndex]);
|
742
|
-
}
|
743
|
-
}
|
744
|
-
}
|
745
|
-
}
|
746
|
-
|
747
|
-
req.responseCb (null, varbinds);
|
748
|
-
}
|
749
|
-
|
750
|
-
var pduVarbinds = [];
|
751
|
-
|
752
|
-
for (var i = 0; i < oids.length; i++) {
|
753
|
-
var varbind = {
|
754
|
-
oid: oids[i]
|
755
|
-
};
|
756
|
-
pduVarbinds.push (varbind);
|
757
|
-
}
|
758
|
-
|
759
|
-
var options = {
|
760
|
-
nonRepeaters: nonRepeaters,
|
761
|
-
maxRepetitions: maxRepetitions
|
762
|
-
};
|
763
|
-
|
764
|
-
this.simpleGet (GetBulkRequestPdu, feedCb, pduVarbinds, responseCb,
|
765
|
-
options);
|
766
|
-
|
767
|
-
return this;
|
768
|
-
};
|
769
|
-
|
770
|
-
Session.prototype.getNext = function (oids, responseCb) {
|
771
|
-
function feedCb (req, message) {
|
772
|
-
var pdu = message.pdu;
|
773
|
-
var varbinds = [];
|
774
|
-
|
775
|
-
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
776
|
-
req.responseCb (new ResponseInvalidError ("Requested OIDs do not "
|
777
|
-
+ "match response OIDs"));
|
778
|
-
} else {
|
779
|
-
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
780
|
-
if (isVarbindError (pdu.varbinds[i])) {
|
781
|
-
varbinds.push (pdu.varbinds[i]);
|
782
|
-
} else if (! oidFollowsOid (req.message.pdu.varbinds[i].oid,
|
783
|
-
pdu.varbinds[i].oid)) {
|
784
|
-
req.responseCb (new ResponseInvalidError ("OID '"
|
785
|
-
+ req.message.pdu.varbinds[i].oid + "' in request at "
|
786
|
-
+ "positiion '" + i + "' does not precede "
|
787
|
-
+ "OID '" + pdu.varbinds[i].oid + "' in response "
|
788
|
-
+ "at position '" + i + "'"));
|
789
|
-
return;
|
790
|
-
} else {
|
791
|
-
varbinds.push (pdu.varbinds[i]);
|
792
|
-
}
|
793
|
-
}
|
794
|
-
|
795
|
-
req.responseCb (null, varbinds);
|
796
|
-
}
|
797
|
-
}
|
798
|
-
|
799
|
-
var pduVarbinds = [];
|
800
|
-
|
801
|
-
for (var i = 0; i < oids.length; i++) {
|
802
|
-
var varbind = {
|
803
|
-
oid: oids[i]
|
804
|
-
};
|
805
|
-
pduVarbinds.push (varbind);
|
806
|
-
}
|
807
|
-
|
808
|
-
this.simpleGet (GetNextRequestPdu, feedCb, pduVarbinds, responseCb);
|
809
|
-
|
810
|
-
return this;
|
811
|
-
};
|
812
|
-
|
813
|
-
Session.prototype.inform = function () {
|
814
|
-
var typeOrOid = arguments[0];
|
815
|
-
var varbinds, options = {}, responseCb;
|
816
|
-
|
817
|
-
/**
|
818
|
-
** Support the following signatures:
|
819
|
-
**
|
820
|
-
** typeOrOid, varbinds, options, callback
|
821
|
-
** typeOrOid, varbinds, callback
|
822
|
-
** typeOrOid, options, callback
|
823
|
-
** typeOrOid, callback
|
824
|
-
**/
|
825
|
-
if (arguments.length >= 4) {
|
826
|
-
varbinds = arguments[1];
|
827
|
-
options = arguments[2];
|
828
|
-
responseCb = arguments[3];
|
829
|
-
} else if (arguments.length >= 3) {
|
830
|
-
if (arguments[1].constructor != Array) {
|
831
|
-
varbinds = [];
|
832
|
-
options = arguments[1];
|
833
|
-
responseCb = arguments[2];
|
834
|
-
} else {
|
835
|
-
varbinds = arguments[1];
|
836
|
-
responseCb = arguments[2];
|
837
|
-
}
|
838
|
-
} else {
|
839
|
-
varbinds = [];
|
840
|
-
responseCb = arguments[1];
|
841
|
-
}
|
842
|
-
|
843
|
-
function feedCb (req, message) {
|
844
|
-
var pdu = message.pdu;
|
845
|
-
var varbinds = [];
|
846
|
-
|
847
|
-
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
848
|
-
req.responseCb (new ResponseInvalidError ("Inform OIDs do not "
|
849
|
-
+ "match response OIDs"));
|
850
|
-
} else {
|
851
|
-
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
852
|
-
if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) {
|
853
|
-
req.responseCb (new ResponseInvalidError ("OID '"
|
854
|
-
+ req.message.pdu.varbinds[i].oid
|
855
|
-
+ "' in inform at positiion '" + i + "' does not "
|
856
|
-
+ "match OID '" + pdu.varbinds[i].oid + "' in response "
|
857
|
-
+ "at position '" + i + "'"));
|
858
|
-
return;
|
859
|
-
} else {
|
860
|
-
varbinds.push (pdu.varbinds[i]);
|
861
|
-
}
|
862
|
-
}
|
863
|
-
|
864
|
-
req.responseCb (null, varbinds);
|
865
|
-
}
|
866
|
-
}
|
867
|
-
|
868
|
-
if (typeof typeOrOid != "string")
|
869
|
-
typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1);
|
870
|
-
|
871
|
-
var pduVarbinds = [
|
872
|
-
{
|
873
|
-
oid: "1.3.6.1.2.1.1.3.0",
|
874
|
-
type: ObjectType.TimeTicks,
|
875
|
-
value: options.upTime || Math.floor (process.uptime () * 100)
|
876
|
-
},
|
877
|
-
{
|
878
|
-
oid: "1.3.6.1.6.3.1.1.4.1.0",
|
879
|
-
type: ObjectType.OID,
|
880
|
-
value: typeOrOid
|
881
|
-
}
|
882
|
-
];
|
883
|
-
|
884
|
-
for (var i = 0; i < varbinds.length; i++) {
|
885
|
-
var varbind = {
|
886
|
-
oid: varbinds[i].oid,
|
887
|
-
type: varbinds[i].type,
|
888
|
-
value: varbinds[i].value
|
889
|
-
};
|
890
|
-
pduVarbinds.push (varbind);
|
891
|
-
}
|
892
|
-
|
893
|
-
options.port = this.trapPort;
|
894
|
-
|
895
|
-
this.simpleGet (InformRequestPdu, feedCb, pduVarbinds, responseCb, options);
|
896
|
-
|
897
|
-
return this;
|
898
|
-
};
|
899
|
-
|
900
|
-
Session.prototype.onClose = function () {
|
901
|
-
this.cancelRequests (new Error ("Socket forcibly closed"));
|
902
|
-
this.emit ("close");
|
903
|
-
};
|
904
|
-
|
905
|
-
Session.prototype.onError = function (error) {
|
906
|
-
this.emit (error);
|
907
|
-
};
|
908
|
-
|
909
|
-
Session.prototype.onMsg = function (buffer, remote) {
|
910
|
-
try {
|
911
|
-
var message = new ResponseMessage (buffer);
|
912
|
-
|
913
|
-
var req = this.unregisterRequest (message.pdu.id);
|
914
|
-
if (! req)
|
915
|
-
return;
|
916
|
-
|
917
|
-
try {
|
918
|
-
if (message.version != req.message.version) {
|
919
|
-
req.responseCb (new ResponseInvalidError ("Version in request '"
|
920
|
-
+ req.message.version + "' does not match version in "
|
921
|
-
+ "response '" + message.version));
|
922
|
-
} else if (message.community != req.message.community) {
|
923
|
-
req.responseCb (new ResponseInvalidError ("Community '"
|
924
|
-
+ req.message.community + "' in request does not match "
|
925
|
-
+ "community '" + message.community + "' in response"));
|
926
|
-
} else if (message.pdu.type == PduType.GetResponse) {
|
927
|
-
req.onResponse (req, message);
|
928
|
-
} else {
|
929
|
-
req.responseCb (new ResponseInvalidError ("Unknown PDU type '"
|
930
|
-
+ message.pdu.type + "' in response"));
|
931
|
-
}
|
932
|
-
} catch (error) {
|
933
|
-
req.responseCb (error);
|
934
|
-
}
|
935
|
-
} catch (error) {
|
936
|
-
this.emit("error", error);
|
937
|
-
}
|
938
|
-
};
|
939
|
-
|
940
|
-
Session.prototype.onSimpleGetResponse = function (req, message) {
|
941
|
-
var pdu = message.pdu;
|
942
|
-
|
943
|
-
if (pdu.errorStatus > 0) {
|
944
|
-
var statusString = ErrorStatus[pdu.errorStatus]
|
945
|
-
|| ErrorStatus.GeneralError;
|
946
|
-
var statusCode = ErrorStatus[statusString]
|
947
|
-
|| ErrorStatus[ErrorStatus.GeneralError];
|
948
|
-
|
949
|
-
if (pdu.errorIndex <= 0 || pdu.errorIndex > pdu.varbinds.length) {
|
950
|
-
req.responseCb (new RequestFailedError (statusString, statusCode));
|
951
|
-
} else {
|
952
|
-
var oid = pdu.varbinds[pdu.errorIndex - 1].oid;
|
953
|
-
var error = new RequestFailedError (statusString + ": " + oid,
|
954
|
-
statusCode);
|
955
|
-
req.responseCb (error);
|
956
|
-
}
|
957
|
-
} else {
|
958
|
-
req.feedCb (req, message);
|
959
|
-
}
|
960
|
-
};
|
961
|
-
|
962
|
-
Session.prototype.registerRequest = function (req) {
|
963
|
-
if (! this.reqs[req.id]) {
|
964
|
-
this.reqs[req.id] = req;
|
965
|
-
if (this.reqCount <= 0)
|
966
|
-
this.dgram.ref();
|
967
|
-
this.reqCount++;
|
968
|
-
}
|
969
|
-
var me = this;
|
970
|
-
req.timer = setTimeout (function () {
|
971
|
-
if (req.retries-- > 0) {
|
972
|
-
me.send (req);
|
973
|
-
} else {
|
974
|
-
me.unregisterRequest (req.id);
|
975
|
-
req.responseCb (new RequestTimedOutError (
|
976
|
-
"Request timed out"));
|
977
|
-
}
|
978
|
-
}, req.timeout);
|
979
|
-
};
|
980
|
-
|
981
|
-
Session.prototype.send = function (req, noWait) {
|
982
|
-
try {
|
983
|
-
var me = this;
|
984
|
-
|
985
|
-
var buffer = req.message.toBuffer ();
|
986
|
-
|
987
|
-
this.dgram.send (buffer, 0, buffer.length, req.port, this.target,
|
988
|
-
function (error, bytes) {
|
989
|
-
if (error) {
|
990
|
-
req.responseCb (error);
|
991
|
-
} else {
|
992
|
-
if (noWait) {
|
993
|
-
req.responseCb (null);
|
994
|
-
} else {
|
995
|
-
me.registerRequest (req);
|
996
|
-
}
|
997
|
-
}
|
998
|
-
});
|
999
|
-
} catch (error) {
|
1000
|
-
req.responseCb (error);
|
1001
|
-
}
|
1002
|
-
|
1003
|
-
return this;
|
1004
|
-
};
|
1005
|
-
|
1006
|
-
Session.prototype.set = function (varbinds, responseCb) {
|
1007
|
-
function feedCb (req, message) {
|
1008
|
-
var pdu = message.pdu;
|
1009
|
-
var varbinds = [];
|
1010
|
-
|
1011
|
-
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
1012
|
-
req.responseCb (new ResponseInvalidError ("Requested OIDs do not "
|
1013
|
-
+ "match response OIDs"));
|
1014
|
-
} else {
|
1015
|
-
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
1016
|
-
if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) {
|
1017
|
-
req.responseCb (new ResponseInvalidError ("OID '"
|
1018
|
-
+ req.message.pdu.varbinds[i].oid
|
1019
|
-
+ "' in request at positiion '" + i + "' does not "
|
1020
|
-
+ "match OID '" + pdu.varbinds[i].oid + "' in response "
|
1021
|
-
+ "at position '" + i + "'"));
|
1022
|
-
return;
|
1023
|
-
} else {
|
1024
|
-
varbinds.push (pdu.varbinds[i]);
|
1025
|
-
}
|
1026
|
-
}
|
1027
|
-
|
1028
|
-
req.responseCb (null, varbinds);
|
1029
|
-
}
|
1030
|
-
}
|
1031
|
-
|
1032
|
-
var pduVarbinds = [];
|
1033
|
-
|
1034
|
-
for (var i = 0; i < varbinds.length; i++) {
|
1035
|
-
var varbind = {
|
1036
|
-
oid: varbinds[i].oid,
|
1037
|
-
type: varbinds[i].type,
|
1038
|
-
value: varbinds[i].value
|
1039
|
-
};
|
1040
|
-
pduVarbinds.push (varbind);
|
1041
|
-
}
|
1042
|
-
|
1043
|
-
this.simpleGet (SetRequestPdu, feedCb, pduVarbinds, responseCb);
|
1044
|
-
|
1045
|
-
return this;
|
1046
|
-
};
|
1047
|
-
|
1048
|
-
Session.prototype.simpleGet = function (pduClass, feedCb, varbinds,
|
1049
|
-
responseCb, options) {
|
1050
|
-
var req = {};
|
1051
|
-
|
1052
|
-
try {
|
1053
|
-
var id = _generateId (this.idBitsSize);
|
1054
|
-
var pdu = new pduClass (id, varbinds, options);
|
1055
|
-
var message = new RequestMessage (this.version, this.community, pdu);
|
1056
|
-
|
1057
|
-
req = {
|
1058
|
-
id: id,
|
1059
|
-
message: message,
|
1060
|
-
responseCb: responseCb,
|
1061
|
-
retries: this.retries,
|
1062
|
-
timeout: this.timeout,
|
1063
|
-
onResponse: this.onSimpleGetResponse,
|
1064
|
-
feedCb: feedCb,
|
1065
|
-
port: (options && options.port) ? options.port : this.port
|
1066
|
-
};
|
1067
|
-
|
1068
|
-
this.send (req);
|
1069
|
-
} catch (error) {
|
1070
|
-
if (req.responseCb)
|
1071
|
-
req.responseCb (error);
|
1072
|
-
}
|
1073
|
-
};
|
1074
|
-
|
1075
|
-
function subtreeCb (req, varbinds) {
|
1076
|
-
var done = 0;
|
1077
|
-
|
1078
|
-
for (var i = varbinds.length; i > 0; i--) {
|
1079
|
-
if (! oidInSubtree (req.baseOid, varbinds[i - 1].oid)) {
|
1080
|
-
done = 1;
|
1081
|
-
varbinds.pop ();
|
1082
|
-
}
|
1083
|
-
}
|
1084
|
-
|
1085
|
-
if (varbinds.length > 0)
|
1086
|
-
req.feedCb (varbinds);
|
1087
|
-
|
1088
|
-
if (done)
|
1089
|
-
return true;
|
1090
|
-
}
|
1091
|
-
|
1092
|
-
Session.prototype.subtree = function () {
|
1093
|
-
var me = this;
|
1094
|
-
var oid = arguments[0];
|
1095
|
-
var maxRepetitions, feedCb, doneCb;
|
1096
|
-
|
1097
|
-
if (arguments.length < 4) {
|
1098
|
-
maxRepetitions = 20;
|
1099
|
-
feedCb = arguments[1];
|
1100
|
-
doneCb = arguments[2];
|
1101
|
-
} else {
|
1102
|
-
maxRepetitions = arguments[1];
|
1103
|
-
feedCb = arguments[2];
|
1104
|
-
doneCb = arguments[3];
|
1105
|
-
}
|
1106
|
-
|
1107
|
-
var req = {
|
1108
|
-
feedCb: feedCb,
|
1109
|
-
doneCb: doneCb,
|
1110
|
-
maxRepetitions: maxRepetitions,
|
1111
|
-
baseOid: oid
|
1112
|
-
};
|
1113
|
-
|
1114
|
-
this.walk (oid, maxRepetitions, subtreeCb.bind (me, req), doneCb);
|
1115
|
-
|
1116
|
-
return this;
|
1117
|
-
};
|
1118
|
-
|
1119
|
-
function tableColumnsResponseCb (req, error) {
|
1120
|
-
if (error) {
|
1121
|
-
req.responseCb (error);
|
1122
|
-
} else if (req.error) {
|
1123
|
-
req.responseCb (req.error);
|
1124
|
-
} else {
|
1125
|
-
if (req.columns.length > 0) {
|
1126
|
-
var column = req.columns.pop ();
|
1127
|
-
var me = this;
|
1128
|
-
this.subtree (req.rowOid + column, req.maxRepetitions,
|
1129
|
-
tableColumnsFeedCb.bind (me, req),
|
1130
|
-
tableColumnsResponseCb.bind (me, req));
|
1131
|
-
} else {
|
1132
|
-
req.responseCb (null, req.table);
|
1133
|
-
}
|
1134
|
-
}
|
1135
|
-
}
|
1136
|
-
|
1137
|
-
function tableColumnsFeedCb (req, varbinds) {
|
1138
|
-
for (var i = 0; i < varbinds.length; i++) {
|
1139
|
-
if (isVarbindError (varbinds[i])) {
|
1140
|
-
req.error = new RequestFailedError (varbindError (varbind[i]));
|
1141
|
-
return true;
|
1142
|
-
}
|
1143
|
-
|
1144
|
-
var oid = varbinds[i].oid.replace (req.rowOid, "");
|
1145
|
-
if (oid && oid != varbinds[i].oid) {
|
1146
|
-
var match = oid.match (/^(\d+)\.(.+)$/);
|
1147
|
-
if (match && match[1] > 0) {
|
1148
|
-
if (! req.table[match[2]])
|
1149
|
-
req.table[match[2]] = {};
|
1150
|
-
req.table[match[2]][match[1]] = varbinds[i].value;
|
1151
|
-
}
|
1152
|
-
}
|
1153
|
-
}
|
1154
|
-
}
|
1155
|
-
|
1156
|
-
Session.prototype.tableColumns = function () {
|
1157
|
-
var me = this;
|
1158
|
-
|
1159
|
-
var oid = arguments[0];
|
1160
|
-
var columns = arguments[1];
|
1161
|
-
var maxRepetitions, responseCb;
|
1162
|
-
|
1163
|
-
if (arguments.length < 4) {
|
1164
|
-
responseCb = arguments[2];
|
1165
|
-
maxRepetitions = 20;
|
1166
|
-
} else {
|
1167
|
-
maxRepetitions = arguments[2];
|
1168
|
-
responseCb = arguments[3];
|
1169
|
-
}
|
1170
|
-
|
1171
|
-
var req = {
|
1172
|
-
responseCb: responseCb,
|
1173
|
-
maxRepetitions: maxRepetitions,
|
1174
|
-
baseOid: oid,
|
1175
|
-
rowOid: oid + ".1.",
|
1176
|
-
columns: columns.slice(0),
|
1177
|
-
table: {}
|
1178
|
-
};
|
1179
|
-
|
1180
|
-
if (req.columns.length > 0) {
|
1181
|
-
var column = req.columns.pop ();
|
1182
|
-
this.subtree (req.rowOid + column, maxRepetitions,
|
1183
|
-
tableColumnsFeedCb.bind (me, req),
|
1184
|
-
tableColumnsResponseCb.bind (me, req));
|
1185
|
-
}
|
1186
|
-
|
1187
|
-
return this;
|
1188
|
-
};
|
1189
|
-
|
1190
|
-
function tableResponseCb (req, error) {
|
1191
|
-
if (error)
|
1192
|
-
req.responseCb (error);
|
1193
|
-
else if (req.error)
|
1194
|
-
req.responseCb (req.error);
|
1195
|
-
else
|
1196
|
-
req.responseCb (null, req.table);
|
1197
|
-
}
|
1198
|
-
|
1199
|
-
function tableFeedCb (req, varbinds) {
|
1200
|
-
for (var i = 0; i < varbinds.length; i++) {
|
1201
|
-
if (isVarbindError (varbinds[i])) {
|
1202
|
-
req.error = new RequestFailedError (varbindError (varbind[i]));
|
1203
|
-
return true;
|
1204
|
-
}
|
1205
|
-
|
1206
|
-
var oid = varbinds[i].oid.replace (req.rowOid, "");
|
1207
|
-
if (oid && oid != varbinds[i].oid) {
|
1208
|
-
var match = oid.match (/^(\d+)\.(.+)$/);
|
1209
|
-
if (match && match[1] > 0) {
|
1210
|
-
if (! req.table[match[2]])
|
1211
|
-
req.table[match[2]] = {};
|
1212
|
-
req.table[match[2]][match[1]] = varbinds[i].value;
|
1213
|
-
}
|
1214
|
-
}
|
1215
|
-
}
|
1216
|
-
}
|
1217
|
-
|
1218
|
-
Session.prototype.table = function () {
|
1219
|
-
var me = this;
|
1220
|
-
|
1221
|
-
var oid = arguments[0];
|
1222
|
-
var maxRepetitions, responseCb;
|
1223
|
-
|
1224
|
-
if (arguments.length < 3) {
|
1225
|
-
responseCb = arguments[1];
|
1226
|
-
maxRepetitions = 20;
|
1227
|
-
} else {
|
1228
|
-
maxRepetitions = arguments[1];
|
1229
|
-
responseCb = arguments[2];
|
1230
|
-
}
|
1231
|
-
|
1232
|
-
var req = {
|
1233
|
-
responseCb: responseCb,
|
1234
|
-
maxRepetitions: maxRepetitions,
|
1235
|
-
baseOid: oid,
|
1236
|
-
rowOid: oid + ".1.",
|
1237
|
-
table: {}
|
1238
|
-
};
|
1239
|
-
|
1240
|
-
this.subtree (oid, maxRepetitions, tableFeedCb.bind (me, req),
|
1241
|
-
tableResponseCb.bind (me, req));
|
1242
|
-
|
1243
|
-
return this;
|
1244
|
-
};
|
1245
|
-
|
1246
|
-
Session.prototype.trap = function () {
|
1247
|
-
var req = {};
|
1248
|
-
|
1249
|
-
try {
|
1250
|
-
var typeOrOid = arguments[0];
|
1251
|
-
var varbinds, options = {}, responseCb;
|
1252
|
-
|
1253
|
-
/**
|
1254
|
-
** Support the following signatures:
|
1255
|
-
**
|
1256
|
-
** typeOrOid, varbinds, options, callback
|
1257
|
-
** typeOrOid, varbinds, agentAddr, callback
|
1258
|
-
** typeOrOid, varbinds, callback
|
1259
|
-
** typeOrOid, agentAddr, callback
|
1260
|
-
** typeOrOid, options, callback
|
1261
|
-
** typeOrOid, callback
|
1262
|
-
**/
|
1263
|
-
if (arguments.length >= 4) {
|
1264
|
-
varbinds = arguments[1];
|
1265
|
-
if (typeof arguments[2] == "string") {
|
1266
|
-
options.agentAddr = arguments[2];
|
1267
|
-
} else if (arguments[2].constructor != Array) {
|
1268
|
-
options = arguments[2];
|
1269
|
-
}
|
1270
|
-
responseCb = arguments[3];
|
1271
|
-
} else if (arguments.length >= 3) {
|
1272
|
-
if (typeof arguments[1] == "string") {
|
1273
|
-
varbinds = [];
|
1274
|
-
options.agentAddr = arguments[1];
|
1275
|
-
} else if (arguments[1].constructor != Array) {
|
1276
|
-
varbinds = [];
|
1277
|
-
options = arguments[1];
|
1278
|
-
} else {
|
1279
|
-
varbinds = arguments[1];
|
1280
|
-
agentAddr = null;
|
1281
|
-
}
|
1282
|
-
responseCb = arguments[2];
|
1283
|
-
} else {
|
1284
|
-
varbinds = [];
|
1285
|
-
responseCb = arguments[1];
|
1286
|
-
}
|
1287
|
-
|
1288
|
-
var pdu, pduVarbinds = [];
|
1289
|
-
|
1290
|
-
for (var i = 0; i < varbinds.length; i++) {
|
1291
|
-
var varbind = {
|
1292
|
-
oid: varbinds[i].oid,
|
1293
|
-
type: varbinds[i].type,
|
1294
|
-
value: varbinds[i].value
|
1295
|
-
};
|
1296
|
-
pduVarbinds.push (varbind);
|
1297
|
-
}
|
1298
|
-
|
1299
|
-
var id = _generateId (this.idBitsSize);
|
1300
|
-
|
1301
|
-
if (this.version == Version2c) {
|
1302
|
-
if (typeof typeOrOid != "string")
|
1303
|
-
typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1);
|
1304
|
-
|
1305
|
-
pduVarbinds.unshift (
|
1306
|
-
{
|
1307
|
-
oid: "1.3.6.1.2.1.1.3.0",
|
1308
|
-
type: ObjectType.TimeTicks,
|
1309
|
-
value: options.upTime || Math.floor (process.uptime () * 100)
|
1310
|
-
},
|
1311
|
-
{
|
1312
|
-
oid: "1.3.6.1.6.3.1.1.4.1.0",
|
1313
|
-
type: ObjectType.OID,
|
1314
|
-
value: typeOrOid
|
1315
|
-
}
|
1316
|
-
);
|
1317
|
-
|
1318
|
-
pdu = new TrapV2Pdu (id, pduVarbinds, options);
|
1319
|
-
} else {
|
1320
|
-
pdu = new TrapPdu (typeOrOid, pduVarbinds, options);
|
1321
|
-
}
|
1322
|
-
|
1323
|
-
var message = new RequestMessage (this.version, this.community, pdu);
|
1324
|
-
|
1325
|
-
req = {
|
1326
|
-
id: id,
|
1327
|
-
message: message,
|
1328
|
-
responseCb: responseCb,
|
1329
|
-
port: this.trapPort
|
1330
|
-
};
|
1331
|
-
|
1332
|
-
this.send (req, true);
|
1333
|
-
} catch (error) {
|
1334
|
-
if (req.responseCb)
|
1335
|
-
req.responseCb (error);
|
1336
|
-
}
|
1337
|
-
|
1338
|
-
return this;
|
1339
|
-
};
|
1340
|
-
|
1341
|
-
Session.prototype.unregisterRequest = function (id) {
|
1342
|
-
var req = this.reqs[id];
|
1343
|
-
if (req) {
|
1344
|
-
delete this.reqs[id];
|
1345
|
-
clearTimeout (req.timer);
|
1346
|
-
delete req.timer;
|
1347
|
-
this.reqCount--;
|
1348
|
-
if (this.reqCount <= 0)
|
1349
|
-
this.dgram.unref();
|
1350
|
-
return req;
|
1351
|
-
} else {
|
1352
|
-
return null;
|
1353
|
-
}
|
1354
|
-
};
|
1355
|
-
|
1356
|
-
function walkCb (req, error, varbinds) {
|
1357
|
-
var done = 0;
|
1358
|
-
var oid;
|
1359
|
-
|
1360
|
-
if (error) {
|
1361
|
-
if (error instanceof RequestFailedError) {
|
1362
|
-
if (error.status != ErrorStatus.NoSuchName) {
|
1363
|
-
req.doneCb (error);
|
1364
|
-
return;
|
1365
|
-
} else {
|
1366
|
-
// signal the version 1 walk code below that it should stop
|
1367
|
-
done = 1;
|
1368
|
-
}
|
1369
|
-
} else {
|
1370
|
-
req.doneCb (error);
|
1371
|
-
return;
|
1372
|
-
}
|
1373
|
-
}
|
1374
|
-
|
1375
|
-
if (this.version == Version2c) {
|
1376
|
-
for (var i = varbinds[0].length; i > 0; i--) {
|
1377
|
-
if (varbinds[0][i - 1].type == ObjectType.EndOfMibView) {
|
1378
|
-
varbinds[0].pop ();
|
1379
|
-
done = 1;
|
1380
|
-
}
|
1381
|
-
}
|
1382
|
-
if (req.feedCb (varbinds[0]))
|
1383
|
-
done = 1;
|
1384
|
-
if (! done)
|
1385
|
-
oid = varbinds[0][varbinds[0].length - 1].oid;
|
1386
|
-
} else {
|
1387
|
-
if (! done) {
|
1388
|
-
if (req.feedCb (varbinds)) {
|
1389
|
-
done = 1;
|
1390
|
-
} else {
|
1391
|
-
oid = varbinds[0].oid;
|
1392
|
-
}
|
1393
|
-
}
|
1394
|
-
}
|
1395
|
-
|
1396
|
-
if (done)
|
1397
|
-
req.doneCb (null);
|
1398
|
-
else
|
1399
|
-
this.walk (oid, req.maxRepetitions, req.feedCb, req.doneCb,
|
1400
|
-
req.baseOid);
|
1401
|
-
}
|
1402
|
-
|
1403
|
-
Session.prototype.walk = function () {
|
1404
|
-
var me = this;
|
1405
|
-
var oid = arguments[0];
|
1406
|
-
var maxRepetitions, feedCb, doneCb, baseOid;
|
1407
|
-
|
1408
|
-
if (arguments.length < 4) {
|
1409
|
-
maxRepetitions = 20;
|
1410
|
-
feedCb = arguments[1];
|
1411
|
-
doneCb = arguments[2];
|
1412
|
-
} else {
|
1413
|
-
maxRepetitions = arguments[1];
|
1414
|
-
feedCb = arguments[2];
|
1415
|
-
doneCb = arguments[3];
|
1416
|
-
}
|
1417
|
-
|
1418
|
-
var req = {
|
1419
|
-
maxRepetitions: maxRepetitions,
|
1420
|
-
feedCb: feedCb,
|
1421
|
-
doneCb: doneCb
|
1422
|
-
};
|
1423
|
-
|
1424
|
-
if (this.version == Version2c)
|
1425
|
-
this.getBulk ([oid], 0, maxRepetitions,
|
1426
|
-
walkCb.bind (me, req));
|
1427
|
-
else
|
1428
|
-
this.getNext ([oid], walkCb.bind (me, req));
|
1429
|
-
|
1430
|
-
return this;
|
1431
|
-
};
|
1432
|
-
|
1433
|
-
/*****************************************************************************
|
1434
|
-
** Exports
|
1435
|
-
**/
|
1436
|
-
|
1437
|
-
exports.Session = Session;
|
1438
|
-
|
1439
|
-
exports.createSession = function (target, community, options) {
|
1440
|
-
return new Session (target, community, options);
|
1441
|
-
};
|
1442
|
-
|
1443
|
-
exports.isVarbindError = isVarbindError;
|
1444
|
-
exports.varbindError = varbindError;
|
1445
|
-
|
1446
|
-
exports.Version1 = Version1;
|
1447
|
-
exports.Version2c = Version2c;
|
1448
|
-
|
1449
|
-
exports.ErrorStatus = ErrorStatus;
|
1450
|
-
exports.TrapType = TrapType;
|
1451
|
-
exports.ObjectType = ObjectType;
|
1452
|
-
|
1453
|
-
exports.ResponseInvalidError = ResponseInvalidError;
|
1454
|
-
exports.RequestInvalidError = RequestInvalidError;
|
1455
|
-
exports.RequestFailedError = RequestFailedError;
|
1456
|
-
exports.RequestTimedOutError = RequestTimedOutError;
|
1457
|
-
|
1458
|
-
/**
|
1459
|
-
** We've added this for testing.
|
1460
|
-
**/
|
1461
|
-
exports.ObjectParser = {
|
1462
|
-
readInt: readInt,
|
1463
|
-
readUint: readUint
|
1464
|
-
};
|
1
|
+
|
2
|
+
// Copyright 2013 Stephen Vickers <stephen.vickers.sv@gmail.com>
|
3
|
+
|
4
|
+
var ber = require ("asn1-ber").Ber;
|
5
|
+
var dgram = require ("dgram");
|
6
|
+
var events = require ("events");
|
7
|
+
var util = require ("util");
|
8
|
+
|
9
|
+
/*****************************************************************************
|
10
|
+
** Constants
|
11
|
+
**/
|
12
|
+
|
13
|
+
function _expandConstantObject (object) {
|
14
|
+
var keys = [];
|
15
|
+
for (var key in object)
|
16
|
+
keys.push (key);
|
17
|
+
for (var i = 0; i < keys.length; i++)
|
18
|
+
object[object[keys[i]]] = parseInt (keys[i]);
|
19
|
+
}
|
20
|
+
|
21
|
+
var ErrorStatus = {
|
22
|
+
0: "NoError",
|
23
|
+
1: "TooBig",
|
24
|
+
2: "NoSuchName",
|
25
|
+
3: "BadValue",
|
26
|
+
4: "ReadOnly",
|
27
|
+
5: "GeneralError",
|
28
|
+
6: "NoAccess",
|
29
|
+
7: "WrongType",
|
30
|
+
8: "WrongLength",
|
31
|
+
9: "WrongEncoding",
|
32
|
+
10: "WrongValue",
|
33
|
+
11: "NoCreation",
|
34
|
+
12: "InconsistentValue",
|
35
|
+
13: "ResourceUnavailable",
|
36
|
+
14: "CommitFailed",
|
37
|
+
15: "UndoFailed",
|
38
|
+
16: "AuthorizationError",
|
39
|
+
17: "NotWritable",
|
40
|
+
18: "InconsistentName"
|
41
|
+
};
|
42
|
+
|
43
|
+
_expandConstantObject (ErrorStatus);
|
44
|
+
|
45
|
+
var ObjectType = {
|
46
|
+
1: "Boolean",
|
47
|
+
2: "Integer",
|
48
|
+
4: "OctetString",
|
49
|
+
5: "Null",
|
50
|
+
6: "OID",
|
51
|
+
64: "IpAddress",
|
52
|
+
65: "Counter",
|
53
|
+
66: "Gauge",
|
54
|
+
67: "TimeTicks",
|
55
|
+
68: "Opaque",
|
56
|
+
70: "Counter64",
|
57
|
+
128: "NoSuchObject",
|
58
|
+
129: "NoSuchInstance",
|
59
|
+
130: "EndOfMibView"
|
60
|
+
};
|
61
|
+
|
62
|
+
_expandConstantObject (ObjectType);
|
63
|
+
|
64
|
+
ObjectType.Integer32 = ObjectType.Integer;
|
65
|
+
ObjectType.Counter32 = ObjectType.Counter;
|
66
|
+
ObjectType.Gauge32 = ObjectType.Gauge;
|
67
|
+
ObjectType.Unsigned32 = ObjectType.Gauge32;
|
68
|
+
|
69
|
+
var PduType = {
|
70
|
+
160: "GetRequest",
|
71
|
+
161: "GetNextRequest",
|
72
|
+
162: "GetResponse",
|
73
|
+
163: "SetRequest",
|
74
|
+
164: "Trap",
|
75
|
+
165: "GetBulkRequest",
|
76
|
+
166: "InformRequest",
|
77
|
+
167: "TrapV2",
|
78
|
+
168: "Report"
|
79
|
+
};
|
80
|
+
|
81
|
+
_expandConstantObject (PduType);
|
82
|
+
|
83
|
+
var TrapType = {
|
84
|
+
0: "ColdStart",
|
85
|
+
1: "WarmStart",
|
86
|
+
2: "LinkDown",
|
87
|
+
3: "LinkUp",
|
88
|
+
4: "AuthenticationFailure",
|
89
|
+
5: "EgpNeighborLoss",
|
90
|
+
6: "EnterpriseSpecific"
|
91
|
+
};
|
92
|
+
|
93
|
+
_expandConstantObject (TrapType);
|
94
|
+
|
95
|
+
var Version1 = 0;
|
96
|
+
var Version2c = 1;
|
97
|
+
|
98
|
+
/*****************************************************************************
|
99
|
+
** Exception class definitions
|
100
|
+
**/
|
101
|
+
|
102
|
+
function ResponseInvalidError (message) {
|
103
|
+
this.name = "ResponseInvalidError";
|
104
|
+
this.message = message;
|
105
|
+
Error.captureStackTrace(this, ResponseInvalidError);
|
106
|
+
}
|
107
|
+
util.inherits (ResponseInvalidError, Error);
|
108
|
+
|
109
|
+
function RequestInvalidError (message) {
|
110
|
+
this.name = "RequestInvalidError";
|
111
|
+
this.message = message;
|
112
|
+
Error.captureStackTrace(this, RequestInvalidError);
|
113
|
+
}
|
114
|
+
util.inherits (RequestInvalidError, Error);
|
115
|
+
|
116
|
+
function RequestFailedError (message, status) {
|
117
|
+
this.name = "RequestFailedError";
|
118
|
+
this.message = message;
|
119
|
+
this.status = status;
|
120
|
+
Error.captureStackTrace(this, RequestFailedError);
|
121
|
+
}
|
122
|
+
util.inherits (RequestFailedError, Error);
|
123
|
+
|
124
|
+
function RequestTimedOutError (message) {
|
125
|
+
this.name = "RequestTimedOutError";
|
126
|
+
this.message = message;
|
127
|
+
Error.captureStackTrace(this, RequestTimedOutError);
|
128
|
+
}
|
129
|
+
util.inherits (RequestTimedOutError, Error);
|
130
|
+
|
131
|
+
/*****************************************************************************
|
132
|
+
** OID and varbind helper functions
|
133
|
+
**/
|
134
|
+
|
135
|
+
function isVarbindError (varbind) {
|
136
|
+
return !!(varbind.type == ObjectType.NoSuchObject
|
137
|
+
|| varbind.type == ObjectType.NoSuchInstance
|
138
|
+
|| varbind.type == ObjectType.EndOfMibView);
|
139
|
+
}
|
140
|
+
|
141
|
+
function varbindError (varbind) {
|
142
|
+
return (ObjectType[varbind.type] || "NotAnError") + ": " + varbind.oid;
|
143
|
+
}
|
144
|
+
|
145
|
+
function oidFollowsOid (oidString, nextString) {
|
146
|
+
var oid = {str: oidString, len: oidString.length, idx: 0};
|
147
|
+
var next = {str: nextString, len: nextString.length, idx: 0};
|
148
|
+
var dotCharCode = ".".charCodeAt (0);
|
149
|
+
|
150
|
+
function getNumber (item) {
|
151
|
+
var n = 0;
|
152
|
+
if (item.idx >= item.len)
|
153
|
+
return null;
|
154
|
+
while (item.idx < item.len) {
|
155
|
+
var charCode = item.str.charCodeAt (item.idx++);
|
156
|
+
if (charCode == dotCharCode)
|
157
|
+
return n;
|
158
|
+
n = (n ? (n * 10) : n) + (charCode - 48);
|
159
|
+
}
|
160
|
+
return n;
|
161
|
+
}
|
162
|
+
|
163
|
+
while (1) {
|
164
|
+
var oidNumber = getNumber (oid);
|
165
|
+
var nextNumber = getNumber (next);
|
166
|
+
|
167
|
+
if (oidNumber !== null) {
|
168
|
+
if (nextNumber !== null) {
|
169
|
+
if (nextNumber > oidNumber) {
|
170
|
+
return true;
|
171
|
+
} else if (nextNumber < oidNumber) {
|
172
|
+
return false;
|
173
|
+
}
|
174
|
+
} else {
|
175
|
+
return true;
|
176
|
+
}
|
177
|
+
} else {
|
178
|
+
return true;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
function oidInSubtree (oidString, nextString) {
|
184
|
+
var oid = oidString.split (".");
|
185
|
+
var next = nextString.split (".");
|
186
|
+
|
187
|
+
if (oid.length > next.length)
|
188
|
+
return false;
|
189
|
+
|
190
|
+
for (var i = 0; i < oid.length; i++) {
|
191
|
+
if (next[i] != oid[i])
|
192
|
+
return false;
|
193
|
+
}
|
194
|
+
|
195
|
+
return true;
|
196
|
+
}
|
197
|
+
|
198
|
+
/**
|
199
|
+
** Some SNMP agents produce integers on the wire such as 00 ff ff ff ff.
|
200
|
+
** The ASN.1 BER parser we use throws an error when parsing this, which we
|
201
|
+
** believe is correct. So, we decided not to bother the "asn1" developer(s)
|
202
|
+
** with this, instead opting to work around it here.
|
203
|
+
**
|
204
|
+
** If an integer is 5 bytes in length we check if the first byte is 0, and if so
|
205
|
+
** simply drop it and parse it like it was a 4 byte integer, otherwise throw
|
206
|
+
** an error since the integer is too large.
|
207
|
+
**/
|
208
|
+
|
209
|
+
function readInt (buffer) {
|
210
|
+
return readUint (buffer, true);
|
211
|
+
}
|
212
|
+
|
213
|
+
function readUint (buffer, isSigned) {
|
214
|
+
buffer.readByte ();
|
215
|
+
var length = buffer.readByte ();
|
216
|
+
var value = 0;
|
217
|
+
var signedBitSet = false;
|
218
|
+
|
219
|
+
if (length > 5) {
|
220
|
+
throw new RangeError ("Integer too long '" + length + "'");
|
221
|
+
} else if (length == 5) {
|
222
|
+
if (buffer.readByte () !== 0)
|
223
|
+
throw new RangeError ("Integer too long '" + length + "'");
|
224
|
+
length = 4;
|
225
|
+
}
|
226
|
+
|
227
|
+
for (var i = 0; i < length; i++) {
|
228
|
+
value *= 256;
|
229
|
+
value += buffer.readByte ();
|
230
|
+
|
231
|
+
if (isSigned && i <= 0) {
|
232
|
+
if ((value & 0x80) == 0x80)
|
233
|
+
signedBitSet = true;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
if (signedBitSet)
|
238
|
+
value -= (1 << (i * 8));
|
239
|
+
|
240
|
+
return value;
|
241
|
+
}
|
242
|
+
|
243
|
+
function readUint64 (buffer) {
|
244
|
+
var value = buffer.readString (ObjectType.Counter64, true);
|
245
|
+
|
246
|
+
return value;
|
247
|
+
}
|
248
|
+
|
249
|
+
function readVarbinds (buffer, varbinds) {
|
250
|
+
buffer.readSequence ();
|
251
|
+
|
252
|
+
while (1) {
|
253
|
+
buffer.readSequence ();
|
254
|
+
var oid = buffer.readOID ();
|
255
|
+
var type = buffer.peek ();
|
256
|
+
|
257
|
+
if (type == null)
|
258
|
+
break;
|
259
|
+
|
260
|
+
var value;
|
261
|
+
|
262
|
+
if (type == ObjectType.Boolean) {
|
263
|
+
value = buffer.readBoolean ();
|
264
|
+
} else if (type == ObjectType.Integer) {
|
265
|
+
value = readInt (buffer);
|
266
|
+
} else if (type == ObjectType.OctetString) {
|
267
|
+
value = buffer.readString (null, true);
|
268
|
+
} else if (type == ObjectType.Null) {
|
269
|
+
buffer.readByte ();
|
270
|
+
buffer.readByte ();
|
271
|
+
value = null;
|
272
|
+
} else if (type == ObjectType.OID) {
|
273
|
+
value = buffer.readOID ();
|
274
|
+
} else if (type == ObjectType.IpAddress) {
|
275
|
+
var bytes = buffer.readString (ObjectType.IpAddress, true);
|
276
|
+
if (bytes.length != 4)
|
277
|
+
throw new ResponseInvalidError ("Length '" + bytes.length
|
278
|
+
+ "' of IP address '" + bytes.toString ("hex")
|
279
|
+
+ "' is not 4");
|
280
|
+
value = bytes[0] + "." + bytes[1] + "." + bytes[2] + "." + bytes[3];
|
281
|
+
} else if (type == ObjectType.Counter) {
|
282
|
+
value = readUint (buffer);
|
283
|
+
} else if (type == ObjectType.Gauge) {
|
284
|
+
value = readUint (buffer);
|
285
|
+
} else if (type == ObjectType.TimeTicks) {
|
286
|
+
value = readUint (buffer);
|
287
|
+
} else if (type == ObjectType.Opaque) {
|
288
|
+
value = buffer.readString (ObjectType.Opaque, true);
|
289
|
+
} else if (type == ObjectType.Counter64) {
|
290
|
+
value = readUint64 (buffer);
|
291
|
+
} else if (type == ObjectType.NoSuchObject) {
|
292
|
+
buffer.readByte ();
|
293
|
+
buffer.readByte ();
|
294
|
+
value = null;
|
295
|
+
} else if (type == ObjectType.NoSuchInstance) {
|
296
|
+
buffer.readByte ();
|
297
|
+
buffer.readByte ();
|
298
|
+
value = null;
|
299
|
+
} else if (type == ObjectType.EndOfMibView) {
|
300
|
+
buffer.readByte ();
|
301
|
+
buffer.readByte ();
|
302
|
+
value = null;
|
303
|
+
} else {
|
304
|
+
throw new ResponseInvalidError ("Unknown type '" + type
|
305
|
+
+ "' in response");
|
306
|
+
}
|
307
|
+
|
308
|
+
varbinds.push ({
|
309
|
+
oid: oid,
|
310
|
+
type: type,
|
311
|
+
value: value
|
312
|
+
});
|
313
|
+
}
|
314
|
+
}
|
315
|
+
|
316
|
+
function writeUint (buffer, type, value) {
|
317
|
+
var b = new Buffer (4);
|
318
|
+
b.writeUInt32BE (value, 0);
|
319
|
+
buffer.writeBuffer (b, type);
|
320
|
+
}
|
321
|
+
|
322
|
+
function writeUint64 (buffer, value) {
|
323
|
+
buffer.writeBuffer (value, ObjectType.Counter64);
|
324
|
+
}
|
325
|
+
|
326
|
+
function writeVarbinds (buffer, varbinds) {
|
327
|
+
buffer.startSequence ();
|
328
|
+
for (var i = 0; i < varbinds.length; i++) {
|
329
|
+
buffer.startSequence ();
|
330
|
+
buffer.writeOID (varbinds[i].oid);
|
331
|
+
|
332
|
+
if (varbinds[i].type && varbinds[i].hasOwnProperty("value")) {
|
333
|
+
var type = varbinds[i].type;
|
334
|
+
var value = varbinds[i].value;
|
335
|
+
|
336
|
+
if (type == ObjectType.Boolean) {
|
337
|
+
buffer.writeBoolean (value ? true : false);
|
338
|
+
} else if (type == ObjectType.Integer) { // also Integer32
|
339
|
+
buffer.writeInt (value);
|
340
|
+
} else if (type == ObjectType.OctetString) {
|
341
|
+
if (typeof value == "string")
|
342
|
+
buffer.writeString (value);
|
343
|
+
else
|
344
|
+
buffer.writeBuffer (value, ObjectType.OctetString);
|
345
|
+
} else if (type == ObjectType.Null) {
|
346
|
+
buffer.writeNull ();
|
347
|
+
} else if (type == ObjectType.OID) {
|
348
|
+
buffer.writeOID (value);
|
349
|
+
} else if (type == ObjectType.IpAddress) {
|
350
|
+
var bytes = value.split (".");
|
351
|
+
if (bytes.length != 4)
|
352
|
+
throw new RequestInvalidError ("Invalid IP address '"
|
353
|
+
+ value + "'");
|
354
|
+
buffer.writeBuffer (new Buffer (bytes), 64);
|
355
|
+
} else if (type == ObjectType.Counter) { // also Counter32
|
356
|
+
writeUint (buffer, ObjectType.Counter, value);
|
357
|
+
} else if (type == ObjectType.Gauge) { // also Gauge32 & Unsigned32
|
358
|
+
writeUint (buffer, ObjectType.Gauge, value);
|
359
|
+
} else if (type == ObjectType.TimeTicks) {
|
360
|
+
writeUint (buffer, ObjectType.TimeTicks, value);
|
361
|
+
} else if (type == ObjectType.Opaque) {
|
362
|
+
buffer.writeBuffer (value, ObjectType.Opaque);
|
363
|
+
} else if (type == ObjectType.Counter64) {
|
364
|
+
writeUint64 (buffer, value);
|
365
|
+
} else {
|
366
|
+
throw new RequestInvalidError ("Unknown type '" + type
|
367
|
+
+ "' in request");
|
368
|
+
}
|
369
|
+
} else {
|
370
|
+
buffer.writeNull ();
|
371
|
+
}
|
372
|
+
|
373
|
+
buffer.endSequence ();
|
374
|
+
}
|
375
|
+
buffer.endSequence ();
|
376
|
+
}
|
377
|
+
|
378
|
+
/*****************************************************************************
|
379
|
+
** PDU class definitions
|
380
|
+
**/
|
381
|
+
|
382
|
+
var SimplePdu = function (id, varbinds, options) {
|
383
|
+
this.id = id;
|
384
|
+
this.varbinds = varbinds;
|
385
|
+
this.options = options || {};
|
386
|
+
};
|
387
|
+
|
388
|
+
SimplePdu.prototype.toBuffer = function (buffer) {
|
389
|
+
buffer.startSequence (this.type);
|
390
|
+
|
391
|
+
buffer.writeInt (this.id);
|
392
|
+
buffer.writeInt ((this.type == PduType.GetBulkRequest)
|
393
|
+
? (this.options.nonRepeaters || 0)
|
394
|
+
: 0);
|
395
|
+
buffer.writeInt ((this.type == PduType.GetBulkRequest)
|
396
|
+
? (this.options.maxRepetitions || 0)
|
397
|
+
: 0);
|
398
|
+
|
399
|
+
writeVarbinds (buffer, this.varbinds);
|
400
|
+
|
401
|
+
buffer.endSequence ();
|
402
|
+
};
|
403
|
+
|
404
|
+
var GetBulkRequestPdu = function () {
|
405
|
+
this.type = PduType.GetBulkRequest;
|
406
|
+
GetBulkRequestPdu.super_.apply (this, arguments);
|
407
|
+
};
|
408
|
+
|
409
|
+
util.inherits (GetBulkRequestPdu, SimplePdu);
|
410
|
+
|
411
|
+
var GetNextRequestPdu = function () {
|
412
|
+
this.type = PduType.GetNextRequest;
|
413
|
+
GetNextRequestPdu.super_.apply (this, arguments);
|
414
|
+
};
|
415
|
+
|
416
|
+
util.inherits (GetNextRequestPdu, SimplePdu);
|
417
|
+
|
418
|
+
var GetResponsePdu = function (buffer) {
|
419
|
+
this.type = PduType.GetResponse;
|
420
|
+
|
421
|
+
buffer.readSequence (this.type);
|
422
|
+
|
423
|
+
this.id = buffer.readInt ();
|
424
|
+
|
425
|
+
this.errorStatus = buffer.readInt ();
|
426
|
+
this.errorIndex = buffer.readInt ();
|
427
|
+
|
428
|
+
this.varbinds = [];
|
429
|
+
|
430
|
+
readVarbinds (buffer, this.varbinds);
|
431
|
+
};
|
432
|
+
|
433
|
+
var GetRequestPdu = function () {
|
434
|
+
this.type = PduType.GetRequest;
|
435
|
+
GetRequestPdu.super_.apply (this, arguments);
|
436
|
+
};
|
437
|
+
|
438
|
+
util.inherits (GetRequestPdu, SimplePdu);
|
439
|
+
|
440
|
+
var InformRequestPdu = function () {
|
441
|
+
this.type = PduType.InformRequest;
|
442
|
+
InformRequestPdu.super_.apply (this, arguments);
|
443
|
+
};
|
444
|
+
|
445
|
+
util.inherits (InformRequestPdu, SimplePdu);
|
446
|
+
|
447
|
+
var SetRequestPdu = function () {
|
448
|
+
this.type = PduType.SetRequest;
|
449
|
+
SetRequestPdu.super_.apply (this, arguments);
|
450
|
+
};
|
451
|
+
|
452
|
+
util.inherits (SetRequestPdu, SimplePdu);
|
453
|
+
|
454
|
+
var TrapPdu = function (typeOrOid, varbinds, options) {
|
455
|
+
this.type = PduType.Trap;
|
456
|
+
|
457
|
+
this.agentAddr = options.agentAddr || "127.0.0.1";
|
458
|
+
this.upTime = options.upTime;
|
459
|
+
|
460
|
+
if (typeof typeOrOid == "string") {
|
461
|
+
this.generic = TrapType.EnterpriseSpecific;
|
462
|
+
this.specific = parseInt (typeOrOid.match (/\.(\d+)$/)[1]);
|
463
|
+
this.enterprise = typeOrOid.replace (/\.(\d+)$/, "");
|
464
|
+
} else {
|
465
|
+
this.generic = typeOrOid;
|
466
|
+
this.specific = 0;
|
467
|
+
this.enterprise = "1.3.6.1.4.1";
|
468
|
+
}
|
469
|
+
|
470
|
+
this.varbinds = varbinds;
|
471
|
+
};
|
472
|
+
|
473
|
+
TrapPdu.prototype.toBuffer = function (buffer) {
|
474
|
+
buffer.startSequence (this.type);
|
475
|
+
|
476
|
+
buffer.writeOID (this.enterprise);
|
477
|
+
buffer.writeBuffer (new Buffer (this.agentAddr.split (".")),
|
478
|
+
ObjectType.IpAddress);
|
479
|
+
buffer.writeInt (this.generic);
|
480
|
+
buffer.writeInt (this.specific);
|
481
|
+
writeUint (buffer, ObjectType.TimeTicks,
|
482
|
+
this.upTime || Math.floor (process.uptime () * 100));
|
483
|
+
|
484
|
+
writeVarbinds (buffer, this.varbinds);
|
485
|
+
|
486
|
+
buffer.endSequence ();
|
487
|
+
};
|
488
|
+
|
489
|
+
var TrapV2Pdu = function () {
|
490
|
+
this.type = PduType.TrapV2;
|
491
|
+
TrapV2Pdu.super_.apply (this, arguments);
|
492
|
+
};
|
493
|
+
|
494
|
+
util.inherits (TrapV2Pdu, SimplePdu);
|
495
|
+
|
496
|
+
/*****************************************************************************
|
497
|
+
** Message class definitions
|
498
|
+
**/
|
499
|
+
|
500
|
+
var RequestMessage = function (version, community, pdu) {
|
501
|
+
this.version = version;
|
502
|
+
this.community = community;
|
503
|
+
this.pdu = pdu;
|
504
|
+
};
|
505
|
+
|
506
|
+
RequestMessage.prototype.toBuffer = function () {
|
507
|
+
if (this.buffer)
|
508
|
+
return this.buffer;
|
509
|
+
|
510
|
+
var writer = new ber.Writer ();
|
511
|
+
|
512
|
+
writer.startSequence ();
|
513
|
+
|
514
|
+
writer.writeInt (this.version);
|
515
|
+
writer.writeString (this.community);
|
516
|
+
|
517
|
+
this.pdu.toBuffer (writer);
|
518
|
+
|
519
|
+
writer.endSequence ();
|
520
|
+
|
521
|
+
this.buffer = writer.buffer;
|
522
|
+
|
523
|
+
return this.buffer;
|
524
|
+
};
|
525
|
+
|
526
|
+
var ResponseMessage = function (buffer) {
|
527
|
+
var reader = new ber.Reader (buffer);
|
528
|
+
|
529
|
+
reader.readSequence ();
|
530
|
+
|
531
|
+
this.version = reader.readInt ();
|
532
|
+
this.community = reader.readString ();
|
533
|
+
|
534
|
+
var type = reader.peek ();
|
535
|
+
|
536
|
+
if (type == PduType.GetResponse) {
|
537
|
+
this.pdu = new GetResponsePdu (reader);
|
538
|
+
} else {
|
539
|
+
throw new ResponseInvalidError ("Unknown PDU type '" + type
|
540
|
+
+ "' in response");
|
541
|
+
}
|
542
|
+
};
|
543
|
+
|
544
|
+
/*****************************************************************************
|
545
|
+
** Session class definition
|
546
|
+
**/
|
547
|
+
|
548
|
+
var Session = function (target, community, options) {
|
549
|
+
this.target = target || "127.0.0.1";
|
550
|
+
this.community = community || "public";
|
551
|
+
|
552
|
+
this.version = (options && options.version)
|
553
|
+
? options.version
|
554
|
+
: Version1;
|
555
|
+
|
556
|
+
this.transport = (options && options.transport)
|
557
|
+
? options.transport
|
558
|
+
: "udp4";
|
559
|
+
this.port = (options && options.port )
|
560
|
+
? options.port
|
561
|
+
: 161;
|
562
|
+
this.trapPort = (options && options.trapPort )
|
563
|
+
? options.trapPort
|
564
|
+
: 162;
|
565
|
+
|
566
|
+
this.retries = (options && (options.retries || options.retries == 0))
|
567
|
+
? options.retries
|
568
|
+
: 1;
|
569
|
+
this.timeout = (options && options.timeout)
|
570
|
+
? options.timeout
|
571
|
+
: 5000;
|
572
|
+
|
573
|
+
this.sourceAddress = (options && options.sourceAddress )
|
574
|
+
? options.sourceAddress
|
575
|
+
: undefined;
|
576
|
+
this.sourcePort = (options && options.sourcePort )
|
577
|
+
? parseInt(options.sourcePort)
|
578
|
+
: undefined;
|
579
|
+
|
580
|
+
this.idBitsSize = (options && options.idBitsSize)
|
581
|
+
? parseInt(options.idBitsSize)
|
582
|
+
: 32;
|
583
|
+
|
584
|
+
this.reqs = {};
|
585
|
+
this.reqCount = 0;
|
586
|
+
|
587
|
+
this.dgram = dgram.createSocket (this.transport);
|
588
|
+
this.dgram.unref();
|
589
|
+
|
590
|
+
var me = this;
|
591
|
+
this.dgram.on ("message", me.onMsg.bind (me));
|
592
|
+
this.dgram.on ("close", me.onClose.bind (me));
|
593
|
+
this.dgram.on ("error", me.onError.bind (me));
|
594
|
+
|
595
|
+
if (this.sourceAddress || this.sourcePort)
|
596
|
+
this.dgram.bind (this.sourcePort, this.sourceAddress);
|
597
|
+
};
|
598
|
+
|
599
|
+
util.inherits (Session, events.EventEmitter);
|
600
|
+
|
601
|
+
Session.prototype.close = function () {
|
602
|
+
this.dgram.close ();
|
603
|
+
return this;
|
604
|
+
};
|
605
|
+
|
606
|
+
Session.prototype.cancelRequests = function (error) {
|
607
|
+
var id;
|
608
|
+
for (id in this.reqs) {
|
609
|
+
var req = this.reqs[id];
|
610
|
+
this.unregisterRequest (req.id);
|
611
|
+
req.responseCb (error);
|
612
|
+
}
|
613
|
+
};
|
614
|
+
|
615
|
+
function _generateId (bitSize) {
|
616
|
+
if (bitSize === 16) {
|
617
|
+
return Math.floor(Math.random() * 10000) % 65535;
|
618
|
+
}
|
619
|
+
return Math.floor(Math.random() * 100000000) % 4294967295;
|
620
|
+
}
|
621
|
+
|
622
|
+
Session.prototype.get = function (oids, responseCb) {
|
623
|
+
function feedCb (req, message) {
|
624
|
+
var pdu = message.pdu;
|
625
|
+
var varbinds = [];
|
626
|
+
|
627
|
+
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
628
|
+
req.responseCb (new ResponseInvalidError ("Requested OIDs do not "
|
629
|
+
+ "match response OIDs"));
|
630
|
+
} else {
|
631
|
+
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
632
|
+
if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) {
|
633
|
+
req.responseCb (new ResponseInvalidError ("OID '"
|
634
|
+
+ req.message.pdu.varbinds[i].oid
|
635
|
+
+ "' in request at positiion '" + i + "' does not "
|
636
|
+
+ "match OID '" + pdu.varbinds[i].oid + "' in response "
|
637
|
+
+ "at position '" + i + "'"));
|
638
|
+
return;
|
639
|
+
} else {
|
640
|
+
varbinds.push (pdu.varbinds[i]);
|
641
|
+
}
|
642
|
+
}
|
643
|
+
|
644
|
+
req.responseCb (null, varbinds);
|
645
|
+
}
|
646
|
+
}
|
647
|
+
|
648
|
+
var pduVarbinds = [];
|
649
|
+
|
650
|
+
for (var i = 0; i < oids.length; i++) {
|
651
|
+
var varbind = {
|
652
|
+
oid: oids[i]
|
653
|
+
};
|
654
|
+
pduVarbinds.push (varbind);
|
655
|
+
}
|
656
|
+
|
657
|
+
this.simpleGet (GetRequestPdu, feedCb, pduVarbinds, responseCb);
|
658
|
+
|
659
|
+
return this;
|
660
|
+
};
|
661
|
+
|
662
|
+
Session.prototype.getBulk = function () {
|
663
|
+
var oids, nonRepeaters, maxRepetitions, responseCb;
|
664
|
+
|
665
|
+
if (arguments.length >= 4) {
|
666
|
+
oids = arguments[0];
|
667
|
+
nonRepeaters = arguments[1];
|
668
|
+
maxRepetitions = arguments[2];
|
669
|
+
responseCb = arguments[3];
|
670
|
+
} else if (arguments.length >= 3) {
|
671
|
+
oids = arguments[0];
|
672
|
+
nonRepeaters = arguments[1];
|
673
|
+
maxRepetitions = 10;
|
674
|
+
responseCb = arguments[2];
|
675
|
+
} else {
|
676
|
+
oids = arguments[0];
|
677
|
+
nonRepeaters = 0;
|
678
|
+
maxRepetitions = 10;
|
679
|
+
responseCb = arguments[1];
|
680
|
+
}
|
681
|
+
|
682
|
+
function feedCb (req, message) {
|
683
|
+
var pdu = message.pdu;
|
684
|
+
var varbinds = [];
|
685
|
+
var i = 0;
|
686
|
+
|
687
|
+
// first walk through and grab non-repeaters
|
688
|
+
if (pdu.varbinds.length < nonRepeaters) {
|
689
|
+
req.responseCb (new ResponseInvalidError ("Varbind count in "
|
690
|
+
+ "response '" + pdu.varbinds.length + "' is less than "
|
691
|
+
+ "non-repeaters '" + nonRepeaters + "' in request"));
|
692
|
+
} else {
|
693
|
+
for ( ; i < nonRepeaters; i++) {
|
694
|
+
if (isVarbindError (pdu.varbinds[i])) {
|
695
|
+
varbinds.push (pdu.varbinds[i]);
|
696
|
+
} else if (! oidFollowsOid (req.message.pdu.varbinds[i].oid,
|
697
|
+
pdu.varbinds[i].oid)) {
|
698
|
+
req.responseCb (new ResponseInvalidError ("OID '"
|
699
|
+
+ req.message.pdu.varbinds[i].oid + "' in request at "
|
700
|
+
+ "positiion '" + i + "' does not precede "
|
701
|
+
+ "OID '" + pdu.varbinds[i].oid + "' in response "
|
702
|
+
+ "at position '" + i + "'"));
|
703
|
+
return;
|
704
|
+
} else {
|
705
|
+
varbinds.push (pdu.varbinds[i]);
|
706
|
+
}
|
707
|
+
}
|
708
|
+
}
|
709
|
+
|
710
|
+
var repeaters = req.message.pdu.varbinds.length - nonRepeaters;
|
711
|
+
|
712
|
+
// secondly walk through and grab repeaters
|
713
|
+
if (pdu.varbinds.length % (repeaters)) {
|
714
|
+
req.responseCb (new ResponseInvalidError ("Varbind count in "
|
715
|
+
+ "response '" + pdu.varbinds.length + "' is not a "
|
716
|
+
+ "multiple of repeaters '" + repeaters
|
717
|
+
+ "' plus non-repeaters '" + nonRepeaters + "' in request"));
|
718
|
+
} else {
|
719
|
+
while (i < pdu.varbinds.length) {
|
720
|
+
for (var j = 0; j < repeaters; j++, i++) {
|
721
|
+
var reqIndex = nonRepeaters + j;
|
722
|
+
var respIndex = i;
|
723
|
+
|
724
|
+
if (isVarbindError (pdu.varbinds[respIndex])) {
|
725
|
+
if (! varbinds[reqIndex])
|
726
|
+
varbinds[reqIndex] = [];
|
727
|
+
varbinds[reqIndex].push (pdu.varbinds[respIndex]);
|
728
|
+
} else if (! oidFollowsOid (
|
729
|
+
req.message.pdu.varbinds[reqIndex].oid,
|
730
|
+
pdu.varbinds[respIndex].oid)) {
|
731
|
+
req.responseCb (new ResponseInvalidError ("OID '"
|
732
|
+
+ req.message.pdu.varbinds[reqIndex].oid
|
733
|
+
+ "' in request at positiion '" + (reqIndex)
|
734
|
+
+ "' does not precede OID '"
|
735
|
+
+ pdu.varbinds[respIndex].oid
|
736
|
+
+ "' in response at position '" + (respIndex) + "'"));
|
737
|
+
return;
|
738
|
+
} else {
|
739
|
+
if (! varbinds[reqIndex])
|
740
|
+
varbinds[reqIndex] = [];
|
741
|
+
varbinds[reqIndex].push (pdu.varbinds[respIndex]);
|
742
|
+
}
|
743
|
+
}
|
744
|
+
}
|
745
|
+
}
|
746
|
+
|
747
|
+
req.responseCb (null, varbinds);
|
748
|
+
}
|
749
|
+
|
750
|
+
var pduVarbinds = [];
|
751
|
+
|
752
|
+
for (var i = 0; i < oids.length; i++) {
|
753
|
+
var varbind = {
|
754
|
+
oid: oids[i]
|
755
|
+
};
|
756
|
+
pduVarbinds.push (varbind);
|
757
|
+
}
|
758
|
+
|
759
|
+
var options = {
|
760
|
+
nonRepeaters: nonRepeaters,
|
761
|
+
maxRepetitions: maxRepetitions
|
762
|
+
};
|
763
|
+
|
764
|
+
this.simpleGet (GetBulkRequestPdu, feedCb, pduVarbinds, responseCb,
|
765
|
+
options);
|
766
|
+
|
767
|
+
return this;
|
768
|
+
};
|
769
|
+
|
770
|
+
Session.prototype.getNext = function (oids, responseCb) {
|
771
|
+
function feedCb (req, message) {
|
772
|
+
var pdu = message.pdu;
|
773
|
+
var varbinds = [];
|
774
|
+
|
775
|
+
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
776
|
+
req.responseCb (new ResponseInvalidError ("Requested OIDs do not "
|
777
|
+
+ "match response OIDs"));
|
778
|
+
} else {
|
779
|
+
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
780
|
+
if (isVarbindError (pdu.varbinds[i])) {
|
781
|
+
varbinds.push (pdu.varbinds[i]);
|
782
|
+
} else if (! oidFollowsOid (req.message.pdu.varbinds[i].oid,
|
783
|
+
pdu.varbinds[i].oid)) {
|
784
|
+
req.responseCb (new ResponseInvalidError ("OID '"
|
785
|
+
+ req.message.pdu.varbinds[i].oid + "' in request at "
|
786
|
+
+ "positiion '" + i + "' does not precede "
|
787
|
+
+ "OID '" + pdu.varbinds[i].oid + "' in response "
|
788
|
+
+ "at position '" + i + "'"));
|
789
|
+
return;
|
790
|
+
} else {
|
791
|
+
varbinds.push (pdu.varbinds[i]);
|
792
|
+
}
|
793
|
+
}
|
794
|
+
|
795
|
+
req.responseCb (null, varbinds);
|
796
|
+
}
|
797
|
+
}
|
798
|
+
|
799
|
+
var pduVarbinds = [];
|
800
|
+
|
801
|
+
for (var i = 0; i < oids.length; i++) {
|
802
|
+
var varbind = {
|
803
|
+
oid: oids[i]
|
804
|
+
};
|
805
|
+
pduVarbinds.push (varbind);
|
806
|
+
}
|
807
|
+
|
808
|
+
this.simpleGet (GetNextRequestPdu, feedCb, pduVarbinds, responseCb);
|
809
|
+
|
810
|
+
return this;
|
811
|
+
};
|
812
|
+
|
813
|
+
Session.prototype.inform = function () {
|
814
|
+
var typeOrOid = arguments[0];
|
815
|
+
var varbinds, options = {}, responseCb;
|
816
|
+
|
817
|
+
/**
|
818
|
+
** Support the following signatures:
|
819
|
+
**
|
820
|
+
** typeOrOid, varbinds, options, callback
|
821
|
+
** typeOrOid, varbinds, callback
|
822
|
+
** typeOrOid, options, callback
|
823
|
+
** typeOrOid, callback
|
824
|
+
**/
|
825
|
+
if (arguments.length >= 4) {
|
826
|
+
varbinds = arguments[1];
|
827
|
+
options = arguments[2];
|
828
|
+
responseCb = arguments[3];
|
829
|
+
} else if (arguments.length >= 3) {
|
830
|
+
if (arguments[1].constructor != Array) {
|
831
|
+
varbinds = [];
|
832
|
+
options = arguments[1];
|
833
|
+
responseCb = arguments[2];
|
834
|
+
} else {
|
835
|
+
varbinds = arguments[1];
|
836
|
+
responseCb = arguments[2];
|
837
|
+
}
|
838
|
+
} else {
|
839
|
+
varbinds = [];
|
840
|
+
responseCb = arguments[1];
|
841
|
+
}
|
842
|
+
|
843
|
+
function feedCb (req, message) {
|
844
|
+
var pdu = message.pdu;
|
845
|
+
var varbinds = [];
|
846
|
+
|
847
|
+
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
848
|
+
req.responseCb (new ResponseInvalidError ("Inform OIDs do not "
|
849
|
+
+ "match response OIDs"));
|
850
|
+
} else {
|
851
|
+
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
852
|
+
if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) {
|
853
|
+
req.responseCb (new ResponseInvalidError ("OID '"
|
854
|
+
+ req.message.pdu.varbinds[i].oid
|
855
|
+
+ "' in inform at positiion '" + i + "' does not "
|
856
|
+
+ "match OID '" + pdu.varbinds[i].oid + "' in response "
|
857
|
+
+ "at position '" + i + "'"));
|
858
|
+
return;
|
859
|
+
} else {
|
860
|
+
varbinds.push (pdu.varbinds[i]);
|
861
|
+
}
|
862
|
+
}
|
863
|
+
|
864
|
+
req.responseCb (null, varbinds);
|
865
|
+
}
|
866
|
+
}
|
867
|
+
|
868
|
+
if (typeof typeOrOid != "string")
|
869
|
+
typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1);
|
870
|
+
|
871
|
+
var pduVarbinds = [
|
872
|
+
{
|
873
|
+
oid: "1.3.6.1.2.1.1.3.0",
|
874
|
+
type: ObjectType.TimeTicks,
|
875
|
+
value: options.upTime || Math.floor (process.uptime () * 100)
|
876
|
+
},
|
877
|
+
{
|
878
|
+
oid: "1.3.6.1.6.3.1.1.4.1.0",
|
879
|
+
type: ObjectType.OID,
|
880
|
+
value: typeOrOid
|
881
|
+
}
|
882
|
+
];
|
883
|
+
|
884
|
+
for (var i = 0; i < varbinds.length; i++) {
|
885
|
+
var varbind = {
|
886
|
+
oid: varbinds[i].oid,
|
887
|
+
type: varbinds[i].type,
|
888
|
+
value: varbinds[i].value
|
889
|
+
};
|
890
|
+
pduVarbinds.push (varbind);
|
891
|
+
}
|
892
|
+
|
893
|
+
options.port = this.trapPort;
|
894
|
+
|
895
|
+
this.simpleGet (InformRequestPdu, feedCb, pduVarbinds, responseCb, options);
|
896
|
+
|
897
|
+
return this;
|
898
|
+
};
|
899
|
+
|
900
|
+
Session.prototype.onClose = function () {
|
901
|
+
this.cancelRequests (new Error ("Socket forcibly closed"));
|
902
|
+
this.emit ("close");
|
903
|
+
};
|
904
|
+
|
905
|
+
Session.prototype.onError = function (error) {
|
906
|
+
this.emit (error);
|
907
|
+
};
|
908
|
+
|
909
|
+
Session.prototype.onMsg = function (buffer, remote) {
|
910
|
+
try {
|
911
|
+
var message = new ResponseMessage (buffer);
|
912
|
+
|
913
|
+
var req = this.unregisterRequest (message.pdu.id);
|
914
|
+
if (! req)
|
915
|
+
return;
|
916
|
+
|
917
|
+
try {
|
918
|
+
if (message.version != req.message.version) {
|
919
|
+
req.responseCb (new ResponseInvalidError ("Version in request '"
|
920
|
+
+ req.message.version + "' does not match version in "
|
921
|
+
+ "response '" + message.version));
|
922
|
+
} else if (message.community != req.message.community) {
|
923
|
+
req.responseCb (new ResponseInvalidError ("Community '"
|
924
|
+
+ req.message.community + "' in request does not match "
|
925
|
+
+ "community '" + message.community + "' in response"));
|
926
|
+
} else if (message.pdu.type == PduType.GetResponse) {
|
927
|
+
req.onResponse (req, message);
|
928
|
+
} else {
|
929
|
+
req.responseCb (new ResponseInvalidError ("Unknown PDU type '"
|
930
|
+
+ message.pdu.type + "' in response"));
|
931
|
+
}
|
932
|
+
} catch (error) {
|
933
|
+
req.responseCb (error);
|
934
|
+
}
|
935
|
+
} catch (error) {
|
936
|
+
this.emit("error", error);
|
937
|
+
}
|
938
|
+
};
|
939
|
+
|
940
|
+
Session.prototype.onSimpleGetResponse = function (req, message) {
|
941
|
+
var pdu = message.pdu;
|
942
|
+
|
943
|
+
if (pdu.errorStatus > 0) {
|
944
|
+
var statusString = ErrorStatus[pdu.errorStatus]
|
945
|
+
|| ErrorStatus.GeneralError;
|
946
|
+
var statusCode = ErrorStatus[statusString]
|
947
|
+
|| ErrorStatus[ErrorStatus.GeneralError];
|
948
|
+
|
949
|
+
if (pdu.errorIndex <= 0 || pdu.errorIndex > pdu.varbinds.length) {
|
950
|
+
req.responseCb (new RequestFailedError (statusString, statusCode));
|
951
|
+
} else {
|
952
|
+
var oid = pdu.varbinds[pdu.errorIndex - 1].oid;
|
953
|
+
var error = new RequestFailedError (statusString + ": " + oid,
|
954
|
+
statusCode);
|
955
|
+
req.responseCb (error);
|
956
|
+
}
|
957
|
+
} else {
|
958
|
+
req.feedCb (req, message);
|
959
|
+
}
|
960
|
+
};
|
961
|
+
|
962
|
+
Session.prototype.registerRequest = function (req) {
|
963
|
+
if (! this.reqs[req.id]) {
|
964
|
+
this.reqs[req.id] = req;
|
965
|
+
if (this.reqCount <= 0)
|
966
|
+
this.dgram.ref();
|
967
|
+
this.reqCount++;
|
968
|
+
}
|
969
|
+
var me = this;
|
970
|
+
req.timer = setTimeout (function () {
|
971
|
+
if (req.retries-- > 0) {
|
972
|
+
me.send (req);
|
973
|
+
} else {
|
974
|
+
me.unregisterRequest (req.id);
|
975
|
+
req.responseCb (new RequestTimedOutError (
|
976
|
+
"Request timed out"));
|
977
|
+
}
|
978
|
+
}, req.timeout);
|
979
|
+
};
|
980
|
+
|
981
|
+
Session.prototype.send = function (req, noWait) {
|
982
|
+
try {
|
983
|
+
var me = this;
|
984
|
+
|
985
|
+
var buffer = req.message.toBuffer ();
|
986
|
+
|
987
|
+
this.dgram.send (buffer, 0, buffer.length, req.port, this.target,
|
988
|
+
function (error, bytes) {
|
989
|
+
if (error) {
|
990
|
+
req.responseCb (error);
|
991
|
+
} else {
|
992
|
+
if (noWait) {
|
993
|
+
req.responseCb (null);
|
994
|
+
} else {
|
995
|
+
me.registerRequest (req);
|
996
|
+
}
|
997
|
+
}
|
998
|
+
});
|
999
|
+
} catch (error) {
|
1000
|
+
req.responseCb (error);
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
return this;
|
1004
|
+
};
|
1005
|
+
|
1006
|
+
Session.prototype.set = function (varbinds, responseCb) {
|
1007
|
+
function feedCb (req, message) {
|
1008
|
+
var pdu = message.pdu;
|
1009
|
+
var varbinds = [];
|
1010
|
+
|
1011
|
+
if (req.message.pdu.varbinds.length != pdu.varbinds.length) {
|
1012
|
+
req.responseCb (new ResponseInvalidError ("Requested OIDs do not "
|
1013
|
+
+ "match response OIDs"));
|
1014
|
+
} else {
|
1015
|
+
for (var i = 0; i < req.message.pdu.varbinds.length; i++) {
|
1016
|
+
if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) {
|
1017
|
+
req.responseCb (new ResponseInvalidError ("OID '"
|
1018
|
+
+ req.message.pdu.varbinds[i].oid
|
1019
|
+
+ "' in request at positiion '" + i + "' does not "
|
1020
|
+
+ "match OID '" + pdu.varbinds[i].oid + "' in response "
|
1021
|
+
+ "at position '" + i + "'"));
|
1022
|
+
return;
|
1023
|
+
} else {
|
1024
|
+
varbinds.push (pdu.varbinds[i]);
|
1025
|
+
}
|
1026
|
+
}
|
1027
|
+
|
1028
|
+
req.responseCb (null, varbinds);
|
1029
|
+
}
|
1030
|
+
}
|
1031
|
+
|
1032
|
+
var pduVarbinds = [];
|
1033
|
+
|
1034
|
+
for (var i = 0; i < varbinds.length; i++) {
|
1035
|
+
var varbind = {
|
1036
|
+
oid: varbinds[i].oid,
|
1037
|
+
type: varbinds[i].type,
|
1038
|
+
value: varbinds[i].value
|
1039
|
+
};
|
1040
|
+
pduVarbinds.push (varbind);
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
this.simpleGet (SetRequestPdu, feedCb, pduVarbinds, responseCb);
|
1044
|
+
|
1045
|
+
return this;
|
1046
|
+
};
|
1047
|
+
|
1048
|
+
Session.prototype.simpleGet = function (pduClass, feedCb, varbinds,
|
1049
|
+
responseCb, options) {
|
1050
|
+
var req = {};
|
1051
|
+
|
1052
|
+
try {
|
1053
|
+
var id = _generateId (this.idBitsSize);
|
1054
|
+
var pdu = new pduClass (id, varbinds, options);
|
1055
|
+
var message = new RequestMessage (this.version, this.community, pdu);
|
1056
|
+
|
1057
|
+
req = {
|
1058
|
+
id: id,
|
1059
|
+
message: message,
|
1060
|
+
responseCb: responseCb,
|
1061
|
+
retries: this.retries,
|
1062
|
+
timeout: this.timeout,
|
1063
|
+
onResponse: this.onSimpleGetResponse,
|
1064
|
+
feedCb: feedCb,
|
1065
|
+
port: (options && options.port) ? options.port : this.port
|
1066
|
+
};
|
1067
|
+
|
1068
|
+
this.send (req);
|
1069
|
+
} catch (error) {
|
1070
|
+
if (req.responseCb)
|
1071
|
+
req.responseCb (error);
|
1072
|
+
}
|
1073
|
+
};
|
1074
|
+
|
1075
|
+
function subtreeCb (req, varbinds) {
|
1076
|
+
var done = 0;
|
1077
|
+
|
1078
|
+
for (var i = varbinds.length; i > 0; i--) {
|
1079
|
+
if (! oidInSubtree (req.baseOid, varbinds[i - 1].oid)) {
|
1080
|
+
done = 1;
|
1081
|
+
varbinds.pop ();
|
1082
|
+
}
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
if (varbinds.length > 0)
|
1086
|
+
req.feedCb (varbinds);
|
1087
|
+
|
1088
|
+
if (done)
|
1089
|
+
return true;
|
1090
|
+
}
|
1091
|
+
|
1092
|
+
Session.prototype.subtree = function () {
|
1093
|
+
var me = this;
|
1094
|
+
var oid = arguments[0];
|
1095
|
+
var maxRepetitions, feedCb, doneCb;
|
1096
|
+
|
1097
|
+
if (arguments.length < 4) {
|
1098
|
+
maxRepetitions = 20;
|
1099
|
+
feedCb = arguments[1];
|
1100
|
+
doneCb = arguments[2];
|
1101
|
+
} else {
|
1102
|
+
maxRepetitions = arguments[1];
|
1103
|
+
feedCb = arguments[2];
|
1104
|
+
doneCb = arguments[3];
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
var req = {
|
1108
|
+
feedCb: feedCb,
|
1109
|
+
doneCb: doneCb,
|
1110
|
+
maxRepetitions: maxRepetitions,
|
1111
|
+
baseOid: oid
|
1112
|
+
};
|
1113
|
+
|
1114
|
+
this.walk (oid, maxRepetitions, subtreeCb.bind (me, req), doneCb);
|
1115
|
+
|
1116
|
+
return this;
|
1117
|
+
};
|
1118
|
+
|
1119
|
+
function tableColumnsResponseCb (req, error) {
|
1120
|
+
if (error) {
|
1121
|
+
req.responseCb (error);
|
1122
|
+
} else if (req.error) {
|
1123
|
+
req.responseCb (req.error);
|
1124
|
+
} else {
|
1125
|
+
if (req.columns.length > 0) {
|
1126
|
+
var column = req.columns.pop ();
|
1127
|
+
var me = this;
|
1128
|
+
this.subtree (req.rowOid + column, req.maxRepetitions,
|
1129
|
+
tableColumnsFeedCb.bind (me, req),
|
1130
|
+
tableColumnsResponseCb.bind (me, req));
|
1131
|
+
} else {
|
1132
|
+
req.responseCb (null, req.table);
|
1133
|
+
}
|
1134
|
+
}
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
function tableColumnsFeedCb (req, varbinds) {
|
1138
|
+
for (var i = 0; i < varbinds.length; i++) {
|
1139
|
+
if (isVarbindError (varbinds[i])) {
|
1140
|
+
req.error = new RequestFailedError (varbindError (varbind[i]));
|
1141
|
+
return true;
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
var oid = varbinds[i].oid.replace (req.rowOid, "");
|
1145
|
+
if (oid && oid != varbinds[i].oid) {
|
1146
|
+
var match = oid.match (/^(\d+)\.(.+)$/);
|
1147
|
+
if (match && match[1] > 0) {
|
1148
|
+
if (! req.table[match[2]])
|
1149
|
+
req.table[match[2]] = {};
|
1150
|
+
req.table[match[2]][match[1]] = varbinds[i].value;
|
1151
|
+
}
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
Session.prototype.tableColumns = function () {
|
1157
|
+
var me = this;
|
1158
|
+
|
1159
|
+
var oid = arguments[0];
|
1160
|
+
var columns = arguments[1];
|
1161
|
+
var maxRepetitions, responseCb;
|
1162
|
+
|
1163
|
+
if (arguments.length < 4) {
|
1164
|
+
responseCb = arguments[2];
|
1165
|
+
maxRepetitions = 20;
|
1166
|
+
} else {
|
1167
|
+
maxRepetitions = arguments[2];
|
1168
|
+
responseCb = arguments[3];
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
var req = {
|
1172
|
+
responseCb: responseCb,
|
1173
|
+
maxRepetitions: maxRepetitions,
|
1174
|
+
baseOid: oid,
|
1175
|
+
rowOid: oid + ".1.",
|
1176
|
+
columns: columns.slice(0),
|
1177
|
+
table: {}
|
1178
|
+
};
|
1179
|
+
|
1180
|
+
if (req.columns.length > 0) {
|
1181
|
+
var column = req.columns.pop ();
|
1182
|
+
this.subtree (req.rowOid + column, maxRepetitions,
|
1183
|
+
tableColumnsFeedCb.bind (me, req),
|
1184
|
+
tableColumnsResponseCb.bind (me, req));
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
return this;
|
1188
|
+
};
|
1189
|
+
|
1190
|
+
function tableResponseCb (req, error) {
|
1191
|
+
if (error)
|
1192
|
+
req.responseCb (error);
|
1193
|
+
else if (req.error)
|
1194
|
+
req.responseCb (req.error);
|
1195
|
+
else
|
1196
|
+
req.responseCb (null, req.table);
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
function tableFeedCb (req, varbinds) {
|
1200
|
+
for (var i = 0; i < varbinds.length; i++) {
|
1201
|
+
if (isVarbindError (varbinds[i])) {
|
1202
|
+
req.error = new RequestFailedError (varbindError (varbind[i]));
|
1203
|
+
return true;
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
var oid = varbinds[i].oid.replace (req.rowOid, "");
|
1207
|
+
if (oid && oid != varbinds[i].oid) {
|
1208
|
+
var match = oid.match (/^(\d+)\.(.+)$/);
|
1209
|
+
if (match && match[1] > 0) {
|
1210
|
+
if (! req.table[match[2]])
|
1211
|
+
req.table[match[2]] = {};
|
1212
|
+
req.table[match[2]][match[1]] = varbinds[i].value;
|
1213
|
+
}
|
1214
|
+
}
|
1215
|
+
}
|
1216
|
+
}
|
1217
|
+
|
1218
|
+
Session.prototype.table = function () {
|
1219
|
+
var me = this;
|
1220
|
+
|
1221
|
+
var oid = arguments[0];
|
1222
|
+
var maxRepetitions, responseCb;
|
1223
|
+
|
1224
|
+
if (arguments.length < 3) {
|
1225
|
+
responseCb = arguments[1];
|
1226
|
+
maxRepetitions = 20;
|
1227
|
+
} else {
|
1228
|
+
maxRepetitions = arguments[1];
|
1229
|
+
responseCb = arguments[2];
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
var req = {
|
1233
|
+
responseCb: responseCb,
|
1234
|
+
maxRepetitions: maxRepetitions,
|
1235
|
+
baseOid: oid,
|
1236
|
+
rowOid: oid + ".1.",
|
1237
|
+
table: {}
|
1238
|
+
};
|
1239
|
+
|
1240
|
+
this.subtree (oid, maxRepetitions, tableFeedCb.bind (me, req),
|
1241
|
+
tableResponseCb.bind (me, req));
|
1242
|
+
|
1243
|
+
return this;
|
1244
|
+
};
|
1245
|
+
|
1246
|
+
Session.prototype.trap = function () {
|
1247
|
+
var req = {};
|
1248
|
+
|
1249
|
+
try {
|
1250
|
+
var typeOrOid = arguments[0];
|
1251
|
+
var varbinds, options = {}, responseCb;
|
1252
|
+
|
1253
|
+
/**
|
1254
|
+
** Support the following signatures:
|
1255
|
+
**
|
1256
|
+
** typeOrOid, varbinds, options, callback
|
1257
|
+
** typeOrOid, varbinds, agentAddr, callback
|
1258
|
+
** typeOrOid, varbinds, callback
|
1259
|
+
** typeOrOid, agentAddr, callback
|
1260
|
+
** typeOrOid, options, callback
|
1261
|
+
** typeOrOid, callback
|
1262
|
+
**/
|
1263
|
+
if (arguments.length >= 4) {
|
1264
|
+
varbinds = arguments[1];
|
1265
|
+
if (typeof arguments[2] == "string") {
|
1266
|
+
options.agentAddr = arguments[2];
|
1267
|
+
} else if (arguments[2].constructor != Array) {
|
1268
|
+
options = arguments[2];
|
1269
|
+
}
|
1270
|
+
responseCb = arguments[3];
|
1271
|
+
} else if (arguments.length >= 3) {
|
1272
|
+
if (typeof arguments[1] == "string") {
|
1273
|
+
varbinds = [];
|
1274
|
+
options.agentAddr = arguments[1];
|
1275
|
+
} else if (arguments[1].constructor != Array) {
|
1276
|
+
varbinds = [];
|
1277
|
+
options = arguments[1];
|
1278
|
+
} else {
|
1279
|
+
varbinds = arguments[1];
|
1280
|
+
agentAddr = null;
|
1281
|
+
}
|
1282
|
+
responseCb = arguments[2];
|
1283
|
+
} else {
|
1284
|
+
varbinds = [];
|
1285
|
+
responseCb = arguments[1];
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
var pdu, pduVarbinds = [];
|
1289
|
+
|
1290
|
+
for (var i = 0; i < varbinds.length; i++) {
|
1291
|
+
var varbind = {
|
1292
|
+
oid: varbinds[i].oid,
|
1293
|
+
type: varbinds[i].type,
|
1294
|
+
value: varbinds[i].value
|
1295
|
+
};
|
1296
|
+
pduVarbinds.push (varbind);
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
var id = _generateId (this.idBitsSize);
|
1300
|
+
|
1301
|
+
if (this.version == Version2c) {
|
1302
|
+
if (typeof typeOrOid != "string")
|
1303
|
+
typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1);
|
1304
|
+
|
1305
|
+
pduVarbinds.unshift (
|
1306
|
+
{
|
1307
|
+
oid: "1.3.6.1.2.1.1.3.0",
|
1308
|
+
type: ObjectType.TimeTicks,
|
1309
|
+
value: options.upTime || Math.floor (process.uptime () * 100)
|
1310
|
+
},
|
1311
|
+
{
|
1312
|
+
oid: "1.3.6.1.6.3.1.1.4.1.0",
|
1313
|
+
type: ObjectType.OID,
|
1314
|
+
value: typeOrOid
|
1315
|
+
}
|
1316
|
+
);
|
1317
|
+
|
1318
|
+
pdu = new TrapV2Pdu (id, pduVarbinds, options);
|
1319
|
+
} else {
|
1320
|
+
pdu = new TrapPdu (typeOrOid, pduVarbinds, options);
|
1321
|
+
}
|
1322
|
+
|
1323
|
+
var message = new RequestMessage (this.version, this.community, pdu);
|
1324
|
+
|
1325
|
+
req = {
|
1326
|
+
id: id,
|
1327
|
+
message: message,
|
1328
|
+
responseCb: responseCb,
|
1329
|
+
port: this.trapPort
|
1330
|
+
};
|
1331
|
+
|
1332
|
+
this.send (req, true);
|
1333
|
+
} catch (error) {
|
1334
|
+
if (req.responseCb)
|
1335
|
+
req.responseCb (error);
|
1336
|
+
}
|
1337
|
+
|
1338
|
+
return this;
|
1339
|
+
};
|
1340
|
+
|
1341
|
+
Session.prototype.unregisterRequest = function (id) {
|
1342
|
+
var req = this.reqs[id];
|
1343
|
+
if (req) {
|
1344
|
+
delete this.reqs[id];
|
1345
|
+
clearTimeout (req.timer);
|
1346
|
+
delete req.timer;
|
1347
|
+
this.reqCount--;
|
1348
|
+
if (this.reqCount <= 0)
|
1349
|
+
this.dgram.unref();
|
1350
|
+
return req;
|
1351
|
+
} else {
|
1352
|
+
return null;
|
1353
|
+
}
|
1354
|
+
};
|
1355
|
+
|
1356
|
+
function walkCb (req, error, varbinds) {
|
1357
|
+
var done = 0;
|
1358
|
+
var oid;
|
1359
|
+
|
1360
|
+
if (error) {
|
1361
|
+
if (error instanceof RequestFailedError) {
|
1362
|
+
if (error.status != ErrorStatus.NoSuchName) {
|
1363
|
+
req.doneCb (error);
|
1364
|
+
return;
|
1365
|
+
} else {
|
1366
|
+
// signal the version 1 walk code below that it should stop
|
1367
|
+
done = 1;
|
1368
|
+
}
|
1369
|
+
} else {
|
1370
|
+
req.doneCb (error);
|
1371
|
+
return;
|
1372
|
+
}
|
1373
|
+
}
|
1374
|
+
|
1375
|
+
if (this.version == Version2c) {
|
1376
|
+
for (var i = varbinds[0].length; i > 0; i--) {
|
1377
|
+
if (varbinds[0][i - 1].type == ObjectType.EndOfMibView) {
|
1378
|
+
varbinds[0].pop ();
|
1379
|
+
done = 1;
|
1380
|
+
}
|
1381
|
+
}
|
1382
|
+
if (req.feedCb (varbinds[0]))
|
1383
|
+
done = 1;
|
1384
|
+
if (! done)
|
1385
|
+
oid = varbinds[0][varbinds[0].length - 1].oid;
|
1386
|
+
} else {
|
1387
|
+
if (! done) {
|
1388
|
+
if (req.feedCb (varbinds)) {
|
1389
|
+
done = 1;
|
1390
|
+
} else {
|
1391
|
+
oid = varbinds[0].oid;
|
1392
|
+
}
|
1393
|
+
}
|
1394
|
+
}
|
1395
|
+
|
1396
|
+
if (done)
|
1397
|
+
req.doneCb (null);
|
1398
|
+
else
|
1399
|
+
this.walk (oid, req.maxRepetitions, req.feedCb, req.doneCb,
|
1400
|
+
req.baseOid);
|
1401
|
+
}
|
1402
|
+
|
1403
|
+
Session.prototype.walk = function () {
|
1404
|
+
var me = this;
|
1405
|
+
var oid = arguments[0];
|
1406
|
+
var maxRepetitions, feedCb, doneCb, baseOid;
|
1407
|
+
|
1408
|
+
if (arguments.length < 4) {
|
1409
|
+
maxRepetitions = 20;
|
1410
|
+
feedCb = arguments[1];
|
1411
|
+
doneCb = arguments[2];
|
1412
|
+
} else {
|
1413
|
+
maxRepetitions = arguments[1];
|
1414
|
+
feedCb = arguments[2];
|
1415
|
+
doneCb = arguments[3];
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
var req = {
|
1419
|
+
maxRepetitions: maxRepetitions,
|
1420
|
+
feedCb: feedCb,
|
1421
|
+
doneCb: doneCb
|
1422
|
+
};
|
1423
|
+
|
1424
|
+
if (this.version == Version2c)
|
1425
|
+
this.getBulk ([oid], 0, maxRepetitions,
|
1426
|
+
walkCb.bind (me, req));
|
1427
|
+
else
|
1428
|
+
this.getNext ([oid], walkCb.bind (me, req));
|
1429
|
+
|
1430
|
+
return this;
|
1431
|
+
};
|
1432
|
+
|
1433
|
+
/*****************************************************************************
|
1434
|
+
** Exports
|
1435
|
+
**/
|
1436
|
+
|
1437
|
+
exports.Session = Session;
|
1438
|
+
|
1439
|
+
exports.createSession = function (target, community, options) {
|
1440
|
+
return new Session (target, community, options);
|
1441
|
+
};
|
1442
|
+
|
1443
|
+
exports.isVarbindError = isVarbindError;
|
1444
|
+
exports.varbindError = varbindError;
|
1445
|
+
|
1446
|
+
exports.Version1 = Version1;
|
1447
|
+
exports.Version2c = Version2c;
|
1448
|
+
|
1449
|
+
exports.ErrorStatus = ErrorStatus;
|
1450
|
+
exports.TrapType = TrapType;
|
1451
|
+
exports.ObjectType = ObjectType;
|
1452
|
+
|
1453
|
+
exports.ResponseInvalidError = ResponseInvalidError;
|
1454
|
+
exports.RequestInvalidError = RequestInvalidError;
|
1455
|
+
exports.RequestFailedError = RequestFailedError;
|
1456
|
+
exports.RequestTimedOutError = RequestTimedOutError;
|
1457
|
+
|
1458
|
+
/**
|
1459
|
+
** We've added this for testing.
|
1460
|
+
**/
|
1461
|
+
exports.ObjectParser = {
|
1462
|
+
readInt: readInt,
|
1463
|
+
readUint: readUint
|
1464
|
+
};
|