net-snmp 3.24.0 → 3.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -0
- package/eslint.config.js +2 -0
- package/example/agentx-subagent.js +44 -9
- package/index.js +280 -121
- package/package.json +1 -1
- package/test/subagent.test.js +2 -2
package/README.md
CHANGED
@@ -1947,6 +1947,8 @@ var myScalarProvider = {
|
|
1947
1947
|
// e.g. can update the MIB data before responding to the request here
|
1948
1948
|
mibRequest.done ();
|
1949
1949
|
}
|
1950
|
+
// Note: handler is optional for scalar providers - if omitted,
|
1951
|
+
// mibRequest.done() is called automatically
|
1950
1952
|
};
|
1951
1953
|
var mib = agent.getMib ();
|
1952
1954
|
mib.registerProvider (myScalarProvider);
|
@@ -2157,6 +2159,8 @@ objects`, below, for details.
|
|
2157
2159
|
* `handler` *(optional)* - an optional callback function, which is called before the request to the
|
2158
2160
|
MIB is made. This could update the MIB value(s) handled by this provider. If not given,
|
2159
2161
|
the values are simply returned from (or set in) the MIB without any other processing.
|
2162
|
+
If no `handler` is provided, the system automatically calls `mibRequest.done()` to complete
|
2163
|
+
the request, making both scalar and table providers fully functional without explicit handlers.
|
2160
2164
|
The callback function takes a `MibRequest` instance, which has a `done()` function. This
|
2161
2165
|
must be called when finished processing the request. To signal an error, give a single error object
|
2162
2166
|
in the form of `{errorStatus: <status>}`, where `<status>` is a value from ErrorStatus e.g.
|
@@ -2704,6 +2708,79 @@ to both register the provider on its internal `Mib` object, *and* send a Registe
|
|
2704
2708
|
agent for the provider's MIB region. The latter step is skipped if registering the provider directly
|
2705
2709
|
on the MIB object.
|
2706
2710
|
|
2711
|
+
## Simplified Provider Example
|
2712
|
+
|
2713
|
+
AgentX subagents provide automatic request handling for both scalar and table providers, making them simple to implement:
|
2714
|
+
|
2715
|
+
```js
|
2716
|
+
// Both scalars and tables work with automatic request handling (no explicit handlers needed)
|
2717
|
+
var stringProvider = {
|
2718
|
+
name: "scalarString",
|
2719
|
+
type: snmp.MibProviderType.Scalar,
|
2720
|
+
oid: "1.3.6.1.4.1.8072.9999.9999.1",
|
2721
|
+
scalarType: snmp.ObjectType.OctetString,
|
2722
|
+
maxAccess: snmp.MaxAccess["read-write"]
|
2723
|
+
// No handler required - automatic fallback will call mibRequest.done()
|
2724
|
+
};
|
2725
|
+
|
2726
|
+
var intProvider = {
|
2727
|
+
name: "scalarInt",
|
2728
|
+
type: snmp.MibProviderType.Scalar,
|
2729
|
+
oid: "1.3.6.1.4.1.8072.9999.9999.3",
|
2730
|
+
scalarType: snmp.ObjectType.Integer,
|
2731
|
+
maxAccess: snmp.MaxAccess["read-write"]
|
2732
|
+
// No handler required - automatic fallback will call mibRequest.done()
|
2733
|
+
};
|
2734
|
+
|
2735
|
+
// Table providers also work without explicit handlers
|
2736
|
+
var tableProvider = {
|
2737
|
+
name: "smallIfTable",
|
2738
|
+
type: snmp.MibProviderType.Table,
|
2739
|
+
oid: "1.3.6.1.4.1.8072.9999.9999.2",
|
2740
|
+
maxAccess: snmp.MaxAccess['not-accessible'],
|
2741
|
+
tableColumns: [
|
2742
|
+
{
|
2743
|
+
number: 1,
|
2744
|
+
name: "ifIndex",
|
2745
|
+
type: snmp.ObjectType.Integer,
|
2746
|
+
maxAccess: snmp.MaxAccess['read-only']
|
2747
|
+
},
|
2748
|
+
{
|
2749
|
+
number: 2,
|
2750
|
+
name: "ifDescr",
|
2751
|
+
type: snmp.ObjectType.OctetString,
|
2752
|
+
maxAccess: snmp.MaxAccess['read-write']
|
2753
|
+
}
|
2754
|
+
],
|
2755
|
+
tableIndex: [
|
2756
|
+
{
|
2757
|
+
columnName: "ifIndex"
|
2758
|
+
}
|
2759
|
+
]
|
2760
|
+
// No handler required - automatic fallback works for tables too!
|
2761
|
+
};
|
2762
|
+
|
2763
|
+
// Register providers and set values
|
2764
|
+
subagent.registerProvider(stringProvider, function(error, data) {
|
2765
|
+
if (!error) {
|
2766
|
+
subagent.getMib().setScalarValue("scalarString", "Hello World!");
|
2767
|
+
}
|
2768
|
+
});
|
2769
|
+
|
2770
|
+
subagent.registerProvider(intProvider, function(error, data) {
|
2771
|
+
if (!error) {
|
2772
|
+
subagent.getMib().setScalarValue("scalarInt", 42);
|
2773
|
+
}
|
2774
|
+
});
|
2775
|
+
|
2776
|
+
subagent.registerProvider(tableProvider, function(error, data) {
|
2777
|
+
if (!error) {
|
2778
|
+
subagent.getMib().addTableRow("smallIfTable", [1, "lo"]);
|
2779
|
+
subagent.getMib().addTableRow("smallIfTable", [2, "eth0"]);
|
2780
|
+
}
|
2781
|
+
});
|
2782
|
+
```
|
2783
|
+
|
2707
2784
|
## snmp.createSubagent (options)
|
2708
2785
|
|
2709
2786
|
The `createSubagent ()` function instantiates and returns an instance of the `Subagent`
|
@@ -2764,6 +2841,11 @@ subsequent `Response` PDU from the master to the `Register` PDU. This is not to
|
|
2764
2841
|
with the `handler` optional callback on the provider definition, which is invoked for any
|
2765
2842
|
"request processing" PDU received by the subagent for MIB objects in the registered MIB region.
|
2766
2843
|
|
2844
|
+
**Note for AgentX subagents**: Neither scalar nor table providers require explicit `handler` functions.
|
2845
|
+
If no `handler` is provided, the subagent automatically calls `mibRequest.done()` to complete the request,
|
2846
|
+
allowing both scalar and table values to be served directly from the MIB without additional processing.
|
2847
|
+
This greatly simplifies provider definitions - you only need to specify the structure and `maxAccess` properties.
|
2848
|
+
|
2767
2849
|
## subagent.unregisterProvider (name, callback)
|
2768
2850
|
|
2769
2851
|
Unregisters a previously registered MIB region by the supplied name of the provider. Sends
|
@@ -2814,6 +2896,48 @@ Sends a "ping" to the master agent using a `Ping` PDU, to confirm that the maste
|
|
2814
2896
|
responsive. The supplied `callback` is called on reception of the subsequent
|
2815
2897
|
`Response` PDU from the master to the `Ping` PDU.
|
2816
2898
|
|
2899
|
+
## subagent.setBulkSetHandler (callback)
|
2900
|
+
|
2901
|
+
Sets a bulk set handler for the subagent that will be called for both **TestSet** and **CommitSet**
|
2902
|
+
phases of SNMP SET operations. This provides atomic validation capabilities, allowing you to validate
|
2903
|
+
all varbinds as a complete set before committing any changes.
|
2904
|
+
|
2905
|
+
The handler callback function receives two arguments:
|
2906
|
+
* `testSet` - A boolean indicating the phase: `true` for TestSet phase, `false` for CommitSet phase
|
2907
|
+
* `varbinds` - An array of all varbinds in the SET request
|
2908
|
+
|
2909
|
+
During the TestSet phase (`testSet = true`), you should validate all the requested changes but not
|
2910
|
+
apply them. During the CommitSet phase (`testSet = false`), you should apply the previously validated changes.
|
2911
|
+
|
2912
|
+
Example usage:
|
2913
|
+
|
2914
|
+
```js
|
2915
|
+
subagent.setBulkSetHandler(function(testSet, varbinds) {
|
2916
|
+
if (testSet) {
|
2917
|
+
// TestSet phase - validate all varbinds atomically
|
2918
|
+
console.log("Validating SET operation with", varbinds.length, "varbinds");
|
2919
|
+
for (let varbind of varbinds) {
|
2920
|
+
// Perform validation logic here
|
2921
|
+
if (!isValidValue(varbind.oid, varbind.value)) {
|
2922
|
+
throw new Error("Invalid value for " + varbind.oid);
|
2923
|
+
}
|
2924
|
+
}
|
2925
|
+
console.log("All varbinds validated successfully");
|
2926
|
+
} else {
|
2927
|
+
// CommitSet phase - apply the changes
|
2928
|
+
console.log("Committing SET operation");
|
2929
|
+
for (let varbind of varbinds) {
|
2930
|
+
// Apply the validated changes here
|
2931
|
+
applyValue(varbind.oid, varbind.value);
|
2932
|
+
}
|
2933
|
+
console.log("All changes committed");
|
2934
|
+
}
|
2935
|
+
});
|
2936
|
+
```
|
2937
|
+
|
2938
|
+
This approach ensures atomic SET operations where either all varbinds in a request succeed or all fail,
|
2939
|
+
maintaining data consistency across your MIB implementation.
|
2940
|
+
|
2817
2941
|
## subagent.on ("close", callback)
|
2818
2942
|
|
2819
2943
|
The `close` event is emitted by the subagent when its underlying TCP socket is closed.
|
@@ -3569,6 +3693,10 @@ Example programs are included under the module's `example` directory.
|
|
3569
3693
|
|
3570
3694
|
* Improve USM error handling compliance with RFC 3414
|
3571
3695
|
|
3696
|
+
# Version 3.25.0 - 28/08/2025
|
3697
|
+
|
3698
|
+
* Add separate AgentX subagent TestSet and CommitSet phases
|
3699
|
+
|
3572
3700
|
# License
|
3573
3701
|
|
3574
3702
|
Copyright (c) 2020 Mark Abrahams <mark@abrahams.co.nz>
|
package/eslint.config.js
CHANGED
@@ -15,33 +15,39 @@ var stringProvider = {
|
|
15
15
|
name: "scalarString",
|
16
16
|
type: snmp.MibProviderType.Scalar,
|
17
17
|
oid: "1.3.6.1.4.1.8072.9999.9999.1",
|
18
|
-
scalarType: snmp.ObjectType.OctetString
|
18
|
+
scalarType: snmp.ObjectType.OctetString,
|
19
|
+
maxAccess: snmp.MaxAccess["read-write"]
|
19
20
|
};
|
20
21
|
var intProvider = {
|
21
22
|
name: "scalarInt",
|
22
23
|
type: snmp.MibProviderType.Scalar,
|
23
24
|
oid: "1.3.6.1.4.1.8072.9999.9999.3",
|
24
|
-
scalarType: snmp.ObjectType.Integer
|
25
|
+
scalarType: snmp.ObjectType.Integer,
|
26
|
+
maxAccess: snmp.MaxAccess["read-write"]
|
25
27
|
};
|
26
28
|
var tableProvider = {
|
27
29
|
name: "smallIfTable",
|
28
30
|
type: snmp.MibProviderType.Table,
|
29
31
|
oid: "1.3.6.1.4.1.8072.9999.9999.2",
|
32
|
+
maxAccess: snmp.MaxAccess['not-accessible'],
|
30
33
|
tableColumns: [
|
31
34
|
{
|
32
35
|
number: 1,
|
33
36
|
name: "ifIndex",
|
34
|
-
type: snmp.ObjectType.Integer
|
37
|
+
type: snmp.ObjectType.Integer,
|
38
|
+
maxAccess: snmp.MaxAccess['read-only']
|
35
39
|
},
|
36
40
|
{
|
37
41
|
number: 2,
|
38
42
|
name: "ifDescr",
|
39
|
-
type: snmp.ObjectType.OctetString
|
43
|
+
type: snmp.ObjectType.OctetString,
|
44
|
+
maxAccess: snmp.MaxAccess['read-write']
|
40
45
|
},
|
41
46
|
{
|
42
47
|
number: 3,
|
43
48
|
name: "ifType",
|
44
|
-
type: snmp.ObjectType.Integer
|
49
|
+
type: snmp.ObjectType.Integer,
|
50
|
+
maxAccess: snmp.MaxAccess['read-only']
|
45
51
|
}
|
46
52
|
],
|
47
53
|
tableIndex: [
|
@@ -49,10 +55,7 @@ var tableProvider = {
|
|
49
55
|
columnName: "ifIndex"
|
50
56
|
}
|
51
57
|
],
|
52
|
-
|
53
|
-
// e.g. can update the table before responding to the request here
|
54
|
-
mibRequest.done ();
|
55
|
-
}
|
58
|
+
|
56
59
|
};
|
57
60
|
|
58
61
|
agent.open(function (error, data) {
|
@@ -66,9 +69,41 @@ agent.open(function (error, data) {
|
|
66
69
|
agent.registerProvider (tableProvider, null);
|
67
70
|
agent.getMib ().addTableRow ("smallIfTable", [1, "lo", 24]);
|
68
71
|
agent.getMib ().addTableRow ("smallIfTable", [2, "eth0", 6]);
|
72
|
+
|
73
|
+
console.log("AgentX subagent ready and providers registered successfully.");
|
74
|
+
|
69
75
|
agent.on("close", function() {
|
70
76
|
console.log ("Subagent socket closed");
|
71
77
|
});
|
78
|
+
|
79
|
+
// Handle graceful shutdown on Ctrl-C
|
80
|
+
process.on('SIGINT', function() {
|
81
|
+
console.log('\nReceived SIGINT. Cleaning up...');
|
82
|
+
|
83
|
+
// Unregister all providers
|
84
|
+
try {
|
85
|
+
agent.unregisterProvider("scalarString", function(err, data) {
|
86
|
+
if (err) console.error("Error unregistering scalarString:", err);
|
87
|
+
});
|
88
|
+
agent.unregisterProvider("scalarInt", function(err, data) {
|
89
|
+
if (err) console.error("Error unregistering scalarInt:", err);
|
90
|
+
});
|
91
|
+
agent.unregisterProvider("smallIfTable", function(err, data) {
|
92
|
+
if (err) console.error("Error unregistering smallIfTable:", err);
|
93
|
+
});
|
94
|
+
} catch (e) {
|
95
|
+
console.error("Error during unregistration:", e.message);
|
96
|
+
}
|
97
|
+
|
98
|
+
// Close the agent after a brief delay to allow unregistrations to complete
|
99
|
+
setTimeout(function() {
|
100
|
+
agent.close(function(err) {
|
101
|
+
if (err) console.error("Error closing agent:", err);
|
102
|
+
console.log("Agent closed gracefully");
|
103
|
+
process.exit(0);
|
104
|
+
});
|
105
|
+
}, 100);
|
106
|
+
});
|
72
107
|
}
|
73
108
|
});
|
74
109
|
|
package/index.js
CHANGED
@@ -213,6 +213,8 @@ var AgentXPduType = {
|
|
213
213
|
17: "RemoveAgentCaps",
|
214
214
|
18: "Response"
|
215
215
|
};
|
216
|
+
const agentXPduTypesRequiringReadAccess = [ 5, 6, 7];
|
217
|
+
const agentXPduTypesRequiringWriteAccess = [ 8, 9, 10, 11, 14, 15, 16, 17 ];
|
216
218
|
|
217
219
|
_expandConstantObject (AgentXPduType);
|
218
220
|
|
@@ -3983,17 +3985,9 @@ MibNode.prototype.getConstraintsFromProvider = function () {
|
|
3983
3985
|
}
|
3984
3986
|
};
|
3985
3987
|
|
3986
|
-
MibNode.prototype.
|
3988
|
+
MibNode.prototype.validateValue = function (typeFromSet, valueFromSet) {
|
3987
3989
|
const constraints = this.getConstraintsFromProvider ();
|
3988
|
-
|
3989
|
-
const castValue = ObjectTypeUtil.castSetValue (typeFromSet, valueFromSet, constraints);
|
3990
|
-
this.value = castValue;
|
3991
|
-
return true;
|
3992
|
-
} catch (error) {
|
3993
|
-
console.error ("Error setting value: " + error.message);
|
3994
|
-
return false;
|
3995
|
-
}
|
3996
|
-
|
3990
|
+
return ObjectTypeUtil.isValid (typeFromSet, valueFromSet, constraints);
|
3997
3991
|
};
|
3998
3992
|
|
3999
3993
|
MibNode.prototype.getInstanceNodeForTableRow = function () {
|
@@ -5253,11 +5247,12 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5253
5247
|
var varbindsLength = requestPdu.varbinds.length;
|
5254
5248
|
var responsePdu = requestPdu.getResponsePduForRequest ();
|
5255
5249
|
var mibRequests = [];
|
5256
|
-
var handlers = [];
|
5257
5250
|
var createResult = [];
|
5258
5251
|
var oldValues = [];
|
5259
5252
|
var securityName = requestMessage.version == Version3 ? requestMessage.user.name : requestMessage.community;
|
5260
5253
|
|
5254
|
+
const isSetRequest = requestPdu.type === PduType.SetRequest;
|
5255
|
+
|
5261
5256
|
for ( let i = 0; i < requestPdu.varbinds.length; i++ ) {
|
5262
5257
|
let instanceNode = this.mib.lookup (requestPdu.varbinds[i].oid);
|
5263
5258
|
let providerNode;
|
@@ -5287,7 +5282,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5287
5282
|
});
|
5288
5283
|
const ancestorProvider = this.mib.getAncestorProviderFromOid(requestPdu.varbinds[i].oid);
|
5289
5284
|
if ( ancestorProvider ) {
|
5290
|
-
|
5285
|
+
mibRequests[i].handler = function getNsiHandler (mibRequestForNsi) {
|
5291
5286
|
mibRequestForNsi.done ({
|
5292
5287
|
errorStatus: ErrorStatus.NoError,
|
5293
5288
|
type: ObjectType.NoSuchInstance,
|
@@ -5295,7 +5290,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5295
5290
|
});
|
5296
5291
|
};
|
5297
5292
|
} else {
|
5298
|
-
|
5293
|
+
mibRequests[i].handler = function getNsoHandler (mibRequestForNso) {
|
5299
5294
|
mibRequestForNso.done ({
|
5300
5295
|
errorStatus: ErrorStatus.NoError,
|
5301
5296
|
type: ObjectType.NoSuchObject,
|
@@ -5310,7 +5305,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5310
5305
|
operation: requestPdu.type,
|
5311
5306
|
oid: requestPdu.varbinds[i].oid
|
5312
5307
|
});
|
5313
|
-
|
5308
|
+
mibRequests[i].handler = function getNsiHandler (mibRequestForNsi) {
|
5314
5309
|
mibRequestForNsi.done ({
|
5315
5310
|
errorStatus: ErrorStatus.NoError,
|
5316
5311
|
type: ObjectType.NoSuchInstance,
|
@@ -5323,7 +5318,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5323
5318
|
operation: requestPdu.type,
|
5324
5319
|
oid: requestPdu.varbinds[i].oid
|
5325
5320
|
});
|
5326
|
-
|
5321
|
+
mibRequests[i].handler = function getRanaHandler (mibRequestForRana) {
|
5327
5322
|
mibRequestForRana.done ({
|
5328
5323
|
errorStatus: ErrorStatus.NoAccess,
|
5329
5324
|
type: ObjectType.Null,
|
@@ -5337,14 +5332,14 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5337
5332
|
operation: requestPdu.type,
|
5338
5333
|
oid: requestPdu.varbinds[i].oid
|
5339
5334
|
});
|
5340
|
-
|
5335
|
+
mibRequests[i].handler = function getAccessDeniedHandler (mibRequestForAccessDenied) {
|
5341
5336
|
mibRequestForAccessDenied.done ({
|
5342
5337
|
errorStatus: ErrorStatus.NoAccess,
|
5343
5338
|
type: ObjectType.Null,
|
5344
5339
|
value: null
|
5345
5340
|
});
|
5346
5341
|
};
|
5347
|
-
} else if (
|
5342
|
+
} else if ( isSetRequest &&
|
5348
5343
|
providerNode.provider.type == MibProviderType.Table &&
|
5349
5344
|
typeof (rowStatusColumn = providerNode.provider.tableColumns.reduce(
|
5350
5345
|
(acc, current) => current.rowStatus ? current.number : acc, null )) == "number" &&
|
@@ -5380,7 +5375,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5380
5375
|
operation: requestPdu.type,
|
5381
5376
|
oid: requestPdu.varbinds[i].oid
|
5382
5377
|
});
|
5383
|
-
|
5378
|
+
mibRequests[i].handler = getIcsHandler;
|
5384
5379
|
}
|
5385
5380
|
break;
|
5386
5381
|
|
@@ -5394,7 +5389,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5394
5389
|
operation: requestPdu.type,
|
5395
5390
|
oid: requestPdu.varbinds[i].oid
|
5396
5391
|
});
|
5397
|
-
|
5392
|
+
mibRequests[i].handler = getIcsHandler;
|
5398
5393
|
}
|
5399
5394
|
break;
|
5400
5395
|
|
@@ -5415,16 +5410,16 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5415
5410
|
operation: requestPdu.type,
|
5416
5411
|
oid: requestPdu.varbinds[i].oid
|
5417
5412
|
});
|
5418
|
-
|
5413
|
+
mibRequests[i].handler = getIcsHandler;
|
5419
5414
|
break;
|
5420
5415
|
}
|
5421
5416
|
}
|
5422
5417
|
|
5423
|
-
if (
|
5418
|
+
if ( isSetRequest && ! createResult[i] ) {
|
5424
5419
|
oldValues[i] = instanceNode.value;
|
5425
5420
|
}
|
5426
5421
|
|
5427
|
-
if ( !
|
5422
|
+
if ( ! mibRequests[i] ) {
|
5428
5423
|
mibRequests[i] = new MibRequest ({
|
5429
5424
|
operation: requestPdu.type,
|
5430
5425
|
providerNode: providerNode,
|
@@ -5432,38 +5427,67 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5432
5427
|
oid: requestPdu.varbinds[i].oid
|
5433
5428
|
});
|
5434
5429
|
|
5435
|
-
|
5436
|
-
|
5437
|
-
|
5430
|
+
mibRequests[i].handler = providerNode.provider.handler;
|
5431
|
+
|
5432
|
+
if ( isSetRequest ) {
|
5433
|
+
mibRequests[i].setType = instanceNode.valueType;
|
5434
|
+
mibRequests[i].setValue = requestPdu.varbinds[i].requestValue ?? requestPdu.varbinds[i].value;
|
5435
|
+
try {
|
5436
|
+
mibRequests[i].setValue =
|
5437
|
+
ObjectTypeUtil.castSetValue (mibRequests[i].setType, mibRequests[i].setValue);
|
5438
|
+
|
5439
|
+
if ( ! mibRequests[i].instanceNode.validateValue (mibRequests[i].setType, mibRequests[i].setValue) ) {
|
5440
|
+
mibRequests[i].handler = function badValueHandler (request) {
|
5441
|
+
request.done ({
|
5442
|
+
errorStatus: ErrorStatus.BadValue,
|
5443
|
+
type: ObjectType.Null,
|
5444
|
+
value: null,
|
5445
|
+
});
|
5446
|
+
};
|
5447
|
+
}
|
5448
|
+
} catch (e) {
|
5449
|
+
debug('Invalid value for type', e, mibRequests[i]);
|
5450
|
+
mibRequests[i].handler = function wrongTypeHandler (request) {
|
5451
|
+
request.done ({
|
5452
|
+
errorStatus: ErrorStatus.WrongType,
|
5453
|
+
type: ObjectType.Null,
|
5454
|
+
value: null,
|
5455
|
+
});
|
5456
|
+
};
|
5457
|
+
}
|
5438
5458
|
}
|
5439
|
-
handlers[i] = providerNode.provider.handler;
|
5440
5459
|
}
|
5441
5460
|
}
|
5442
5461
|
|
5443
5462
|
(function (savedIndex) {
|
5444
|
-
|
5445
|
-
|
5463
|
+
const mibRequest = mibRequests[savedIndex];
|
5464
|
+
mibRequest.done = function (error) {
|
5465
|
+
mibRequest.error = error ?? { errorStatus: ErrorStatus.NoError };
|
5466
|
+
let responseVarbind;
|
5446
5467
|
let rowIndex = null;
|
5447
5468
|
let row = null;
|
5448
5469
|
let deleted = false;
|
5449
5470
|
let column = -1;
|
5450
5471
|
responseVarbind = {
|
5451
|
-
oid:
|
5472
|
+
oid: mibRequest.oid
|
5452
5473
|
};
|
5453
5474
|
if ( error ) {
|
5454
|
-
if ( (typeof responsePdu.errorStatus == "undefined" || responsePdu.errorStatus == ErrorStatus.NoError) &&
|
5475
|
+
if ( (typeof responsePdu.errorStatus == "undefined" || responsePdu.errorStatus == ErrorStatus.NoError) &&
|
5476
|
+
error.errorStatus != ErrorStatus.NoError ) {
|
5455
5477
|
responsePdu.errorStatus = error.errorStatus;
|
5456
5478
|
responsePdu.errorIndex = savedIndex + 1;
|
5457
5479
|
}
|
5458
5480
|
responseVarbind.type = error.type || ObjectType.Null;
|
5459
|
-
responseVarbind.value = error.value
|
5481
|
+
responseVarbind.value = error.value ?? null;
|
5460
5482
|
//responseVarbind.errorStatus: error.errorStatus
|
5461
5483
|
if ( error.errorStatus != ErrorStatus.NoError ) {
|
5462
5484
|
responseVarbind.errorStatus = error.errorStatus;
|
5463
5485
|
}
|
5464
5486
|
} else {
|
5465
|
-
|
5466
|
-
|
5487
|
+
const instanceNode = mibRequest.instanceNode;
|
5488
|
+
const providerNode = mibRequest.providerNode;
|
5489
|
+
const provider = providerNode ? providerNode.provider : null;
|
5490
|
+
const providerName = provider ? provider.name : null;
|
5467
5491
|
let subOid;
|
5468
5492
|
let subAddr;
|
5469
5493
|
if ( providerNode && providerNode.provider && providerNode.provider.type == MibProviderType.Table ) {
|
@@ -5474,7 +5498,7 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5474
5498
|
rowIndex = Mib.getRowIndexFromOid( subAddr.join("."), provider.tableIndex );
|
5475
5499
|
row = me.mib.getTableRowCells ( providerName, rowIndex );
|
5476
5500
|
}
|
5477
|
-
if (
|
5501
|
+
if ( isSetRequest && mibRequest.commitSet ) {
|
5478
5502
|
// Is this a RowStatus column with a value of 6 (delete)?
|
5479
5503
|
let rowStatusColumn = provider.type == MibProviderType.Table
|
5480
5504
|
? provider.tableColumns.reduce( (acc, current) => current.rowStatus ? current.number : acc, null )
|
@@ -5498,26 +5522,16 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5498
5522
|
|
5499
5523
|
} else {
|
5500
5524
|
// No special handling required. Just save the new value.
|
5501
|
-
|
5502
|
-
requestPdu.varbinds[savedIndex].type,
|
5503
|
-
requestPdu.varbinds[savedIndex].value
|
5504
|
-
);
|
5505
|
-
if ( ! setResult ) {
|
5506
|
-
if ( typeof responsePdu.errorStatus == "undefined" || responsePdu.errorStatus == ErrorStatus.NoError ) {
|
5507
|
-
responsePdu.errorStatus = ErrorStatus.WrongValue;
|
5508
|
-
responsePdu.errorIndex = savedIndex + 1;
|
5509
|
-
}
|
5510
|
-
responseVarbind.errorStatus = ErrorStatus.WrongValue;
|
5511
|
-
}
|
5525
|
+
mibRequest.instanceNode.value = mibRequest.setValue;
|
5512
5526
|
}
|
5513
5527
|
}
|
5514
5528
|
if ( ( requestPdu.type == PduType.GetNextRequest || requestPdu.type == PduType.GetBulkRequest ) &&
|
5515
5529
|
requestPdu.varbinds[savedIndex].type == ObjectType.EndOfMibView ) {
|
5516
5530
|
responseVarbind.type = ObjectType.EndOfMibView;
|
5517
5531
|
} else {
|
5518
|
-
responseVarbind.type =
|
5532
|
+
responseVarbind.type = mibRequest.instanceNode.valueType;
|
5519
5533
|
}
|
5520
|
-
responseVarbind.value =
|
5534
|
+
responseVarbind.value = mibRequest.instanceNode.value;
|
5521
5535
|
if ( responseVarbind.value === undefined || responseVarbind.value === null ) {
|
5522
5536
|
responseVarbind.type = ObjectType.NoSuchInstance;
|
5523
5537
|
}
|
@@ -5528,16 +5542,19 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5528
5542
|
if ( requestPdu.type == PduType.GetNextRequest || requestPdu.type == PduType.GetNextRequest ) {
|
5529
5543
|
responseVarbind.previousOid = requestPdu.varbinds[savedIndex].previousOid;
|
5530
5544
|
}
|
5531
|
-
|
5545
|
+
const isTestSet = mibRequest.testSet;
|
5546
|
+
if ( isSetRequest ) {
|
5547
|
+
if ( mibRequest.testSet ) {
|
5548
|
+
delete mibRequest.testSet;
|
5549
|
+
mibRequest.commitSet = true;
|
5550
|
+
if ( mibRequest.error.errorStatus === ErrorStatus.NoError )
|
5551
|
+
delete mibRequest.error;
|
5552
|
+
}
|
5532
5553
|
if ( oldValues[savedIndex] !== undefined ) {
|
5533
5554
|
responseVarbind.oldValue = oldValues[savedIndex];
|
5534
5555
|
}
|
5535
|
-
responseVarbind.requestType =
|
5536
|
-
|
5537
|
-
responseVarbind.requestValue = ObjectTypeUtil.castSetValue (requestPdu.varbinds[savedIndex].type, requestPdu.varbinds[savedIndex].requestValue);
|
5538
|
-
} else {
|
5539
|
-
responseVarbind.requestValue = ObjectTypeUtil.castSetValue (requestPdu.varbinds[savedIndex].type, requestPdu.varbinds[savedIndex].value);
|
5540
|
-
}
|
5556
|
+
responseVarbind.requestType = mibRequests[savedIndex].setType;
|
5557
|
+
responseVarbind.requestValue = mibRequests[savedIndex].setValue;
|
5541
5558
|
}
|
5542
5559
|
if ( createResult[savedIndex] ) {
|
5543
5560
|
responseVarbind.autoCreated = true;
|
@@ -5555,16 +5572,56 @@ Agent.prototype.request = function (socket, requestMessage, rinfo) {
|
|
5555
5572
|
}
|
5556
5573
|
me.setSingleVarbind (responsePdu, savedIndex, responseVarbind);
|
5557
5574
|
if ( ++varbindsCompleted == varbindsLength) {
|
5575
|
+
// If all varbind have been tested, apply
|
5576
|
+
// the handlers again in commit mode.
|
5577
|
+
if (isTestSet && !responsePdu.errorIndex) {
|
5578
|
+
varbindsCompleted = 0;
|
5579
|
+
setImmediate(() => applySetHandlers(/*testSet=*/false));
|
5580
|
+
return;
|
5581
|
+
}
|
5558
5582
|
me.sendResponse.call (me, socket, rinfo, requestMessage, responsePdu);
|
5559
5583
|
}
|
5560
5584
|
};
|
5585
|
+
if ( isSetRequest )
|
5586
|
+
mibRequest.testSet = true;
|
5561
5587
|
})(i);
|
5562
|
-
if ( handlers[i] ) {
|
5563
|
-
handlers[i] (mibRequests[i]);
|
5564
|
-
} else {
|
5565
|
-
mibRequests[i].done ();
|
5566
|
-
}
|
5567
5588
|
}
|
5589
|
+
const applyHandlers = testSet => {
|
5590
|
+
for ( const mibRequest of mibRequests ) {
|
5591
|
+
if ( mibRequest.error === undefined && testSet === !!mibRequest.testSet ) {
|
5592
|
+
if ( mibRequest.handler ) {
|
5593
|
+
mibRequest.handler (mibRequest);
|
5594
|
+
} else {
|
5595
|
+
mibRequest.done ();
|
5596
|
+
}
|
5597
|
+
}
|
5598
|
+
}
|
5599
|
+
};
|
5600
|
+
const applySetHandlers = testSet => {
|
5601
|
+
if ( this.bulkSetHandler ) {
|
5602
|
+
const errorStatus = this.bulkSetHandler( mibRequests, this.mib, testSet ) ?? ErrorStatus.NoError;
|
5603
|
+
if ( errorStatus !== ErrorStatus.NoError ) {
|
5604
|
+
for ( const mibRequest of mibRequests ) {
|
5605
|
+
if ( mibRequest.error === undefined ) {
|
5606
|
+
mibRequest.done ({
|
5607
|
+
errorStatus,
|
5608
|
+
type: ObjectType.Null,
|
5609
|
+
value: null
|
5610
|
+
});
|
5611
|
+
}
|
5612
|
+
}
|
5613
|
+
}
|
5614
|
+
}
|
5615
|
+
applyHandlers(testSet);
|
5616
|
+
};
|
5617
|
+
if ( isSetRequest )
|
5618
|
+
applySetHandlers(/*testSet=*/true);
|
5619
|
+
else
|
5620
|
+
applyHandlers(false);
|
5621
|
+
};
|
5622
|
+
|
5623
|
+
Agent.prototype.setBulkSetHandler = function setBulkSetHandler(cb) {
|
5624
|
+
this.bulkSetHandler = cb;
|
5568
5625
|
};
|
5569
5626
|
|
5570
5627
|
Agent.prototype.getRequest = function (socket, requestMessage, rinfo) {
|
@@ -5915,6 +5972,13 @@ AgentXPdu.createFromVariables = function (vars) {
|
|
5915
5972
|
pdu.index = vars.index || 0;
|
5916
5973
|
pdu.varbinds = vars.varbinds || null;
|
5917
5974
|
break;
|
5975
|
+
case AgentXPduType.TestSet:
|
5976
|
+
pdu.varbinds = vars.varbinds || null;
|
5977
|
+
break;
|
5978
|
+
case AgentXPduType.CommitSet:
|
5979
|
+
case AgentXPduType.UndoSet:
|
5980
|
+
case AgentXPduType.CleanupSet:
|
5981
|
+
break;
|
5918
5982
|
default:
|
5919
5983
|
// unsupported PDU type - should never happen as we control these
|
5920
5984
|
throw new RequestInvalidError ("Unknown PDU type '" + pdu.pduType
|
@@ -6339,35 +6403,39 @@ Subagent.prototype.onMsg = function (buffer, rinfo) {
|
|
6339
6403
|
debug ("Received AgentX " + AgentXPduType[pdu.pduType] + " PDU");
|
6340
6404
|
debug (pdu);
|
6341
6405
|
|
6342
|
-
|
6343
|
-
|
6344
|
-
|
6345
|
-
|
6346
|
-
|
6347
|
-
|
6348
|
-
|
6349
|
-
|
6350
|
-
|
6351
|
-
|
6352
|
-
|
6353
|
-
|
6354
|
-
|
6355
|
-
|
6356
|
-
|
6357
|
-
|
6358
|
-
|
6359
|
-
|
6360
|
-
|
6361
|
-
|
6362
|
-
|
6363
|
-
|
6364
|
-
|
6365
|
-
|
6366
|
-
|
6367
|
-
|
6368
|
-
|
6369
|
-
|
6370
|
-
|
6406
|
+
try {
|
6407
|
+
switch (pdu.pduType) {
|
6408
|
+
case AgentXPduType.Response:
|
6409
|
+
this.response (pdu);
|
6410
|
+
break;
|
6411
|
+
case AgentXPduType.Get:
|
6412
|
+
this.getRequest (pdu);
|
6413
|
+
break;
|
6414
|
+
case AgentXPduType.GetNext:
|
6415
|
+
this.getNextRequest (pdu);
|
6416
|
+
break;
|
6417
|
+
case AgentXPduType.GetBulk:
|
6418
|
+
this.getBulkRequest (pdu);
|
6419
|
+
break;
|
6420
|
+
case AgentXPduType.TestSet:
|
6421
|
+
this.testSet (pdu);
|
6422
|
+
break;
|
6423
|
+
case AgentXPduType.CommitSet:
|
6424
|
+
this.commitSet (pdu);
|
6425
|
+
break;
|
6426
|
+
case AgentXPduType.UndoSet:
|
6427
|
+
this.undoSet (pdu);
|
6428
|
+
break;
|
6429
|
+
case AgentXPduType.CleanupSet:
|
6430
|
+
this.cleanupSet (pdu);
|
6431
|
+
break;
|
6432
|
+
default:
|
6433
|
+
// Unknown PDU type - shouldn't happen as master agents shouldn't send administrative PDUs
|
6434
|
+
throw new RequestInvalidError ("Unknown PDU type '" + pdu.pduType
|
6435
|
+
+ "' in request");
|
6436
|
+
}
|
6437
|
+
} catch (e) {
|
6438
|
+
console.error(e);
|
6371
6439
|
}
|
6372
6440
|
};
|
6373
6441
|
|
@@ -6406,82 +6474,141 @@ Subagent.prototype.response = function (pdu) {
|
|
6406
6474
|
}
|
6407
6475
|
};
|
6408
6476
|
|
6477
|
+
Subagent.prototype.isAllowed = function (pduType, provider, instanceNode) {
|
6478
|
+
const requestedAccess =
|
6479
|
+
agentXPduTypesRequiringReadAccess.includes(pduType)? MaxAccess["read-only"] :
|
6480
|
+
agentXPduTypesRequiringWriteAccess.includes(pduType)? MaxAccess["read-write"] :
|
6481
|
+
undefined;
|
6482
|
+
|
6483
|
+
if (requestedAccess === undefined)
|
6484
|
+
return true;
|
6485
|
+
|
6486
|
+
if (provider.type === MibProviderType.Scalar)
|
6487
|
+
return provider.maxAccess >= requestedAccess;
|
6488
|
+
|
6489
|
+
// It's a table column. Use that column's maxAccess.
|
6490
|
+
const column = instanceNode.getTableColumnFromInstanceNode();
|
6491
|
+
|
6492
|
+
// In the typical case, we could use (column - 1) to index
|
6493
|
+
// into tableColumns to get to the correct entry. There is no
|
6494
|
+
// guarantee, however, that column numbers in the OID are
|
6495
|
+
// necessarily consecutive; theoretically some could be
|
6496
|
+
// missing. We'll therefore play it safe and search for the
|
6497
|
+
// specified column entry.
|
6498
|
+
|
6499
|
+
const columnEntry = provider.tableColumns.find(entry => entry.number === column);
|
6500
|
+
const maxAccess = columnEntry ? columnEntry.maxAccess || MaxAccess['not-accessible'] : MaxAccess['not-accessible'];
|
6501
|
+
return maxAccess >= requestedAccess;
|
6502
|
+
};
|
6503
|
+
|
6504
|
+
|
6409
6505
|
Subagent.prototype.request = function (pdu, requestVarbinds) {
|
6410
6506
|
const me = this;
|
6411
6507
|
const varbindsLength = requestVarbinds.length;
|
6412
6508
|
const responseVarbinds = [];
|
6413
6509
|
const responsePdu = pdu.getResponsePduForRequest ();
|
6510
|
+
const mibRequests = [];
|
6414
6511
|
let varbindsCompleted = 0;
|
6512
|
+
let firstVarbindError;
|
6513
|
+
const isTestSet = pdu.pduType == AgentXPduType.TestSet;
|
6514
|
+
const isSetRequest = isTestSet ||
|
6515
|
+
pdu.pduType == AgentXPduType.CommitSet ||
|
6516
|
+
pdu.pduType == AgentXPduType.UndoSet;
|
6415
6517
|
|
6416
6518
|
for ( let i = 0; i < varbindsLength; i++ ) {
|
6417
6519
|
const requestVarbind = requestVarbinds[i];
|
6418
|
-
|
6419
|
-
|
6420
|
-
|
6421
|
-
var handler;
|
6422
|
-
var responseVarbindType;
|
6520
|
+
const instanceNode = this.mib.lookup (requestVarbind.oid);
|
6521
|
+
let providerNode;
|
6522
|
+
let responseVarbindType;
|
6423
6523
|
|
6424
6524
|
if ( ! instanceNode ) {
|
6425
|
-
|
6525
|
+
mibRequests[i] = new MibRequest ({
|
6426
6526
|
operation: pdu.pduType,
|
6427
6527
|
oid: requestVarbind.oid
|
6428
6528
|
});
|
6429
|
-
|
6430
|
-
mibRequestForNso.done ({
|
6529
|
+
mibRequests[i].error = {
|
6431
6530
|
errorStatus: ErrorStatus.NoError,
|
6432
6531
|
errorIndex: 0,
|
6433
6532
|
type: ObjectType.NoSuchObject,
|
6434
6533
|
value: null
|
6435
|
-
});
|
6436
6534
|
};
|
6437
6535
|
} else {
|
6438
6536
|
providerNode = this.mib.getProviderNodeForInstance (instanceNode);
|
6439
6537
|
if ( ! providerNode ) {
|
6440
|
-
|
6538
|
+
mibRequests[i] = new MibRequest ({
|
6441
6539
|
operation: pdu.pduType,
|
6442
6540
|
oid: requestVarbind.oid
|
6443
6541
|
});
|
6444
|
-
|
6445
|
-
mibRequestForNsi.done ({
|
6542
|
+
mibRequests[i].error = {
|
6446
6543
|
errorStatus: ErrorStatus.NoError,
|
6447
6544
|
errorIndex: 0,
|
6448
6545
|
type: ObjectType.NoSuchInstance,
|
6449
6546
|
value: null
|
6450
|
-
});
|
6451
6547
|
};
|
6452
6548
|
} else {
|
6453
|
-
|
6549
|
+
mibRequests[i] = new MibRequest ({
|
6454
6550
|
operation: pdu.pduType,
|
6455
6551
|
providerNode: providerNode,
|
6456
6552
|
instanceNode: instanceNode,
|
6457
|
-
oid: requestVarbind.oid
|
6553
|
+
oid: requestVarbind.oid,
|
6458
6554
|
});
|
6459
|
-
|
6460
|
-
|
6461
|
-
|
6555
|
+
mibRequests[i].handler = providerNode.provider.handler;
|
6556
|
+
if ( ! me.isAllowed(pdu.pduType, mibRequests[i].providerNode?.provider, mibRequests[i].instanceNode) ) {
|
6557
|
+
mibRequests[i].error = {
|
6558
|
+
errorStatus: ErrorStatus.NoAccess,
|
6559
|
+
errorIndex: i + 1,
|
6560
|
+
type: ObjectType.Null,
|
6561
|
+
value: null
|
6562
|
+
};
|
6563
|
+
}
|
6564
|
+
if ( isSetRequest ) {
|
6565
|
+
mibRequests[i].setType = instanceNode.valueType;
|
6566
|
+
mibRequests[i].setValue = requestVarbind.requestValue ?? requestVarbind.value;
|
6567
|
+
mibRequests[i].requestIndex = i + 1;
|
6568
|
+
try {
|
6569
|
+
mibRequests[i].setValue =
|
6570
|
+
ObjectTypeUtil.castSetValue (mibRequests[i].setType, mibRequests[i].setValue);
|
6571
|
+
|
6572
|
+
if ( ! mibRequests[i].instanceNode.validateValue (mibRequests[i].setType, mibRequests[i].setValue) ) {
|
6573
|
+
mibRequests[i].error = {
|
6574
|
+
errorStatus: ErrorStatus.BadValue,
|
6575
|
+
errorIndex: i + 1,
|
6576
|
+
type: mibRequests[i].setType,
|
6577
|
+
value: mibRequests[i].setValue,
|
6578
|
+
};
|
6579
|
+
}
|
6580
|
+
} catch (e) {
|
6581
|
+
debug('Invalid value for type', e, mibRequests[i]);
|
6582
|
+
mibRequests[i].error = {
|
6583
|
+
errorStatus: ErrorStatus.WrongType,
|
6584
|
+
errorIndex: i + 1,
|
6585
|
+
type: mibRequests[i].setType,
|
6586
|
+
value: mibRequests[i].setValue,
|
6587
|
+
};
|
6588
|
+
}
|
6462
6589
|
}
|
6463
|
-
handler = providerNode.provider.handler;
|
6464
6590
|
}
|
6465
6591
|
}
|
6466
6592
|
|
6467
6593
|
(function (savedIndex) {
|
6594
|
+
const mibRequest = mibRequests[savedIndex];
|
6595
|
+
const requestVarbind = requestVarbinds[savedIndex];
|
6468
6596
|
mibRequest.done = function (error) {
|
6597
|
+
mibRequest.error = error ?? { errorStatus: ErrorStatus.NoError };
|
6469
6598
|
let responseVarbind;
|
6470
6599
|
if ( error ) {
|
6471
6600
|
responseVarbind = {
|
6472
6601
|
oid: mibRequest.oid,
|
6473
6602
|
type: error.type || ObjectType.Null,
|
6474
|
-
value: error.value
|
6603
|
+
value: error.value ?? null
|
6475
6604
|
};
|
6476
|
-
|
6477
|
-
|
6478
|
-
responsePdu.index = savedIndex + 1;
|
6479
|
-
}
|
6605
|
+
error.errorIndex = savedIndex + 1;
|
6606
|
+
firstVarbindError = firstVarbindError ?? error;
|
6480
6607
|
if ( error.errorStatus != ErrorStatus.NoError ) {
|
6481
6608
|
responseVarbind.errorStatus = error.errorStatus;
|
6482
6609
|
}
|
6483
6610
|
} else {
|
6484
|
-
if (
|
6611
|
+
if ( isTestSet ) {
|
6485
6612
|
// more tests?
|
6486
6613
|
} else if ( pdu.pduType == AgentXPduType.CommitSet ) {
|
6487
6614
|
me.setTransactions[pdu.transactionID].originalValue = mibRequest.instanceNode.value;
|
@@ -6501,23 +6628,54 @@ Subagent.prototype.request = function (pdu, requestVarbinds) {
|
|
6501
6628
|
value: mibRequest.instanceNode.value
|
6502
6629
|
};
|
6503
6630
|
}
|
6504
|
-
responseVarbinds[savedIndex] = responseVarbind;
|
6505
|
-
if ( ++varbindsCompleted == varbindsLength) {
|
6506
|
-
if (
|
6507
|
-
|
6631
|
+
responseVarbinds[savedIndex] = mibRequest.response = responseVarbind;
|
6632
|
+
if ( ++varbindsCompleted == varbindsLength ) {
|
6633
|
+
if ( isSetRequest ) {
|
6634
|
+
responsePdu.error = firstVarbindError?.errorStatus ?? 0;
|
6635
|
+
responsePdu.index = firstVarbindError?.errorIndex ?? 0;
|
6508
6636
|
me.sendResponse.call (me, responsePdu);
|
6509
6637
|
} else {
|
6510
6638
|
me.sendResponse.call (me, responsePdu, responseVarbinds);
|
6511
6639
|
}
|
6512
6640
|
}
|
6513
6641
|
};
|
6642
|
+
if ( isTestSet )
|
6643
|
+
mibRequests[i].testSet = true;
|
6644
|
+
else if ( pdu.pduType == AgentXPduType.CommitSet )
|
6645
|
+
mibRequests[i].commitSet = true;
|
6646
|
+
if ( mibRequest.error )
|
6647
|
+
mibRequest.done(mibRequest.error);
|
6514
6648
|
})(i);
|
6515
|
-
|
6516
|
-
|
6517
|
-
|
6518
|
-
|
6649
|
+
}
|
6650
|
+
if ( isSetRequest && this.bulkSetHandler ) {
|
6651
|
+
const errorStatus = this.bulkSetHandler( mibRequests, this.mib, isTestSet ) ?? ErrorStatus.NoError;
|
6652
|
+
if ( errorStatus !== ErrorStatus.NoError ) {
|
6653
|
+
for ( const mibRequest of mibRequests ) {
|
6654
|
+
if ( !mibRequest.response ) {
|
6655
|
+
mibRequest.done ({
|
6656
|
+
errorStatus,
|
6657
|
+
type: ObjectType.Null,
|
6658
|
+
value: null
|
6659
|
+
});
|
6660
|
+
}
|
6661
|
+
}
|
6662
|
+
return;
|
6519
6663
|
}
|
6520
6664
|
}
|
6665
|
+
for ( let i = 0; i < requestVarbinds.length; i++ ) {
|
6666
|
+
if ( !mibRequests[i].response ) {
|
6667
|
+
const handler = mibRequests[i].handler;
|
6668
|
+
if ( handler ) {
|
6669
|
+
handler (mibRequests[i]);
|
6670
|
+
} else {
|
6671
|
+
mibRequests[i].done ();
|
6672
|
+
}
|
6673
|
+
}
|
6674
|
+
}
|
6675
|
+
};
|
6676
|
+
|
6677
|
+
Subagent.prototype.setBulkSetHandler = function setBulkSetHandler(cb) {
|
6678
|
+
this.bulkSetHandler = cb;
|
6521
6679
|
};
|
6522
6680
|
|
6523
6681
|
Subagent.prototype.addGetNextVarbind = function (targetVarbinds, startOid) {
|
@@ -6680,6 +6838,7 @@ exports.ErrorStatus = ErrorStatus;
|
|
6680
6838
|
exports.TrapType = TrapType;
|
6681
6839
|
exports.ObjectType = ObjectType;
|
6682
6840
|
exports.PduType = PduType;
|
6841
|
+
exports.AgentXPdu = AgentXPdu;
|
6683
6842
|
exports.AgentXPduType = AgentXPduType;
|
6684
6843
|
exports.MibProviderType = MibProviderType;
|
6685
6844
|
exports.SecurityLevel = SecurityLevel;
|
package/package.json
CHANGED
package/test/subagent.test.js
CHANGED
@@ -357,7 +357,7 @@ describe('Subagent', function() {
|
|
357
357
|
subagent.getMib().setScalarValue('testScalar', 100);
|
358
358
|
});
|
359
359
|
|
360
|
-
|
360
|
+
it('manages set transactions correctly', function() {
|
361
361
|
// Create proper AgentXPdu objects using createFromVariables
|
362
362
|
const testSetPdu = snmp.AgentXPdu.createFromVariables({
|
363
363
|
pduType: snmp.AgentXPduType.TestSet,
|
@@ -383,7 +383,7 @@ describe('Subagent', function() {
|
|
383
383
|
assert(!subagent.setTransactions[123]);
|
384
384
|
});
|
385
385
|
|
386
|
-
|
386
|
+
it('handles unexpected transaction IDs', function() {
|
387
387
|
const commitSetPdu = snmp.AgentXPdu.createFromVariables({
|
388
388
|
pduType: snmp.AgentXPduType.CommitSet,
|
389
389
|
sessionID: subagent.sessionID,
|