net-snmp 3.21.2 → 3.23.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.cn.md CHANGED
@@ -100,6 +100,7 @@ var session = snmp.createSession ("127.0.0.1", "public", options);
100
100
  * `version` - `snmp.Version1`或`snmp.Version2c`,默认为`snmp.Version1`。
101
101
  * "backwardsGetNexts"----允许进行GetNext操作的布尔值,以检索词法上在前的OIDs。
102
102
  * `idBitsSize` - `16`或`32`,默认为`32`。用来减少生成的id的大小,以便与一些旧设备兼容。
103
+ * `dgramModule` – 一个与 Node.js [`dgram`](https://nodejs.org/api/dgram.html) 模块接口兼容的模块。您可以通过提供自定义或包装的 `dgram` 实现来扩展或覆盖默认的 UDP 套接字行为。
103
104
 
104
105
  当一个会话结束后,应该关闭它。
105
106
 
package/README.md CHANGED
@@ -344,7 +344,7 @@ Actions
344
344
  - `4 - ECouldNotDecrypt`
345
345
  - `5 - EAuthFailure`
346
346
  - `6 - EReqResOidNoMatch`
347
- - `7 - (no longer used)
347
+ - `7 - (no longer used)`
348
348
  - `8 - EOutOfOrder`
349
349
  - `9 - EVersionNoMatch`
350
350
  - `10 - ECommunityNoMatch`
@@ -588,7 +588,8 @@ var options = {
588
588
  version: snmp.Version1,
589
589
  backwardsGetNexts: true,
590
590
  reportOidMismatchErrors: false,
591
- idBitsSize: 32
591
+ idBitsSize: 32,
592
+ dgramModule: dgram
592
593
  };
593
594
 
594
595
  var session = snmp.createSession ("127.0.0.1", "public", options);
@@ -620,6 +621,10 @@ is an object, and can contain the following items:
620
621
  requests and responses, defaults to `false`
621
622
  * `idBitsSize` - Either `16` or `32`, defaults to `32`. Used to reduce the size
622
623
  of the generated id for compatibility with some older devices.
624
+ * `dgramModule` – A module that is interface-compatible with the Node.js [`dgram`](https://nodejs.org/api/dgram.html) module.
625
+ This can be used to extend or override the default UDP socket behavior by supplying
626
+ a custom or wrapped implementation of `dgram`.
627
+
623
628
 
624
629
  When a session has been finished with it should be closed:
625
630
 
@@ -2493,6 +2498,27 @@ pre-loaded "base" modules is:
2493
2498
  * SNMPv2-TC
2494
2499
  * SNMPv2-MIB
2495
2500
 
2501
+ By default, the `createModuleStore()` function creates a new `ModuleStore` instance with all the base modules pre-loaded.
2502
+ However, you can now customize which base modules are loaded by passing an options object:
2503
+
2504
+ ```js
2505
+ // Example of selecting only SNMPv2 MIBs
2506
+ const store = snmp.createModuleStore({
2507
+ baseModules: [
2508
+ 'SNMPv2-SMI',
2509
+ 'SNMPv2-CONF',
2510
+ 'SNMPv2-TC',
2511
+ 'SNMPv2-MIB',
2512
+ ],
2513
+ });
2514
+ ```
2515
+
2516
+ The `options` object can contain:
2517
+
2518
+ * `baseModules` - An array of module names to use as the base modules. This allows you to explicitly control which MIBs are loaded, which can be useful to avoid unexpected type overrides that might occur with the full set of base modules.
2519
+
2520
+ This feature is helpful when dealing with constraints for SNMPv2-TC defined textual conventions like DisplayString that might get preempted by subsequent definitions as plain OCTET STRING in RFC MIBs.
2521
+
2496
2522
  ## store.loadFromFile (fileName)
2497
2523
 
2498
2524
  Loads all MIB modules in the given file into the module store. By convention, there is
@@ -3529,6 +3555,16 @@ Example programs are included under the module's `example` directory.
3529
3555
 
3530
3556
  * Add custom base module list
3531
3557
 
3558
+ # Version 3.22.0 - 27/04/2025
3559
+
3560
+ * Fix incorrect SNMPv3 engineID handling
3561
+
3562
+ * Add custom base module list
3563
+
3564
+ # Version 3.23.0 - 20/06/2025
3565
+
3566
+ * Add support for custom dgram module
3567
+
3532
3568
  # License
3533
3569
 
3534
3570
  Copyright (c) 2020 Mark Abrahams <mark@abrahams.co.nz>
package/index.js CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  // Copyright 2013 Stephen Vickers <stephen.vickers.sv@gmail.com>
3
2
 
4
3
  const ber = require ("asn1-ber").Ber;
@@ -2038,12 +2037,13 @@ var Session = function (target, authenticator, options) {
2038
2037
  DEBUG |= options.debug;
2039
2038
 
2040
2039
  this.engine = new Engine ({
2041
- engineId: options.engineID
2040
+ engineID: options.engineID
2042
2041
  });
2043
2042
  this.reqs = {};
2044
2043
  this.reqCount = 0;
2045
2044
 
2046
- this.dgram = dgram.createSocket (this.transport);
2045
+ const dgramMod = options.dgramModule || dgram;
2046
+ this.dgram = dgramMod.createSocket (this.transport);
2047
2047
  this.dgram.unref();
2048
2048
 
2049
2049
  var me = this;
@@ -3009,7 +3009,7 @@ Session.createV3 = function (target, user, options) {
3009
3009
  };
3010
3010
 
3011
3011
  var Engine = function (engineOptions) {
3012
- const { engineID } = engineOptions;
3012
+ let { engineID } = engineOptions;
3013
3013
  if ( engineID ) {
3014
3014
  if ( ! (engineID instanceof Buffer) ) {
3015
3015
  engineID = engineID.replace('0x', '');
@@ -3035,10 +3035,8 @@ Engine.prototype.generateEngineID = function() {
3035
3035
  var Listener = function (options, receiver) {
3036
3036
  this.receiver = receiver;
3037
3037
  this.callback = receiver.onMsg;
3038
- // this.transport = options.transport || 'udp4';
3039
- // this.port = options.port || 161;
3040
- // this.address = options.address;
3041
3038
  this.disableAuthorization = options.disableAuthorization || false;
3039
+ this.dgramModule = options.dgramModule || dgram;
3042
3040
  if ( options.sockets ) {
3043
3041
  this.socketOptions = options.sockets;
3044
3042
  } else {
@@ -3061,7 +3059,8 @@ Listener.prototype.startListening = function () {
3061
3059
  var me = this;
3062
3060
  this.sockets = {};
3063
3061
  for ( const socketOptions of this.socketOptions ) {
3064
- const socket = dgram.createSocket (socketOptions.transport);
3062
+ const dgramMod = this.dgramModule;
3063
+ const socket = dgramMod.createSocket (socketOptions.transport);
3065
3064
  socket.on ("error", me.receiver.callback);
3066
3065
  socket.bind (socketOptions.port, socketOptions.address);
3067
3066
  socket.on ("message", me.callback.bind (me.receiver, socket));
@@ -3355,7 +3354,7 @@ var Receiver = function (options, callback) {
3355
3354
  DEBUG |= options.debug;
3356
3355
  this.authorizer = new Authorizer (options);
3357
3356
  this.engine = new Engine ({
3358
- engineId: options.engineID
3357
+ engineID: options.engineID
3359
3358
  });
3360
3359
 
3361
3360
  this.engineBoots = 0;
@@ -4874,7 +4873,7 @@ var Agent = function (options, callback, mib) {
4874
4873
  DEBUG |= options.debug;
4875
4874
  this.listener = new Listener (options, this);
4876
4875
  this.engine = new Engine ({
4877
- engineId: options.engineID
4876
+ engineID: options.engineID
4878
4877
  });
4879
4878
  this.authorizer = new Authorizer (options);
4880
4879
  this.callback = callback || function () {};
package/package.json CHANGED
@@ -1,19 +1,16 @@
1
1
  {
2
2
  "name": "net-snmp",
3
- "version": "3.21.2",
3
+ "version": "3.23.0",
4
4
  "description": "JavaScript implementation of the Simple Network Management Protocol (SNMP)",
5
+ "author": "Mark Abrahams <mark@abrahams.co.nz>",
6
+ "license": "MIT",
5
7
  "main": "index.js",
6
8
  "directories": {
7
9
  "example": "example"
8
10
  },
9
- "dependencies": {
10
- "asn1-ber": "^1.2.1",
11
- "smart-buffer": "^4.1.0"
12
- },
13
- "devDependencies": {
14
- "eslint": "^9.9.1",
15
- "getopts": "^2.3.0",
16
- "mocha": "^11.0.1"
11
+ "scripts": {
12
+ "lint": "eslint . ./**/*.js",
13
+ "test": "node --openssl-legacy-provider ./node_modules/mocha/bin/mocha.js"
17
14
  },
18
15
  "contributors": [
19
16
  {
@@ -45,10 +42,13 @@
45
42
  "monitor",
46
43
  "monitoring"
47
44
  ],
48
- "author": "Mark Abrahams <mark@abrahams.co.nz>",
49
- "license": "MIT",
50
- "scripts": {
51
- "lint": "eslint . ./**/*.js",
52
- "test": "./node_modules/mocha/bin/mocha.js"
45
+ "dependencies": {
46
+ "asn1-ber": "^1.2.1",
47
+ "smart-buffer": "^4.1.0"
48
+ },
49
+ "devDependencies": {
50
+ "eslint": "^9.9.1",
51
+ "getopts": "^2.3.0",
52
+ "mocha": "^11.0.1"
53
53
  }
54
54
  }
@@ -0,0 +1,384 @@
1
+ const assert = require('assert');
2
+ // crypto is used indirectly by Authentication and Encryption modules
3
+ const snmp = require('../');
4
+ const { SecurityLevel, AuthProtocols, PrivProtocols, Authentication, Encryption } = snmp;
5
+
6
+ describe('SNMPv3 Authentication and Encryption', function () {
7
+ // Sample data for tests
8
+ const authPassword = 'test_auth_password';
9
+ const privPassword = 'test_priv_password';
10
+ const engineID = Buffer.from('8000B98380ABCDEF', 'hex');
11
+
12
+ // Test data that will be encrypted/authenticated
13
+ const testData = Buffer.from('Test data for SNMP authentication and privacy tests', 'utf8');
14
+
15
+ describe('Authentication', function () {
16
+ it('should support noAuthNoPriv security level', function () {
17
+ // noAuthNoPriv doesn't use authentication, verify this is handled appropriately
18
+ const user = {
19
+ name: 'noAuthUser',
20
+ level: SecurityLevel.noAuthNoPriv,
21
+ };
22
+
23
+ // No authentication should be required for this user
24
+ assert.strictEqual(user.level, SecurityLevel.noAuthNoPriv);
25
+ assert.strictEqual(user.authProtocol, undefined);
26
+ assert.strictEqual(user.authKey, undefined);
27
+ });
28
+
29
+ it('should support MD5 authentication protocol', function () {
30
+ // Generate authentication key using MD5
31
+ const authKey = Authentication.passwordToKey(AuthProtocols.md5, authPassword, engineID);
32
+
33
+ // Verify key length matches expected MD5 output length
34
+ assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.md5].KEY_LENGTH);
35
+
36
+ // Create a test digest
37
+ const digest = Authentication.calculateDigest(testData, AuthProtocols.md5, authPassword, engineID);
38
+
39
+ // Verify digest length
40
+ assert.strictEqual(digest.length, Authentication.algorithms[AuthProtocols.md5].AUTHENTICATION_CODE_LENGTH);
41
+
42
+ // Verify authentication works
43
+ const testBuffer = Buffer.concat([testData]);
44
+ const digestInMessage = Buffer.alloc(
45
+ Authentication.algorithms[AuthProtocols.md5].AUTHENTICATION_CODE_LENGTH
46
+ );
47
+ Authentication.writeParameters(testBuffer, AuthProtocols.md5, authPassword, engineID, digestInMessage);
48
+
49
+ assert.strictEqual(
50
+ Authentication.isAuthentic(testBuffer, AuthProtocols.md5, authPassword, engineID, digestInMessage),
51
+ true
52
+ );
53
+ });
54
+
55
+ it('should support SHA authentication protocol', function () {
56
+ // Generate authentication key using SHA
57
+ const authKey = Authentication.passwordToKey(AuthProtocols.sha, authPassword, engineID);
58
+
59
+ // Verify key length matches expected SHA output length
60
+ assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.sha].KEY_LENGTH);
61
+
62
+ // Create a test digest
63
+ const digest = Authentication.calculateDigest(testData, AuthProtocols.sha, authPassword, engineID);
64
+
65
+ // Verify digest length
66
+ assert.strictEqual(digest.length, Authentication.algorithms[AuthProtocols.sha].AUTHENTICATION_CODE_LENGTH);
67
+
68
+ // Verify authentication works
69
+ const testBuffer = Buffer.concat([testData]);
70
+ const digestInMessage = Buffer.alloc(
71
+ Authentication.algorithms[AuthProtocols.sha].AUTHENTICATION_CODE_LENGTH
72
+ );
73
+ Authentication.writeParameters(testBuffer, AuthProtocols.sha, authPassword, engineID, digestInMessage);
74
+
75
+ assert.strictEqual(
76
+ Authentication.isAuthentic(testBuffer, AuthProtocols.sha, authPassword, engineID, digestInMessage),
77
+ true
78
+ );
79
+ });
80
+
81
+ it('should support SHA-256 authentication protocol', function () {
82
+ // Generate authentication key using SHA-256
83
+ const authKey = Authentication.passwordToKey(AuthProtocols.sha256, authPassword, engineID);
84
+
85
+ // Verify key length matches expected SHA-256 output length
86
+ assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.sha256].KEY_LENGTH);
87
+
88
+ // Create a test digest
89
+ const digest = Authentication.calculateDigest(testData, AuthProtocols.sha256, authPassword, engineID);
90
+
91
+ // Verify digest length
92
+ assert.strictEqual(
93
+ digest.length,
94
+ Authentication.algorithms[AuthProtocols.sha256].AUTHENTICATION_CODE_LENGTH
95
+ );
96
+
97
+ // Verify authentication works
98
+ const testBuffer = Buffer.concat([testData]);
99
+ const digestInMessage = Buffer.alloc(
100
+ Authentication.algorithms[AuthProtocols.sha256].AUTHENTICATION_CODE_LENGTH
101
+ );
102
+ Authentication.writeParameters(testBuffer, AuthProtocols.sha256, authPassword, engineID, digestInMessage);
103
+
104
+ assert.strictEqual(
105
+ Authentication.isAuthentic(testBuffer, AuthProtocols.sha256, authPassword, engineID, digestInMessage),
106
+ true
107
+ );
108
+ });
109
+
110
+ it('should support SHA-512 authentication protocol', function () {
111
+ // Generate authentication key using SHA-512
112
+ const authKey = Authentication.passwordToKey(AuthProtocols.sha512, authPassword, engineID);
113
+
114
+ // Verify key length matches expected SHA-512 output length
115
+ assert.strictEqual(authKey.length, Authentication.algorithms[AuthProtocols.sha512].KEY_LENGTH);
116
+
117
+ // Create a test digest
118
+ const digest = Authentication.calculateDigest(testData, AuthProtocols.sha512, authPassword, engineID);
119
+
120
+ // Verify digest length
121
+ assert.strictEqual(
122
+ digest.length,
123
+ Authentication.algorithms[AuthProtocols.sha512].AUTHENTICATION_CODE_LENGTH
124
+ );
125
+
126
+ // Verify authentication works
127
+ const testBuffer = Buffer.concat([testData]);
128
+ const digestInMessage = Buffer.alloc(
129
+ Authentication.algorithms[AuthProtocols.sha512].AUTHENTICATION_CODE_LENGTH
130
+ );
131
+ Authentication.writeParameters(testBuffer, AuthProtocols.sha512, authPassword, engineID, digestInMessage);
132
+
133
+ assert.strictEqual(
134
+ Authentication.isAuthentic(testBuffer, AuthProtocols.sha512, authPassword, engineID, digestInMessage),
135
+ true
136
+ );
137
+ });
138
+ });
139
+
140
+ describe('Encryption', function () {
141
+ // Create a mock engine for encryption tests
142
+ const engine = {
143
+ engineID: engineID,
144
+ engineBoots: 1,
145
+ engineTime: 123,
146
+ };
147
+
148
+ it('should support DES encryption protocol', function () {
149
+ // Test DES encryption/decryption with SHA authentication
150
+ const authProtocol = AuthProtocols.sha;
151
+ const privProtocol = PrivProtocols.des;
152
+
153
+ // Encrypt the test data
154
+ const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
155
+ privProtocol,
156
+ testData,
157
+ privPassword,
158
+ authProtocol,
159
+ engine
160
+ );
161
+
162
+ // Verify encryption was done (output should be different from input)
163
+ assert.notDeepStrictEqual(encryptedPdu, testData);
164
+
165
+ // Decrypt the data
166
+ const decryptedPdu = Encryption.decryptPdu(
167
+ privProtocol,
168
+ encryptedPdu,
169
+ msgPrivacyParameters,
170
+ privPassword,
171
+ authProtocol,
172
+ engine
173
+ );
174
+
175
+ // Verify decryption works
176
+ assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
177
+ });
178
+
179
+ it('should support AES encryption protocol', function () {
180
+ // Test AES encryption/decryption with SHA authentication
181
+ const authProtocol = AuthProtocols.sha;
182
+ const privProtocol = PrivProtocols.aes;
183
+
184
+ // Encrypt the test data
185
+ const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
186
+ privProtocol,
187
+ testData,
188
+ privPassword,
189
+ authProtocol,
190
+ engine
191
+ );
192
+
193
+ // Verify encryption was done (output should be different from input)
194
+ assert.notDeepStrictEqual(encryptedPdu, testData);
195
+
196
+ // Decrypt the data
197
+ const decryptedPdu = Encryption.decryptPdu(
198
+ privProtocol,
199
+ encryptedPdu,
200
+ msgPrivacyParameters,
201
+ privPassword,
202
+ authProtocol,
203
+ engine
204
+ );
205
+
206
+ // Verify decryption works
207
+ assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
208
+ });
209
+
210
+ it('should support AES-256b (Blumenthal) encryption protocol', function () {
211
+ // Test AES-256 Blumenthal encryption/decryption with SHA authentication
212
+ const authProtocol = AuthProtocols.sha;
213
+ const privProtocol = PrivProtocols.aes256b;
214
+
215
+ // Encrypt the test data
216
+ const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
217
+ privProtocol,
218
+ testData,
219
+ privPassword,
220
+ authProtocol,
221
+ engine
222
+ );
223
+
224
+ // Verify encryption was done (output should be different from input)
225
+ assert.notDeepStrictEqual(encryptedPdu, testData);
226
+
227
+ // Decrypt the data
228
+ const decryptedPdu = Encryption.decryptPdu(
229
+ privProtocol,
230
+ encryptedPdu,
231
+ msgPrivacyParameters,
232
+ privPassword,
233
+ authProtocol,
234
+ engine
235
+ );
236
+
237
+ // Verify decryption works
238
+ assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
239
+ });
240
+
241
+ it('should support AES-256r (Reeder) encryption protocol', function () {
242
+ // Test AES-256 Reeder encryption/decryption with SHA authentication
243
+ const authProtocol = AuthProtocols.sha;
244
+ const privProtocol = PrivProtocols.aes256r;
245
+
246
+ // Encrypt the test data
247
+ const { encryptedPdu, msgPrivacyParameters } = Encryption.encryptPdu(
248
+ privProtocol,
249
+ testData,
250
+ privPassword,
251
+ authProtocol,
252
+ engine
253
+ );
254
+
255
+ // Verify encryption was done (output should be different from input)
256
+ assert.notDeepStrictEqual(encryptedPdu, testData);
257
+
258
+ // Decrypt the data
259
+ const decryptedPdu = Encryption.decryptPdu(
260
+ privProtocol,
261
+ encryptedPdu,
262
+ msgPrivacyParameters,
263
+ privPassword,
264
+ authProtocol,
265
+ engine
266
+ );
267
+
268
+ // Verify decryption works
269
+ assert.deepStrictEqual(decryptedPdu.slice(0, testData.length), testData);
270
+ });
271
+ });
272
+
273
+ describe('SecurityLevel combinations', function () {
274
+ it('should support authNoPriv security level', function () {
275
+ // Create a user with authentication but no privacy
276
+ const user = {
277
+ name: 'authNoPrivUser',
278
+ level: SecurityLevel.authNoPriv,
279
+ authProtocol: AuthProtocols.sha,
280
+ authKey: 'authPassword',
281
+ };
282
+
283
+ assert.strictEqual(user.level, SecurityLevel.authNoPriv);
284
+ assert.strictEqual(user.authProtocol, AuthProtocols.sha);
285
+ assert.strictEqual(user.authKey, 'authPassword');
286
+ assert.strictEqual(user.privProtocol, undefined);
287
+ assert.strictEqual(user.privKey, undefined);
288
+ });
289
+
290
+ it('should support authPriv security level', function () {
291
+ // Create a user with authentication and privacy
292
+ const user = {
293
+ name: 'authPrivUser',
294
+ level: SecurityLevel.authPriv,
295
+ authProtocol: AuthProtocols.sha256,
296
+ authKey: 'authPassword',
297
+ privProtocol: PrivProtocols.aes,
298
+ privKey: 'privPassword',
299
+ };
300
+
301
+ assert.strictEqual(user.level, SecurityLevel.authPriv);
302
+ assert.strictEqual(user.authProtocol, AuthProtocols.sha256);
303
+ assert.strictEqual(user.authKey, 'authPassword');
304
+ assert.strictEqual(user.privProtocol, PrivProtocols.aes);
305
+ assert.strictEqual(user.privKey, 'privPassword');
306
+ });
307
+
308
+ it('should validate all required parameters are provided for each security level', function () {
309
+ // noAuthNoPriv only requires username and level
310
+ const user1 = {
311
+ name: 'user1',
312
+ level: SecurityLevel.noAuthNoPriv,
313
+ };
314
+
315
+ // authNoPriv requires authentication parameters
316
+ const user2 = {
317
+ name: 'user2',
318
+ level: SecurityLevel.authNoPriv,
319
+ authProtocol: AuthProtocols.sha,
320
+ authKey: 'authPassword',
321
+ };
322
+
323
+ // authPriv requires both authentication and privacy parameters
324
+ const user3 = {
325
+ name: 'user3',
326
+ level: SecurityLevel.authPriv,
327
+ authProtocol: AuthProtocols.sha,
328
+ authKey: 'authPassword',
329
+ privProtocol: PrivProtocols.aes,
330
+ privKey: 'privPassword',
331
+ };
332
+
333
+ // This function would typically be part of parameter validation
334
+ function validateUser(user) {
335
+ if (user.level === SecurityLevel.authNoPriv || user.level === SecurityLevel.authPriv) {
336
+ assert.ok(user.authProtocol, 'authProtocol required for this security level');
337
+ assert.ok(user.authKey, 'authKey required for this security level');
338
+ }
339
+
340
+ if (user.level === SecurityLevel.authPriv) {
341
+ assert.ok(user.privProtocol, 'privProtocol required for this security level');
342
+ assert.ok(user.privKey, 'privKey required for this security level');
343
+ }
344
+
345
+ return true;
346
+ }
347
+
348
+ assert.strictEqual(validateUser(user1), true);
349
+ assert.strictEqual(validateUser(user2), true);
350
+ assert.strictEqual(validateUser(user3), true);
351
+ });
352
+ });
353
+
354
+ describe('Custom engineID handling', function () {
355
+ it('should correctly use engineID parameter', function () {
356
+ // This test verifies the fix for issue #283
357
+ // Create a session with default settings (no engineID)
358
+ const defaultSession = new snmp.Session({
359
+ host: 'example.org',
360
+ version: snmp.Version3
361
+ });
362
+
363
+ // Default session should have an engineID of expected format (17 bytes)
364
+ assert.strictEqual(defaultSession.engine.engineID.length, 17);
365
+
366
+ // Convert to hex string for easier inspection
367
+ const defaultEngineIDHex = defaultSession.engine.engineID.toString('hex');
368
+ // First 5 bytes should match the standard format 8000B98380
369
+ assert.strictEqual(defaultEngineIDHex.substring(0, 10), '8000b98380');
370
+
371
+ // Create a second session - should generate a different random engineID
372
+ const anotherDefaultSession = new snmp.Session({
373
+ host: 'example.org',
374
+ version: snmp.Version3
375
+ });
376
+
377
+ // The two sessions should have different engineIDs (random part differs)
378
+ assert.notStrictEqual(
379
+ defaultSession.engine.engineID.toString('hex'),
380
+ anotherDefaultSession.engine.engineID.toString('hex')
381
+ );
382
+ });
383
+ });
384
+ });
@@ -0,0 +1,71 @@
1
+ const assert = require('assert');
2
+ const snmp = require('../');
3
+
4
+ describe('Custom dgram module support', function () {
5
+ it('should use custom dgram module in Session', function (done) {
6
+ let createSocketCalled = false;
7
+ const mockDgram = {
8
+ createSocket: function (transport) {
9
+ createSocketCalled = true;
10
+ assert.equal(transport, 'udp4');
11
+
12
+ // Return a mock socket
13
+ return {
14
+ unref: function () {},
15
+ on: function () {},
16
+ bind: function () {},
17
+ close: function () {}
18
+ };
19
+ }
20
+ };
21
+
22
+ const session = snmp.createSession('127.0.0.1', 'public', {
23
+ dgramModule: mockDgram
24
+ });
25
+
26
+ assert(createSocketCalled, 'Custom dgram module createSocket should have been called');
27
+ session.close();
28
+ done();
29
+ });
30
+
31
+ it('should use custom dgram module in Receiver', function (done) {
32
+ let createSocketCalled = false;
33
+ const mockDgram = {
34
+ createSocket: function (transport) {
35
+ createSocketCalled = true;
36
+ assert.equal(transport, 'udp4');
37
+
38
+ // Return a mock socket
39
+ return {
40
+ on: function () {},
41
+ bind: function () {},
42
+ close: function () {},
43
+ address: function () {
44
+ return { address: '127.0.0.1', family: 'IPv4', port: 162 };
45
+ }
46
+ };
47
+ }
48
+ };
49
+
50
+ const receiver = snmp.createReceiver({
51
+ dgramModule: mockDgram,
52
+ port: 1162
53
+ }, function () {});
54
+
55
+ assert(createSocketCalled, 'Custom dgram module createSocket should have been called');
56
+ receiver.close();
57
+ done();
58
+ });
59
+
60
+ it('should fallback to default dgram when no custom module provided', function (done) {
61
+ // This should not throw an error
62
+ const session = snmp.createSession('127.0.0.1', 'public', {
63
+ // No dgramModule specified
64
+ });
65
+
66
+ // Session should be created successfully
67
+ assert(session);
68
+ session.close();
69
+ done();
70
+ });
71
+ });
@@ -0,0 +1,53 @@
1
+ const assert = require('assert');
2
+ const snmp = require('../index.js');
3
+
4
+ describe('Transport Option Handling in createV3Session', function() {
5
+ const user = {
6
+ name: "testuser",
7
+ level: snmp.SecurityLevel.noAuthNoPriv
8
+ };
9
+
10
+ afterEach(function() {
11
+ // Clean up any open sessions
12
+ // Note: sessions are closed in individual tests
13
+ });
14
+
15
+ it('should use default transport when not specified', function() {
16
+ const session = snmp.createV3Session("127.0.0.1", user);
17
+ assert.strictEqual(session.transport, "udp4");
18
+ session.close();
19
+ });
20
+
21
+ it('should use default transport when options is empty object', function() {
22
+ const session = snmp.createV3Session("127.0.0.1", user, {});
23
+ assert.strictEqual(session.transport, "udp4");
24
+ session.close();
25
+ });
26
+
27
+ it('should preserve explicit udp4 transport', function() {
28
+ const session = snmp.createV3Session("127.0.0.1", user, { transport: "udp4" });
29
+ assert.strictEqual(session.transport, "udp4");
30
+ session.close();
31
+ });
32
+
33
+ it('should preserve udp6 transport', function() {
34
+ const session = snmp.createV3Session("127.0.0.1", user, { transport: "udp6" });
35
+ assert.strictEqual(session.transport, "udp6");
36
+ session.close();
37
+ });
38
+
39
+ it('should handle null transport by using default', function() {
40
+ const session = snmp.createV3Session("127.0.0.1", user, { transport: null });
41
+ assert.strictEqual(session.transport, "udp4");
42
+ session.close();
43
+ });
44
+
45
+ it('should preserve invalid transport values (let Node.js validate)', function() {
46
+ assert.throws(function() {
47
+ snmp.createV3Session("127.0.0.1", user, { transport: "invalid" });
48
+ }, function(err) {
49
+ return err.code === 'ERR_SOCKET_BAD_TYPE';
50
+ });
51
+ });
52
+
53
+ });