$port_neighbours) { $port = get_port_by_index_cache($device, $ifIndex); //$port = dbFetchRow("SELECT * FROM `ports` WHERE `device_id` = ? AND `ifIndex` = ?", array($device['device_id'], $ifIndex)); foreach ($port_neighbours as $cdpCacheDeviceIndex => $cdp_entry) { // Init $remote_mac = NULL; $remote_hostname = ''; // Remote hostname // NOTE. cdpCacheDeviceId have undocumented limit by 40 chars! if (preg_match('/^([A-F\d]{2}\s?){6}$/i', $cdp_entry['cdpCacheDeviceId'])) { // HEX mac address // cdpCacheDeviceId.3.1 = "98 90 96 D1 59 5A " // cdpCacheDeviceId.3.1 = "549fc6fd89c7" $remote_hostname = $cdp_entry['cdpCacheDeviceId']; $remote_mac = str_replace(' ', '', $cdp_entry['cdpCacheDeviceId']); } elseif (preg_match('/^01 (?([A-F\d]{2}\s?){4})$/', $cdp_entry['cdpCacheDeviceId'], $matches)) { // HEX ip address // cdpCacheDeviceId.5.2 = "01 90 7F 93 3E " $remote_hostname = hex2ip($matches['ip']); } else { $remote_hostname = snmp_hexstring($cdp_entry['cdpCacheDeviceId']); if (preg_match('/^(?:SEP|SIP|\w+\-)?([a-f\d]{12})$/i', $remote_hostname, $matches)) { // Meraki report mac instead hostname // Axis: axis- // Cisco IP Phone: SEP // SIP-, $remote_hostname = $cdp_entry['cdpCacheDeviceId']; $remote_mac = $matches[1]; } elseif (preg_match(OBS_PATTERN_NOPRINT, $remote_hostname)) { // Non-printable chars, seems as ID is not hostname, keep as is $tmp = preg_replace(OBS_PATTERN_NOPRINT, '', $remote_hostname); if (is_valid_hostname($tmp)) { print_debug("Probably valid hostname with broken chars? '" . $cdp_entry['cdpCacheDeviceId'] . "' => '$tmp'"); } $remote_hostname = $cdp_entry['cdpCacheDeviceId']; } else { $remote_hostname = explode('(', $remote_hostname)[0]; // Fix for Nexus CDP neighbors: (serial number) } } $hostname_len = strlen($remote_hostname); // cdpCacheSysName if (isset($cdp_entry['cdpCacheSysName'])) { $cdp_entry['cdpCacheSysName'] = snmp_hexstring($cdp_entry['cdpCacheSysName']); $sysname_len = strlen($cdp_entry['cdpCacheSysName']); if (is_valid_hostname($cdp_entry['cdpCacheSysName']) && $sysname_len > $hostname_len) { $remote_hostname = $cdp_entry['cdpCacheSysName']; } elseif ($sysname_len && preg_match('/^[a-f\d]{12}$/i', $cdp_entry['cdpCacheDeviceId'])) { // DeviceId is mac, prefer sysName $remote_hostname = $cdp_entry['cdpCacheSysName']; } } // Remote address $remote_address = hex2ip($cdp_entry['cdpCacheAddress']); // MGMT address, select best $mgmt_address = hex2ip($cdp_entry['cdpCachePrimaryMgmtAddr']); if ($mgmt_address && $remote_address !== $mgmt_address) { $remote_type = get_ip_type($remote_address); $mgmt_type = get_ip_type($mgmt_address); // cdpCacheAddressType.436207616.16318465 = ip // cdpCacheAddress.436207616.16318465 = "64 69 00 31 " -> 100.105.0.49 (cgnat) // cdpCachePrimaryMgmtAddrType.436207616.16318465 = ip // cdpCachePrimaryMgmtAddr.436207616.16318465 = "0A AF 0C 3C " -> 10.175.12.60 // cdpCacheSecondaryMgmtAddrType.436207616.16318465 = ip // cdpCacheSecondaryMgmtAddr.436207616.16318465 = "" if (in_array($remote_type, [ 'cgnat', 'link-local' ]) && !in_array($mgmt_type, [ 'cgnat', 'link-local' ])) { print_debug("Select best address:\n cdpCacheAddress - $remote_address ($remote_type),\n* cdpCachePrimaryMgmtAddr - $mgmt_address ($mgmt_type)"); $remote_address = $mgmt_address; } else { print_debug("Select best address:\n* cdpCacheAddress - $remote_address ($remote_type),\n cdpCachePrimaryMgmtAddr - $mgmt_address ($mgmt_type)"); } } // Last change /* Derp. Do not use Last change from neighbour, it's not correct for us * (seems as changed uptime by remote host, not possible correct calculate unixtime) $last_change = timeticks_to_sec($cdp_entry['cdpCacheLastChange']); if ($last_change > 0) { $last_change = get_time() - $device_sysUptime + $last_change; } */ // Remote MAC on some devices $if = NULL; if (preg_match('/^([A-F\d]{2}\s?){6}$/', $cdp_entry['cdpCacheDevicePort'])) { $remote_mac = $cdp_entry['cdpCacheDevicePort']; } else { $cdp_entry['cdpCacheDevicePort'] = snmp_hexstring($cdp_entry['cdpCacheDevicePort']); if (preg_match('/^[a-f\d]{12}$/i', $cdp_entry['cdpCacheDevicePort'])) { $remote_mac = $cdp_entry['cdpCacheDevicePort']; } else { $if = $cdp_entry['cdpCacheDevicePort']; } } // Try to find a remote device and check if already cached $remote_device_id = get_autodiscovery_device_id($device, $remote_hostname, $remote_address, $remote_mac); if (is_null($remote_device_id) && // NULL - never cached in other rounds check_autodiscovery($remote_hostname, $remote_address)) { // Check all previous autodiscovery rounds // Neighbour never checked, try autodiscovery $remote_device_id = autodiscovery_device($remote_hostname, $remote_address, 'CDP', $cdp_entry['cdpCachePlatform'], $device, $port); } $remote_port_id = NULL; if ($remote_device_id) { //$if = $cdp_entry['cdpCacheDevicePort']; if (!is_null($if)) { $query = 'SELECT `port_id` FROM `ports` WHERE (`ifName` = ? OR `ifDescr` = ? OR `port_label_short` = ?) AND `device_id` = ? AND `deleted` = ?'; $remote_port_id = dbFetchCell($query, [$if, $if, $if, $remote_device_id, 0]); // Aruba devices can report ifAlias instead ifDescr if (!$remote_port_id && !is_hex_string($if)) { $query = 'SELECT `port_id` FROM `ports` WHERE `ifAlias` = ? AND `device_id` = ? AND `deleted` = ?'; $remote_port_id = dbFetchCell($query, [$if, $remote_device_id, 0]); } } if (!$remote_port_id) { if (!is_null($remote_mac)) { // By MAC $remote_port_id = get_port_id_by_mac($remote_device_id, $remote_mac); } elseif (!is_null($if)) { // Try by ifAlias $query = 'SELECT `port_id` FROM `ports` WHERE `ifAlias` = ? AND `device_id` = ? AND `deleted` = ?'; $remote_port_id = dbFetchCell($query, [$if, $remote_device_id, 0]); } if (!$remote_port_id) { // Try by IP $peer_where = generate_query_values_and($remote_device_id, 'device_id'); // Additional filter for include self IPs // Fetch all ports with peer IP and filter by UP if ($ids = get_entity_ids_ip_by_network('port', $remote_address, $peer_where)) { $remote_port_id = $ids[0]; //$port = get_port_by_id_cache($ids[0]); } } } } $neighbour = [ 'remote_device_id' => $remote_device_id, 'remote_port_id' => $remote_port_id, 'remote_hostname' => $remote_hostname, 'remote_port' => $cdp_entry['cdpCacheDevicePort'], 'remote_platform' => $cdp_entry['cdpCachePlatform'], 'remote_version' => $cdp_entry['cdpCacheVersion'], 'remote_address' => $remote_address, //'last_change' => $last_change ]; discover_neighbour($port, 'cdp', $neighbour); } } // EOF