Issues (2963)

includes/discovery/discovery-protocols.inc.php (1 issue)

1
<?php
2
3
use LibreNMS\Config;
4
use LibreNMS\Util\IP;
5
6
global $link_exists;
7
8
if ($device['os'] == 'ironware') {
9
    echo ' Brocade FDP: ';
10
    $fdp_array = snmpwalk_group($device, 'snFdpCacheEntry', 'FOUNDRY-SN-SWITCH-GROUP-MIB', 2);
11
12
    foreach ($fdp_array as $key => $fdp_if_array) {
13
        $interface = get_port_by_ifIndex($device['device_id'], $key);
14
        d_echo($fdp_if_array);
15
16
        foreach ($fdp_if_array as $entry_key => $fdp) {
17
            $remote_device_id = find_device_id($fdp['snFdpCacheDeviceId']);
18
19
            if (! $remote_device_id &&
20
                ! can_skip_discovery($fdp['snFdpCacheDeviceId'], $fdp['snFdpCacheVersion'])
21
            ) {
22
                if (Config::get('autodiscovery.xdp') === true) {
23
                    $remote_device_id = discover_new_device($fdp['snFdpCacheDeviceId'], $device, 'FDP', $interface);
24
                }
25
            }
26
27
            $remote_port_id = find_port_id($fdp['snFdpCacheDevicePort'], '', $remote_device_id);
28
            discover_link(
29
                $interface['port_id'],
30
                $fdp['snFdpCacheVendorId'],
31
                $remote_port_id,
32
                $fdp['snFdpCacheDeviceId'],
33
                $fdp['snFdpCacheDevicePort'],
34
                $fdp['snFdpCachePlatform'],
35
                $fdp['snFdpCacheVersion'],
36
                $device['device_id'],
37
                $remote_device_id
38
            );
39
        }
40
    }//end foreach
41
    echo PHP_EOL;
42
}//end if
43
44
echo ' CISCO-CDP-MIB: ';
45
$cdp_array = snmpwalk_group($device, 'cdpCache', 'CISCO-CDP-MIB', 2);
46
47
foreach ($cdp_array as $key => $cdp_if_array) {
48
    $interface = get_port_by_ifIndex($device['device_id'], $key);
49
50
    foreach ($cdp_if_array as $entry_key => $cdp) {
51
        d_echo($cdp);
52
53
        $cdp_ip = IP::fromHexString($cdp['cdpCacheAddress'], true);
54
        $remote_device_id = find_device_id($cdp['cdpCacheDeviceId'], $cdp_ip);
55
56
        if (! $remote_device_id &&
57
            ! can_skip_discovery($cdp['cdpCacheDeviceId'], $cdp['cdpCacheVersion'], $cdp['cdpCachePlatform']) &&
58
            Config::get('autodiscovery.xdp') === true
59
        ) {
60
            $remote_device_id = discover_new_device($cdp['cdpCacheDeviceId'], $device, 'CDP', $interface);
61
62
            if (! $remote_device_id && Config::get('discovery_by_ip', false)) {
63
                $remote_device_id = discover_new_device($cdp_ip, $device, 'CDP', $interface);
64
            }
65
        }
66
67
        if ($interface['port_id'] && $cdp['cdpCacheDeviceId'] && $cdp['cdpCacheDevicePort']) {
68
            $remote_port_id = find_port_id($cdp['cdpCacheDevicePort'], '', $remote_device_id);
69
            discover_link(
70
                $interface['port_id'],
71
                'cdp',
72
                $remote_port_id,
73
                $cdp['cdpCacheDeviceId'],
74
                $cdp['cdpCacheDevicePort'],
75
                $cdp['cdpCachePlatform'],
76
                $cdp['cdpCacheVersion'],
77
                $device['device_id'],
78
                $remote_device_id
79
            );
80
        }
81
    }//end foreach
82
}//end foreach
83
echo PHP_EOL;
84
85
if (($device['os'] == 'routeros')) {
86
    echo ' LLDP-MIB: ';
87
    $lldp_array = snmpwalk_group($device, 'lldpRemEntry', 'LLDP-MIB', 3);
88
    if (! empty($lldp_array)) {
89
        // workaround for routeros returning the incorrect index
90
        if (! empty($lldp_array[0][0])) {
91
            $lldp_array = $lldp_array[0][0];
92
        }
93
94
        $lldp_ports = snmpwalk_group($device, 'mtxrInterfaceStatsName', 'MIKROTIK-MIB');
95
        $lldp_ports_num = snmpwalk_group($device, 'mtxrNeighborInterfaceID', 'MIKROTIK-MIB');
96
97
        foreach ($lldp_array as $key => $lldp) {
98
            $local_port_ifName = $lldp_ports[hexdec($lldp_ports_num[$key]['mtxrNeighborInterfaceID'])]['mtxrInterfaceStatsName'];
99
            $local_port_id = find_port_id($local_port_ifName, null, $device['device_id']);
100
            $interface = get_port_by_id($local_port_id);
101
            if ($lldp['lldpRemPortIdSubtype'] == 3) { // 3 = macaddress
102
                $remote_port_mac = str_replace([' ', ':', '-'], '', strtolower($lldp['lldpRemPortId']));
103
            }
104
105
            $remote_device_id = find_device_id($lldp['lldpRemSysName'], $lldp['lldpRemManAddr'], $remote_port_mac);
106
107
            if (! $remote_device_id &&
108
                \LibreNMS\Util\Validate::hostname($lldp['lldpRemSysName']) &&
109
                ! can_skip_discovery($lldp['lldpRemSysName'], $lldp['lldpRemSysDesc']) &&
110
                Config::get('autodiscovery.xdp') === true) {
111
                $remote_device_id = discover_new_device($lldp['lldpRemSysName'], $device, 'LLDP', $interface);
112
            }
113
114
            if ($interface['port_id'] && $lldp['lldpRemSysName'] && $lldp['lldpRemPortId']) {
115
                $remote_port_id = find_port_id($lldp['lldpRemPortDesc'], $lldp['lldpRemPortId'], $remote_device_id);
116
                discover_link(
117
                    $interface['port_id'],
118
                    'lldp',
119
                    $remote_port_id,
120
                    $lldp['lldpRemSysName'],
121
                    $lldp['lldpRemPortId'],
122
                    null,
123
                    $lldp['lldpRemSysDesc'],
124
                    $device['device_id'],
125
                    $remote_device_id
126
                );
127
            }
128
        }//end foreach
129
    }
130
    echo PHP_EOL;
131
} elseif (($device['os'] == 'pbn' || $device['os'] == 'bdcom')) {
132
    echo ' NMS-LLDP-MIB: ';
133
    $lldp_array = snmpwalk_group($device, 'lldpRemoteSystemsData', 'NMS-LLDP-MIB');
134
135
    foreach ($lldp_array as $key => $lldp) {
136
        d_echo($lldp);
137
        $interface = get_port_by_ifIndex($device['device_id'], $lldp['lldpRemLocalPortNum']);
138
        $remote_device_id = find_device_id($lldp['lldpRemSysName']);
139
140
        if (! $remote_device_id &&
141
            \LibreNMS\Util\Validate::hostname($lldp['lldpRemSysName']) &&
142
            ! can_skip_discovery($lldp['lldpRemSysName'], $lldp['lldpRemSysDesc'] &&
143
            Config::get('autodiscovery.xdp') === true)
144
        ) {
145
            $remote_device_id = discover_new_device($lldp['lldpRemSysName'], $device, 'LLDP', $interface);
146
        }
147
148
        if ($interface['port_id'] && $lldp['lldpRemSysName'] && $lldp['lldpRemPortId']) {
149
            $remote_port_id = find_port_id($lldp['lldpRemPortDesc'], $lldp['lldpRemPortId'], $remote_device_id);
150
            discover_link(
151
                $interface['port_id'],
152
                'lldp',
153
                $remote_port_id,
154
                $lldp['lldpRemSysName'],
155
                $lldp['lldpRemPortId'],
156
                null,
157
                $lldp['lldpRemSysDesc'],
158
                $device['device_id'],
159
                $remote_device_id
160
            );
161
        }
162
    }//end foreach
163
    echo PHP_EOL;
164
} elseif (($device['os'] == 'timos')) {
165
    echo ' TIMETRA-LLDP-MIB: ';
166
    $lldp_array = snmpwalk_group($device, 'tmnxLldpRemoteSystemsData', 'TIMETRA-LLDP-MIB');
167
    foreach ($lldp_array as $key => $lldp) {
168
        $ifIndex = key($lldp['tmnxLldpRemPortId']);
169
        $MacIndex = key($lldp['tmnxLldpRemPortId'][$ifIndex]);
170
        $RemIndex = key($lldp['tmnxLldpRemPortId'][$ifIndex][$MacIndex]);
171
        $interface = get_port_by_ifIndex($device['device_id'], $ifIndex);
172
        $remote_device_id = find_device_id($lldp['tmnxLldpRemSysName'][$ifIndex][$MacIndex][$RemIndex]);
173
174
        if (! $remote_device_id &&
175
            \LibreNMS\Util\Validate::hostname($lldp['tmnxLldpRemSysName'][$ifIndex][$MacIndex][$RemIndex]) &&
176
            ! can_skip_discovery($lldp['tmnxLldpRemSysName'][$ifIndex][$MacIndex][$RemIndex], $lldp['tmnxLldpRemSysDesc'][$ifIndex][$MacIndex][$RemIndex]) &&
177
            Config::get('autodiscovery.xdp') === true
178
        ) {
179
            $remote_device_id = discover_new_device($lldp['tmnxLldpRemSysName'][$ifIndex][$MacIndex][$RemIndex], $device, 'LLDP', $interface);
180
        }
181
182
        if ($interface['port_id'] && $lldp['tmnxLldpRemSysName'][$ifIndex][$MacIndex][$RemIndex] && $lldp['tmnxLldpRemPortId'][$ifIndex][$MacIndex][$RemIndex]) {
183
            $remote_port_id = find_port_id($lldp['tmnxLldpRemPortDesc'][$ifIndex][$MacIndex][$RemIndex], $lldp['tmnxLldpRemPortId'][$ifIndex][$MacIndex][$RemIndex], $remote_device_id);
184
            discover_link(
185
                $interface['port_id'],
186
                'lldp',
187
                $remote_port_id,
188
                $lldp['tmnxLldpRemSysName'][$ifIndex][$MacIndex][$RemIndex],
189
                $lldp['tmnxLldpRemPortId'][$ifIndex][$MacIndex][$RemIndex],
190
                null,
191
                $lldp['tmnxLldpRemSysDesc'][$ifIndex][$MacIndex][$RemIndex],
192
                $device['device_id'],
193
                $remote_device_id
194
            );
195
        }
196
    }//end foreach
197
    echo PHP_EOL;
198
} elseif (($device['os'] == 'jetstream')) {
199
    echo ' JETSTREAM-LLDP MIB: ';
200
201
    $lldp_array = snmpwalk_group($device, 'lldpNeighborInfoEntry', 'TPLINK-LLDPINFO-MIB');
202
203
    foreach ($lldp_array as $key => $lldp) {
204
        $IndexId = key($lldp['lldpNeighborPortIndexId']);
205
206
        $local_ifName = $lldp['lldpNeighborPortId'][$IndexId];
207
        $local_port_id = find_port_id('gigabitEthernet ' . $local_ifName, null, $device['device_id']);
208
209
        $remote_device_id = find_device_id($lldp['lldpNeighborDeviceName'][$IndexId]);
210
        $remote_device_name = $lldp['lldpNeighborDeviceName'][$IndexId];
211
        $remote_device_sysDescr = $lldp['lldpNeighborDeviceDescr'][$IndexId];
212
        $remote_device_ip = $lldp['lldpNeighborManageIpAddr'][$IndexId];
213
        $remote_port_descr = $lldp['lldpNeighborPortIdDescr'][$IndexId];
214
        $remote_port_id = find_port_id($remote_port_descr, null, $remote_device_id);
215
216
        if (! $remote_device_id &&
217
            \LibreNMS\Util\Validate::hostname($remote_device_name) &&
218
            ! can_skip_discovery($remote_device_name, $remote_device_ip) &&
219
            Config::get('autodiscovery.xdp') === true) {
220
            $remote_device_id = discover_new_device($remote_device_name, $device, 'LLDP', $local_ifName);
221
        }
222
223
        discover_link(
224
            $local_port_id, //our port id from database
225
            'lldp',
226
            $remote_port_id, //remote port id from database if applicable
227
            $remote_device_name, //remote device name from SNMP walk
228
            $remote_port_descr, //remote port description from SNMP walk
229
            null,
230
            $remote_device_sysDescr, //remote device description from SNMP walk
231
            $device['device_id'], //our device id
232
            $remote_device_id //remote device id if applicable
233
        );
234
    }
235
    echo PHP_EOL;
236
} else {
237
    echo ' LLDP-MIB: ';
238
    $lldp_array = snmpwalk_group($device, 'lldpRemTable', 'LLDP-MIB', 3);
239
    if (! empty($lldp_array)) {
240
        $lldp_remAddr_num = snmpwalk_cache_multi_oid($device, '.1.0.8802.1.1.2.1.4.2.1.3', [], 'LLDP-MIB', null, '-OQun');
241
        foreach ($lldp_remAddr_num as $key => $value) {
242
            $res = preg_match("/1\.0\.8802\.1\.1\.2\.1\.4\.2\.1\.3\.([^\.]*)\.([^\.]*)\.([^\.]*)\.([^\.]*)\.([^\.]*).(([^\.]*)(\.([^\.]*))+)/", $key, $matches);
243
            if ($res) {
244
                //collect the Management IP address from the OID
245
                if ($matches[5] == 4) {
246
                    $lldp_array[$matches[1]][$matches[2]][$matches[3]]['lldpRemManAddr'] = $matches[6];
247
                } else {
248
                    $ipv6 = implode(
249
                        ':',
250
                        array_map(
251
                            function ($v) {
252
                                return sprintf('%02x', $v);
253
                            },
254
                            explode('.', $matches[6])
255
                        )
256
                    );
257
                    $ipv6 = preg_replace('/([^:]{2}):([^:]{2})/i', '$1$2', $ipv6);
258
                    $lldp_array[$matches[1]][$matches[2]][$matches[3]]['lldpRemManAddr'] = $ipv6;
259
                }
260
            }
261
        }
262
        if (($device['os'] == 'aos7')) {
263
            $lldp_local = snmpwalk_cache_oid($device, 'lldpLocPortEntry', [], 'LLDP-MIB');
264
            $lldp_ports = snmpwalk_group($device, 'lldpLocPortId', 'LLDP-MIB');
265
        } else {
266
            $dot1d_array = snmpwalk_group($device, 'dot1dBasePortIfIndex', 'BRIDGE-MIB');
267
            $lldp_ports = snmpwalk_group($device, 'lldpLocPortId', 'LLDP-MIB');
268
        }
269
    }
270
271
    foreach ($lldp_array as $key => $lldp_if_array) {
272
        foreach ($lldp_if_array as $entry_key => $lldp_instance) {
273
            if (($device['os'] == 'aos7')) {
274
                $ifName = $lldp_local[$entry_key]['lldpLocPortDesc'];
275
            } elseif (is_numeric($dot1d_array[$entry_key]['dot1dBasePortIfIndex'])) {
276
                $ifIndex = $dot1d_array[$entry_key]['dot1dBasePortIfIndex'];
277
            } else {
278
                $ifIndex = $entry_key;
279
            }
280
            if (($device['os'] == 'aos7')) {
281
                $local_port_id = find_port_id($ifName, null, $device['device_id']);
282
            } else {
283
                $local_port_id = find_port_id($lldp_ports[$entry_key]['lldpLocPortId'], $ifIndex, $device['device_id']);
284
            }
285
            $interface = get_port_by_id($local_port_id);
286
287
            d_echo($lldp_instance);
288
289
            foreach ($lldp_instance as $entry_instance => $lldp) {
290
                // normalize MAC address if present
291
                $remote_port_mac = '';
292
                $remote_port_name = $lldp['lldpRemPortId'];
293
                if ($lldp['lldpRemChassisIdSubtype'] == 4) { // 4 = macaddress
294
                    $remote_port_mac = str_replace([' ', ':', '-'], '', strtolower($lldp['lldpRemChassisId']));
295
                }
296
                if ($lldp['lldpRemPortIdSubtype'] == 3) { // 3 = macaddress
297
                    $remote_port_mac = str_replace([' ', ':', '-'], '', strtolower($lldp['lldpRemPortId']));
298
                }
299
                if ($lldp['lldpRemChassisIdSubtype'] == 6 || $lldp['lldpRemChassisIdSubtype'] == 2) { // 6=ifName 2=ifAlias
300
                    $remote_port_name = $lldp['lldpRemChassisId'];
301
                }
302
303
                $remote_device_id = find_device_id($lldp['lldpRemSysName'], $lldp['lldpRemManAddr'], $remote_port_mac);
304
305
                // add device if configured to do so
306
                if (! $remote_device_id && ! can_skip_discovery($lldp['lldpRemSysName'], $lldp['lldpRemSysDesc']) &&
307
                Config::get('autodiscovery.xdp') === true) {
308
                    $remote_device_id = discover_new_device($lldp['lldpRemSysName'], $device, 'LLDP', $interface);
309
310
                    if (! $remote_device_id && Config::get('discovery_by_ip', false)) {
311
                        $ptopo_array = snmpwalk_group($device, 'ptopoConnEntry', 'PTOPO-MIB');
312
                        d_echo($ptopo_array);
313
                        foreach ($ptopo_array as $ptopo) {
314
                            if (strcmp(trim($ptopo['ptopoConnRemoteChassis']), trim($lldp['lldpRemChassisId'])) == 0) {
315
                                $ip = IP::fromHexString($ptopo['ptopoConnAgentNetAddr'], true);
316
                                $remote_device_id = discover_new_device($ip, $device, 'LLDP', $interface);
317
                                break;
318
                            }
319
                        }
320
                        if (! $remote_device_id && isset($lldp['lldpRemManAddr'])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $remote_device_id of type false|integer is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
321
                            $remote_device_id = discover_new_device($lldp['lldpRemManAddr'], $device, 'LLDP', $interface);
322
                        }
323
                        unset($ptopo_array);
324
                    }
325
                }
326
327
                $remote_device = device_by_id_cache($remote_device_id);
328
                if ($remote_device['os'] == 'calix') {
329
                    $remote_port_name = 'EthPort ' . $lldp['lldpRemPortId'];
330
                }
331
332
                if ($remote_device['os'] == 'xos') {
333
                    $slot_port = explode(':', $remote_port_name);
334
                    if (sizeof($slot_port) == 2) {
335
                        $n_slot = (int) $slot_port[0];
336
                        $n_port = (int) $slot_port[1];
337
                    } else {
338
                        $n_slot = 1;
339
                        $n_port = (int) $slot_port[0];
340
                    }
341
                    $remote_port_name = (string) ($n_slot * 1000 + $n_port);
342
                }
343
344
                $remote_port_id = find_port_id(
345
                    $lldp['lldpRemPortDesc'],
346
                    $remote_port_name,
347
                    $remote_device_id,
348
                    $remote_port_mac
349
                );
350
                if ($remote_port_id == 0) { //We did not find it
351
                    $remote_port_name = $remote_port_name . ' (' . $remote_port_mac . ')';
352
                }
353
                if (empty($lldp['lldpRemSysName'])) {
354
                    $lldp['lldpRemSysName'] = $remote_device['sysName'] ?: $remote_device['hostname'];
355
                }
356
                if (empty($lldp['lldpRemSysName'])) {
357
                    $lldp['lldpRemSysName'] = $lldp['lldpRemSysDesc'];
358
                }
359
                if ($interface['port_id'] && $lldp['lldpRemSysName'] && $remote_port_name) {
360
                    discover_link(
361
                        $interface['port_id'],
362
                        'lldp',
363
                        $remote_port_id,
364
                        $lldp['lldpRemSysName'],
365
                        $remote_port_name,
366
                        null,
367
                        $lldp['lldpRemSysDesc'],
368
                        $device['device_id'],
369
                        $remote_device_id
370
                    );
371
                }
372
            }//end foreach
373
        }//end foreach
374
    }//end foreach
375
376
    unset(
377
        $dot1d_array
378
    );
379
    echo PHP_EOL;
380
}//end elseif
381
382
if (Config::get('autodiscovery.ospf') === true) {
383
    echo ' OSPF Discovery: ';
384
    $sql = 'SELECT DISTINCT(`ospfNbrIpAddr`),`device_id` FROM `ospf_nbrs` WHERE `device_id`=?';
385
    foreach (dbFetchRows($sql, [$device['device_id']]) as $nbr) {
386
        try {
387
            $ip = IP::parse($nbr['ospfNbrIpAddr']);
388
389
            if ($ip->inNetworks(Config::get('autodiscovery.nets-exclude'))) {
390
                echo 'x';
391
                continue;
392
            }
393
394
            if (! $ip->inNetworks(Config::get('nets'))) {
395
                echo 'i';
396
                continue;
397
            }
398
399
            $name = gethostbyaddr($ip);
400
            $remote_device_id = discover_new_device($name, $device, 'OSPF');
401
        } catch (\LibreNMS\Exceptions\InvalidIpException $e) {
402
            //
403
        }
404
    }
405
    echo PHP_EOL;
406
}
407
408
d_echo($link_exists);
409
410
$sql = 'SELECT * FROM `links` AS L, `ports` AS I WHERE L.local_port_id = I.port_id AND I.device_id = ?';
411
foreach (dbFetchRows($sql, [$device['device_id']]) as $test) {
412
    $local_port_id = $test['local_port_id'];
413
    $remote_hostname = $test['remote_hostname'];
414
    $remote_port = $test['remote_port'];
415
    d_echo("$local_port_id -> $remote_hostname -> $remote_port \n");
416
417
    if (! $link_exists[$local_port_id][$remote_hostname][$remote_port]) {
418
        echo '-';
419
        $rows = dbDelete('links', '`id` = ?', [$test['id']]);
420
        d_echo("$rows deleted ");
421
    }
422
}
423
424
// remove orphaned links
425
$deleted = (int) dbDeleteOrphans('links', ['devices.device_id.local_device_id']);
426
echo str_repeat('-', $deleted);
427
d_echo(" $deleted orphaned links deleted\n");
428
429
unset(
430
    $link_exists,
431
    $sql,
432
    $fdp_array,
433
    $cdp_array,
434
    $lldp_array,
435
    $deleted
436
);
437