array( [mtxrNeighborIpAddress] => string(11) "10.24.99.65" [mtxrNeighborMacAddress] => string(15) "0:4:56:ef:f1:c9" [mtxrNeighborVersion] => string(5) "3.5.2" [mtxrNeighborPlatform] => string(18) "5G Force 200 (ROW)" [mtxrNeighborIdentity] => string(20) "Fortuna_Skladskaya28" [mtxrNeighborSoftwareID] => string(10) "MAC-Telnet" [mtxrNeighborInterfaceID] => string(1) "9" ) LLDP-MIB: [1502] => array( [lldpRemChassisIdSubtype] => string(10) "macAddress" [lldpRemChassisId] => string(17) "00:04:56:EF:F1:C9" [lldpRemPortIdSubtype] => string(13) "interfaceName" [lldpRemPortId] => string(9) "br-lan.98" [lldpRemSysName] => string(20) "Fortuna_Skladskaya28" [lldpRemManAddr] => string(11) "10.24.99.65" [lldpRemSysDesc] => string(0) "" ) */ $mtxr_array = snmpwalk_cache_oid($device, "mtxrNeighbor", array(), "MIKROTIK-MIB", NULL, OBS_SNMP_ALL | OBS_SNMP_CONCAT); if ($mtxr_array) { print_debug_vars($mtxr_array); // Extend remote port names by discovery in LLDP-MIB (but do not use this MIB self, mikrotik not reports local port there) $lldp_array = snmpwalk_cache_oid($device, 'lldpRemChassisId', [], "LLDP-MIB"); if (snmp_status()) { $lldp_array = snmpwalk_cache_oid($device, 'lldpRemPortIdSubtype', $lldp_array, "LLDP-MIB"); $lldp_array = snmpwalk_cache_oid($device, 'lldpRemPortId', $lldp_array, "LLDP-MIB"); $lldp_array = snmpwalk_cache_oid($device, 'lldpRemSysDesc', $lldp_array, "LLDP-MIB", NULL, OBS_SNMP_ALL_MULTILINE); print_debug_vars($lldp_array); } foreach ($mtxr_array as $key => $entry) { if (isset($lldp_array[$key])) { // older fw versions $entry = array_merge($entry, $lldp_array[$key]); } elseif (isset($lldp_array['0.0.'.$key])) { // latest fw versions $entry = array_merge($entry, $lldp_array['0.0.'.$key]); } // Need to straighten out the MAC first for use later. Mikrotik does not pad the numbers! (i.e. 0:12:23:3:5c:6b) //$remote_mac = mac_zeropad($entry['mtxrNeighborMacAddress']); $entry['mtxrNeighborMacAddress'] = format_mac($entry['mtxrNeighborMacAddress']); // Note, mtxrNeighborInterfaceID really hex number, ie: // mtxrNeighborInterfaceID.1 = a $ifIndex = hexdec($entry['mtxrNeighborInterfaceID']); $remote_platform = strlen($entry['mtxrNeighborPlatform']) ? $entry['mtxrNeighborPlatform'] : $entry['lldpRemSysDesc']; $remote_port = strlen($entry['lldpRemPortId']) ? $entry['lldpRemPortId'] : format_mac($entry['mtxrNeighborMacAddress'], ' '); // Get the port using BRIDGE-MIB (Why without Vlan?) //$port = dbFetchRow("SELECT * FROM `ports` WHERE `device_id` = ? AND `ifIndex` = ? AND `ifDescr` NOT LIKE 'Vlan%'", array($device['device_id'], $ifIndex)); $port = get_port_by_index_cache($device, $ifIndex); $remote_device_id = NULL; $remote_port_id = NULL; // Try find remote device and check if already cached $remote_device_id = get_autodiscovery_device_id($device, $entry['mtxrNeighborIdentity'], $entry['mtxrNeighborIpAddress'], $entry['mtxrNeighborMacAddress']); if (is_null($remote_device_id) && // NULL - never cached in other rounds check_autodiscovery($entry['mtxrNeighborIdentity'], $entry['mtxrNeighborIpAddress'])) // Check all previous autodiscovery rounds { // Neighbour never checked, try autodiscovery $remote_device_id = autodiscovery_device($entry['mtxrNeighborIdentity'], $entry['mtxrNeighborIpAddress'], 'MNDP', $remote_platform, $device, $port); } if ($remote_device_id) { // Detect remote port by LLDP if (strlen($entry['lldpRemPortId'])) { $id = $entry['lldpRemPortId']; switch ($entry['lldpRemPortIdSubtype']) { case 'interfaceAlias': $remote_port_id = dbFetchCell("SELECT `port_id` FROM `ports` WHERE `ifAlias` = ? AND `device_id` = ?", [ $id, $remote_device_id ]); break; case 'interfaceName': // Try lldpRemPortId $query = 'SELECT `port_id` FROM `ports` WHERE (`ifName` = ? OR `ifDescr` = ? OR `port_label_short` = ?) AND `device_id` = ?'; $remote_port_id = dbFetchCell($query, [ $id, $id, $id, $remote_device_id ]); break; case 'macAddress': $remote_port_id = get_port_id_by_mac($remote_device_id, $id); break; case 'networkAddress': $ip_version = get_ip_version($id); if ($ip_version) { $ip = ip_uncompress($id); $remote_port_id = dbFetchCell("SELECT `port_id` FROM `ipv" . $ip_version . "_addresses` LEFT JOIN `ports` USING (`port_id`) WHERE `ipv" . $ip_version . "_address` = ? AND `device_id` = ?", [ $ip, $remote_device_id ]); } break; case 'local': // local not always ifIndex or FIXME (see: http://jira.observium.org/browse/OBSERVIUM-1716) if (!ctype_digit($id)) { // Not sure what should be if $id ifName and it just numeric $query = 'SELECT `port_id` FROM `ports` WHERE (`ifName` = ? OR `ifDescr` = ? OR `port_label_short` = ?) AND `device_id` = ?'; $remote_port_id = dbFetchCell($query, [ $id, $id, $id, $remote_device_id ]); } break; } } else { // No way to find a remote port other than by MAC address, with the data we're getting from Mikrotik. Only proceed when only one remote port matches... $remote_port_id = get_port_id_by_mac($remote_device_id, $entry['mtxrNeighborMacAddress']); } } $neighbour = [ 'remote_port_id' => $remote_port_id, 'remote_hostname' => $entry['mtxrNeighborIdentity'], 'remote_port' => $remote_port, 'remote_platform' => $remote_platform, 'remote_version' => $entry['mtxrNeighborVersion'], 'remote_address' => $entry['mtxrNeighborIpAddress'] ]; discover_neighbour($port, 'mndp', $neighbour); } } // EOF