-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscan-missing-links.mjs
More file actions
123 lines (98 loc) · 4.01 KB
/
scan-missing-links.mjs
File metadata and controls
123 lines (98 loc) · 4.01 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import Database from 'better-sqlite3';
import NetMapSNMP from './libsnmp.js';
const db = new Database('./netmap.db');
const snmp = new NetMapSNMP(process.env.SNMP_COMMUNITY || 'public');
console.log('=== SCANSIONE DEVICE SENZA LINK ===\n');
// Device senza link
const devicesNoLinks = db.prepare(`
SELECT d.id, d.ip, d.sysname
FROM devices d
WHERE d.status = 'active' AND d.id NOT IN (
SELECT DISTINCT device_id FROM links
UNION
SELECT DISTINCT remote_device_id FROM links WHERE remote_device_id IS NOT NULL
)
ORDER BY d.ip
`).all();
console.log(`Trovati ${devicesNoLinks.length} device senza link. Scansione LLDP...\n`);
let totalLinksAdded = 0;
for (const device of devicesNoLinks) {
console.log(`\n--- ${device.ip} (${device.sysname}) ---`);
try {
const discovery = await snmp.discoverProtocols(device.ip, 8000);
const neighbors = [
...discovery.lldp.map(n => ({ ...n, protocol: 'LLDP' })),
...discovery.cdp.map(n => ({ ...n, protocol: 'CDP' })),
];
console.log(`LLDP neighbors: ${discovery.lldp.length}, CDP neighbors: ${discovery.cdp.length}`);
if (neighbors.length === 0) {
console.log('→ Nessun neighbor trovato (LLDP potrebbe essere disabilitato)');
continue;
}
// Salva i link
let linksAdded = 0;
for (const neighbor of neighbors) {
// Trova remote device
let remoteDevice = null;
let remoteIp = neighbor.ip || null;
let neighborName = neighbor.sysName || null;
if (neighborName) {
remoteDevice = db.prepare('SELECT * FROM devices WHERE sysname = ?').get(neighborName);
}
if (!remoteDevice && remoteIp) {
remoteDevice = db.prepare('SELECT * FROM devices WHERE ip = ?').get(remoteIp);
}
// Cross-reference con MAC
if (!remoteDevice && neighbor.chassisId && /^[0-9a-fA-F:.-]{12,17}$/.test(neighbor.chassisId)) {
const normalizedMAC = neighbor.chassisId.replace(/[:.|-]/g, '').toLowerCase();
const iface = db.prepare(`
SELECT d.* FROM interfaces i
JOIN devices d ON i.device_id = d.id
WHERE REPLACE(REPLACE(REPLACE(LOWER(i.ifphysaddress), ':', ''), '.', ''), '-', '') = ?
LIMIT 1
`).get(normalizedMAC);
if (iface) remoteDevice = iface;
}
console.log(` → ${neighbor.sysName || neighbor.chassisId || 'unknown'} (porta ${neighbor.localPort || neighbor.ifIndex}) → ${remoteDevice ? 'RISOLTO: ' + remoteDevice.sysname : 'NON RISOLTO'}`);
// Salva link
db.prepare(`
INSERT INTO links (device_id, local_ifindex, remote_device_id, remote_ip, remote_sysname, remote_chassisid, remote_portid, remote_portdesc, protocol)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT DO UPDATE SET
remote_device_id = COALESCE(excluded.remote_device_id, remote_device_id),
lastseen = strftime('%s', 'now')
`).run(
device.id,
parseInt(neighbor.localPort) || neighbor.ifIndex || null,
remoteDevice?.id || null,
remoteDevice?.ip || remoteIp || null,
neighborName || null,
neighbor.chassisId || null,
neighbor.portId || null,
neighbor.sysDesc || null,
neighbor.protocol
);
linksAdded++;
}
console.log(` ✓ ${linksAdded} link salvati`);
totalLinksAdded += linksAdded;
} catch (err) {
console.log(` ✗ Errore: ${err.message}`);
}
}
console.log(`\n=== COMPLETATO ===`);
console.log(`Link totali aggiunti: ${totalLinksAdded}`);
// Verifica finale
const stats = db.prepare(`
SELECT
COUNT(DISTINCT d.id) as withLinks
FROM devices d
WHERE d.id IN (
SELECT DISTINCT device_id FROM links
UNION
SELECT DISTINCT remote_device_id FROM links WHERE remote_device_id IS NOT NULL
)
`).get();
const total = db.prepare('SELECT COUNT(*) as count FROM devices WHERE status = "active"').get();
console.log(`Device con link: ${stats.withLinks}/${total.count} (${Math.round(stats.withLinks / total.count * 100)}%)`);
db.close();