1<?php 2 3/** 4 * Observium 5 * 6 * This file is part of Observium. 7 * 8 * @package observium 9 * @subpackage poller 10 * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited 11 * 12 */ 13 14// Include description parser (usually ifAlias) if config option set 15$custom_port_parser = FALSE; 16if (isset($config['port_descr_parser']) && is_file($config['install_dir'] . "/" . $config['port_descr_parser'])) 17{ 18 include_once($config['install_dir'] . "/" . $config['port_descr_parser']); 19 20 if (function_exists('custom_port_parser')) 21 { 22 $custom_port_attribs = array('type', 'descr', 'circuit', 'speed', 'notes'); 23 $custom_port_parser = TRUE; 24 } else { 25 print_warning("WARNING: Rewrite your custom ports parser in file [".$config['install_dir'] . "/" . $config['port_descr_parser']."], using a function custom_port_parser()."); 26 $custom_port_parser = 'old'; 27 } 28} 29 30// Cache ports table from DB 31$ports = array(); 32 33// FIXME -- this stuff is a little messy, looping the array to make an array just seems wrong. :> 34// -- i can make it a function, so that you don't know what it's doing. 35// -- $ports = adamasMagicFunction($ports_db); ? 36 37$query = 'SELECT * FROM `ports`'; 38//$query .= ' LEFT JOIN `ports-state` USING(`port_id`)'; 39$query .= ' WHERE `device_id` = ?'; 40 41$ports_db = dbFetchRows($query, array($device['device_id'])); 42$ports_attribs = get_device_entities_attribs($device['device_id'], 'port'); // Get all attribs 43//print_vars($ports_attribs); 44foreach ($ports_db as $port) 45{ 46 if (isset($ports_attribs['port'][$port['port_id']])) 47 { 48 $port = array_merge($port, $ports_attribs['port'][$port['port_id']]); 49 } 50 $ports[$port['ifIndex']] = $port; 51} 52$ports_ignored_count_db = intval(get_entity_attrib('device', $device, 'ports_ignored_count')); // Cache last ports ignored count 53 54// Ports module options 55$ports_modules = array(); // Ports sub-modules enabled/disabled 56foreach (array_keys($config) as $ports_module) 57{ 58 if (!str_starts($ports_module, 'enable_ports_')) { continue; } // Filter only enable_ports_* config entries 59 $ports_module = str_replace('enable_ports_', '', $ports_module); 60 61 $ports_modules[$ports_module] = isset($attribs['enable_ports_' . $ports_module]) ? (bool)$attribs['enable_ports_' . $ports_module] : $config['enable_ports_' . $ports_module]; 62} 63// Additionally force enable separate walk feature for some device oses, but only if ports total count >10 64$ports_module = 'separate_walk'; 65if (!$ports_modules[$ports_module] && $config['os'][$device['os']]['ports_'.$ports_module]) 66{ 67 if (isset($attribs['enable_ports_' . $ports_module]) && !$attribs['enable_ports_' . $ports_module]) {} // forcing disabled in device config 68 else 69 { 70 $ports_total_count = $ports_ignored_count_db + dbFetchCell('SELECT COUNT(*) FROM `ports` WHERE `device_id` = ? AND `deleted` = 0', array($device['device_id'])); 71 $ports_modules[$ports_module] = $ports_total_count > 10; 72 if (OBS_DEBUG && $ports_modules[$ports_module]) 73 { 74 print_debug('Forced ports separate walk feature!'); 75 } 76 } 77} 78//print_vars($ports_modules); 79 80$table_rows = array(); 81 82// Build SNMP Cache Array 83 84// IF-MIB OIDs that go into the ports table 85 86$data_oids_ifEntry = array( 87 // ifEntry 88 'ifDescr', 'ifType', 'ifMtu', 'ifSpeed', 'ifPhysAddress', 89 'ifAdminStatus', 'ifOperStatus', 'ifLastChange', 90); 91$data_oids_ifXEntry = array( 92 // ifXEntry 93 'ifName', 'ifAlias', 'ifHighSpeed', 'ifPromiscuousMode', 'ifConnectorPresent', 94); 95$data_oids = array_merge($data_oids_ifEntry, 96 $data_oids_ifXEntry, 97 array('ifDuplex', 'ifTrunk', 'ifVlan')); // Add additional oids 98 99// IF-MIB statistics OIDs that go into RRD 100 101$stat_oids_ifEntry = array( 102 // ifEntry 103 'ifInOctets', 'ifOutOctets', 104 'ifInUcastPkts', 'ifOutUcastPkts', 105 'ifInNUcastPkts', 'ifOutNUcastPkts', // Note, (In|Out)NUcastPkts deprecated, for HC counters use Broadcast+Multicast instead 106 'ifInDiscards', 'ifOutDiscards', 107 'ifInErrors', 'ifOutErrors', 108 'ifInUnknownProtos', 109); 110 111$stat_oids_ifXEntry = array( 112 // ifXEntry 113 'ifInMulticastPkts', 'ifOutMulticastPkts', 114 'ifInBroadcastPkts', 'ifOutBroadcastPkts', 115 // HC counters 116 'ifHCInOctets', 'ifHCOutOctets', 117 'ifHCInUcastPkts', 'ifHCOutUcastPkts', 118 'ifHCInMulticastPkts', 'ifHCOutMulticastPkts', 119 'ifHCInBroadcastPkts', 'ifHCOutBroadcastPkts', 120); 121 122// This oids definitions used only for Upstream/Downstream interface types 123$upstream_oids = array( 124 // ifEntry 125 'ifInOctets', 'ifInUcastPkts', 'ifInNUcastPkts', 'ifInDiscards', 'ifInErrors', 126 // ifXEntry 127 'ifInMulticastPkts', 'ifInBroadcastPkts', 'ifHCInOctets', 'ifHCInUcastPkts', 'ifHCInMulticastPkts', 'ifHCInBroadcastPkts', 128); 129$downstream_oids = array( 130 // ifEntry 131 'ifOutOctets', 'ifOutUcastPkts', 'ifOutNUcastPkts', 'ifOutDiscards', 'ifOutErrors', 132 // ifXEntry 133 'ifOutMulticastPkts', 'ifOutBroadcastPkts', 'ifHCOutOctets', 'ifHCOutUcastPkts', 'ifHCOutMulticastPkts', 'ifHCOutBroadcastPkts', 134); 135 136// Remove HC oids from stat arrays for SNMP v1 137if ($device['snmp_version'] == 'v1') 138{ 139 $hc_oids = array( 140 // HC counters 141 'ifHCInOctets', 'ifHCOutOctets', 142 'ifHCInUcastPkts', 'ifHCOutUcastPkts', 143 'ifHCInMulticastPkts', 'ifHCOutMulticastPkts', 144 'ifHCInBroadcastPkts', 'ifHCOutBroadcastPkts', 145 ); 146 $stat_oids_ifXEntry = array_diff($stat_oids_ifXEntry, $hc_oids); 147 $upstream_oids = array_diff($upstream_oids, $hc_oids); 148 $downstream_oids = array_diff($downstream_oids, $hc_oids); 149} 150 151// Merge stat oids 152$stat_oids = array_merge($stat_oids_ifEntry, $stat_oids_ifXEntry); 153 154// Cisco old locIf OIDs. Currently unused. 155 156$cisco_oids = array('locIfHardType', 'locIfInRunts', 'locIfInGiants', 'locIfInCRC', 'locIfInFrame', 'locIfInOverrun', 'locIfInIgnored', 'locIfInAbort', 157 'locIfCollisions', 'locIfInputQueueDrops', 'locIfOutputQueueDrops'); 158 159// PAgP OIDs 160 161//$pagp_oids = array('pagpOperationMode', 'pagpPortState', 'pagpPartnerDeviceId', 'pagpPartnerLearnMethod', 'pagpPartnerIfIndex', 'pagpPartnerGroupIfIndex', 162// 'pagpPartnerDeviceName', 'pagpEthcOperationMode', 'pagpDeviceId', 'pagpGroupIfIndex'); 163$pagp_oids = array(); // PAgP disabled since r7987, while not moved to new polling style 164 165//$ifmib_oids = array_merge($data_oids, $stat_oids); 166 167print_cli_data_field("Caching Oids"); 168$port_stats = array(); 169if (is_device_mib($device, "IF-MIB")) 170{ 171 if (!$ports_modules['separate_walk']) 172 { 173 print_debug("Used full table ifEntry/ifXEntry snmpwalk."); 174 $ifmib_oids = ['ifEntry', 'ifXEntry']; 175 foreach ($ifmib_oids as $oid) 176 { 177 $has_name = 'has_' . $oid; 178 echo("$oid "); 179 $port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "IF-MIB"); 180 $$has_name = snmp_status() || snmp_error_code() === 2; // $has_ifEntry, $has_ifXEntry 181 //print_vars($$has_name); 182 if ($oid == 'ifEntry') 183 { 184 // Store error_code, 1000 == not exist table, 2 and 3 - not complete request 185 $has_ifEntry_error_code = snmp_error_code(); 186 } 187 } 188 189 } 190 else 191 { 192 193 print_debug("Used separate data tables snmpwalk and per port snmpget."); 194 195 $has_ifEntry = FALSE; 196 // Data fields 197 // ifDescr, ifAlias, ifName, ifType, ifOperStatus 198 foreach (['ifDescr', 'ifType', 'ifOperStatus'] as $oid) 199 { 200 echo("$oid "); 201 $port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "IF-MIB"); 202 $has_ifEntry = $has_ifEntry || snmp_status(); 203 $has_ifEntry_error_code = snmp_error_code(); 204 } 205 $has_ifXEntry = FALSE; 206 foreach (['ifAlias', 'ifName', 'ifHighSpeed'] as $oid) 207 { 208 echo("$oid "); 209 $port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "IF-MIB"); 210 $has_ifXEntry = $has_ifXEntry || $GLOBALS['snmp_status']; 211 } 212 213 // Per port snmpget 214 if ($port_stats) 215 { 216 // Collect oids for per port snmpget 217 if ($has_ifXEntry) 218 { 219 $port_oids = array_merge($stat_oids_ifXEntry, $stat_oids_ifEntry); 220 $port_oids = array_merge($port_oids, array_diff($data_oids_ifEntry, ['ifDescr', 'ifType', 'ifOperStatus'])); 221 $port_oids = array_merge($port_oids, array_diff($data_oids_ifXEntry, ['ifAlias', 'ifName', 'ifHighSpeed'])); 222 } 223 else 224 { 225 $port_oids = array_merge($stat_oids_ifEntry, 226 array_diff($data_oids_ifEntry, ['ifDescr', 'ifType', 'ifOperStatus'])); 227 } 228 229 // Use snmpget for each (not ignored) port 230 // NOTE. This method reduce polling time when too many ports (>100) 231 echo(implode(' ', $port_oids) . ", ifIndex: "); 232 foreach ($port_stats as $ifIndex => $port) 233 { 234 $port_disabled = isset($ports[$ifIndex]['disabled']) && $ports[$ifIndex]['disabled']; // Port polling disabled from WUI 235 if (!$port_disabled && is_port_valid($port, $device)) 236 { 237 echo("$ifIndex "); 238 $port_oid = implode(".$ifIndex ", $port_oids) . ".$ifIndex"; 239 $port_stats = snmp_get_multi_oid($device, $port_oid, $port_stats, "IF-MIB"); 240 } 241 } 242 } 243 } 244} else { // End IF-MIB permitted 245 // This part for devices who not have IF-MIB stats, but have own vendor tree with ports 246} 247echo PHP_EOL; // End IF-MIB section 248 249////////// 250foreach (get_device_mibs_permitted($device) as $mib) 251{ 252 merge_private_mib($device, 'ports', $mib, $port_stats, NULL); 253} 254//////// 255 256// Prevent mark ports as DELETED when ifEntry snmpwalk return not complete data! 257$allow_delete_ports = $has_ifEntry_error_code !== 2 && $has_ifEntry_error_code !== 3; 258 259// Store polled time exactly after walk IF-MIB, for more correct port speed calculate! 260$polled = time(); 261 262// Device uptime and polled time (required for ifLastChange) 263if (isset($cache['devices']['uptime'][$device['device_id']])) 264{ 265 $device_uptime = &$cache['devices']['uptime'][$device['device_id']]; 266} else { 267 print_error("Device uptime not cached, ifLastChange will incorrect. Check polling system module."); 268} 269 270// Subset of IF-MIB OIDs that we put into the state table 271$stat_oids_db = array('ifInOctets', 'ifOutOctets', 'ifInErrors', 'ifOutErrors', 'ifInUcastPkts', 'ifOutUcastPkts', 'ifInNUcastPkts', 'ifOutNUcastPkts', 272 'ifInBroadcastPkts', 'ifOutBroadcastPkts', 'ifInMulticastPkts', 'ifOutMulticastPkts', 'ifInDiscards', 'ifOutDiscards'); 273 274// Subset of IF-MIB OIDs that we put into the ports table 275$data_oids_db = array_diff($data_oids, array('ifLastChange')); // remove ifLastChange, because it added separate 276$data_oids_db = array_merge($data_oids_db, array('port_label', 'port_label_short', 'port_label_base', 'port_label_num')); 277 278// Additional MIBS and modules 279$process_port_functions = array('label' => TRUE); // collect processing functions 280$process_port_db = array(); // collect processing db fields 281 282// Additionaly include per MIB functions and snmpwalks (uses include_once) 283$port_stats_count = count($port_stats); 284$include_lib = TRUE; 285$include_dir = "includes/polling/ports/"; 286include("includes/include-dir-mib.inc.php"); 287 288if (count($port_stats)) 289{ 290 // FIXME This probably needs re-enabled. We need to clear these things when they get unset, too. 291 #foreach ($cisco_oids as $oid) { $port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "OLD-CISCO-INTERFACES-MIB"); } 292 293 // If the device is cisco, pull a few cisco-specific MIBs and try to get vlan data from CISCO-VTP-MIB 294 if ($device['os_group'] == "cisco") 295 { 296 //FIXME. All PAGP operations should be moved to separate "stacks" module and separate table (not in ports table) 297 /* PAgP disabled since r7987, while not moved to new polling style 298 foreach ($pagp_oids as $oid) 299 { 300 $port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "CISCO-PAGP-MIB"); 301 // Break if no PAGP tables on device 302 if ($oid == 'pagpOperationMode' && $GLOBALS['snmp_status'] === FALSE) { break; } 303 } 304 */ 305 } 306 307 // End Building SNMP Cache Array 308 309 $graphs['bits'] = TRUE; // Create global device_bits graph, since we have ports. 310 311 print_debug_vars($port_stats); 312} 313 314// New interface detection 315$ports_ignored_count = 0; // Counting ignored ports 316$ports_db_deleted = array(); // MultiUpdate deleted ports db 317$ports_db_state = array(); // MultiUpdate state ports db 318foreach ($port_stats as $ifIndex => $port) 319{ 320 // Always use ifIndex from index part (not from Oid!), 321 // Oid can have incorrect ifIndex, ie: 322 // ifIndex.0 = 1 323 $port['ifIndex'] = $ifIndex; 324 325 if (is_port_valid($port, $device)) 326 { 327 if (!is_array($ports[$port['ifIndex']])) 328 { 329 $port_insert = array('device_id' => $device['device_id'], 330 'ifIndex' => $ifIndex, 331 'ignore' => isset($port['ignore']) ? $port['ignore'] : '0', 332 'disabled' => isset($port['disabled']) ? $port['disabled'] : '0'); 333 $port_id = dbInsert(array('device_id' => $device['device_id'], 'ifIndex' => $ifIndex), 'ports'); 334 $ports[$port['ifIndex']] = dbFetchRow("SELECT * FROM `ports` WHERE `port_id` = ?", array($port_id)); 335 print_message("Adding: ".$port['ifDescr']."(".$ifIndex.")(".$ports[$port['ifIndex']]['port_id'].")"); 336 } 337 else if ($ports[$ifIndex]['deleted'] == "1") 338 { 339 $ports_db_deleted[] = array('port_id' => $ports[$ifIndex]['port_id'], 'ifIndex' => $ifIndex, 'device_id' => $device['device_id'], // UNIQUE fields 340 'deleted' => '0', 'ifLastChange' => date('Y-m-d H:i:s', $polled)); // Update this fields 341 //dbUpdate(array('deleted' => '0'), 'ports', '`port_id` = ?', array($ports[$ifIndex]['port_id'])); 342 log_event("Interface DELETED mark removed", $device, 'port', $ports[$ifIndex]); 343 $ports[$ifIndex]['deleted'] = "0"; 344 } 345 } else { 346 if (isset($ports[$port['ifIndex']]) && $ports[$port['ifIndex']]['deleted'] != '1' && $allow_delete_ports) 347 { 348 $ports_db_deleted[] = array('port_id' => $ports[$ifIndex]['port_id'], 'ifIndex' => $ifIndex, 'device_id' => $device['device_id'], // UNIQUE fields 349 'deleted' => '1', 'ifLastChange' => date('Y-m-d H:i:s', $polled)); // Update this fields 350 //dbUpdate(array('deleted' => '1', 'ifLastChange' => date('Y-m-d H:i:s', $polled)), 'ports', '`port_id` = ?', array($ports[$ifIndex]['port_id'])); 351 log_event("Interface was marked as DELETED", $device, 'port', $ports[$ifIndex]); 352 $ports[$ifIndex]['deleted'] = "1"; 353 } 354 $ports_ignored_count++; // Counting ignored ports 355 } 356} 357 358if (!$allow_delete_ports) 359{ 360 log_event("WARNING! Ports snmpwalk did not complete. Try to increase SNMP timeout on the device properties page.", $device, 'device', $device['device_id'], 7); 361} 362if ($ports_ignored_count !== $ports_ignored_count_db) 363{ 364 set_entity_attrib('device', $device, 'ports_ignored_count', $ports_ignored_count); 365} 366// End New interface detection 367 368echo(PHP_EOL . PHP_EOL); 369 370// Loop ports in the DB and update where necessary 371foreach ($ports as $port) 372{ 373 // Notes: 374 // $port_stats - array of ports from snmpwalks 375 // $this_port - link to port array from snmpwalk 376 // $ports - array of ports based on current db entries 377 // $port - current port array from db 378 if ($port['deleted']) { continue; } // Skip updating RRDs and DB if interface marked as DELETED (also skipped bad_if's) 379 380 if ($port_stats[$port['ifIndex']] && $port['disabled'] != "1") 381 { // Check to make sure Port data is cached. 382 $this_port = &$port_stats[$port['ifIndex']]; 383 384 $polled_period = $polled - $port['poll_time']; 385 386 $port['update'] = array(); 387 $port['state'] = array(); // State field for update 388 389 $port['state']['poll_time'] = $polled; 390 $port['state']['poll_period'] = $polled_period; 391 392 $this_port['port_id'] = $port['port_id']; 393 $this_port['ifIndex'] = $port['ifIndex']; 394 $this_port_indexes = array('port_id' => $ports[$port['ifIndex']]['port_id'], 'ifIndex' => $port['ifIndex'], 'device_id' => $device['device_id']); // UNIQUE port indexes 395 396 // Store original port walked OIDs for debugging later 397 if ($config['debug_port']['spikes'] || $config['debug_port'][$port['port_id']]) 398 { 399 $debug_port = $this_port; // DEBUG 400 } 401 402 // Before process_port_label() 403 // Fix ord (UTF-8) chars, ie: 404 // ifAlias.3 = Conexi<F3>n de <E1>rea local* 3 405 foreach (array('ifAlias', 'ifDescr', 'ifName') as $oid_fix) 406 { 407 if (isset($this_port[$oid_fix])) { $this_port[$oid_fix] = snmp_fix_string($this_port[$oid_fix]); } 408 /// DEVEL, test escaping 409 if ($this_port['port_id'] == 42430) 410 { 411 $this_port[$oid_fix] .= ' <>'; 412 } 413 } 414 415 //print_vars($process_port_functions); 416 foreach ($process_port_functions as $func => $ok) 417 { 418 if ($ok && function_exists('process_port_' . $func)) 419 { 420 if (OBS_DEBUG > 1) 421 { 422 print_debug("Processing port ifIndex ".$this_port['ifIndex']." with function process_port_{$func}() "); 423 } 424 // Note, used call by array, because parameters for call_user_func() are not passed by reference 425 call_user_func_array('process_port_' . $func, array(&$this_port, $device, $port)); 426 } 427 } 428 //print_vars($this_port); 429 430# // Copy ifHC[In|Out] values to non-HC if they exist 431# // Check if they're greater than zero to work around stupid devices which expose HC counters, but don't populate them. HERPDERP. - adama 432# if ($device['os'] == "netapp") { $hc_prefixes = array('HC', '64'); } else { $hc_prefixes = array('HC'); } 433# foreach ($hc_prefixes as $hc_prefix) 434# { 435# foreach (array('Octets', 'UcastPkts', 'BroadcastPkts', 'MulticastPkts') as $hc) 436# { 437# $hcin = 'if'.$hc_prefix.'In'.$hc; 438# $hcout = 'if'.$hc_prefix.'Out'.$hc; 439# if (is_numeric($this_port[$hcin]) && $this_port[$hcin] > 0 && is_numeric($this_port[$hcout]) && $this_port[$hcout] > 0) 440# { 441# // echo(" ".$hc_prefix." $hc, "); 442# $this_port['ifIn'.$hc] = $this_port[$hcin]; 443# $this_port['ifOut'.$hc] = $this_port[$hcout]; 444# } 445# } 446# } 447 448 // Here special checks for Upstream/Downstream ports, because it have only In or only Out counters 449 if (strpos($this_port['ifType'], 'Upstream') !== FALSE) 450 { 451 // Upstream has only In counters 452 foreach ($upstream_oids as $oid_in) 453 { 454 $oid_out = str_replace('In', 'Out', $oid_in); 455 if (is_numeric($this_port[$oid_in]) && !is_numeric($this_port[$oid_out])) 456 { 457 $this_port[$oid_out] = 0; // Set it all to zero 458 } 459 } 460 } 461 else if (strpos($this_port['ifType'], 'Downstream') !== FALSE) 462 { 463 // Downstream has only Out counters 464 foreach ($downstream_oids as $oid_out) 465 { 466 $oid_in = str_replace('Out', 'In', $oid_out); 467 if (is_numeric($this_port[$oid_out]) && !is_numeric($this_port[$oid_in])) 468 { 469 $this_port[$oid_in] = 0; // Set it all to zero 470 } 471 } 472 } 473 474 // If we're not using SNMPv1, assumt there are 64-bit values and overwrite the 32-bit OIDs. 475 if ($device['snmp_version'] != 'v1') 476 { 477 $hc_prefix = 'HC'; 478 $port_has_64bit = is_numeric($this_port['if'.$hc_prefix.'InOctets']) && is_numeric($this_port['if'.$hc_prefix.'OutOctets']); 479 480 // We've never tested for 64bit. Lets do it now. Lots of devices seem to not support 64bit counters for all ports. 481 if ($port['port_64bit'] == NULL) 482 { 483 // We have 64-bit traffic counters. Lets set port_64bit 484 if ($port_has_64bit) 485 { 486 $port['port_64bit'] = 1; 487 $port['update']['port_64bit'] = 1; 488 } else { 489 $port['port_64bit'] = 0; 490 $port['update']['port_64bit'] = 0; 491 } 492 } 493 else if ($has_ifXEntry && $port_has_64bit && !$port['port_64bit']) 494 { 495 // Port changed to 64-bit 496 $port['port_64bit'] = 1; 497 $port['update']['port_64bit'] = 1; 498 log_event('Interface changed: [HC] -> Counter64 (may cause disposable spike)', $device, 'port', $port); 499 } 500 501 $port_has_mcbc = is_numeric($this_port['ifInBroadcastPkts']) && is_numeric($this_port['ifOutBroadcastPkts']) && 502 is_numeric($this_port['ifInMulticastPkts']) && is_numeric($this_port['ifOutMulticastPkts']); 503 504 if ($port['port_mcbc'] == NULL) 505 { 506 // We have Broadcast/Multicast traffic counters. Lets set port_mcbc 507 if ($port_has_mcbc) 508 { 509 $port['port_mcbc'] = 1; 510 $port['update']['port_mcbc'] = 1; 511 } else { 512 $port['port_mcbc'] = 0; 513 $port['update']['port_mcbc'] = 0; 514 } 515 } 516 else if ($has_ifXEntry && $port_has_mcbc && !$port['port_mcbc']) 517 { 518 // Port acquired multicast/broadcast! 519 $port['port_mcbc'] = 1; 520 $port['update']['port_mcbc'] = 1; 521 log_event('Interface changed: Separated Multicast/Broadcast statistics appeared.', $device, 'port', $port); 522 } 523 524 //else if (!$port_has_64bit && $port['port_64bit']) 525 //{ 526 // // Port changed to 32-bit 527 // $port['port_64bit'] = 0; 528 // $port['update']['port_64bit'] = 0; 529 // log_event('Interface changed: [HC] -> Counter32', $device, 'port', $port); 530 //} 531 532 if ($port['port_64bit']) 533 { 534 print_debug("64-bit, "); 535 foreach (array('Octets', 'UcastPkts', 'BroadcastPkts', 'MulticastPkts') as $hc) 536 { 537 $hcin = 'if'.$hc_prefix.'In'.$hc; 538 $hcout = 'if'.$hc_prefix.'Out'.$hc; 539 $this_port['ifIn'.$hc] = $this_port[$hcin]; 540 $this_port['ifOut'.$hc] = $this_port[$hcout]; 541 } 542 // Additionally override (In|Out)NUcastPkts 543 // see: http://jira.observium.org/browse/OBSERVIUM-1749 544 $this_port['ifInNUcastPkts'] = int_add($this_port['ifInBroadcastPkts'], $this_port['ifInMulticastPkts']); 545 $this_port['ifOutNUcastPkts'] = int_add($this_port['ifOutBroadcastPkts'], $this_port['ifOutMulticastPkts']); 546 } 547 } 548 549 // rewrite the ifPhysAddress 550 // IF-MIB::ifPhysAddress.2 = STRING: 66:c:9b:1b:62:7e 551 // IF-MIB::ifPhysAddress.2 = Hex-STRING: 00 02 99 09 E9 84 552 $this_port['ifPhysAddress'] = mac_zeropad($this_port['ifPhysAddress']); 553 554 // ifSpeed processing 555 if (isset($port['ifSpeed_custom']) && $port['ifSpeed_custom'] > 0) 556 { 557 // Custom ifSpeed from WebUI 558 $this_port['ifSpeed'] = intval($port['ifSpeed_custom']); 559 print_debug('Port ifSpeed manually set.'); 560 } else { 561 // Detect port speed by ifHighSpeed 562 if (is_numeric($this_port['ifHighSpeed'])) 563 { 564 // Use old ifHighSpeed if current speed '0', seems as some error on device 565 if ($this_port['ifHighSpeed'] == '0' && $port['ifHighSpeed'] > '0') 566 { 567 $this_port['ifHighSpeed'] = $port['ifHighSpeed']; 568 print_debug('Port ifHighSpeed fixed from zero.'); 569 } 570 571 // Maximum possible ifSpeed value is 4294967295 572 // Overwrite ifSpeed with ifHighSpeed if it's over 4G or ifSpeed equals to zero 573 // ifSpeed is more accurate for low speeds (ie: ifSpeed.60 = 1536000, ifHighSpeed.60 = 2) 574 // other case when (incorrect ifSpeed): ifSpeed.6 = 1000, ifHighSpeed.6 = 1000) 575 $ifSpeed_max = max($this_port['ifHighSpeed'] * 1000000, $this_port['ifSpeed']); 576 if ($this_port['ifHighSpeed'] > 0 && 577 ($ifSpeed_max > 4000000000 || $this_port['ifSpeed'] == 0 || $this_port['ifSpeed'] == $this_port['ifHighSpeed'])) 578 { 579 // echo("HighSpeed, "); 580 $this_port['ifSpeed'] = $ifSpeed_max; 581 } 582 } 583 if ($this_port['ifSpeed'] == '0' && $port['ifSpeed'] > '0') 584 { 585 // Use old ifSpeed if current speed '0', seems as some error on device 586 $this_port['ifSpeed'] = $port['ifSpeed']; 587 print_debug('Port ifSpeed fixed from zero.'); 588 } 589 } 590 591 // Simple override of ifAlias -- mostly for testing 592 if(isset($config['ports']['ifAlias_map']['ifIndex'][$device['hostname']][$port['ifIndex']])) 593 { 594 $this_port['ifAlias'] = $config['ports']['ifAlias_map']['ifIndex'][$device['hostname']][$port['ifIndex']]; 595 } 596 if(isset($config['ports']['ifAlias_map']['ifName'][$device['hostname']][$port['ifName']])) 597 { 598 $this_port['ifAlias'] = $config['ports']['ifAlias_map']['ifName'][$device['hostname']][$port['ifName']]; 599 } 600 601 602 // Update TrustSec 603 if ($this_port['encrypted']) 604 { 605 if ($port['encrypted'] === '0') 606 { 607 log_event("Interface is now encrypted", $device, 'port', $port); 608 $port['update']['encrypted'] = '1'; 609 } 610 } 611 else if ($port['encrypted'] === '1') 612 { 613 log_event("Interface is no longer encrypted", $device, 'port', $port); 614 $port['update']['encrypted'] = '0'; 615 } 616 617 // Make sure ifOperStatus is valid (FIXME. not exist statuses already "filtered" in is_port_valid()) 618 if (isset($this_port['ifOperStatus']) && 619 !in_array($this_port['ifOperStatus'], array('testing', 'notPresent', 'dormant', 'down', 'lowerLayerDown', 'unknown', 'up', 'monitoring'))) 620 { 621 $this_port['ifOperStatus'] = 'unknown'; 622 } 623 624 if (isset($this_port['ifAdminStatus']) && 625 !in_array($this_port['ifAdminStatus'], array('up', 'down', 'testing'))) 626 { 627 $this_port['ifAdminStatus'] = ''; // or NULL? 628 } 629 630 if (isset($this_port['ifConnectorPresent']) && 631 !in_array($this_port['ifConnectorPresent'], array('true', 'false'))) 632 { 633 $this_port['ifConnectorPresent'] = NULL; 634 } 635 636 // Update IF-MIB data 637 638 $log_event = array(); 639 foreach ($data_oids_db as $oid) 640 { 641 if ($port[$oid] != $this_port[$oid]) 642 { 643 if (isset($this_port[$oid])) 644 { 645 $port['update'][$oid] = $this_port[$oid]; 646 $msg = "[$oid] '" . $port[$oid] . "' -> '" . $this_port[$oid] . "'"; 647 } else { 648 $port['update'][$oid] = array('NULL'); 649 $msg = "[$oid] '" . $port[$oid] . "' -> NULL"; 650 } 651 if ($oid == 'ifOperStatus' && ($port[$oid] == 'up' || $port[$oid] == 'down') && isset($this_port[$oid])) 652 { 653 // Specific log_event for port Up/Down 654 log_event('Interface '.ucfirst($this_port[$oid]) . ": [$oid] '" . $port[$oid] . "' -> '" . $this_port[$oid] . "'", $device, 'port', $port, 'warning'); 655 } else { 656 $log_event[] = $msg; 657 } 658 if (OBS_DEBUG) { echo($msg." "); } // else { echo($oid . " "); } 659 } 660 } 661 662 // ifLastChange 663 if (isset($this_port['ifLastChange']) && $this_port['ifLastChange'] != '') 664 { 665 // Convert ifLastChange from timetick to timestamp 666 /** 667 * The value of sysUpTime at the time the interface entered 668 * its current operational state. If the current state was 669 * entered prior to the last re-initialization of the local 670 * network management subsystem, then this object contains a 671 * zero value. 672 * 673 * NOTE, observium uses last change timestamp. 674 */ 675 $if_lastchange_uptime = timeticks_to_sec($this_port['ifLastChange']); 676 if (($device_uptime['sysUpTime'] - $if_lastchange_uptime) > 90) 677 { 678 $if_lastchange = $device_uptime['polled'] - $device_uptime['sysUpTime'] + $if_lastchange_uptime; 679 print_debug('IFLASTCHANGE = '.$device_uptime['polled'].'s - '.$device_uptime['sysUpTime'].'s + '.$if_lastchange_uptime.'s'); 680 if (abs($if_lastchange - strtotime($port['ifLastChange'])) > 90) 681 { 682 // Compare lastchange with previous, update only if more than 60 sec (for exclude random dispersion) 683 $port['update']['ifLastChange'] = date('Y-m-d H:i:s', $if_lastchange); // Convert to timestamp 684 } 685 } else { 686 // Device sysUpTime more than if uptime or too small difference.. impossible, seems as bug on device 687 $if_lastchange_uptime = FALSE; 688 } 689 } else { 690 // ifLastChange not exist 691 $if_lastchange_uptime = FALSE; 692 } 693 694 if ($if_lastchange_uptime === FALSE) 695 { 696 if (empty($port['ifLastChange']) || $port['ifLastChange'] == '0000-00-00 00:00:00' || // Newer set (first time) 697 isset($port['update']['ifOperStatus']) || isset($port['update']['ifAdminStatus']) || isset($port['update']['ifSpeed']) || isset($port['update']['ifDuplex'])) 698 { 699 $port['update']['ifLastChange'] = date('Y-m-d H:i:s', $polled); 700 } 701 print_debug("IFLASTCHANGE unknown/false, used system times."); 702 } 703 if (isset($port['update']['ifLastChange'])) 704 { 705 print_debug("IFLASTCHANGE (" . $port['ifIndex'] . "): " . $port['update']['ifLastChange']); 706 if ($port['ifLastChange'] && $port['ifLastChange'] != '0000-00-00 00:00:00' && count($log_event)) 707 { 708 $log_event[] = "[ifLastChange] '" . $port['ifLastChange'] . "' -> '" . $port['update']['ifLastChange'] . "'"; 709 } 710 } 711 if ((bool)$log_event) { log_event('Interface changed: ' . implode('; ', $log_event), $device, 'port', $port); } 712 713 // Parse description (usually ifAlias) if config option set 714 if ($custom_port_parser) 715 { 716 $log_event = array(); 717 if ($custom_port_parser !== 'old') 718 { 719 $port_ifAlias = custom_port_parser($this_port); 720 } else { 721 $custom_port_attribs = array('type', 'descr', 'circuit', 'speed', 'notes'); 722 723 include($config['install_dir'] . "/" . $config['port_descr_parser']); 724 } 725 726 foreach ($custom_port_attribs as $attrib) 727 { 728 $attrib_key = "port_descr_".$attrib; 729 if ($port_ifAlias[$attrib] != $port[$attrib_key]) 730 { 731 if (isset($port_ifAlias[$attrib])) 732 { 733 $port['update'][$attrib_key] = $port_ifAlias[$attrib]; 734 $msg = "[$attrib] " . $port[$attrib_key] . " -> " . $port_ifAlias[$attrib]; 735 } else { 736 $port['update'][$attrib_key] = array('NULL'); 737 $msg = "[$attrib] " . $port[$attrib_key] . " -> NULL"; 738 } 739 $log_event[] = $msg; 740 } 741 } 742 if ((bool)$log_event) { log_event('Interface changed (attrib): ' . implode('; ', $log_event), $device, 'port', $port); } 743 } 744 // End parse ifAlias 745 746 // Update IF-MIB metrics 747 foreach ($stat_oids_db as $oid) 748 { 749 $port['state'][$oid] = $this_port[$oid]; 750 if (isset($port[$oid]) && is_numeric($port[$oid])) 751 { 752 //$oid_diff = $this_port[$oid] - $port[$oid]; 753 $oid_diff = int_sub($this_port[$oid], $port[$oid]); // Use accurate substract 754 $oid_rate = $oid_diff / $polled_period; 755 if ($oid_rate < 0) 756 { 757 print_warning("Negative $oid. Possible spike on next poll!"); 758 $port['stats'][$oid.'_negative_rate'] = $oid_rate; 759 $oid_rate = "0"; 760 } 761 $port['stats'][$oid.'_rate'] = $oid_rate; 762 763 764 // Perhaps need to protect these from false polls. 765 $port['alert_array'][$oid.'_rate'] = $oid_rate; 766 $port['alert_array'][$oid.'_delta'] = $oid_diff; 767 768 $port['stats'][$oid.'_diff'] = $oid_diff; 769 $port['state'][$oid.'_rate'] = $oid_rate; 770 771 // Record delta in database only for In/Out errors. 772 if ($oid == "ifInErrors" || $oid == "ifOutErrors") 773 { 774 $port['state'][$oid.'_delta'] = $oid_diff; 775 } 776 777 print_debug("\n $oid ($oid_diff B) $oid_rate Bps $polled_period secs"); 778 } else { 779 // Add zero defaults for correct multiupdate! 780 $port['state'][$oid] = $port[$oid]; // Keep old value 781 $port['state'][$oid.'_rate'] = '0'; 782 783 // Record delta in database only for In/Out errors. 784 if ($oid == "ifInErrors" || $oid == "ifOutErrors") 785 { 786 $port['state'][$oid.'_delta'] = '0'; 787 } 788 } 789 790 } 791 792 foreach ($stat_oids as $oid) 793 { 794 // Update StatsD/Carbon 795 if ($config['statsd']['enable'] == TRUE && !strpos($oid, "HC") && is_numeric($this_port[$oid])) 796 { 797 StatsD::gauge(str_replace(".", "_", $device['hostname']).'.'.'port'.'.'.$port['ifIndex'].'.'.$oid, $this_port[$oid]); 798 } 799 } 800 801 $port['stats']['ifInBits_rate'] = round($port['stats']['ifInOctets_rate'] * 8); 802 $port['stats']['ifOutBits_rate'] = round($port['stats']['ifOutOctets_rate'] * 8); 803 804 $port['alert_array']['ifInBits_rate'] = $port['stats']['ifInBits_rate']; 805 $port['alert_array']['ifOutBits_rate'] = $port['stats']['ifOutBits_rate']; 806 807 // If we have been told to debug this port, output the counters we collected earlier, with the rates stuck on the end. 808 if ($config['debug_port'][$port['port_id']]) 809 { 810 print_debug("Wrote port debugging data"); 811 $debug_file = "/tmp/port_debug_".$port['port_id'].".txt"; 812 //FIXME. I think formatted debug out (as for spikes) more informative, but output here more parsable as CSV 813 $port_msg = $port['port_id']."|".$polled."|".$polled_period."|".$debug_port['ifInOctets']."|".$debug_port['ifOutOctets']."|".$debug_port['ifHCInOctets']."|".$debug_port['ifHCOutOctets']; 814 $port_msg .= "|".formatRates($port['stats']['ifInOctets_rate'])."|".formatRates($port['stats']['ifOutOctets_rate'])."|".$device['snmp_version']."\n"; 815 file_put_contents($debug_file, $port_msg, FILE_APPEND); 816 } 817 818 // If we see a spike above ifSpeed or negative rate, output it to /tmp/port_debug_spikes.txt 819 // Example how to read usefull info from this debug by grep: 820 // grep -B 1 -A 6 'ID:\ 520' /tmp/port_debug_spikes.txt 821 if ($config['debug_port']['spikes'] && $this_port['ifSpeed'] > "0" && 822 ($port['stats']['ifInBits_rate'] > $this_port['ifSpeed'] || $port['stats']['ifOutBits_rate'] > $this_port['ifSpeed'] || 823 isset($port['stats']['ifInOctets_negative_rate']) || isset($port['stats']['ifOutOctets_negative_rate']))) 824 { 825 if (!$port['port_64bit']) { $hc_prefix = ''; } 826 print_warning("Spike above ifSpeed or negative rate detected! See debug info here: "); 827 $debug_file = "/tmp/port_debug_spikes.txt"; 828 $debug_format = "| %20s | %20s | %20s |\n"; 829 $debug_msg = sprintf("+%'-68s+\n", ''); 830 $debug_msg .= sprintf("|%67s |\n", $device['hostname']." ".$debug_port['ifDescr']." (ID: ".$port['port_id'].") ".formatRates($debug_port['ifSpeed'])." ".($port['port_64bit'] ? 'Counter64' : 'Counter32')); 831 $debug_msg .= sprintf("+%'-68s+\n", ''); 832 $debug_msg .= sprintf("| %-20s | %-20s | %-20s |\n", 'Polled time', 'if'.$hc_prefix.'OutOctets', 'if'.$hc_prefix.'InOctets'); 833 $debug_msg .= sprintf($debug_format, '(prev) '.$port['poll_time'], $port['ifOutOctets'], $port['ifInOctets']); 834 $debug_msg .= sprintf($debug_format, '(now) '.$polled, $this_port['ifOutOctets'], $this_port['ifInOctets']); 835 $debug_msg .= sprintf($debug_format, format_unixtime($polled), formatRates($port['stats']['ifOutBits_rate']*8), formatRates($port['stats']['ifInBits_rate'])); 836 $debug_msg .= sprintf("%'+70s\n", ''); 837 $debug_msg .= sprintf("| %-67s|\n", 'Port dump:'); 838 // Added full original port variable dump 839 foreach ($debug_port as $debug_key => $debug_var) 840 { 841 $debug_msg .= sprintf("| %-66s|\n", "'$debug_key' => '$debug_var',"); 842 } 843 $debug_msg .= sprintf("+%'-68s+\n\n", ''); 844 file_put_contents($debug_file, $debug_msg, FILE_APPEND); 845 } 846 847 // Put States into alert array 848 foreach (array('ifOperStatus', 'ifAdminStatus', 'ifMtu', 'ifDuplex', 'ifVlan') as $oid) 849 { 850 if (isset($this_port[$oid])) 851 { 852 $port['alert_array'][$oid] = $this_port[$oid]; 853 } 854 } 855 856 // If we have a valid ifSpeed we should populate the percentage stats for checking. 857 if (is_numeric($this_port['ifSpeed'])) 858 { 859 $port['stats']['ifInBits_perc'] = round($port['stats']['ifInBits_rate'] / $this_port['ifSpeed'] * 100); 860 $port['stats']['ifOutBits_perc'] = round($port['stats']['ifOutBits_rate'] / $this_port['ifSpeed'] * 100); 861 $port['alert_array']['ifSpeed'] = $this_port['ifSpeed']; 862 } 863 864 if (is_numeric($this_port['ifHighSpeed'])) 865 { 866 $port['alert_array']['ifHighSpeed'] = $this_port['ifHighSpeed']; 867 } 868 869 $port['state']['ifInOctets_perc'] = $port['stats']['ifInBits_perc']; 870 $port['state']['ifOutOctets_perc'] = $port['stats']['ifOutBits_perc']; 871 872 $port['alert_array']['ifInOctets_perc'] = $port['stats']['ifInBits_perc']; 873 $port['alert_array']['ifOutOctets_perc'] = $port['stats']['ifOutBits_perc']; 874 875 $port['alert_array']['rx_ave_pktsize'] = $port['state']['ifInOctets_delta'] / ($port['state']['ifInUcastPkts_delta'] + $port['state']['ifInNUcastPkts_delta']); 876 $port['alert_array']['tx_ave_pktsize'] = $port['state']['ifOutOctets_delta'] / ($port['state']['ifOutUcastPkts_delta'] + $port['state']['ifOutNUcastPkts_delta']); 877 878 // Store aggregate in/out state 879 $port['state']['ifOctets_rate'] = $port['stats']['ifOutOctets_rate'] + $port['stats']['ifInOctets_rate']; 880 $port['state']['ifUcastPkts_rate'] = $port['stats']['ifOutUcastPkts_rate'] + $port['stats']['ifInUcastPkts_rate']; 881 $port['state']['ifErrors_rate'] = $port['stats']['ifOutErrors_rate'] + $port['stats']['ifInErrors_rate']; 882 $port['state']['ifDiscards_rate'] = $port['stats']['ifOutDiscards_rate'] + $port['stats']['ifInDiscards_rate']; 883 884 // Send aggregate data to alerter too 885 $port['alert_array']['ifOctets_rate'] = $port['state']['ifOctets_rate']; 886 $port['alert_array']['ifUcastPkts_rate'] = $port['state']['ifUcastPkts_rate']; 887 $port['alert_array']['ifNUcastPkts_rate'] = $port['stats']['ifOutNUcastPkts_rate'] + $port['stats']['ifInNUcastPkts_rate']; 888 $port['alert_array']['ifErrors_rate'] = $port['state']['ifErrors_rate']; 889 $port['alert_array']['ifBroadcastPkts_rate'] = $port['stats']['ifOutBroadcastPkts_rate'] + $port['stats']['ifInBroadcastPkts_rate']; 890 $port['alert_array']['ifMulticastPkts_rate'] = $port['stats']['ifOutMulticastPkts_rate'] + $port['stats']['ifInMulticastPkts_rate']; 891 $port['alert_array']['ifDiscards_rate'] = $port['stats']['ifOutDiscards_rate'] + $port['stats']['ifInDiscards_rate']; 892 893 // Update RRDs 894 rrdtool_update_ng($device, 'port', array( 895 'INOCTETS' => $this_port['ifInOctets'], 896 'OUTOCTETS' => $this_port['ifOutOctets'], 897 'INERRORS' => $this_port['ifInErrors'], 898 'OUTERRORS' => $this_port['ifOutErrors'], 899 'INUCASTPKTS' => $this_port['ifInUcastPkts'], 900 'OUTUCASTPKTS' => $this_port['ifOutUcastPkts'], 901 'INNUCASTPKTS' => $this_port['ifInNUcastPkts'], 902 'OUTNUCASTPKTS' => $this_port['ifOutNUcastPkts'], 903 'INDISCARDS' => $this_port['ifInDiscards'], 904 'OUTDISCARDS' => $this_port['ifOutDiscards'], 905 'INUNKNOWNPROTOS' => $this_port['ifInUnknownProtos'], 906 'INBROADCASTPKTS' => $this_port['ifInBroadcastPkts'], 907 'OUTBROADCASTPKTS' => $this_port['ifOutBroadcastPkts'], 908 'INMULTICASTPKTS' => $this_port['ifInMulticastPkts'], 909 'OUTMULTICASTPKTS' => $this_port['ifOutMulticastPkts'], 910 ), get_port_rrdindex($port), TRUE, ['speed' => $this_port['ifSpeed']]); 911 912 // End Update IF-MIB 913 914 // Update additional MIBS and modules 915 foreach ($process_port_db as $port_module => $oids) 916 { 917 $log_event = array(); 918 foreach ($oids as $oid) 919 { 920 if ($port[$oid] != $this_port[$oid]) 921 { 922 if (isset($this_port[$oid])) 923 { 924 // Changed Oid 925 $port['update'][$oid] = $this_port[$oid]; 926 $msg = "[$oid] '" . $port[$oid] . "' -> '" . $this_port[$oid] . "'"; 927 } else { 928 // Removed/empty Oid 929 $port['update'][$oid] = array('NULL'); 930 $msg = "[$oid] '" . $port[$oid] . "' -> NULL"; 931 } 932 $log_event[] = $msg; 933 if (OBS_DEBUG) { echo($msg." "); } 934 } 935 } 936 if ((bool)$log_event) { log_event('Interface changed ('.$port_module.'): ' . implode('; ', $log_event), $device, 'port', $port); } 937 } 938 // End update additional MIBS 939 940 /* PAgP disabled since r7987, while not moved to new polling style 941 // Update PAgP 942 if ($this_port['pagpOperationMode'] || $port['pagpOperationMode']) 943 { 944 $log_event = array(); 945 foreach ($pagp_oids as $oid) 946 { // Loop the OIDs 947 if ($this_port[$oid] != $port[$oid]) 948 { // If data has changed, build a query 949 $port['update'][$oid] = $this_port[$oid]; 950 $log_event[] = "[$oid] " . $port[$oid] . " -> " . $this_port[$oid]; 951 } 952 } 953 if ((bool)$log_event) { log_event('Interface changed (pagp): ' . implode('; ', $log_event), $device, 'port', $port); } 954 } 955 // End Update PAgP 956 */ 957 958# if (OBS_DEBUG > 1) { print_vars($port['alert_array']); echo(PHP_EOL); print_vars($this_port);} 959 960 check_entity('port', $port, $port['alert_array']); 961 962 // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module 963 if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['ports']) 964 { 965 $json_data = array_merge($this_port, $port['state']) ; 966 unset($json_data['rrd_update']); // FIXME unset no longer needed when switched to rrdtool_update_ng() ! 967 messagebus_send(array('attribs' => array('t' => $polled, 'device' => $device['hostname'], 'device_id' => $device['device_id'], 'e_type' => 'port', 'e_index' => $port['ifIndex']), 'data' => $json_data)); 968 unset($json_data); 969 } 970 971# // Do Alcatel Detailed Stats 972# if ($device['os'] == "aos") { include("port-alcatel.inc.php"); } 973 974 // Unified state update 975 976 //$port['update'] = array_merge($port['state'], $port['update']); 977 //$updated = dbUpdate($port['update'], 'ports', '`port_id` = ?', array($port['port_id'])); 978 979 // Add to MultiUpdate ports state as single query 980 $ports_db_state[] = array_merge($this_port_indexes, $port['state']); 981 982 // Update Database 983 if (count($port['update'])) 984 { 985 $updated = dbUpdate($port['update'], 'ports', '`port_id` = ?', array($port['port_id'])); 986 //print_debug("PORT updated rows=$updated"); 987 } 988 989 // Add table row 990 991 $table_row = array(); 992 $table_row[] = $port['ifIndex']; 993 $table_row[] = $port['port_label_short']; 994 $table_row[] = rewrite_iftype($port['ifType']); 995 $table_row[] = formatRates($port['ifSpeed']); 996 $table_row[] = formatRates($port['stats']['ifInBits_rate']); 997 $table_row[] = formatRates($port['stats']['ifOutBits_rate']); 998 $table_row[] = formatStorage($port['stats']['ifInOctets_diff']); 999 $table_row[] = formatStorage($port['stats']['ifOutOctets_diff']); 1000 $table_row[] = format_si($port['stats']['ifInUcastPkts_rate']); 1001 $table_row[] = format_si($port['stats']['ifOutUcastPkts_rate']); 1002 $table_row[] = ($port['port_64bit'] ? "%gY%w" : "%rN%w"); 1003 $table_rows[] = $table_row; 1004 unset($table_row); 1005 1006 // End Update Database 1007 } 1008 elseif ($port['disabled'] != "1") 1009 { 1010 print_message("Port Deleted."); // Port missing from SNMP cache. 1011 if (isset($port['ifIndex']) && $port['deleted'] != "1") 1012 { 1013 $ports_db_deleted[] = array('port_id' => $ports[$port['ifIndex']]['port_id'], 'ifIndex' => $port['ifIndex'], 'device_id' => $device['device_id'], // UNIQUE fields 1014 'deleted' => '1', 'ifLastChange' => date('Y-m-d H:i:s', $polled)); // Update this fields 1015 //dbUpdate(array('deleted' => '1', 'ifLastChange' => date('Y-m-d H:i:s', $polled)), 'ports', '`device_id` = ? AND `ifIndex` = ?', array($device['device_id'], $port['ifIndex'])); 1016 log_event("Interface was marked as DELETED", $device, 'port', $port); 1017 } 1018 } else { 1019 print_message("Port Disabled."); 1020 } 1021 1022 //echo("\n"); 1023 1024 // Clear Per-Port Variables Here 1025 unset($this_port); 1026} 1027 1028// MultiUpdate deleted ports 1029if (count($ports_db_deleted)) 1030{ 1031 print_debug("MultiUpdate deleted ports DB."); 1032 // MultiUpdate required all UNIQUE keys! 1033 dbUpdateMulti($ports_db_deleted, 'ports', array('deleted', 'ifLastChange')); 1034} 1035 1036// MultiUpdate ports state 1037if (count($ports_db_state)) 1038{ 1039 print_debug("MultiUpdate ports states DB."); 1040 // MultiUpdate required all UNIQUE keys! 1041 dbUpdateMulti($ports_db_state, 'ports'); 1042 // Better to pass keys need to update, but without also normal 1043 //$columns = array_diff(array_keys($port['state']), array_keys($this_port_indexes)); 1044 //dbUpdateMulti($ports_db_state, 'ports', $columns); 1045} 1046 1047$headers = array('%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'); 1048print_cli_table($table_rows, $headers); 1049 1050echo(PHP_EOL); 1051 1052// Clear Variables Here 1053unset($port_stats, $process_port_functions, $process_port_db, $has_ifEntry, $has_ifXEntry, $has_ifEntry_error_code, $ports_ignored_count, $ports_ignored_count_db); 1054 1055// EOF 1056