From be24993cbb9c303d2b7d511acd955ab9b4ce60be Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Thu, 5 Oct 2023 01:29:22 -0500 Subject: [PATCH] Remove snmp functions that are barely used (#15377) * Remove snmp functions that are barely used Replace them with SnmpQuery calls * Apply fixes from StyleCI * Fix missing namespace * Import Oid * No more variables left may be repeated multiple times at the end with snmpsim, remove them all * update data fixed by SnmpResponse bugfix --------- Co-authored-by: StyleCI Bot --- LibreNMS/Data/Source/SnmpResponse.php | 2 +- LibreNMS/Device/Processor.php | 2 +- LibreNMS/OS/Shared/Foundry.php | 73 +++++---- LibreNMS/Util/Oid.php | 13 ++ includes/discovery/cisco-cef.inc.php | 3 +- includes/discovery/sensors/netscaler.inc.php | 2 +- includes/polling/applications/bird2.inc.php | 2 +- includes/polling/cisco-asa-firewall.inc.php | 26 ++-- includes/polling/cisco-cef.inc.php | 3 +- includes/polling/cisco-mac-accounting.inc.php | 40 +++-- includes/polling/functions.inc.php | 2 +- includes/snmp.inc.php | 142 ------------------ scripts/json-app-tool.php | 2 +- tests/data/ios_stp-vlans.json | 14 ++ tests/data/ironware.json | 4 +- 15 files changed, 101 insertions(+), 229 deletions(-) diff --git a/LibreNMS/Data/Source/SnmpResponse.php b/LibreNMS/Data/Source/SnmpResponse.php index 6b22fe7b80..1ea7f6871d 100644 --- a/LibreNMS/Data/Source/SnmpResponse.php +++ b/LibreNMS/Data/Source/SnmpResponse.php @@ -252,7 +252,7 @@ class SnmpResponse { return (string) preg_replace([ '/^.*No Such Instance currently exists.*$/m', - '/\n[^\r\n]+No more variables left[^\r\n]+$/s', + '/(\n[^\r\n]+No more variables left[^\r\n]+)+$/', ], '', $this->raw); } diff --git a/LibreNMS/Device/Processor.php b/LibreNMS/Device/Processor.php index 4957fdb960..49038aeeb1 100644 --- a/LibreNMS/Device/Processor.php +++ b/LibreNMS/Device/Processor.php @@ -93,7 +93,7 @@ class Processor extends Model implements DiscoveryModule, PollerModule, Discover // handle string indexes if (Str::contains($oid, '"')) { $oid = preg_replace_callback('/"([^"]+)"/', function ($matches) { - return string_to_oid($matches[1]); + return \LibreNMS\Util\Oid::ofString($matches[1]); }, $oid); } $proc->processor_oid = '.' . ltrim($oid, '.'); diff --git a/LibreNMS/OS/Shared/Foundry.php b/LibreNMS/OS/Shared/Foundry.php index b0be7f0774..b78cee066c 100644 --- a/LibreNMS/OS/Shared/Foundry.php +++ b/LibreNMS/OS/Shared/Foundry.php @@ -39,47 +39,44 @@ class Foundry extends OS implements ProcessorDiscovery */ public function discoverProcessors() { - $processors_data = snmpwalk_cache_triple_oid($this->getDeviceArray(), 'snAgentCpuUtilTable', [], 'FOUNDRY-SN-AGENT-MIB'); $module_descriptions = $this->getCacheByIndex('snAgentConfigModuleDescription', 'FOUNDRY-SN-AGENT-MIB'); - $processors = []; - foreach ($processors_data as $index => $entry) { - // use the 5 minute readings - if ($entry['snAgentCpuUtilInterval'] != 300) { - continue; + return \SnmpQuery::walk('FOUNDRY-SN-AGENT-MIB::snAgentCpuUtilTable')->mapTable(function ($entry, $slot, $cpu, $interval) use ($module_descriptions) { + // only discover 5min + if ($interval == 300) { + $module_description = ''; + if (isset($module_descriptions[$slot])) { + $module_description = $module_descriptions[$slot]; + [$module_description] = explode(' ', $module_description); + } + + $descr = "Slot $slot $module_description [$cpu]"; + $index = "$slot.$cpu.$interval"; + + if (is_numeric($entry['FOUNDRY-SN-AGENT-MIB::snAgentCpuUtil100thPercent'])) { + return Processor::discover( + $this->getName(), + $this->getDeviceId(), + '.1.3.6.1.4.1.1991.1.1.2.11.1.1.6.' . $index, + $index, + $descr, + 100, + $entry['FOUNDRY-SN-AGENT-MIB::snAgentCpuUtil100thPercent'] / 100 + ); + } elseif (is_numeric($entry['FOUNDRY-SN-AGENT-MIB::snAgentCpuUtilPercent'])) { + return Processor::discover( + $this->getName(), + $this->getDeviceId(), + '.1.3.6.1.4.1.1991.1.1.2.11.1.1.4.' . $index, + $index, + $descr, + 1, + $entry['FOUNDRY-SN-AGENT-MIB::snAgentCpuUtilPercent'] + ); + } } - if (is_numeric($entry['snAgentCpuUtil100thPercent'])) { - $usage_oid = '.1.3.6.1.4.1.1991.1.1.2.11.1.1.6.' . $index; - $precision = 100; - $usage = $entry['snAgentCpuUtil100thPercent'] / $precision; - } elseif (is_numeric($entry['snAgentCpuUtilValue'])) { - $usage_oid = '.1.3.6.1.4.1.1991.1.1.2.11.1.1.4.' . $index; - $precision = 1; - $usage = $entry['snAgentCpuUtilValue'] / $precision; - } else { - continue; - } - - $module_description = null; - if (isset($module_descriptions[$entry['snAgentCpuUtilSlotNum']])) { - $module_description = $module_descriptions[$entry['snAgentCpuUtilSlotNum']]; - [$module_description] = explode(' ', $module_description); - } - - $descr = "Slot {$entry['snAgentCpuUtilSlotNum']} $module_description [{$entry['snAgentCpuUtilSlotNum']}]"; - - $processors[] = Processor::discover( - $this->getName(), - $this->getDeviceId(), - $usage_oid, - $index, - $descr, - $precision, - $usage - ); - } - - return $processors; + return null; + })->filter()->values()->all(); } } diff --git a/LibreNMS/Util/Oid.php b/LibreNMS/Util/Oid.php index d91ec10024..fce69d94d4 100644 --- a/LibreNMS/Util/Oid.php +++ b/LibreNMS/Util/Oid.php @@ -85,4 +85,17 @@ class Oid return $numeric_oid; } + + /** + * Convert a string to an oid encoded string + */ + public static function ofString(string $string): string + { + $oid = strlen($string); + for ($i = 0; $i != strlen($string); $i++) { + $oid .= '.' . ord($string[$i]); + } + + return $oid; + } } diff --git a/includes/discovery/cisco-cef.inc.php b/includes/discovery/cisco-cef.inc.php index 5a27c43585..f34d852e39 100644 --- a/includes/discovery/cisco-cef.inc.php +++ b/includes/discovery/cisco-cef.inc.php @@ -1,7 +1,6 @@ walk('CISCO-CEF-MIB::cefSwitchingPath')->table(3); d_echo($cefs); if (is_array($cefs)) { diff --git a/includes/discovery/sensors/netscaler.inc.php b/includes/discovery/sensors/netscaler.inc.php index 3b773c3bde..00937122bb 100644 --- a/includes/discovery/sensors/netscaler.inc.php +++ b/includes/discovery/sensors/netscaler.inc.php @@ -13,7 +13,7 @@ if (! is_array($ns_sensor_array)) { foreach ($ns_sensor_array as $descr => $data) { $current = $data['sysHealthCounterValue']; - $oid = '.1.3.6.1.4.1.5951.4.1.1.41.7.1.2.' . string_to_oid($descr); + $oid = '.1.3.6.1.4.1.5951.4.1.1.41.7.1.2.' . \LibreNMS\Util\Oid::ofString($descr); $divisor = 1; if (str_contains($descr, 'Temp')) { diff --git a/includes/polling/applications/bird2.inc.php b/includes/polling/applications/bird2.inc.php index 1203ff668d..d050a97cec 100644 --- a/includes/polling/applications/bird2.inc.php +++ b/includes/polling/applications/bird2.inc.php @@ -11,7 +11,7 @@ if (! \LibreNMS\Config::get('enable_bgp')) { return; } -$birdOutput = snmp_get($device, 'nsExtendOutputFull.' . string_to_oid($name), '-Oqv', 'NET-SNMP-EXTEND-MIB'); +$birdOutput = snmp_get($device, 'nsExtendOutputFull.' . \LibreNMS\Util\Oid::ofString($name), '-Oqv', 'NET-SNMP-EXTEND-MIB'); // make sure we actually get something back if (empty($birdOutput)) { diff --git a/includes/polling/cisco-asa-firewall.inc.php b/includes/polling/cisco-asa-firewall.inc.php index 5b79dab3f4..3487210570 100644 --- a/includes/polling/cisco-asa-firewall.inc.php +++ b/includes/polling/cisco-asa-firewall.inc.php @@ -15,25 +15,19 @@ use LibreNMS\RRD\RrdDefinition; if ($device['os_group'] == 'cisco' && ($device['os'] == 'asa' || $device['os'] == 'ftd') && $device['type'] == 'firewall') { - $oid_list = 'cfwConnectionStatValue.protoIp.currentInUse'; - $temp_data = snmpwalk_cache_double_oid($device, $oid_list, [], 'CISCO-FIREWALL-MIB'); - foreach ($temp_data as $oid => $result) { - $oid = substr(strchr($oid, '.'), 1); - $data[$oid]['data'] = $result['cfwConnectionStatValue']; - $asa_db = dbFetchCell('SELECT `ciscoASA_id` FROM `ciscoASA` WHERE `device_id` = ? AND `oid` = ?', [$device['device_id'], $oid]); - if (! is_numeric($asa_db)) { - $asa_db = dbInsert(['device_id' => $device['device_id'], 'oid' => $oid, 'data' => $result['cfwConnectionStatValue']], 'ciscoASA'); - } else { - $asa_db = dbUpdate(['data' => $result['cfwConnectionStatValue']], 'ciscoASA', 'device_id=?', [$device['device_id']]); - } + $connections = SnmpQuery::get('CISCO-FIREWALL-MIB::cfwConnectionStatValue.protoIp.currentInUse')->value(); - $data[$oid]['db_id'] = $asa_db; - } + if ($connections) { + DB::table('ciscoASA')->updateOrInsert([ + 'device_id' => $device['device_id'], + 'oid' => 'currentInUse', + ], [ + 'data' => $connections, + ]); - if ($data['currentInUse']) { $rrd_def = RrdDefinition::make()->addDataset('connections', 'GAUGE', 0); $fields = [ - 'connections' => $data['currentInUse']['data'], + 'connections' => $connections, ]; $tags = compact('rrd_def'); @@ -43,5 +37,5 @@ if ($device['os_group'] == 'cisco' && ($device['os'] == 'asa' || $device['os'] = echo ' ASA Connections'; } - unset($data, $rrd_def); + unset($connections, $data, $rrd_def, $fields, $tags); }//end if diff --git a/includes/polling/cisco-cef.inc.php b/includes/polling/cisco-cef.inc.php index 789a7b351b..41842cb45b 100644 --- a/includes/polling/cisco-cef.inc.php +++ b/includes/polling/cisco-cef.inc.php @@ -3,8 +3,7 @@ use LibreNMS\RRD\RrdDefinition; if ($device['os_group'] == 'cisco') { - $cefs = []; - $cefs = snmpwalk_cache_threepart_oid($device, 'CISCO-CEF-MIB::cefSwitchingStatsEntry', $cefs, 'CISCO-CEF-MIB'); + $cefs = SnmpQuery::hideMib()->walk('CISCO-CEF-MIB::cefSwitchingStatsTable')->table(3); $polled = time(); $cefs_query = dbFetchRows('SELECT * FROM `cef_switching` WHERE `device_id` = ?', [$device['device_id']]); diff --git a/includes/polling/cisco-mac-accounting.inc.php b/includes/polling/cisco-mac-accounting.inc.php index 0910be6c3f..43a917c69b 100644 --- a/includes/polling/cisco-mac-accounting.inc.php +++ b/includes/polling/cisco-mac-accounting.inc.php @@ -10,32 +10,29 @@ if ($device['os_group'] == 'cisco') { 'cipMacHCSwitchedBytes', 'cipMacHCSwitchedPkts', ]; - $cip_array = []; - foreach (array_merge($cip_oids, ['cipMacSwitchedBytes', 'cipMacSwitchedPkts']) as $oid) { - echo "$oid "; - $cip_array = snmpwalk_cache_cip($device, $oid, $cip_array, 'CISCO-IP-STAT-MIB'); + $cip_response = SnmpQuery::walk([ + 'CISCO-IP-STAT-MIB::cipMacHCSwitchedBytes', + 'CISCO-IP-STAT-MIB::cipMacHCSwitchedPkts', + ]); + if (! $cip_response->isValid()) { + $cip_response = SnmpQuery::walk([ + 'CISCO-IP-STAT-MIB::cipMacSwitchedBytes', + 'CISCO-IP-STAT-MIB::cipMacSwitchedPkts', + ]); } // Normalize cip_array - $cip_array = array_map(function ($entries) { - return array_map(function ($entry) { - $new_entry = []; - - foreach (['Bytes', 'Pkts'] as $unit) { - $returned_oid = (array_key_exists('cipMacHCSwitched' . $unit, $entry)) ? 'cipMacHCSwitched' : 'cipMacSwitched'; - $new_value = []; - - foreach ($entry[$returned_oid . $unit] as $key => $value) { - $new_value[$key] = intval($value); - } - - $new_entry['cipMacHCSwitched' . $unit] = $new_value; + $cip_array = []; + foreach ($cip_response->table(3) as $ifIndex => $port_data) { + foreach ($port_data as $direction => $dir_data) { + foreach ($dir_data as $mac => $mac_data) { + $mac = \LibreNMS\Util\Rewrite::macToHex($mac); + $cip_array[$ifIndex][$mac]['cipMacHCSwitchedBytes'][$direction] = $mac_data['CISCO-IP-STAT-MIB::cipMacHCSwitchedBytes'] ?? $mac_data['CISCO-IP-STAT-MIB::cipMacSwitchedBytes'] ?? null; + $cip_array[$ifIndex][$mac]['cipMacHCSwitchedPkts'][$direction] = $mac_data['CISCO-IP-STAT-MIB::cipMacHCSwitchedPkts'] ?? $mac_data['CISCO-IP-STAT-MIB::cipMacSwitchedPkts'] ?? null; } - - return $new_entry; - }, $entries); - }, $cip_array); + } + } $polled = time(); @@ -117,6 +114,7 @@ if ($device['os_group'] == 'cisco') { unset( $cip_oids, + $cip_response, $oid, $polled, $mac_entries, diff --git a/includes/polling/functions.inc.php b/includes/polling/functions.inc.php index ade69957b7..d64ce079d1 100644 --- a/includes/polling/functions.inc.php +++ b/includes/polling/functions.inc.php @@ -441,7 +441,7 @@ function update_application($app, $response, $metrics = [], $status = '') */ function json_app_get($device, $extend, $min_version = 1) { - $output = snmp_get($device, 'nsExtendOutputFull.' . string_to_oid($extend), '-Oqv', 'NET-SNMP-EXTEND-MIB'); + $output = snmp_get($device, 'nsExtendOutputFull.' . \LibreNMS\Util\Oid::ofString($extend), '-Oqv', 'NET-SNMP-EXTEND-MIB'); // save for returning if not JSON $orig_output = $output; diff --git a/includes/snmp.inc.php b/includes/snmp.inc.php index 0e87626b02..e777759e9e 100644 --- a/includes/snmp.inc.php +++ b/includes/snmp.inc.php @@ -19,20 +19,9 @@ use App\Models\Device; use App\Polling\Measure\Measurement; use Illuminate\Support\Str; use LibreNMS\Config; -use LibreNMS\Util\Debug; use LibreNMS\Util\Oid; use Symfony\Component\Process\Exception\ProcessTimedOutException; -function string_to_oid($string) -{ - $oid = strlen($string); - for ($i = 0; $i != strlen($string); $i++) { - $oid .= '.' . ord($string[$i]); - } - - return $oid; -}//end string_to_oid() - function prep_snmp_setting($device, $setting) { if (isset($device[$setting]) && is_numeric($device[$setting]) && $device[$setting] > 0) { @@ -435,65 +424,6 @@ function snmp_walk($device, $oid, $options = null, $mib = null, $mibdir = null) return $data; }//end snmp_walk() -function snmpwalk_cache_cip($device, $oid, $array = [], $mib = 0) -{ - $cmd = gen_snmpwalk_cmd($device, $oid, '-OsnQ', $mib); - $data = trim(external_exec($cmd)); - - if (empty($data)) { - return $array; - } - - // echo("Caching: $oid\n"); - foreach (explode("\n", $data) as $entry) { - [$this_oid, $this_value] = preg_split('/=/', $entry); - $this_oid = trim($this_oid); - $this_value = trim($this_value); - $this_oid = substr($this_oid, 30); - [$ifIndex, $dir, $a, $b, $c, $d, $e, $f] = explode('.', $this_oid); - $h_a = zeropad(dechex($a)); - $h_b = zeropad(dechex($b)); - $h_c = zeropad(dechex($c)); - $h_d = zeropad(dechex($d)); - $h_e = zeropad(dechex($e)); - $h_f = zeropad(dechex($f)); - $mac = "$h_a$h_b$h_c$h_d$h_e$h_f"; - - if ($dir == '1') { - $dir = 'input'; - } elseif ($dir == '2') { - $dir = 'output'; - } - - if ($mac && $dir) { - $array[$ifIndex][$mac][$oid][$dir] = $this_value; - } - }//end foreach - - return $array; -}//end snmpwalk_cache_cip() - -function snmp_cache_ifIndex($device) -{ - // FIXME: this is not yet using our own snmp_* - $cmd = gen_snmpwalk_cmd($device, 'ifIndex', '-OQs', 'IF-MIB'); - $data = trim(external_exec($cmd)); - - $array = []; - foreach (explode("\n", $data) as $entry) { - [$this_oid, $this_value] = preg_split('/=/', $entry); - [$this_oid, $this_index] = explode('.', $this_oid, 2); - $this_index = trim($this_index); - $this_oid = trim($this_oid); - $this_value = trim($this_value); - if (! strstr($this_value, 'at this OID') && $this_index) { - $array[] = $this_value; - } - } - - return $array; -}//end snmp_cache_ifIndex() - function snmpwalk_cache_oid($device, $oid, $array = [], $mib = null, $mibdir = null, $snmpflags = '-OQUs') { $data = snmp_walk($device, $oid, $snmpflags, $mib, $mibdir); @@ -626,28 +556,6 @@ function snmpwalk_cache_multi_oid($device, $oid, $array = [], $mib = null, $mibd return $cache['snmp'][$device['device_id']][$oid]; }//end snmpwalk_cache_multi_oid() -function snmpwalk_cache_double_oid($device, $oid, $array = [], $mib = null, $mibdir = null) -{ - $data = snmp_walk($device, $oid, '-OQUs', $mib, $mibdir); - - if (empty($data)) { - return $array; - } - - foreach (explode("\n", $data) as $entry) { - [$oid,$value] = explode('=', $entry, 2); - $oid = trim($oid); - $value = trim($value); - [$oid, $first, $second] = explode('.', $oid); - if (! strstr($value, 'at this OID') && isset($oid) && isset($first) && isset($second)) { - $double = $first . '.' . $second; - $array[$double][$oid] = $value; - } - } - - return $array; -}//end snmpwalk_cache_double_oid() - function snmpwalk_cache_index($device, $oid, $array = [], $mib = null, $mibdir = null) { $data = snmp_walk($device, $oid, '-OQUs', $mib, $mibdir); @@ -669,28 +577,6 @@ function snmpwalk_cache_index($device, $oid, $array = [], $mib = null, $mibdir = return $array; }//end snmpwalk_cache_double_oid() -function snmpwalk_cache_triple_oid($device, $oid, $array = [], $mib = null, $mibdir = null) -{ - $data = snmp_walk($device, $oid, '-OQUs', $mib, $mibdir); - - if (empty($data)) { - return $array; - } - - foreach (explode("\n", $data) as $entry) { - [$oid,$value] = explode('=', $entry, 2); - $oid = trim($oid); - $value = trim($value); - [$oid, $first, $second, $third] = explode('.', $oid); - if (! strstr($value, 'at this OID') && isset($oid) && isset($first) && isset($second)) { - $index = $first . '.' . $second . '.' . $third; - $array[$index][$oid] = $value; - } - } - - return $array; -}//end snmpwalk_cache_triple_oid() - /** * Walk an snmp mib oid and group items together based on the index. * This is intended to be used with a string based oid. @@ -784,34 +670,6 @@ function snmpwalk_cache_twopart_oid($device, $oid, $array = [], $mib = 0, $mibdi return $array; }//end snmpwalk_cache_twopart_oid() -function snmpwalk_cache_threepart_oid($device, $oid, $array = [], $mib = 0) -{ - $cmd = gen_snmpwalk_cmd($device, $oid, '-OQUs', $mib); - $data = trim(external_exec($cmd)); - - if (empty($data)) { - return $array; - } - - foreach (explode("\n", $data) as $entry) { - [$oid,$value] = explode('=', $entry, 2); - $oid = trim($oid); - $value = trim($value); - $value = str_replace('"', '', $value); - [$oid, $first, $second, $third] = explode('.', $oid); - - if (Debug::isEnabled()) { - echo "$entry || $oid || $first || $second || $third\n"; - } - - if (! strstr($value, 'at this OID') && isset($oid) && isset($first) && isset($second) && isset($third)) { - $array[$first][$second][$third][$oid] = $value; - } - } - - return $array; -}//end snmpwalk_cache_threepart_oid() - /** * generate snmp auth arguments * diff --git a/scripts/json-app-tool.php b/scripts/json-app-tool.php index 58ee5c84b6..5bc445ef3f 100755 --- a/scripts/json-app-tool.php +++ b/scripts/json-app-tool.php @@ -147,7 +147,7 @@ if (! isset($options['S'])) { // Output snmprec data for snmpsim for use with testing. if (isset($options['s'])) { - $oid = string_to_oid($options['S']); + $oid = \LibreNMS\Util\Oid::ofString($options['S']); echo "1.3.6.1.2.1.1.1.0|4|Linux server 3.10.0-693.5.2.el7.x86_64 #1 SMP Fri Oct 20 20:32:50 UTC 2017 x86_64\n" . "1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.8072.3.2.10\n" . "1.3.6.1.2.1.1.3.0|67|77550514\n" . diff --git a/tests/data/ios_stp-vlans.json b/tests/data/ios_stp-vlans.json index e024fb7575..2bab2917c8 100644 --- a/tests/data/ios_stp-vlans.json +++ b/tests/data/ios_stp-vlans.json @@ -7210,6 +7210,20 @@ "designatedPort": 14, "forwardTransitions": 1, "ifIndex": 10624 + }, + { + "vlan": 98, + "port_index": 80, + "priority": 128, + "state": "forwarding", + "enable": "enabled", + "pathCost": 4, + "designatedRoot": "0c85255ce500", + "designatedCost": 0, + "designatedBridge": "0c85255ce500", + "designatedPort": 80, + "forwardTransitions": 1, + "ifIndex": 10624 } ] }, diff --git a/tests/data/ironware.json b/tests/data/ironware.json index d2f792945b..b746ccb222 100644 --- a/tests/data/ironware.json +++ b/tests/data/ironware.json @@ -22051,7 +22051,7 @@ "processor_index": "2.1.300", "processor_type": "ironware", "processor_usage": 1, - "processor_descr": "Slot 2 4x10G [2]", + "processor_descr": "Slot 2 4x10G [1]", "processor_precision": 100, "processor_perc_warn": 75 }, @@ -22062,7 +22062,7 @@ "processor_index": "3.1.300", "processor_type": "ironware", "processor_usage": 1, - "processor_descr": "Slot 3 [3]", + "processor_descr": "Slot 3 [1]", "processor_precision": 100, "processor_perc_warn": 75 }