librenms-librenms/tests/mocks/mock.snmp.inc.php
Tony Murray cab2597807 Remove some debug output.
Don't call terminate on null (it will be called automatically anyway)
2016-09-23 15:24:24 -05:00

278 lines
7.3 KiB
PHP

<?php
/**
* mock.snmp.inc.php
*
* Mock functions from includes/snmp.inc.php to allow tests to run without real snmp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2016 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
$snmpMockCache = array();
/**
* Cache the data from an snmprec file
* in ./tests/snmpsim/
*
* @param string $file the snmprec file name (excluding .snmprec)
*/
function cache_snmprec($file)
{
global $config, $snmpMockCache;
if (isset($snmpMockCache[$file])) {
return;
}
$snmpMockCache[$file] = array();
$data = file_get_contents($config['install_dir'] . "/tests/snmpsim/$file.snmprec");
$line = strtok($data, "\r\n");
while ($line !== false) {
list($oid, $type, $data) = explode('|', $line, 3);
if ($type == 4) {
$data = trim($data);
} elseif ($type == 6) {
$data = trim($data, '.');
}
$snmpMockCache[$file][$oid] = array($type, $data);
$line = strtok("\r\n");
}
}
/**
* Get all data of the specified $community from the snmprec cache
*
* @param string $community snmp community to return
* @return array array of the data containing: [$oid][$type, $data]
* @throws Exception this $community is not cached
*/
function snmprec_get($community)
{
global $snmpMockCache;
cache_snmprec($community);
d_echo($snmpMockCache);
if (isset($snmpMockCache[$community])) {
return $snmpMockCache[$community];
}
throw new Exception("SNMPREC: community $community not cached");
}
/**
* Get an $oid from the specified $community
*
* @param string $community the community to fetch data from
* @param string $oid numeric oid of data to fetch
* @return array array of the data containing: [$type, $data]
* @throws Exception this $oid is not cached
*/
function snmprec_get_oid($community, $oid)
{
global $snmpMockCache;
cache_snmprec($community);
if (isset($snmpMockCache[$community]) && isset($snmpMockCache[$community][$oid])) {
return $snmpMockCache[$community][$oid];
}
throw new Exception("SNMPREC: oid $community:$oid not cached");
}
/**
* Get the numeric oid of an oid
* The leading dot is ommited by default to be compatible with snmpsim
*
* @param string $oid the oid to tranlslate
* @param string $mib mib to use
* @param string $mibdir mib dir to look for mib in
* @return string the oid in numeric format (.1.3.4.5)
* @throws Exception Could not translate the oid
*/
function snmp_translate_number($oid, $mib = null, $mibdir = null)
{
global $config;
// optimizations (35s -> 1.6s on my laptop)
if ($oid == 'SNMPv2-MIB::sysDescr.0') {
return '1.3.6.1.2.1.1.1.0';
}
if ($oid == 'SNMPv2-MIB::sysObjectID.0') {
return '1.3.6.1.2.1.1.2.0';
}
if ($oid == 'ENTITY-MIB::entPhysicalDescr.1') {
return '1.3.6.1.2.1.47.1.1.1.1.2.1';
}
if ($oid == 'SML-MIB::product-Name.0') {
return '1.3.6.1.4.1.2.6.182.3.3.1.0';
}
if ($oid == 'ENTITY-MIB::entPhysicalMfgName.1') {
return '1.3.6.1.2.1.47.1.1.1.1.12.1';
}
if ($oid == 'GAMATRONIC-MIB::psUnitManufacture.0') {
return '1.3.6.1.4.1.6050.1.1.2.0';
}
// end optimizations
if (preg_match('/^[\.\d]*$/', $oid)) {
return ltrim($oid, '.');
}
$cmd = "snmptranslate -IR -On $oid";
$cmd .= ' -M ' . (isset($mibdir) ? $mibdir : $config['mibdir']);
if (isset($mib) && $mib) {
$cmd .= " -m $mib";
}
$number = shell_exec($cmd);
if (empty($number)) {
throw new Exception('Could not translate oid: ' . $oid . PHP_EOL . 'Tried: ' . $cmd);
}
return trim($number, ". \n\r");
}
function snmp_translate_type($oid, $mib = null, $mibdir = null)
{
global $config;
$cmd = "snmptranslate -IR -Td $oid";
$cmd .= ' -M ' . (isset($mibdir) ? $mibdir : $config['mibdir']);
if (isset($mib) && $mib) {
$cmd .= " -m $mib";
}
$result = shell_exec($cmd);
if (empty($result)) {
throw new Exception('Could not translate oid: ' . $oid . PHP_EOL . 'Tried: ' . $cmd);
}
if (str_contains($result, 'OCTET STRING')) {
return 4;
}
if (str_contains($result, 'Integer32')) {
return 2;
}
if (str_contains($result, 'NULL')) {
return 5;
}
if (str_contains($result, 'OBJECT IDENTIFIER')) {
return 6;
}
if (str_contains($result, 'IpAddress')) {
return 64;
}
if (str_contains($result, 'Counter32')) {
return 65;
}
if (str_contains($result, 'Gauge32')) {
return 66;
}
if (str_contains($result, 'TimeTicks')) {
return 67;
}
if (str_contains($result, 'Opaque')) {
return 68;
}
if (str_contains($result, 'Counter64')) {
return 70;
}
throw new Exception('Unknown type');
}
// Mocked functions
function snmp_get($device, $oid, $options = null, $mib = null, $mibdir = null)
{
$community = $device['community'];
$num_oid = snmp_translate_number($oid, $mib, $mibdir);
try {
$data = snmprec_get_oid($community, $num_oid);
$result = $data[1];
if ($data[0] == 6) {
$result = '.' . $data[1];
}
d_echo("[SNMP] snmpget $community $num_oid: $result\n");
return $result;
} catch (Exception $e) {
d_echo("[SNMP] snmpget $community $num_oid: no data\n");
return false;
}
}
function snmp_walk($device, $oid, $options = null, $mib = null, $mibdir = null)
{
$community = $device['community'];
$dev = snmprec_get($community);
$num_oid = snmp_translate_number($oid, $mib, $mibdir);
$output = '';
foreach ($dev as $key => $data) {
if (starts_with($key, $num_oid)) {
if ($data[0] == 6) {
$output .= '.' . $data[1] . PHP_EOL;
} else {
$output .= $data[1] . PHP_EOL;
}
}
}
d_echo("[SNMP] snmpwalk $community $num_oid: ");
if (empty($output)) {
d_echo("no data\n");
// does this match the behavior of the real snmp_walk()?
return false;
} else {
d_echo($output);
return $output;
}
}
function register_mibs()
{
// stub
}
function getHostOS($device)
{
global $config;
$sysDescr = snmp_get($device, "SNMPv2-MIB::sysDescr.0", "-Ovq");
$sysObjectId = snmp_get($device, "SNMPv2-MIB::sysObjectID.0", "-Ovqn");
d_echo("| $sysDescr | $sysObjectId | \n");
$os = null;
$pattern = $config['install_dir'] . '/includes/discovery/os/*.inc.php';
foreach (glob($pattern) as $file) {
include $file;
if (isset($os)) {
return $os;
}
}
return "generic";
}