diff --git a/LibreNMS/Data/Source/NetSnmpQuery.php b/LibreNMS/Data/Source/NetSnmpQuery.php index f71215a2d7..5bf06e8c48 100644 --- a/LibreNMS/Data/Source/NetSnmpQuery.php +++ b/LibreNMS/Data/Source/NetSnmpQuery.php @@ -33,6 +33,7 @@ use Illuminate\Support\Str; use LibreNMS\Config; use LibreNMS\Enum\Alert; use LibreNMS\Util\Debug; +use LibreNMS\Util\Oid; use LibreNMS\Util\Rewrite; use Log; use Symfony\Component\Process\Process; @@ -76,9 +77,9 @@ class NetSnmpQuery implements SnmpQueryInterface */ private $context = ''; /** - * @var string + * @var string[] */ - private $mibDir; + private array $mibDirs = []; /** * @var array|string */ @@ -158,7 +159,7 @@ class NetSnmpQuery implements SnmpQueryInterface */ public function mibDir(?string $dir): SnmpQueryInterface { - $this->mibDir = $dir; + $this->mibDirs[] = $dir; return $this; } @@ -283,13 +284,29 @@ class NetSnmpQuery implements SnmpQueryInterface * Translate an OID. * call numeric() on the query to output numeric OID */ - public function translate(string $oid, ?string $mib = null): SnmpResponse + public function translate(string $oid, ?string $mib = null): string { - if ($mib) { - $this->options = array_merge($this->options, ['-m', $mib]); + $this->options = array_diff($this->options, [self::DEFAULT_FLAGS]); // remove default options + + $this->options[] = '-Pu'; // don't error on _ + + // user did not specify numeric, output full text + if (! in_array('-On', $this->options)) { + $this->options[] = '-OS'; + } elseif (Oid::isNumeric($oid)) { + return Str::start($oid, '.'); // numeric to numeric optimization } - return $this->exec('snmptranslate', [$oid]); + // if mib is not directly specified and it doesn't have a numeric root + if (! str_contains($oid, '::') && ! Oid::hasNumericRoot($oid)) { + $this->options[] = '-IR'; // search for mib + } + + if ($mib) { + array_push($this->options, '-m', $mib); + } + + return $this->exec('snmptranslate', [$oid])->value(); } private function buildCli(string $command, array $oids): array @@ -438,8 +455,8 @@ class NetSnmpQuery implements SnmpQueryInterface $dirs[] = $base . '/' . $this->device->os; } - if ($this->mibDir) { - $dirs[] = "$base/$this->mibDir"; + foreach ($this->mibDirs as $mibDir) { + $dirs[] = "$base/$mibDir"; } // remove trailing /, remove empty dirs, and remove duplicates diff --git a/LibreNMS/Data/Source/SnmpQueryInterface.php b/LibreNMS/Data/Source/SnmpQueryInterface.php index c0faaf52f1..c04b38ad15 100644 --- a/LibreNMS/Data/Source/SnmpQueryInterface.php +++ b/LibreNMS/Data/Source/SnmpQueryInterface.php @@ -127,5 +127,5 @@ interface SnmpQueryInterface * Translate an OID. * Call numeric method prior output numeric OID. */ - public function translate(string $oid, ?string $mib = null): SnmpResponse; + public function translate(string $oid, ?string $mib = null): string; } diff --git a/LibreNMS/Data/Source/SnmpResponse.php b/LibreNMS/Data/Source/SnmpResponse.php index 94d68bd18d..ae2c792c8f 100644 --- a/LibreNMS/Data/Source/SnmpResponse.php +++ b/LibreNMS/Data/Source/SnmpResponse.php @@ -242,4 +242,9 @@ class SnmpResponse return $this; } + + public function __toString(): string + { + return $this->raw; + } } diff --git a/LibreNMS/Device/YamlDiscovery.php b/LibreNMS/Device/YamlDiscovery.php index 6ee204ee95..2f3f9cbbeb 100644 --- a/LibreNMS/Device/YamlDiscovery.php +++ b/LibreNMS/Device/YamlDiscovery.php @@ -26,19 +26,16 @@ namespace LibreNMS\Device; use App\View\SimpleTemplate; -use Cache; use Illuminate\Support\Arr; use Illuminate\Support\Str; use LibreNMS\Config; -use LibreNMS\Exceptions\InvalidOidException; use LibreNMS\Interfaces\Discovery\DiscoveryItem; use LibreNMS\OS; use LibreNMS\Util\Compare; +use LibreNMS\Util\Oid; class YamlDiscovery { - private static $cache_time = 1800; // 30 min, Used for oid translation cache - /** * @param OS $os * @param DiscoveryItem|string $class @@ -145,7 +142,7 @@ class YamlDiscovery } try { - $num_oid = static::oidToNumeric($data['value'], $os->getDeviceArray(), $search_mib); + $num_oid = Oid::toNumeric($data['value'], $search_mib); } catch (\Exception $e) { throw $e; } @@ -380,46 +377,4 @@ class YamlDiscovery return false; } - - /** - * Translate an oid to numeric format (if already numeric, return as-is) - * - * @param string $oid - * @param array|null $device - * @param string $mib - * @return string numeric oid - * - * @throws \LibreNMS\Exceptions\InvalidOidException - */ - public static function oidToNumeric($oid, $device = null, $mib = 'ALL') - { - if (self::oidIsNumeric($oid)) { - return $oid; - } - $key = 'YamlDiscovery:oidToNumeric:' . $mib . '/' . $oid; - if (Cache::has($key)) { - $numeric_oid = Cache::get($key); - } else { - foreach (explode(':', $mib) as $mib_name) { - $numeric_oid = snmp_translate($oid, $mib_name, null, null, $device); - if ($numeric_oid) { - break; - } - } - } - - //Store the value - Cache::put($key, $numeric_oid, self::$cache_time); - - if (empty($numeric_oid)) { - throw new InvalidOidException("Unable to translate oid $oid"); - } - - return $numeric_oid; - } - - public static function oidIsNumeric($oid) - { - return (bool) preg_match('/^[.\d]+$/', $oid); - } } diff --git a/LibreNMS/OS/Edgecos.php b/LibreNMS/OS/Edgecos.php index b8a000a243..9d9610ec69 100644 --- a/LibreNMS/OS/Edgecos.php +++ b/LibreNMS/OS/Edgecos.php @@ -30,10 +30,10 @@ use App\Models\Mempool; use Illuminate\Support\Collection; use Illuminate\Support\Str; use LibreNMS\Device\Processor; -use LibreNMS\Device\YamlDiscovery; use LibreNMS\Interfaces\Discovery\MempoolsDiscovery; use LibreNMS\Interfaces\Discovery\ProcessorDiscovery; use LibreNMS\OS; +use LibreNMS\Util\Oid; class Edgecos extends OS implements MempoolsDiscovery, ProcessorDiscovery { @@ -56,9 +56,9 @@ class Edgecos extends OS implements MempoolsDiscovery, ProcessorDiscovery ]); if (! empty($data['memoryAllocated.0'])) { - $mempool->mempool_used_oid = YamlDiscovery::oidToNumeric('memoryAllocated.0', $this->getDeviceArray(), $mib); + $mempool->mempool_used_oid = Oid::toNumeric('memoryAllocated.0', $mib); } else { - $mempool->mempool_free_oid = YamlDiscovery::oidToNumeric('memoryFreed.0', $this->getDeviceArray(), $mib); + $mempool->mempool_free_oid = Oid::toNumeric('memoryFreed.0', $mib); } $mempool->fillUsage($data['memoryAllocated.0'] ?? null, $data['memoryTotal.0'] ?? null, $data['memoryFreed.0']); diff --git a/LibreNMS/OS/Junose.php b/LibreNMS/OS/Junose.php index f29e42551b..24ecec0d1c 100644 --- a/LibreNMS/OS/Junose.php +++ b/LibreNMS/OS/Junose.php @@ -37,7 +37,7 @@ class Junose extends \LibreNMS\OS return; } - $junose_hardware = \SnmpQuery::translate($device->sysObjectID, 'Juniper-Products-MIB')->value(); + $junose_hardware = \SnmpQuery::translate($device->sysObjectID, 'Juniper-Products-MIB'); $device->hardware = $this->rewriteHardware($junose_hardware) ?: null; $junose_version = \SnmpQuery::get('Juniper-System-MIB::juniSystemSwVersion.0')->value(); diff --git a/LibreNMS/OS/Traits/YamlMempoolsDiscovery.php b/LibreNMS/OS/Traits/YamlMempoolsDiscovery.php index b484eba8b7..7e78f290b7 100644 --- a/LibreNMS/OS/Traits/YamlMempoolsDiscovery.php +++ b/LibreNMS/OS/Traits/YamlMempoolsDiscovery.php @@ -28,6 +28,7 @@ namespace LibreNMS\OS\Traits; use App\Models\Mempool; use Illuminate\Support\Collection; use LibreNMS\Device\YamlDiscovery; +use LibreNMS\Util\Oid; trait YamlMempoolsDiscovery { @@ -107,12 +108,12 @@ trait YamlMempoolsDiscovery private function getOid($field, $index, $yaml) { - if (YamlDiscovery::oidIsNumeric($yaml[$field] ?? '')) { + if (Oid::isNumeric($yaml[$field] ?? '')) { return $yaml[$field]; } if (isset($this->mempoolsOids[$field])) { - return YamlDiscovery::oidToNumeric("{$this->mempoolsOids[$field]}.$index", $this->getDeviceArray()); + return Oid::toNumeric("{$this->mempoolsOids[$field]}.$index", 'ALL'); } return null; @@ -137,7 +138,7 @@ trait YamlMempoolsDiscovery foreach ($this->mempoolsFields as $field) { if (isset($yaml[$field]) && ! is_numeric($yaml[$field])) { // allow for hard-coded values $oid = $yaml[$field]; - if (YamlDiscovery::oidIsNumeric($oid)) { // if numeric oid, it is not a table, just fetch it + if (Oid::isNumeric($oid)) { // if numeric oid, it is not a table, just fetch it $this->mempoolsData[0][$oid] = snmp_get($this->getDeviceArray(), $oid, '-Oqv'); continue; } @@ -145,7 +146,7 @@ trait YamlMempoolsDiscovery if (empty($yaml['oid'])) { // if table given, skip individual oids $this->mempoolsData = snmpwalk_cache_oid($this->getDeviceArray(), $oid, $this->mempoolsData, null, null, $options); } - $this->mempoolsOids[$field] = YamlDiscovery::oidToNumeric($oid, $this->getDeviceArray(), $mib); + $this->mempoolsOids[$field] = Oid::toNumeric($oid, $mib); } } } diff --git a/LibreNMS/OS/Traits/YamlOSDiscovery.php b/LibreNMS/OS/Traits/YamlOSDiscovery.php index 436c2dbc59..0f29114ce6 100644 --- a/LibreNMS/OS/Traits/YamlOSDiscovery.php +++ b/LibreNMS/OS/Traits/YamlOSDiscovery.php @@ -29,6 +29,7 @@ use App\Models\Device; use App\Models\Location; use App\View\SimpleTemplate; use Illuminate\Support\Arr; +use LibreNMS\Util\Oid; use LibreNMS\Util\StringHelpers; use Log; @@ -62,7 +63,7 @@ trait YamlOSDiscovery $oids = Arr::only($os_yaml, $this->osFields); $fetch_oids = array_unique(Arr::flatten($oids)); - $numeric = $this->isNumeric($fetch_oids); + $numeric = Oid::hasNumeric($fetch_oids); $data = $this->fetch($fetch_oids, $numeric); Log::debug('Yaml OS data:', $data); @@ -93,7 +94,7 @@ trait YamlOSDiscovery $lng = $os_yaml['long'] ?? null; $oids = array_filter([$name, $lat, $lng]); - $numeric = $this->isNumeric($oids); + $numeric = Oid::hasNumeric($oids); $data = $this->fetch($oids, $numeric); Log::debug('Yaml location data:', $data); @@ -111,7 +112,7 @@ trait YamlOSDiscovery { foreach (Arr::wrap($oids) as $oid) { // translate all to numeric to make it easier to match - $oid = ($numeric && ! oid_is_numeric($oid)) ? snmp_translate($oid, 'ALL', null, null, $this->getDeviceArray()) : $oid; + $oid = ($numeric && ! Oid::isNumeric($oid)) ? snmp_translate($oid, 'ALL', null, null, $this->getDeviceArray()) : $oid; if (! empty($data[$oid])) { return $data[$oid]; } @@ -150,17 +151,6 @@ trait YamlOSDiscovery return snmp_get_multi_oid($this->getDeviceArray(), $oids, $numeric ? '-OUQn' : '-OUQ'); } - private function isNumeric($oids) - { - foreach ($oids as $oid) { - if (oid_is_numeric($oid)) { - return true; - } - } - - return false; - } - private function replaceStringsInFields(Device $device, array $os_yaml): void { foreach ($this->osFields as $field) { diff --git a/LibreNMS/Util/Oid.php b/LibreNMS/Util/Oid.php new file mode 100644 index 0000000000..748b222061 --- /dev/null +++ b/LibreNMS/Util/Oid.php @@ -0,0 +1,82 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2022 Tony Murray + * @author Tony Murray + */ + +namespace LibreNMS\Util; + +use Cache; +use LibreNMS\Exceptions\InvalidOidException; + +class Oid +{ + public static function isNumeric(string $oid): bool + { + return (bool) preg_match('/^[.\d]+$/', $oid); + } + + public static function hasNumericRoot(string $oid): bool + { + return (bool) preg_match('/^\.?1/', $oid); + } + + public static function hasNumeric(array $oids): bool + { + foreach ($oids as $oid) { + if (self::isNumeric($oid)) { + return true; + } + } + + return false; + } + + /** + * Converts an oid to numeric and caches the result + * + * @throws \LibreNMS\Exceptions\InvalidOidException + */ + public static function toNumeric(string $oid, string $mib = 'ALL', int $cache = 1800): string + { + if (Oid::isNumeric($oid)) { + return $oid; + } + + // we already have a specific mib, don't add a bunch of others + if (str_contains($oid, '::')) { + $mib = null; + } + + $key = 'Oid:toNumeric:' . $oid . '/' . $mib; + + $numeric_oid = Cache::remember($key, $cache, function () use ($oid, $mib) { + return \SnmpQuery::numeric()->translate($oid, $mib); + }); + + if (empty($numeric_oid)) { + throw new InvalidOidException("Unable to translate oid $oid"); + } + + return $numeric_oid; + } +} diff --git a/app/Console/Commands/SnmpFetch.php b/app/Console/Commands/SnmpFetch.php index c1763addd6..57f04daacc 100644 --- a/app/Console/Commands/SnmpFetch.php +++ b/app/Console/Commands/SnmpFetch.php @@ -56,19 +56,23 @@ class SnmpFetch extends LnmsCommand } $return = 0; + $type = $this->option('type'); + $output = $this->option('output') ?: ($type == 'walk' ? 'table' : 'value'); foreach ($device_ids as $device_id) { DeviceCache::setPrimary($device_id); $this->info(DeviceCache::getPrimary()->displayName() . ':'); - $type = $this->option('type'); - $output = $this->option('output') - ?: ($type == 'walk' ? 'table' : 'value'); - /** @var \LibreNMS\Data\Source\SnmpResponse $res */ $res = SnmpQuery::numeric($this->option('numeric')) ->$type($this->argument('oid')); + if ($type == 'translate') { + $this->line($res); + + return 0; + } + if (! $res->isValid()) { $this->warn(trans('commands.snmp:fetch.failed')); $this->line($res->getErrorMessage()); diff --git a/includes/snmp.inc.php b/includes/snmp.inc.php index b7cab8a9dc..41772416ec 100644 --- a/includes/snmp.inc.php +++ b/includes/snmp.inc.php @@ -20,6 +20,7 @@ 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) @@ -857,7 +858,7 @@ function snmp_gen_auth(&$device, $cmd = []) * Default options for a textual oid is -On * You may override these by setting $options (an empty string for no options) * - * @param string $oid + * @param string|null $oid * @param string $mib * @param string $mibdir the mib directory (relative to the LibreNMS mibs directory) * @param array|string $options Options to pass to snmptranslate @@ -866,10 +867,14 @@ function snmp_gen_auth(&$device, $cmd = []) */ function snmp_translate($oid, $mib = 'ALL', $mibdir = null, $options = null, $device = null) { + if (empty($oid)) { + return ''; + } + $measure = Measurement::start('snmptranslate'); $cmd = [Config::get('snmptranslate', 'snmptranslate'), '-M', mibdir($mibdir, $device), '-m', $mib]; - if (oid_is_numeric($oid)) { + if (Oid::isNumeric($oid)) { $default_options = ['-Os', '-Pu']; } else { if ($mib != 'ALL' && ! Str::contains($oid, '::')) { @@ -966,14 +971,3 @@ function get_device_max_repeaters($device) return $device['attribs']['snmp_max_repeaters'] ?? Config::getOsSetting($device['os'], 'snmp.max_repeaters', Config::get('snmp.max_repeaters', false)); } - -/** - * Check if a given oid is numeric. - * - * @param string $oid - * @return bool - */ -function oid_is_numeric($oid) -{ - return \LibreNMS\Device\YamlDiscovery::oidIsNumeric($oid); -} diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index db376a0c7b..4a20fb6259 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2450,26 +2450,11 @@ parameters: count: 1 path: LibreNMS/Device/WirelessSensor.php - - - message: "#^Method LibreNMS\\\\Device\\\\YamlDiscovery\\:\\:oidIsNumeric\\(\\) has no return type specified\\.$#" - count: 1 - path: LibreNMS/Device/YamlDiscovery.php - - - - message: "#^Method LibreNMS\\\\Device\\\\YamlDiscovery\\:\\:oidIsNumeric\\(\\) has parameter \\$oid with no type specified\\.$#" - count: 1 - path: LibreNMS/Device/YamlDiscovery.php - - message: "#^Method LibreNMS\\\\Device\\\\YamlDiscovery\\:\\:preCache\\(\\) has no return type specified\\.$#" count: 1 path: LibreNMS/Device/YamlDiscovery.php - - - message: "#^Property LibreNMS\\\\Device\\\\YamlDiscovery\\:\\:\\$cache_time has no type specified\\.$#" - count: 1 - path: LibreNMS/Device/YamlDiscovery.php - - message: "#^Method LibreNMS\\\\Exceptions\\\\ApiException\\:\\:__construct\\(\\) has parameter \\$message with no type specified\\.$#" count: 1 @@ -3485,16 +3470,6 @@ parameters: count: 1 path: LibreNMS/OS.php - - - message: "#^Method LibreNMS\\\\OS\\:\\:isNumeric\\(\\) has no return type specified\\.$#" - count: 1 - path: LibreNMS/OS.php - - - - message: "#^Method LibreNMS\\\\OS\\:\\:isNumeric\\(\\) has parameter \\$oids with no type specified\\.$#" - count: 1 - path: LibreNMS/OS.php - - message: "#^Method LibreNMS\\\\OS\\:\\:memValid\\(\\) has no return type specified\\.$#" count: 1 @@ -3965,16 +3940,6 @@ parameters: count: 1 path: LibreNMS/OS/Shared/Cisco.php - - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Cisco\\:\\:isNumeric\\(\\) has no return type specified\\.$#" - count: 1 - path: LibreNMS/OS/Shared/Cisco.php - - - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Cisco\\:\\:isNumeric\\(\\) has parameter \\$oids with no type specified\\.$#" - count: 1 - path: LibreNMS/OS/Shared/Cisco.php - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Cisco\\:\\:parseRegex\\(\\) has no return type specified\\.$#" count: 1 @@ -4105,16 +4070,6 @@ parameters: count: 1 path: LibreNMS/OS/Shared/Unix.php - - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Unix\\:\\:isNumeric\\(\\) has no return type specified\\.$#" - count: 1 - path: LibreNMS/OS/Shared/Unix.php - - - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Unix\\:\\:isNumeric\\(\\) has parameter \\$oids with no type specified\\.$#" - count: 1 - path: LibreNMS/OS/Shared/Unix.php - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Unix\\:\\:parseRegex\\(\\) has no return type specified\\.$#" count: 1 @@ -4185,16 +4140,6 @@ parameters: count: 1 path: LibreNMS/OS/Shared/Zyxel.php - - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Zyxel\\:\\:isNumeric\\(\\) has no return type specified\\.$#" - count: 1 - path: LibreNMS/OS/Shared/Zyxel.php - - - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Zyxel\\:\\:isNumeric\\(\\) has parameter \\$oids with no type specified\\.$#" - count: 1 - path: LibreNMS/OS/Shared/Zyxel.php - - message: "#^Method LibreNMS\\\\OS\\\\Shared\\\\Zyxel\\:\\:parseRegex\\(\\) has no return type specified\\.$#" count: 1 diff --git a/tests/Mocks/SnmpQueryMock.php b/tests/Mocks/SnmpQueryMock.php index 646e23172d..5e8bec992f 100644 --- a/tests/Mocks/SnmpQueryMock.php +++ b/tests/Mocks/SnmpQueryMock.php @@ -33,7 +33,7 @@ use Illuminate\Support\Str; use LibreNMS\Data\Source\NetSnmpQuery; use LibreNMS\Data\Source\SnmpQueryInterface; use LibreNMS\Data\Source\SnmpResponse; -use LibreNMS\Device\YamlDiscovery; +use LibreNMS\Util\Oid; use Log; class SnmpQueryMock implements SnmpQueryInterface @@ -101,7 +101,7 @@ class SnmpQueryMock implements SnmpQueryInterface return $this; } - public function translate(string $oid, ?string $mib = null): SnmpResponse + public function translate(string $oid, ?string $mib = null): string { // call real snmptranslate $options = $this->options; @@ -288,15 +288,15 @@ class SnmpQueryMock implements SnmpQueryInterface private function outputLine(string $oid, string $num_oid, string $type, string $data): string { if ($type == 6) { - $data = $this->numeric ? ".$data" : $this->translate($data, $this->extractMib($oid))->value(); + $data = $this->numeric ? ".$data" : $this->translate($data, $this->extractMib($oid)); } if ($this->numeric) { return "$num_oid = $data"; } - if (! empty($oid) && YamlDiscovery::oidIsNumeric($oid)) { - $oid = $this->translate($oid)->value(); + if (! empty($oid) && Oid::isNumeric($oid)) { + $oid = $this->translate($oid); } return "$oid = $data"; @@ -332,7 +332,7 @@ class SnmpQueryMock implements SnmpQueryInterface return '1.3.6.1.4.1.6574.1.1.0'; } - if (YamlDiscovery::oidIsNumeric($oid)) { + if (Oid::isNumeric($oid)) { return ltrim($oid, '.'); } @@ -342,7 +342,7 @@ class SnmpQueryMock implements SnmpQueryInterface } $number = NetSnmpQuery::make()->mibDir($this->mibDir) - ->options(array_merge($options, $this->options))->numeric()->translate($oid)->value(); + ->options(array_merge($options, $this->options))->numeric()->translate($oid); if (empty($number)) { throw new Exception('Could not translate oid: ' . $oid . PHP_EOL); diff --git a/tests/Unit/SnmpTranslateTest.php b/tests/Unit/SnmpTranslateTest.php new file mode 100644 index 0000000000..3916ce2790 --- /dev/null +++ b/tests/Unit/SnmpTranslateTest.php @@ -0,0 +1,143 @@ +. + * + * @link https://www.librenms.org + * + * @copyright 2022 Tony Murray + * @author Tony Murray + */ + +namespace LibreNMS\Tests\Unit; + +use App\Models\Device; +use LibreNMS\Tests\TestCase; + +class SnmpTranslateTest extends TestCase +{ + public function testSimpleInput(): void + { + $actual = \SnmpQuery::numeric()->translate('IF-MIB::ifTable'); + $this->assertEquals('.1.3.6.1.2.1.2.2', $actual); + + $actual = \SnmpQuery::numeric()->translate('ifTable', 'IF-MIB'); + $this->assertEquals('.1.3.6.1.2.1.2.2', $actual); + + $actual = \SnmpQuery::numeric()->translate('ifTable', 'ALL'); + $this->assertEquals('.1.3.6.1.2.1.2.2', $actual); + + $actual = \SnmpQuery::translate('IF-MIB::ifTable'); + $this->assertEquals('IF-MIB::ifTable', $actual); + + $actual = \SnmpQuery::numeric()->translate('.1.3.6.1.2.1.2.2'); + $this->assertEquals('.1.3.6.1.2.1.2.2', $actual); + + $actual = \SnmpQuery::translate('.1.3.6.1.2.1.2.2', 'IF-MIB'); + $this->assertEquals('IF-MIB::ifTable', $actual); + + $actual = \SnmpQuery::numeric()->translate('1.3.6.1.2.1.2.2'); + $this->assertEquals('.1.3.6.1.2.1.2.2', $actual); + + $actual = \SnmpQuery::translate('.1.3.6.1.2.1.2.2', 'ALL'); + $this->assertEquals('RFC1213-MIB::ifTable', $actual); + + $actual = \SnmpQuery::numeric()->translate('ifTable', 'IP-MIB'); + $this->assertEquals('.1.3.6.1.2.1.2.2', $actual); + + $actual = \SnmpQuery::translate('ifTable', 'IP-MIB'); + $this->assertEquals('IF-MIB::ifTable', $actual); + + // with index + $actual = \SnmpQuery::numeric()->translate('IF-MIB::ifTable.0'); + $this->assertEquals('.1.3.6.1.2.1.2.2.0', $actual); + + $actual = \SnmpQuery::numeric()->translate('ifTable.0', 'IF-MIB'); + $this->assertEquals('.1.3.6.1.2.1.2.2.0', $actual); + + $actual = \SnmpQuery::numeric()->translate('ifTable.0', 'ALL'); + $this->assertEquals('.1.3.6.1.2.1.2.2.0', $actual); + + $actual = \SnmpQuery::translate('IF-MIB::ifTable.0'); + $this->assertEquals('IF-MIB::ifTable.0', $actual); + + $actual = \SnmpQuery::numeric()->translate('.1.3.6.1.2.1.2.2.0'); + $this->assertEquals('.1.3.6.1.2.1.2.2.0', $actual); + + $actual = \SnmpQuery::translate('.1.3.6.1.2.1.2.2.0', 'IF-MIB'); + $this->assertEquals('IF-MIB::ifTable.0', $actual); + + $actual = \SnmpQuery::numeric()->translate('1.3.6.1.2.1.2.2.0'); + $this->assertEquals('.1.3.6.1.2.1.2.2.0', $actual); + + $actual = \SnmpQuery::translate('.1.3.6.1.2.1.2.2.0', 'ALL'); + $this->assertEquals('RFC1213-MIB::ifTable.0', $actual); + + $actual = \SnmpQuery::translate('ifTable.0', 'IP-MIB'); + $this->assertEquals('IF-MIB::ifTable.0', $actual); + + $actual = \SnmpQuery::translate('iso.3.6.1.2.1.1.1.0', 'SNMPv2-MIB'); + $this->assertEquals('SNMPv2-MIB::sysDescr.0', $actual); + + $actual = \SnmpQuery::numeric()->translate('iso.3.6.1.2.1.1.1.0', 'SNMPv2-MIB'); + $this->assertEquals('.1.3.6.1.2.1.1.1.0', $actual); + } + + public function testFailedInput(): void + { + $actual = \SnmpQuery::numeric()->translate('ifTable'); + $this->assertEquals('', $actual); + + $actual = \SnmpQuery::translate('ifTable'); + $this->assertEquals('', $actual); + + $actual = \SnmpQuery::numeric()->translate('ifTable', 'ASDF-MIB:SNMPv2-MIB'); + $this->assertEquals('', $actual); + + $actual = \SnmpQuery::translate('ifTable'); + $this->assertEquals('', $actual); + + $actual = \SnmpQuery::numeric()->translate('ifTable'); + $this->assertEquals('', $actual); + + $actual = \SnmpQuery::translate('ifTable'); + $this->assertEquals('', $actual); + } + + public function testComplexInput(): void + { + $actual = \SnmpQuery::translate('.1.3.6.1.2.1.2.2', 'RFC1213-MIB:IF-MIB'); + $this->assertEquals('RFC1213-MIB::ifTable', $actual); + + $actual = \SnmpQuery::translate('.1.3.6.1.2.1.2.2', 'IF-MIB:RFC1213-MIB'); + $this->assertEquals('IF-MIB::ifTable', $actual); + + $actual = \SnmpQuery::translate('ifTable', 'RFC1213-MIB:IF-MIB'); + $this->assertEquals('RFC1213-MIB::ifTable', $actual); + + $actual = \SnmpQuery::translate('ifTable', 'IF-MIB:RFC1213-MIB'); + $this->assertEquals('IF-MIB::ifTable', $actual); + + // partial numeric + $device = Device::factory()->make(['os' => 'dlink']); + $actual = \SnmpQuery::device($device)->numeric()->translate('.1.3.6.1.4.1.171.14.5.1.4.1.4.1.dram', 'EQUIPMENT-MIB:DLINKSW-ENTITY-EXT-MIB'); + $this->assertEquals('.1.3.6.1.4.1.171.14.5.1.4.1.4.1.1', $actual); + + $actual = \SnmpQuery::device($device)->numeric()->translate('iso.3.6.1.4.1.171.14.5.1.4.1.4.1.dram', 'EQUIPMENT-MIB:DLINKSW-ENTITY-EXT-MIB'); + $this->assertEquals('.1.3.6.1.4.1.171.14.5.1.4.1.4.1.1', $actual); + } +}