176 lines
7.7 KiB
PHP
176 lines
7.7 KiB
PHP
<?php
|
|
/**
|
|
* Observium
|
|
*
|
|
* This file is part of Observium.
|
|
*
|
|
* @package observium
|
|
* @subpackage discovery
|
|
* @copyright (C) Adam Armstrong
|
|
*
|
|
*/
|
|
|
|
// Not sure why we check for VTP, but this data comes from that MIB, so... (I think just validate that here data exist)
|
|
$vtpversion = snmp_get_oid($device, 'vtpVersion.0', 'CISCO-VTP-MIB', NULL, OBS_SNMP_ALL_NUMERIC);
|
|
|
|
switch ($vtpversion) {
|
|
case 'none':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case 'one':
|
|
case 'two':
|
|
case 'three':
|
|
// FIXME - can have multiple VTP domains.
|
|
$vtpdomains = snmpwalk_cache_oid($device, 'vlanManagementDomains', [], 'CISCO-VTP-MIB');
|
|
if (snmp_status()) {
|
|
//$vtpvlans = snmpwalk_cache_twopart_oid($device, 'vtpVlanEntry', array(), 'CISCO-VTP-MIB');
|
|
$vtpvlans = snmpwalk_cache_twopart_oid($device, 'vtpVlanState', [], 'CISCO-VTP-MIB');
|
|
$vtpvlans = snmpwalk_cache_twopart_oid($device, 'vtpVlanType', $vtpvlans, 'CISCO-VTP-MIB');
|
|
$vtpvlans = snmpwalk_cache_twopart_oid($device, 'vtpVlanName', $vtpvlans, 'CISCO-VTP-MIB');
|
|
$vtpvlans = snmpwalk_cache_twopart_oid($device, 'vtpVlanMtu', $vtpvlans, 'CISCO-VTP-MIB');
|
|
$vtpvlans = snmpwalk_cache_twopart_oid($device, 'vtpVlanIfIndex', $vtpvlans, 'CISCO-VTP-MIB');
|
|
}
|
|
|
|
foreach ($vtpdomains as $vtp_domain_index => $vtpdomain) {
|
|
// Skip disabled vtp domains
|
|
if (in_array($vtpdomain['managementDomainRowStatus'], [ 'notInService', 'notReady', 'destroy' ])) {
|
|
continue;
|
|
}
|
|
|
|
if ($vtpdomain['managementDomainName']) {
|
|
echo("(Domain $vtp_domain_index " . $vtpdomain['managementDomainName'] . ")");
|
|
} else {
|
|
echo("(Domain $vtp_domain_index" . ")");
|
|
}
|
|
|
|
foreach ($vtpvlans[$vtp_domain_index] as $vlan_id => $vlan) {
|
|
// Skip extra entries with unknown state
|
|
if (!isset($vlan['vtpVlanState'], $vlan['vtpVlanType'])) {
|
|
continue;
|
|
}
|
|
|
|
// Vlan context exist validated below
|
|
$vlan_array = [
|
|
'ifIndex' => $vlan['vtpVlanIfIndex'],
|
|
'vlan_domain' => $vtp_domain_index,
|
|
'vlan_vlan' => $vlan_id,
|
|
'vlan_name' => $vlan['vtpVlanName'],
|
|
'vlan_mtu' => $vlan['vtpVlanMtu'],
|
|
'vlan_type' => $vlan['vtpVlanType'],
|
|
'vlan_status' => $vlan['vtpVlanState'],
|
|
'vlan_context' => 0
|
|
];
|
|
$discovery_vlans[$vtp_domain_index][$vlan_id] = $vlan_array;
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Check if per port vlans (with contexts) supported by Q-BRIDGE-MIB
|
|
$check_ports_vlans = isset($config['os'][$device['os']]['snmp']['virtual']) &&
|
|
$config['os'][$device['os']]['snmp']['virtual'];
|
|
if ($check_ports_vlans && is_device_mib($device, 'Q-BRIDGE-MIB')) {
|
|
// This shit only seems to work on Cisco (probably only IOS/IOS-XE and NX-OS),
|
|
// But doesn't worry, walking do only if vlans previously found
|
|
|
|
$ios_version = explode('(', $device['version'])[0];
|
|
|
|
if (!safe_empty($device['snmp_context'])) {
|
|
// Already configured snmp context
|
|
print_warning("WARNING: Device already configured with SNMP context, polling ports vlans not possible.");
|
|
$check_ports_vlans = FALSE;
|
|
} elseif ($device['snmp_version'] === 'v3' && $device['os'] === "ios" && version_compare($ios_version, '12.1', '<=')) {
|
|
// vlan context isn't worked on Cisco IOS <= 12.1 (SNMPv3)
|
|
print_error("ERROR: For VLAN context to work on this device please use SNMP v2/v1 for this device (or upgrade IOS).");
|
|
$check_ports_vlans = FALSE;
|
|
}
|
|
}
|
|
|
|
if ($check_ports_vlans && safe_count($discovery_vlans)) { // Per port vlans walking allowed (see above)
|
|
// Fetch first domain index
|
|
$vtp_domain_index = array_key_first($discovery_vlans);
|
|
|
|
$vlans = array_keys($discovery_vlans[$vtp_domain_index]);
|
|
shuffle($vlans); // Shuffle vlans, prevent vlan1 be first
|
|
foreach ($vlans as $vlan_id) {
|
|
/* Per port vlans */
|
|
|
|
// /usr/bin/snmpbulkwalk -v2c -c kglk5g3l454@988 -OQUs -m BRIDGE-MIB -M /opt/observium/mibs/ udp:sw2.ahf:161 dot1dStpPortEntry
|
|
// /usr/bin/snmpbulkwalk -v2c -c kglk5g3l454@988 -OQUs -m BRIDGE-MIB -M /opt/observium/mibs/ udp:sw2.ahf:161 dot1dBasePortEntry
|
|
|
|
// FIXME - do this only when vlan type == ethernet?
|
|
// Cisco IOS Vlans:
|
|
// 0, 4095 For system use only. You cannot see or use these VLANs.
|
|
// 1002-1005 Cisco defaults for FDDI and Token Ring. You cannot delete VLANs 1002-1005
|
|
if (is_numeric($vlan_id) &&
|
|
$vlan_id != 4095 && ($vlan_id < 1002 || $vlan_id > 1005)) { // Ignore reserved VLAN IDs
|
|
$vlan_data = [];
|
|
|
|
// Vlan specific context
|
|
if ($device['snmp_version'] === 'v3') {
|
|
$context = 'vlan-' . $vlan_id;
|
|
} else {
|
|
$context = $vlan_id;
|
|
}
|
|
|
|
$context_valid = snmp_virtual_exist($device, $context);
|
|
if ($context_valid) {
|
|
$device_context = $device;
|
|
// Add vlan context for snmp auth
|
|
$device_context['snmp_context'] = $context;
|
|
// Set retries to 1 for speedup walking
|
|
//$device_context['snmp_retries'] = 1;
|
|
|
|
$vlan_data = snmpwalk_cache_oid($device_context, "dot1dBasePortIfIndex", $vlan_data, "BRIDGE-MIB");
|
|
if (snmp_status()) {
|
|
// FIXME. disable STP by default?
|
|
$vlan_data = snmpwalk_cache_oid($device_context, "dot1dStpPortEntry", $vlan_data, "BRIDGE-MIB:Q-BRIDGE-MIB");
|
|
//$vlan_data = snmpwalk_cache_oid($device_context, "dot1dStpPortPriority", $vlan_data, "BRIDGE-MIB:Q-BRIDGE-MIB");
|
|
//$vlan_data = snmpwalk_cache_oid($device_context, "dot1dStpPortState", $vlan_data, "BRIDGE-MIB:Q-BRIDGE-MIB");
|
|
//$vlan_data = snmpwalk_cache_oid($device_context, "dot1dStpPortPathCost", $vlan_data, "BRIDGE-MIB:Q-BRIDGE-MIB");
|
|
}
|
|
unset($device_context);
|
|
|
|
// At this point vlan context is validated and exist
|
|
$discovery_vlans[$vtp_domain_index][$vlan_id]['vlan_context'] = 1;
|
|
} elseif ($context_valid === FALSE &&
|
|
!snmp_virtual_exist($device, $context, 'dot1dBaseNumPorts')) {
|
|
// dot1dBaseBridgeAddress.0 = 0:0:0:0:0:0
|
|
// dot1dBaseNumPorts.0 = 0
|
|
// dot1dBaseType.0 = transparent-only
|
|
|
|
print_debug("VLANs context failed, loop stopped.");
|
|
|
|
// Stop loop for other vlans
|
|
break;
|
|
}
|
|
|
|
if ($vlan_data) {
|
|
print_debug(str_pad("dot1d id", 10) . str_pad("ifIndex", 10) . str_pad("Port Name", 25) .
|
|
str_pad("Priority", 10) . str_pad("State", 15) . str_pad("Cost", 10));
|
|
}
|
|
|
|
foreach ($vlan_data as $vlan_port_id => $vlan_port) {
|
|
$ifIndex = $vlan_port['dot1dBasePortIfIndex'];
|
|
$discovery_ports_vlans[$ifIndex][$vlan_id] = [
|
|
'vlan' => $vlan_id,
|
|
// FIXME. move STP to separate table
|
|
'baseport' => $vlan_port_id,
|
|
'priority' => $vlan_port['dot1dStpPortPriority'],
|
|
'state' => $vlan_port['dot1dStpPortState'],
|
|
'cost' => $vlan_port['dot1dStpPortPathCost']
|
|
];
|
|
}
|
|
} else {
|
|
unset($module_stats[$vlan_id]);
|
|
}
|
|
/* End per port vlans */
|
|
}
|
|
}
|
|
|
|
echo(PHP_EOL);
|
|
|
|
// EOF
|