-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscan_lldp.js
More file actions
103 lines (95 loc) · 2.59 KB
/
scan_lldp.js
File metadata and controls
103 lines (95 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import snmp from 'net-snmp';
import Cidr from 'ip-cidr';
const COMMUNITY = process.env.SNMP_COMMUNITY || 'public';
const CIDR = process.env.CIDR || '192.168.1.0/24';
const LIMIT = Number(process.env.LIMIT || 256);
const CONCURRENCY = Number(process.env.CONCURRENCY || 6);
const TIMEOUT = Number(process.env.TIMEOUT || 3000);
function expandCidr(cidrStr, limit = 256) {
if (!Cidr.isValidCIDR(cidrStr)) throw new Error('CIDR non valido');
const cidr = new Cidr(cidrStr);
return cidr.toArray({ limit });
}
// Decode helper
function decodeValue(vb) {
if (!vb) return '';
if (Buffer.isBuffer(vb)) return vb.toString('hex');
if (typeof vb === 'object' && vb instanceof Buffer) return vb.toString('hex');
return vb.toString();
}
async function walk(ip, oid) {
return new Promise((resolve) => {
const session = snmp.createSession(ip, COMMUNITY, {
timeout: TIMEOUT,
retries: 1,
version: snmp.Version2c,
});
const rows = [];
session.subtree(
oid,
50,
(vb) => {
const list = Array.isArray(vb) ? vb : [vb];
for (const v of list) {
if (v?.oid) {
rows.push({ oid: v.oid, type: v.type, value: v.value });
}
}
},
(err) => {
session.close();
resolve({ err: err ? err.toString() : null, rows });
}
);
});
}
async function scanHost(ip) {
const res = { ip, sysName: null, lldp: [] };
// sysName
await new Promise((resolve) => {
const session = snmp.createSession(ip, COMMUNITY, {
timeout: TIMEOUT,
retries: 1,
version: snmp.Version2c,
});
session.get(['1.3.6.1.2.1.1.5.0'], (err, vbs) => {
if (!err && vbs?.[0]?.value) res.sysName = vbs[0].value.toString();
session.close();
resolve();
});
});
// LLDP RemTable
const rem = await walk(ip, '1.0.8802.1.1.2.1.4.1.1');
if (rem.rows.length) {
res.lldp = rem.rows.map((r) => ({
oid: r.oid,
value: decodeValue(r.value),
type: r.type,
}));
}
return res;
}
async function run() {
const hosts = expandCidr(CIDR, LIMIT);
const queue = [...hosts];
const results = [];
const workers = Array(CONCURRENCY)
.fill(null)
.map(async () => {
while (queue.length) {
const ip = queue.shift();
try {
const r = await scanHost(ip);
if (r.lldp.length || r.sysName) results.push(r);
} catch (e) {
results.push({ ip, error: e.message });
}
}
});
await Promise.all(workers);
console.log(JSON.stringify(results, null, 2));
}
run().catch((e) => {
console.error(e);
process.exit(1);
});