966 lines
46 KiB
PHP
966 lines
46 KiB
PHP
<?php
|
|
/**
|
|
* Observium
|
|
*
|
|
* This file is part of Observium.
|
|
*
|
|
* @package observium
|
|
* @subpackage poller
|
|
* @copyright (C) Adam Armstrong
|
|
*
|
|
*/
|
|
|
|
// Include description parser (usually ifAlias) if config option set
|
|
$custom_port_parser = FALSE;
|
|
if (isset($config['port_descr_parser']) && $config['port_descr_parser'] != FALSE &&
|
|
is_file($config['install_dir'] . "/" . $config['port_descr_parser'])) {
|
|
include_once($config['install_dir'] . "/" . $config['port_descr_parser']);
|
|
|
|
if (function_exists('custom_port_parser')) {
|
|
$custom_port_attribs = ['type', 'descr', 'circuit', 'speed', 'notes'];
|
|
$custom_port_parser = TRUE;
|
|
} else {
|
|
print_error("ERROR: Rewrite your custom ports parser in file [" . $config['install_dir'] . "/" . $config['port_descr_parser'] . "], using a function custom_port_parser().");
|
|
$custom_port_parser = 'old';
|
|
}
|
|
}
|
|
|
|
// Cache ports table from DB
|
|
$ports = [];
|
|
|
|
// FIXME -- this stuff is a little messy, looping the array to make an array just seems wrong. :>
|
|
// -- i can make it a function, so that you don't know what it's doing.
|
|
// -- $ports = adamasMagicFunction($ports_db); ?
|
|
|
|
$query = 'SELECT * FROM `ports` WHERE `device_id` = ?';
|
|
|
|
//$ports_db = dbFetchRows($query, [ $device['device_id'] ]); // Termporary var, no need to assign
|
|
$ports_attribs = get_device_entities_attribs($device['device_id'], 'port'); // Get all attribs
|
|
//print_vars($ports_attribs);
|
|
foreach (dbFetchRows($query, [$device['device_id']]) as $port) {
|
|
if (isset($ports_attribs['port'][$port['port_id']])) {
|
|
$port = array_merge($port, $ports_attribs['port'][$port['port_id']]);
|
|
}
|
|
$ports[$port['ifIndex']] = $port;
|
|
}
|
|
$ports_ignored_count_db = (int)get_entity_attrib('device', $device, 'ports_ignored_count'); // Cache last ports ignored count
|
|
|
|
// Ports module options
|
|
$ports_modules = []; // Ports sub-modules enabled/disabled
|
|
foreach (array_keys($config) as $ports_module) {
|
|
if (!str_starts($ports_module, 'enable_ports_')) {
|
|
continue;
|
|
} // Filter only enable_ports_* config entries
|
|
$ports_module = str_replace('enable_ports_', '', $ports_module);
|
|
|
|
//$ports_modules[$ports_module] = isset($attribs['enable_ports_' . $ports_module]) ? (bool)$attribs['enable_ports_' . $ports_module] : $config['enable_ports_' . $ports_module];
|
|
$ports_modules[$ports_module] = is_module_enabled($device, 'ports_' . $ports_module);
|
|
}
|
|
// Additionally, force enable separate walk feature for some device oses, but only if ports total count >10
|
|
$ports_module = 'separate_walk';
|
|
// Model definition can override os definition
|
|
$model_separate_walk = isset($model['ports_' . $ports_module]) && $model['ports_' . $ports_module];
|
|
if (!$ports_modules[$ports_module] && $model_separate_walk) {
|
|
if (isset($attribs['enable_ports_' . $ports_module]) && !$attribs['enable_ports_' . $ports_module]) {
|
|
} // forcing disabled in device config
|
|
else {
|
|
$ports_total_count = $ports_ignored_count_db + dbFetchCell('SELECT COUNT(*) FROM `ports` WHERE `device_id` = ? AND `deleted` = 0', [$device['device_id']]);
|
|
$ports_modules[$ports_module] = $ports_total_count > 10;
|
|
if (OBS_DEBUG && $ports_modules[$ports_module]) {
|
|
print_debug('Forced ports separate walk feature!');
|
|
}
|
|
}
|
|
}
|
|
print_debug_vars($ports_modules);
|
|
|
|
$table_rows = [];
|
|
|
|
// Build SNMP Cache Array
|
|
|
|
// IF-MIB OIDs that go into the ports table
|
|
|
|
$data_oids_ifEntry = [
|
|
// ifEntry
|
|
'ifDescr', 'ifType', 'ifMtu', 'ifSpeed', 'ifPhysAddress',
|
|
'ifAdminStatus', 'ifOperStatus', 'ifLastChange',
|
|
];
|
|
$data_oids_ifXEntry = [
|
|
// ifXEntry
|
|
'ifName', 'ifAlias', 'ifHighSpeed', 'ifPromiscuousMode', 'ifConnectorPresent',
|
|
];
|
|
$data_oids = array_merge($data_oids_ifEntry,
|
|
$data_oids_ifXEntry,
|
|
[ 'ifDuplex', 'ifTrunk', 'ifVlan' ]); // Add additional oids
|
|
|
|
// IF-MIB statistics OIDs that go into RRD
|
|
|
|
$stat_oids_ifEntry = [
|
|
// ifEntry
|
|
'ifInOctets', 'ifOutOctets',
|
|
'ifInUcastPkts', 'ifOutUcastPkts',
|
|
'ifInNUcastPkts', 'ifOutNUcastPkts', // Note, (In|Out)NUcastPkts deprecated, for HC counters use Broadcast+Multicast instead
|
|
'ifInDiscards', 'ifOutDiscards',
|
|
'ifInErrors', 'ifOutErrors',
|
|
'ifInUnknownProtos',
|
|
];
|
|
|
|
$stat_oids_ifXEntry = [
|
|
// ifXEntry
|
|
'ifInMulticastPkts', 'ifOutMulticastPkts',
|
|
'ifInBroadcastPkts', 'ifOutBroadcastPkts',
|
|
// HC counters
|
|
'ifHCInOctets', 'ifHCOutOctets',
|
|
'ifHCInUcastPkts', 'ifHCOutUcastPkts',
|
|
'ifHCInMulticastPkts', 'ifHCOutMulticastPkts',
|
|
'ifHCInBroadcastPkts', 'ifHCOutBroadcastPkts',
|
|
];
|
|
|
|
// This oids definitions used only for Upstream/Downstream interface types
|
|
$upstream_oids = [
|
|
// ifEntry
|
|
'ifInOctets', 'ifInUcastPkts', 'ifInNUcastPkts', 'ifInDiscards', 'ifInErrors',
|
|
// ifXEntry
|
|
'ifInMulticastPkts', 'ifInBroadcastPkts', 'ifHCInOctets', 'ifHCInUcastPkts', 'ifHCInMulticastPkts', 'ifHCInBroadcastPkts',
|
|
];
|
|
$downstream_oids = [
|
|
// ifEntry
|
|
'ifOutOctets', 'ifOutUcastPkts', 'ifOutNUcastPkts', 'ifOutDiscards', 'ifOutErrors',
|
|
// ifXEntry
|
|
'ifOutMulticastPkts', 'ifOutBroadcastPkts', 'ifHCOutOctets', 'ifHCOutUcastPkts', 'ifHCOutMulticastPkts', 'ifHCOutBroadcastPkts',
|
|
];
|
|
|
|
// Remove HC oids from stat arrays for SNMP v1 or 64bit module disabled
|
|
if ($device['snmp_version'] === 'v1' || !$ports_modules['64bit']) {
|
|
$hc_oids = [
|
|
// HC counters
|
|
'ifHCInOctets', 'ifHCOutOctets',
|
|
'ifHCInUcastPkts', 'ifHCOutUcastPkts',
|
|
'ifHCInMulticastPkts', 'ifHCOutMulticastPkts',
|
|
'ifHCInBroadcastPkts', 'ifHCOutBroadcastPkts',
|
|
];
|
|
$stat_oids_ifXEntry = array_diff($stat_oids_ifXEntry, $hc_oids);
|
|
$upstream_oids = array_diff($upstream_oids, $hc_oids);
|
|
$downstream_oids = array_diff($downstream_oids, $hc_oids);
|
|
}
|
|
|
|
// Merge stat oids
|
|
$stat_oids = array_merge($stat_oids_ifEntry, $stat_oids_ifXEntry);
|
|
|
|
// PAgP OIDs
|
|
|
|
// PAgP disabled since r7987, while not moved to new polling style
|
|
//$pagp_oids = array('pagpOperationMode', 'pagpPortState', 'pagpPartnerDeviceId', 'pagpPartnerLearnMethod', 'pagpPartnerIfIndex', 'pagpPartnerGroupIfIndex',
|
|
// 'pagpPartnerDeviceName', 'pagpEthcOperationMode', 'pagpDeviceId', 'pagpGroupIfIndex');
|
|
|
|
//$ifmib_oids = array_merge($data_oids, $stat_oids);
|
|
|
|
print_cli_data_field("Caching Oids");
|
|
$port_stats = [];
|
|
$include_stats = [];
|
|
if (is_device_mib($device, "IF-MIB")) {
|
|
$inc_start = microtime(TRUE); // MIB timing start
|
|
|
|
if (!$ports_modules['separate_walk']) {
|
|
print_debug("Used full table ifEntry/ifXEntry snmpwalk.");
|
|
$ifmib_oids = [ 'ifEntry', 'ifXEntry' ];
|
|
foreach ($ifmib_oids as $oid) {
|
|
$has_name = 'has_' . $oid;
|
|
echo("$oid ");
|
|
|
|
// End walk before Oid have effect only for nobulk!
|
|
if ($oid === 'ifEntry') {
|
|
// stop walk after ifOutErrors (next ifOutQLen)
|
|
snmpwalk_oid_end('ifOutQLen');
|
|
} else {
|
|
// stop walk after ifAlias (next ifCounterDiscontinuityTime)
|
|
snmpwalk_oid_end('ifCounterDiscontinuityTime');
|
|
}
|
|
|
|
$port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "IF-MIB");
|
|
$$has_name = snmp_status() || snmp_error_code() === OBS_SNMP_ERROR_REQUEST_NOT_COMPLETED; // $has_ifEntry, $has_ifXEntry
|
|
//print_vars($$has_name);
|
|
if ($oid === 'ifEntry') {
|
|
// Store error_code, 1000 == not exist table, 2 and 3 - not complete request
|
|
$has_ifEntry_error_code = snmp_error_code();
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
print_debug("Used separate data tables snmpwalk and per port snmpget.");
|
|
|
|
$has_ifEntry = FALSE;
|
|
// Data fields
|
|
// ifDescr, ifAlias, ifName, ifType, ifOperStatus
|
|
foreach ([ 'ifDescr', 'ifType', 'ifOperStatus', 'ifAdminStatus' ] as $oid) {
|
|
echo("$oid ");
|
|
$port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "IF-MIB");
|
|
$has_ifEntry = $has_ifEntry || snmp_status();
|
|
$has_ifEntry_error_code = snmp_error_code();
|
|
}
|
|
$has_ifXEntry = FALSE;
|
|
foreach ([ 'ifAlias', 'ifName', 'ifHighSpeed' ] as $oid) {
|
|
echo("$oid ");
|
|
$port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "IF-MIB");
|
|
$has_ifXEntry = $has_ifXEntry || snmp_status();
|
|
}
|
|
|
|
// Per port snmpget
|
|
if ($port_stats) {
|
|
// Collect oids for per port snmpget
|
|
if ($has_ifXEntry) {
|
|
$port_oids = array_merge($stat_oids_ifXEntry, $stat_oids_ifEntry);
|
|
$port_oids = array_merge($port_oids, array_diff($data_oids_ifEntry, [ 'ifDescr', 'ifType', 'ifOperStatus', 'ifAdminStatus' ]));
|
|
$port_oids = array_merge($port_oids, array_diff($data_oids_ifXEntry, [ 'ifAlias', 'ifName', 'ifHighSpeed' ]));
|
|
} else {
|
|
$port_oids = array_merge($stat_oids_ifEntry,
|
|
array_diff($data_oids_ifEntry, [ 'ifDescr', 'ifType', 'ifOperStatus' ]));
|
|
}
|
|
|
|
// Use snmpget for each (not ignored) port
|
|
// NOTE. This method reduce polling time when too many ports (>100)
|
|
echo(implode(' ', $port_oids) . ", ifIndex: ");
|
|
foreach ($port_stats as $ifIndex => $port) {
|
|
$port_disabled = isset($ports[$ifIndex]['disabled']) && $ports[$ifIndex]['disabled']; // Port polling disabled from WUI
|
|
// On some Brocade NOS
|
|
if ($port['ifOperStatus'] === '-1') {
|
|
$port['ifOperStatus'] = 'unknown';
|
|
}
|
|
|
|
if (!$port_disabled && is_port_valid($device, $port)) {
|
|
echo("\nifIndex $ifIndex (ifAdminStatus = {$port['ifAdminStatus']}, ifOperStatus = {$port['ifOperStatus']}). ");
|
|
|
|
// Skip get snmp data when port down and not changed from previous
|
|
$port_skip_data = $ports[$ifIndex]['ifOperStatus'] === $port['ifOperStatus'] &&
|
|
$ports[$ifIndex]['ifAdminStatus'] === $port['ifAdminStatus'] &&
|
|
($port['ifOperStatus'] === 'down' || $port['ifOperStatus'] === 'lowerLayerDown' ||
|
|
$port['ifOperStatus'] === 'notPresent' || $port['ifAdminStatus'] === 'down');
|
|
|
|
if ($port_skip_data) {
|
|
print_debug("Skipped snmpget for ifOperStatus or ifAdminStatus down");
|
|
|
|
$port_has_64bit = $device['snmp_version'] !== 'v1' && $ports_modules['64bit'] && $ports[$ifIndex]['port_64bit'];
|
|
foreach ($port_oids as $port_oid) {
|
|
// Copy previous values
|
|
if ($port_has_64bit && str_starts_with($port_oid, 'ifHC')) {
|
|
// Copy HC counter
|
|
$port_oid_old = str_replace('ifHC', 'if', $port_oid);
|
|
$port_stats[$ifIndex][$port_oid] = $ports[$ifIndex][$port_oid_old];
|
|
} else {
|
|
$port_stats[$ifIndex][$port_oid] = $ports[$ifIndex][$port_oid] ?? '0'; // ifInUnknownProtos not stored in db
|
|
}
|
|
}
|
|
print_debug_vars($port_stats[$ifIndex]);
|
|
} else {
|
|
$port_oid = implode(".$ifIndex ", $port_oids) . ".$ifIndex";
|
|
$port_stats = snmp_get_multi_oid($device, $port_oid, $port_stats, "IF-MIB");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// MIB timing
|
|
$include_stats['IF-MIB'] = elapsed_time($inc_start);
|
|
// End IF-MIB permitted
|
|
}
|
|
//else {
|
|
// This part for devices who not have IF-MIB stats, but have own vendor tree with ports
|
|
//}
|
|
echo PHP_EOL; // End IF-MIB section
|
|
|
|
//////////
|
|
$private_stats = [];
|
|
foreach (get_device_mibs_permitted($device) as $mib) {
|
|
$private_stats[] = merge_private_mib($device, 'ports', $mib, $port_stats, NULL);
|
|
}
|
|
$include_stats = array_merge($include_stats, ...$private_stats);
|
|
unset($private_stats);
|
|
print_debug_vars($include_stats);
|
|
////////
|
|
|
|
// Prevent mark ports as DELETED when ifEntry snmpwalk return not complete data!
|
|
$allow_delete_ports = $has_ifEntry_error_code !== OBS_SNMP_ERROR_REQUEST_NOT_COMPLETED && $has_ifEntry_error_code !== OBS_SNMP_ERROR_TOO_LONG_RESPONSE;
|
|
|
|
// Store polled time exactly after walk IF-MIB, for more correct port speed calculate!
|
|
$polled = time();
|
|
|
|
// Device uptime and polled time (required for ifLastChange)
|
|
if (isset($cache['devices']['uptime'][$device['device_id']])) {
|
|
$device_uptime = &$cache['devices']['uptime'][$device['device_id']];
|
|
} else {
|
|
print_error("Device uptime not cached, ifLastChange will incorrect. Check polling system module.");
|
|
}
|
|
|
|
// Subset of IF-MIB OIDs that we put into the state table
|
|
$stat_oids_db = [ 'ifInOctets', 'ifOutOctets', 'ifInErrors', 'ifOutErrors', 'ifInUcastPkts', 'ifOutUcastPkts',
|
|
'ifInNUcastPkts', 'ifOutNUcastPkts', 'ifInBroadcastPkts', 'ifOutBroadcastPkts',
|
|
'ifInMulticastPkts', 'ifOutMulticastPkts', 'ifInDiscards', 'ifOutDiscards' ];
|
|
|
|
// Subset of IF-MIB OIDs that we put into the ports table
|
|
$data_oids_db = array_diff($data_oids, ['ifLastChange']); // remove ifLastChange, because it added separate
|
|
$data_oids_db = array_merge($data_oids_db, ['port_label', 'port_label_short', 'port_label_base', 'port_label_num']);
|
|
|
|
// Additional MIBS and modules
|
|
$process_port_functions = []; // collect processing functions
|
|
$process_port_db = []; // collect processing db fields
|
|
|
|
// Additionally include per MIB functions and snmpwalks (uses include_once)
|
|
$port_stats_count = safe_count($port_stats);
|
|
$include_lib = TRUE;
|
|
$include_dir = "includes/polling/ports/";
|
|
include("includes/include-dir-mib.inc.php");
|
|
|
|
if (!safe_empty($include_stats)) {
|
|
// Set per mib polling times
|
|
$device_state['poller_ports_perf'] = $include_stats;
|
|
}
|
|
print_debug_vars($include_stats);
|
|
unset($include_stats);
|
|
|
|
if (safe_count($port_stats)) {
|
|
|
|
// If the device is cisco, pull a few cisco-specific MIBs and try to get vlan data from CISCO-VTP-MIB
|
|
/* PAgP disabled since r7987, while not moved to new polling style
|
|
if ($device['os_group'] === "cisco") {
|
|
//FIXME. All PAGP operations should be moved to separate "stacks" module and separate table (not in ports table)
|
|
foreach ($pagp_oids as $oid)
|
|
{
|
|
$port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "CISCO-PAGP-MIB");
|
|
// Break if no PAGP tables on device
|
|
if ($oid == 'pagpOperationMode' && $GLOBALS['snmp_status'] === FALSE) { break; }
|
|
}
|
|
}
|
|
*/
|
|
|
|
// End Building SNMP Cache Array
|
|
|
|
$graphs['bits'] = TRUE; // Create global device_bits graph, since we have ports.
|
|
|
|
print_debug_vars($port_stats);
|
|
}
|
|
|
|
// New interface detection
|
|
$ports_ignored_count = 0; // Counting ignored ports
|
|
$ports_deleted_count = 0; // Counting deleted ports
|
|
$ports_db_deleted = []; // MultiUpdate deleted ports db
|
|
$ports_db_state = []; // MultiUpdate state ports db
|
|
foreach ($port_stats as $ifIndex => $port) {
|
|
// Always use ifIndex from index part (not from Oid!),
|
|
// Oid can have incorrect ifIndex, ie:
|
|
// ifIndex.0 = 1
|
|
$port['ifIndex'] = $ifIndex;
|
|
|
|
// On some Brocade NOS
|
|
if ($port['ifOperStatus'] === '-1') {
|
|
$port['ifOperStatus'] = 'unknown';
|
|
}
|
|
|
|
if (is_port_valid($device, $port)) {
|
|
if (!is_array($ports[$port['ifIndex']])) {
|
|
$port_insert = ['device_id' => $device['device_id'],
|
|
'ifIndex' => $ifIndex,
|
|
'ignore' => isset($port['ignore']) ? $port['ignore'] : '0',
|
|
'disabled' => isset($port['disabled']) ? $port['disabled'] : '0'];
|
|
$port_id = dbInsert(['device_id' => $device['device_id'], 'ifIndex' => $ifIndex], 'ports');
|
|
$ports[$port['ifIndex']] = dbFetchRow("SELECT * FROM `ports` WHERE `port_id` = ?", [$port_id]);
|
|
print_message("Adding: " . $port['ifDescr'] . "(" . $ifIndex . ")(" . $ports[$port['ifIndex']]['port_id'] . ")");
|
|
} elseif ($ports[$ifIndex]['deleted'] == "1") {
|
|
$ports_db_deleted[] = [
|
|
// UNIQUE fields
|
|
'port_id' => $ports[$ifIndex]['port_id'], 'ifIndex' => $ifIndex, 'device_id' => $device['device_id'],
|
|
// Update this fields
|
|
'deleted' => '0', 'ifLastChange' => date('Y-m-d H:i:s', $polled)
|
|
];
|
|
log_event("Interface DELETED mark removed", $device, 'port', $ports[$ifIndex]);
|
|
$ports[$ifIndex]['deleted'] = "0";
|
|
}
|
|
} else {
|
|
if (isset($ports[$port['ifIndex']]) && $ports[$port['ifIndex']]['deleted'] != '1' && $allow_delete_ports) {
|
|
$ports_db_deleted[] = [
|
|
// UNIQUE fields
|
|
'port_id' => $ports[$ifIndex]['port_id'], 'ifIndex' => $ifIndex, 'device_id' => $device['device_id'],
|
|
// Update this fields
|
|
'deleted' => '1', 'ifLastChange' => date('Y-m-d H:i:s', $polled)
|
|
];
|
|
//log_event("Interface was marked as DELETED", $device, 'port', $ports[$ifIndex]);
|
|
$ports[$ifIndex]['deleted'] = "1";
|
|
$ports_deleted_count++;
|
|
}
|
|
$ports_ignored_count++; // Counting ignored ports
|
|
}
|
|
}
|
|
|
|
if (!$allow_delete_ports) {
|
|
log_event("WARNING! Ports snmpwalk did not complete. Try to increase SNMP timeout on the device properties page.", $device, 'device', $device['device_id'], 7);
|
|
} elseif ($ports_deleted_count > 0) {
|
|
// Recheck device is snmpable, can be case when device down while polling
|
|
$device['snmpable'] = is_snmpable($device);
|
|
if (!$device['snmpable']) {
|
|
// When device down, prevent other ports updates
|
|
log_event("WARNING! Poll ports ended prematurely because the device became unavailable. Try to increase SNMP timeout on the device properties page.", $device, 'device', $device['device_id'], 7);
|
|
$device['status'] = 0;
|
|
return;
|
|
}
|
|
|
|
foreach ($ports_db_deleted as $entry) {
|
|
if ($entry['deleted'] == '1') {
|
|
log_event("Interface was marked as DELETED", $device, 'port', $entry['port_id']);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($ports_ignored_count !== $ports_ignored_count_db) {
|
|
set_entity_attrib('device', $device, 'ports_ignored_count', $ports_ignored_count);
|
|
}
|
|
// End New interface detection
|
|
|
|
echo(PHP_EOL . PHP_EOL);
|
|
|
|
// Loop ports in the DB and update where necessary
|
|
foreach ($ports as $port) {
|
|
// Notes:
|
|
// $port_stats - array of ports from snmpwalks
|
|
// $this_port - link to port array from snmpwalk
|
|
// $ports - array of ports based on current db entries
|
|
// $port - current port array from db
|
|
if ($port['deleted']) {
|
|
continue;
|
|
} // Skip updating RRDs and DB if interface marked as DELETED (also skipped bad_if's)
|
|
|
|
if ($port_stats[$port['ifIndex']] && $port['disabled'] != "1") {
|
|
// Check to make sure Port data is cached.
|
|
$this_port = &$port_stats[$port['ifIndex']];
|
|
|
|
$port['update'] = [];
|
|
$port['state'] = []; // State field for update
|
|
|
|
// Poll time and period
|
|
if (isset($this_port['polled']) && is_intnum($this_port['polled']) &&
|
|
($this_port['polled'] > OBS_MIN_UNIXTIME)) {
|
|
// See SPECTRA-LOGIC-STRATA-MIB definition
|
|
} else {
|
|
$this_port['polled'] = $polled;
|
|
}
|
|
$polled_period = $this_port['polled'] - $port['poll_time'];
|
|
$port['state']['poll_time'] = $this_port['polled'];
|
|
$port['state']['poll_period'] = $polled_period;
|
|
// $polled_period = $polled - $port['poll_time'];
|
|
// $port['state']['poll_time'] = $polled;
|
|
// $port['state']['poll_period'] = $polled_period;
|
|
|
|
$this_port['port_id'] = $port['port_id'];
|
|
$this_port['ifIndex'] = $port['ifIndex'];
|
|
$this_port_indexes = ['port_id' => $ports[$port['ifIndex']]['port_id'], 'ifIndex' => $port['ifIndex'], 'device_id' => $device['device_id']]; // UNIQUE port indexes
|
|
|
|
// Store original port walked OIDs for debugging later
|
|
if ($config['debug_port']['spikes'] || $config['debug_port'][$port['port_id']]) {
|
|
$debug_port = $this_port; // DEBUG
|
|
}
|
|
|
|
//print_vars($process_port_functions);
|
|
foreach ($process_port_functions as $func => $ok) {
|
|
if ($ok && function_exists('process_port_' . $func)) {
|
|
if (OBS_DEBUG > 1) {
|
|
print_debug("Processing port ifIndex " . $this_port['ifIndex'] . " with function process_port_{$func}() ");
|
|
}
|
|
// Note, used call by array, because parameters for call_user_func() are not passed by reference
|
|
call_user_func_array('process_port_' . $func, [&$this_port, $device, $port]);
|
|
}
|
|
}
|
|
|
|
/* Start process_port_label() */
|
|
// Before process_port_label()
|
|
// Fix ord (UTF-8) chars, ie:
|
|
// ifAlias.3 = Conexi<F3>n de <E1>rea local* 3
|
|
foreach ([ 'ifAlias', 'ifDescr', 'ifName' ] as $oid_fix) {
|
|
if (!isset($this_port[$oid_fix]) ||
|
|
($oid_fix !== 'ifAlias' && is_hex_string($this_port[$oid_fix]))) {
|
|
// In cases, when device have memory leak, they return hex string instead UTF, rewritten in process_port_label()
|
|
continue;
|
|
}
|
|
|
|
$this_port[$oid_fix] = snmp_fix_string($this_port[$oid_fix]);
|
|
}
|
|
process_port_label($this_port, $device);
|
|
/* End process_port_label() */
|
|
//print_vars($this_port);
|
|
|
|
# // Copy ifHC[In|Out] values to non-HC if they exist
|
|
# // Check if they're greater than zero to work around stupid devices which expose HC counters, but don't populate them. HERPDERP. - adama
|
|
# if ($device['os'] == "netapp") { $hc_prefixes = array('HC', '64'); } else { $hc_prefixes = array('HC'); }
|
|
# foreach ($hc_prefixes as $hc_prefix)
|
|
# {
|
|
# foreach (array('Octets', 'UcastPkts', 'BroadcastPkts', 'MulticastPkts') as $hc)
|
|
# {
|
|
# $hcin = 'if'.$hc_prefix.'In'.$hc;
|
|
# $hcout = 'if'.$hc_prefix.'Out'.$hc;
|
|
# if (is_numeric($this_port[$hcin]) && $this_port[$hcin] > 0 && is_numeric($this_port[$hcout]) && $this_port[$hcout] > 0)
|
|
# {
|
|
# // echo(" ".$hc_prefix." $hc, ");
|
|
# $this_port['ifIn'.$hc] = $this_port[$hcin];
|
|
# $this_port['ifOut'.$hc] = $this_port[$hcout];
|
|
# }
|
|
# }
|
|
# }
|
|
|
|
// Here special checks for Upstream/Downstream ports, because it have only In or only Out counters
|
|
if (str_contains($this_port['ifType'], 'Upstream')) {
|
|
// Upstream has only In counters
|
|
foreach ($upstream_oids as $oid_in) {
|
|
$oid_out = str_replace('In', 'Out', $oid_in);
|
|
if (is_numeric($this_port[$oid_in]) && !is_numeric($this_port[$oid_out])) {
|
|
$this_port[$oid_out] = 0; // Set it all to zero
|
|
}
|
|
}
|
|
} elseif (str_contains($this_port['ifType'], 'Downstream')) {
|
|
// Downstream has only Out counters
|
|
foreach ($downstream_oids as $oid_out) {
|
|
$oid_in = str_replace('Out', 'In', $oid_out);
|
|
if (is_numeric($this_port[$oid_out]) && !is_numeric($this_port[$oid_in])) {
|
|
$this_port[$oid_in] = 0; // Set it all to zero
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we're not using SNMPv1, assume there are 64-bit values and overwrite the 32-bit OIDs.
|
|
if ($device['snmp_version'] !== 'v1' && $ports_modules['64bit']) {
|
|
$hc_prefix = 'HC';
|
|
$port_has_64bit = is_numeric($this_port['if' . $hc_prefix . 'InOctets']) && is_numeric($this_port['if' . $hc_prefix . 'OutOctets']);
|
|
|
|
// We've never tested for 64bit. Lets do it now. Lots of devices seem to not support 64bit counters for all ports.
|
|
if (safe_empty($port['port_64bit'])) {
|
|
// We have 64-bit traffic counters. Lets set port_64bit
|
|
if ($port_has_64bit) {
|
|
$port['port_64bit'] = 1;
|
|
$port['update']['port_64bit'] = 1;
|
|
} else {
|
|
$port['port_64bit'] = 0;
|
|
$port['update']['port_64bit'] = 0;
|
|
}
|
|
} elseif ($has_ifXEntry && $port_has_64bit && !$port['port_64bit']) {
|
|
// Port changed to 64-bit
|
|
$port['port_64bit'] = 1;
|
|
$port['update']['port_64bit'] = 1;
|
|
log_event('Interface changed: [HC] 64bit counters enabled (may cause disposable spike)', $device, 'port', $port);
|
|
}
|
|
|
|
$port_has_mcbc = is_numeric($this_port['ifInBroadcastPkts']) && is_numeric($this_port['ifOutBroadcastPkts']) &&
|
|
is_numeric($this_port['ifInMulticastPkts']) && is_numeric($this_port['ifOutMulticastPkts']);
|
|
|
|
if ($port['port_mcbc'] == NULL) {
|
|
// We have Broadcast/Multicast traffic counters. Let's set port_mcbc
|
|
if ($port_has_mcbc) {
|
|
$port['port_mcbc'] = 1;
|
|
$port['update']['port_mcbc'] = 1;
|
|
} else {
|
|
$port['port_mcbc'] = 0;
|
|
$port['update']['port_mcbc'] = 0;
|
|
}
|
|
} elseif ($has_ifXEntry && $port_has_mcbc && !$port['port_mcbc']) {
|
|
// Port acquired multicast/broadcast!
|
|
$port['port_mcbc'] = 1;
|
|
$port['update']['port_mcbc'] = 1;
|
|
log_event('Interface changed: Separated Multicast/Broadcast statistics appeared.', $device, 'port', $port);
|
|
}
|
|
|
|
//elseif (!$port_has_64bit && $port['port_64bit'])
|
|
//{
|
|
// // Port changed to 32-bit
|
|
// $port['port_64bit'] = 0;
|
|
// $port['update']['port_64bit'] = 0;
|
|
// log_event('Interface changed: [HC] -> Counter32', $device, 'port', $port);
|
|
//}
|
|
|
|
if ($port['port_64bit']) {
|
|
print_debug("64-bit, ");
|
|
foreach ([ 'Octets', 'UcastPkts', 'BroadcastPkts', 'MulticastPkts' ] as $hc) {
|
|
$hcin = 'if' . $hc_prefix . 'In' . $hc;
|
|
$hcout = 'if' . $hc_prefix . 'Out' . $hc;
|
|
$this_port['ifIn' . $hc] = $this_port[$hcin];
|
|
$this_port['ifOut' . $hc] = $this_port[$hcout];
|
|
}
|
|
// Additionally override (In|Out)NUcastPkts
|
|
// see: http://jira.observium.org/browse/OBSERVIUM-1749
|
|
$this_port['ifInNUcastPkts'] = int_add($this_port['ifInBroadcastPkts'], $this_port['ifInMulticastPkts']);
|
|
$this_port['ifOutNUcastPkts'] = int_add($this_port['ifOutBroadcastPkts'], $this_port['ifOutMulticastPkts']);
|
|
}
|
|
} elseif ($port['port_64bit']) {
|
|
$port['port_64bit'] = 0;
|
|
$port['update']['port_64bit'] = 0;
|
|
if ($port['port_mcbc']) {
|
|
$port['port_mcbc'] = 0;
|
|
$port['update']['port_mcbc'] = 0;
|
|
}
|
|
log_event('Interface changed: [HC] 64bit counters disabled (may cause disposable spike)', $device, 'port', $port);
|
|
}
|
|
|
|
// rewrite the ifPhysAddress
|
|
// IF-MIB::ifPhysAddress.2 = STRING: 66:c:9b:1b:62:7e
|
|
// IF-MIB::ifPhysAddress.2 = Hex-STRING: 00 02 99 09 E9 84
|
|
// deeerp device return snmp string instead mac
|
|
// ifPhysAddress.3 = 30:30:2d:30:36:2d:33:39:2d:30:41:2d:35:46:2d:36:38
|
|
// ifPhysAddress.3 = STRING: "00-06-39-0A-5F-68"
|
|
$this_port['ifPhysAddress'] = mac_zeropad($this_port['ifPhysAddress']);
|
|
|
|
// ifSpeed processing
|
|
process_port_speed($this_port, $device, $port);
|
|
$port['alert_array']['ifSpeed'] = is_numeric($this_port['ifSpeed']) ? $this_port['ifSpeed'] : 0;
|
|
if (is_numeric($this_port['ifHighSpeed'])) {
|
|
$port['alert_array']['ifHighSpeed'] = $this_port['ifHighSpeed'];
|
|
}
|
|
|
|
// Simple override of ifAlias -- mostly for testing
|
|
if (isset($config['ports']['ifAlias_map']['ifIndex'][$device['hostname']][$port['ifIndex']])) {
|
|
$this_port['ifAlias'] = $config['ports']['ifAlias_map']['ifIndex'][$device['hostname']][$port['ifIndex']];
|
|
}
|
|
if (isset($config['ports']['ifAlias_map']['ifName'][$device['hostname']][$port['ifName']])) {
|
|
$this_port['ifAlias'] = $config['ports']['ifAlias_map']['ifName'][$device['hostname']][$port['ifName']];
|
|
}
|
|
|
|
// Update TrustSec
|
|
if ($this_port['encrypted']) {
|
|
if ($port['encrypted'] === '0') {
|
|
log_event("Interface is now encrypted", $device, 'port', $port);
|
|
$port['update']['encrypted'] = '1';
|
|
}
|
|
} elseif ($port['encrypted'] === '1') {
|
|
log_event("Interface is no longer encrypted", $device, 'port', $port);
|
|
$port['update']['encrypted'] = '0';
|
|
}
|
|
|
|
// Make sure ifOperStatus is valid (FIXME. not exist statuses already "filtered" in is_port_valid())
|
|
if (isset($this_port['ifOperStatus']) &&
|
|
!in_array($this_port['ifOperStatus'], [ 'testing', 'notPresent', 'dormant', 'down', 'lowerLayerDown', 'unknown', 'up', 'monitoring' ])) {
|
|
$this_port['ifOperStatus'] = 'unknown';
|
|
}
|
|
|
|
if (isset($this_port['ifAdminStatus']) &&
|
|
!in_array($this_port['ifAdminStatus'], [ 'up', 'down', 'testing' ])) {
|
|
$this_port['ifAdminStatus'] = ''; // or NULL?
|
|
}
|
|
|
|
if (isset($this_port['ifConnectorPresent']) &&
|
|
!in_array($this_port['ifConnectorPresent'], [ 'true', 'false' ])) {
|
|
$this_port['ifConnectorPresent'] = NULL;
|
|
}
|
|
|
|
// Update IF-MIB data
|
|
|
|
$log_event = [];
|
|
foreach ($data_oids_db as $oid) {
|
|
if ($port[$oid] != $this_port[$oid]) {
|
|
if (isset($this_port[$oid])) {
|
|
$port['update'][$oid] = $this_port[$oid];
|
|
$msg = "[$oid] '" . $port[$oid] . "' -> '" . $this_port[$oid] . "'";
|
|
} else {
|
|
$port['update'][$oid] = ['NULL'];
|
|
$msg = "[$oid] '" . $port[$oid] . "' -> NULL";
|
|
}
|
|
if ($oid === 'ifOperStatus' && ($port[$oid] === 'up' || $port[$oid] === 'down') && isset($this_port[$oid])) {
|
|
// Specific log_event for port Up/Down
|
|
log_event('Interface ' . ucfirst($this_port[$oid]) . ": [$oid] '" . $port[$oid] . "' -> '" . $this_port[$oid] . "'", $device, 'port', $port, 'warning');
|
|
} else {
|
|
$log_event[] = $msg;
|
|
}
|
|
if (OBS_DEBUG) {
|
|
echo($msg . " ");
|
|
} // else { echo($oid . " "); }
|
|
}
|
|
}
|
|
|
|
// ifLastChange
|
|
if (isset($this_port['ifLastChange']) && $this_port['ifLastChange'] != '') {
|
|
// Convert ifLastChange from timetick to timestamp
|
|
/**
|
|
* The value of sysUpTime at the time the interface entered
|
|
* its current operational state. If the current state was
|
|
* entered prior to the last re-initialization of the local
|
|
* network management subsystem, then this object contains a
|
|
* zero value.
|
|
*
|
|
* NOTE, observium uses last change timestamp.
|
|
*/
|
|
$if_lastchange_uptime = timeticks_to_sec($this_port['ifLastChange']);
|
|
if (preg_match(OBS_PATTERN_TIMESTAMP, $this_port['ifLastChange'])) {
|
|
// This ifLastChange copied from previous
|
|
$if_lastchange_uptime = TRUE;
|
|
} elseif (($device_uptime['sysUpTime'] - $if_lastchange_uptime) > 90) {
|
|
$if_lastchange = $device_uptime['polled'] - $device_uptime['sysUpTime'] + $if_lastchange_uptime;
|
|
print_debug('IFLASTCHANGE = ' . $device_uptime['polled'] . 's - ' . $device_uptime['sysUpTime'] . 's + ' . $if_lastchange_uptime . 's');
|
|
if (abs($if_lastchange - strtotime($port['ifLastChange'])) > 90) {
|
|
// Compare lastchange with previous, update only if more than 60 sec (for exclude random dispersion)
|
|
$port['update']['ifLastChange'] = date('Y-m-d H:i:s', $if_lastchange); // Convert to timestamp
|
|
}
|
|
} else {
|
|
// Device sysUpTime more than if uptime or too small difference.. impossible, seems as bug on device
|
|
$if_lastchange_uptime = FALSE;
|
|
}
|
|
} else {
|
|
// ifLastChange not exist
|
|
$if_lastchange_uptime = FALSE;
|
|
}
|
|
|
|
if ($if_lastchange_uptime === FALSE) {
|
|
if (empty($port['ifLastChange']) || $port['ifLastChange'] === '0000-00-00 00:00:00' || // Newer set (first time)
|
|
isset($port['update']['ifOperStatus']) || isset($port['update']['ifAdminStatus']) ||
|
|
isset($port['update']['ifSpeed']) || isset($port['update']['ifDuplex'])) {
|
|
$port['update']['ifLastChange'] = date('Y-m-d H:i:s', $this_port['polled']);
|
|
}
|
|
print_debug("IFLASTCHANGE unknown/false, used system times.");
|
|
}
|
|
if (isset($port['update']['ifLastChange'])) {
|
|
print_debug("IFLASTCHANGE (" . $port['ifIndex'] . "): " . $port['update']['ifLastChange']);
|
|
if ($port['ifLastChange'] && $port['ifLastChange'] !== '0000-00-00 00:00:00' && safe_count($log_event)) {
|
|
$log_event[] = "[ifLastChange] '" . $port['ifLastChange'] . "' -> '" . $port['update']['ifLastChange'] . "'";
|
|
}
|
|
}
|
|
if ((bool)$log_event) {
|
|
log_event('Interface changed: ' . implode('; ', $log_event), $device, 'port', $port);
|
|
}
|
|
|
|
// Parse description (usually ifAlias) if config option set
|
|
if ($custom_port_parser) {
|
|
$log_event = [];
|
|
if ($custom_port_parser !== 'old') {
|
|
$port_ifAlias = custom_port_parser($this_port);
|
|
} else {
|
|
$custom_port_attribs = ['type', 'descr', 'circuit', 'speed', 'notes'];
|
|
|
|
include($config['install_dir'] . "/" . $config['port_descr_parser']);
|
|
}
|
|
|
|
foreach ($custom_port_attribs as $attrib) {
|
|
$attrib_key = "port_descr_" . $attrib;
|
|
if ($port_ifAlias[$attrib] != $port[$attrib_key]) {
|
|
if (isset($port_ifAlias[$attrib])) {
|
|
$port['update'][$attrib_key] = $port_ifAlias[$attrib];
|
|
$msg = "[$attrib] " . $port[$attrib_key] . " -> " . $port_ifAlias[$attrib];
|
|
} else {
|
|
$port['update'][$attrib_key] = ['NULL'];
|
|
$msg = "[$attrib] " . $port[$attrib_key] . " -> NULL";
|
|
}
|
|
$log_event[] = $msg;
|
|
}
|
|
}
|
|
if ((bool)$log_event) {
|
|
log_event('Interface changed (attrib): ' . implode('; ', $log_event), $device, 'port', $port);
|
|
}
|
|
}
|
|
// End parse ifAlias
|
|
|
|
// Update IF-MIB metrics
|
|
foreach ($stat_oids_db as $oid) {
|
|
calculate_port_oid_stats($this_port, $port, $oid, $polled_period);
|
|
}
|
|
|
|
if ($config['statsd']['enable']) {
|
|
// Update StatsD/Carbon
|
|
foreach ($stat_oids as $oid) {
|
|
if (!str_contains($oid, "HC") && is_numeric($this_port[$oid])) {
|
|
StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'port' . '.' . $port['ifIndex'] . '.' . $oid, $this_port[$oid]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we have been told to debug this port, output the counters we collected earlier, with the rates stuck on the end.
|
|
debug_port($device, $this_port, $debug_port, $port, $hc_prefix, $polled_period);
|
|
|
|
// Put States into alert array
|
|
foreach ([ 'ifOperStatus', 'ifAdminStatus', 'ifMtu', 'ifDuplex', 'ifVlan' ] as $oid) {
|
|
if (isset($this_port[$oid])) {
|
|
$port['alert_array'][$oid] = $this_port[$oid];
|
|
}
|
|
}
|
|
|
|
// Store average in/out packets size
|
|
if ($in_pkts_delta = int_add($port['alert_array']['ifInUcastPkts_delta'], $port['alert_array']['ifInNUcastPkts_delta'])) {
|
|
$port['alert_array']['rx_ave_pktsize'] = $port['alert_array']['ifInOctets_delta'] / $in_pkts_delta;
|
|
} else {
|
|
$port['alert_array']['rx_ave_pktsize'] = 0;
|
|
}
|
|
if ($out_pkts_delta = int_add($port['alert_array']['ifOutUcastPkts_delta'], $port['alert_array']['ifOutNUcastPkts_delta'])) {
|
|
$port['alert_array']['tx_ave_pktsize'] = $port['alert_array']['ifOutOctets_delta'] / $out_pkts_delta;
|
|
} else {
|
|
$port['alert_array']['tx_ave_pktsize'] = 0;
|
|
}
|
|
|
|
// Store aggregate in/out state
|
|
$port['state']['ifOctets_rate'] = $port['stats']['ifOutOctets_rate'] + $port['stats']['ifInOctets_rate'];
|
|
$port['state']['ifUcastPkts_rate'] = $port['stats']['ifOutUcastPkts_rate'] + $port['stats']['ifInUcastPkts_rate'];
|
|
$port['state']['ifErrors_rate'] = $port['stats']['ifOutErrors_rate'] + $port['stats']['ifInErrors_rate'];
|
|
$port['state']['ifDiscards_rate'] = $port['stats']['ifOutDiscards_rate'] + $port['stats']['ifInDiscards_rate'];
|
|
|
|
// Send aggregate data to alerter too
|
|
$port['alert_array']['ifOctets_rate'] = $port['state']['ifOctets_rate'];
|
|
$port['alert_array']['ifUcastPkts_rate'] = $port['state']['ifUcastPkts_rate'];
|
|
$port['alert_array']['ifNUcastPkts_rate'] = $port['stats']['ifOutNUcastPkts_rate'] + $port['stats']['ifInNUcastPkts_rate'];
|
|
$port['alert_array']['ifErrors_rate'] = $port['state']['ifErrors_rate'];
|
|
$port['alert_array']['ifBroadcastPkts_rate'] = $port['stats']['ifOutBroadcastPkts_rate'] + $port['stats']['ifInBroadcastPkts_rate'];
|
|
$port['alert_array']['ifMulticastPkts_rate'] = $port['stats']['ifOutMulticastPkts_rate'] + $port['stats']['ifInMulticastPkts_rate'];
|
|
$port['alert_array']['ifDiscards_rate'] = $port['state']['ifDiscards_rate'];
|
|
print_debug_vars($port['alert_array']);
|
|
|
|
// Set per port RRD options
|
|
$rrd_options = [ 'speed' => $this_port['ifSpeed'] ];
|
|
// Grow max for ports with 40G+ ifSpeed
|
|
if (isset($port['update']['ifSpeed']) && $port['update']['ifSpeed'] > 40000000000) {
|
|
//$rrd_options['speed'] += 20000000000; // DEBUG
|
|
$rrd_options['update_max'] = TRUE;
|
|
}
|
|
|
|
// Update RRDs
|
|
rrdtool_update_ng($device, 'port', [
|
|
'INOCTETS' => $this_port['ifInOctets'],
|
|
'OUTOCTETS' => $this_port['ifOutOctets'],
|
|
'INERRORS' => $this_port['ifInErrors'],
|
|
'OUTERRORS' => $this_port['ifOutErrors'],
|
|
'INUCASTPKTS' => $this_port['ifInUcastPkts'],
|
|
'OUTUCASTPKTS' => $this_port['ifOutUcastPkts'],
|
|
'INNUCASTPKTS' => $this_port['ifInNUcastPkts'],
|
|
'OUTNUCASTPKTS' => $this_port['ifOutNUcastPkts'],
|
|
'INDISCARDS' => $this_port['ifInDiscards'],
|
|
'OUTDISCARDS' => $this_port['ifOutDiscards'],
|
|
'INUNKNOWNPROTOS' => $this_port['ifInUnknownProtos'],
|
|
'INBROADCASTPKTS' => $this_port['ifInBroadcastPkts'],
|
|
'OUTBROADCASTPKTS' => $this_port['ifOutBroadcastPkts'],
|
|
'INMULTICASTPKTS' => $this_port['ifInMulticastPkts'],
|
|
'OUTMULTICASTPKTS' => $this_port['ifOutMulticastPkts'],
|
|
], get_port_rrdindex($port), TRUE, $rrd_options);
|
|
|
|
// End Update IF-MIB
|
|
|
|
// Update additional MIBS and modules
|
|
foreach ($process_port_db as $port_module => $oids) {
|
|
$log_event = [];
|
|
foreach ($oids as $oid) {
|
|
if ($port[$oid] != $this_port[$oid]) {
|
|
if (isset($this_port[$oid])) {
|
|
// Changed Oid
|
|
$port['update'][$oid] = $this_port[$oid];
|
|
$msg = "[$oid] '" . $port[$oid] . "' -> '" . $this_port[$oid] . "'";
|
|
} else {
|
|
// Removed/empty Oid
|
|
$port['update'][$oid] = ['NULL'];
|
|
$msg = "[$oid] '" . $port[$oid] . "' -> NULL";
|
|
}
|
|
$log_event[] = $msg;
|
|
if (OBS_DEBUG) {
|
|
echo($msg . " ");
|
|
}
|
|
}
|
|
}
|
|
if ((bool)$log_event) {
|
|
log_event('Interface changed (' . $port_module . '): ' . implode('; ', $log_event), $device, 'port', $port);
|
|
}
|
|
}
|
|
// End update additional MIBS
|
|
|
|
/* PAgP disabled since r7987, while not moved to new polling style
|
|
// Update PAgP
|
|
if ($this_port['pagpOperationMode'] || $port['pagpOperationMode'])
|
|
{
|
|
$log_event = [];
|
|
foreach ($pagp_oids as $oid)
|
|
{ // Loop the OIDs
|
|
if ($this_port[$oid] != $port[$oid])
|
|
{ // If data has changed, build a query
|
|
$port['update'][$oid] = $this_port[$oid];
|
|
$log_event[] = "[$oid] " . $port[$oid] . " -> " . $this_port[$oid];
|
|
}
|
|
}
|
|
if ((bool)$log_event) { log_event('Interface changed (pagp): ' . implode('; ', $log_event), $device, 'port', $port); }
|
|
}
|
|
// End Update PAgP
|
|
*/
|
|
|
|
# if (OBS_DEBUG > 1) { print_vars($port['alert_array']); echo(PHP_EOL); print_vars($this_port);}
|
|
|
|
check_entity('port', $port, $port['alert_array']);
|
|
|
|
// Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module
|
|
if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['ports']) {
|
|
$json_data = array_merge($this_port, $port['state']);
|
|
unset($json_data['rrd_update']); // FIXME unset no longer needed when switched to rrdtool_update_ng() !
|
|
messagebus_send(['attribs' => ['t' => $this_port['polled'], 'device' => $device['hostname'],
|
|
'device_id' => $device['device_id'], 'e_type' => 'port',
|
|
'e_index' => $port['ifIndex']], 'data' => $json_data]);
|
|
unset($json_data);
|
|
}
|
|
|
|
// Unified state update
|
|
|
|
//$port['update'] = array_merge($port['state'], $port['update']);
|
|
//$updated = dbUpdate($port['update'], 'ports', '`port_id` = ?', array($port['port_id']));
|
|
|
|
// Add to MultiUpdate ports state as single query
|
|
$ports_db_state[] = array_merge($this_port_indexes, $port['state']);
|
|
|
|
// Update Database
|
|
if (!safe_empty($port['update'])) {
|
|
$updated = dbUpdate($port['update'], 'ports', '`port_id` = ?', [$port['port_id']]);
|
|
//print_debug("PORT updated rows=$updated");
|
|
}
|
|
|
|
// Add table row
|
|
|
|
$table_row = [];
|
|
$table_row[] = $port['ifIndex'];
|
|
$table_row[] = $port['port_label_short'];
|
|
$table_row[] = rewrite_iftype($port['ifType']);
|
|
$table_row[] = format_bps($port['ifSpeed']);
|
|
$table_row[] = format_bps($port['stats']['ifInBits_rate']);
|
|
$table_row[] = format_bps($port['stats']['ifOutBits_rate']);
|
|
$table_row[] = format_bytes($port['stats']['ifInOctets_diff']);
|
|
$table_row[] = format_bytes($port['stats']['ifOutOctets_diff']);
|
|
$table_row[] = format_si($port['stats']['ifInUcastPkts_rate']);
|
|
$table_row[] = format_si($port['stats']['ifOutUcastPkts_rate']);
|
|
$table_row[] = ($port['port_64bit'] ? "%gY%w" : "%rN%w");
|
|
$table_rows[] = $table_row;
|
|
unset($table_row);
|
|
|
|
// End Update Database
|
|
} elseif ($port['disabled'] != "1") {
|
|
print_message("Port Deleted."); // Port missing from SNMP cache.
|
|
if (isset($port['ifIndex']) && $port['deleted'] != "1") {
|
|
$ports_db_deleted[] = ['port_id' => $ports[$port['ifIndex']]['port_id'], 'ifIndex' => $port['ifIndex'], 'device_id' => $device['device_id'], // UNIQUE fields
|
|
'deleted' => '1', 'ifLastChange' => date('Y-m-d H:i:s', $polled)]; // Update this fields
|
|
//dbUpdate(array('deleted' => '1', 'ifLastChange' => date('Y-m-d H:i:s', $polled)), 'ports', '`device_id` = ? AND `ifIndex` = ?', array($device['device_id'], $port['ifIndex']));
|
|
log_event("Interface was marked as DELETED", $device, 'port', $port);
|
|
}
|
|
} else {
|
|
print_message("Port Disabled.");
|
|
}
|
|
|
|
//echo("\n");
|
|
|
|
// Clear Per-Port Variables Here
|
|
unset($this_port);
|
|
}
|
|
|
|
// MultiUpdate deleted ports
|
|
if (!safe_empty($ports_db_deleted)) {
|
|
print_debug("MultiUpdate deleted ports DB.");
|
|
// MultiUpdate required all UNIQUE keys!
|
|
dbUpdateMulti($ports_db_deleted, 'ports', ['deleted', 'ifLastChange']);
|
|
}
|
|
|
|
// MultiUpdate ports state
|
|
if (!safe_empty($ports_db_state)) {
|
|
print_debug("MultiUpdate ports states DB.");
|
|
// MultiUpdate required all UNIQUE keys!
|
|
dbUpdateMulti($ports_db_state, 'ports');
|
|
// Better to pass keys need to update, but without also normal
|
|
//$columns = array_diff(array_keys($port['state']), array_keys($this_port_indexes));
|
|
//dbUpdateMulti($ports_db_state, 'ports', $columns);
|
|
}
|
|
|
|
$headers = ['%WifIndex%n', '%WLabel%n', '%WType%n', '%WSpeed%n', '%WBPS In%n', '%WBPS Out%n', '%WData In%n', '%WData Out%n', '%WPPS In%n', '%WPPS Out%n', '%WHC%n'];
|
|
print_cli_table($table_rows, $headers);
|
|
|
|
echo(PHP_EOL);
|
|
|
|
// Clear Variables Here
|
|
unset($port_stats, $process_port_functions, $process_port_db, $has_ifEntry, $has_ifXEntry, $has_ifEntry_error_code, $ports_ignored_count, $ports_ignored_count_db);
|
|
|
|
// EOF
|