disableCache(); * $snmp->get( ... ); * $snmp->enableCache(); */ protected $_disableCache = false; /** * SNMP output constants to mirror those of PHP * @var SNMP output constants to mirror those of PHP */ const OID_OUTPUT_FULL = SNMP_OID_OUTPUT_FULL; /** * SNMP output constants to mirror those of PHP * @var SNMP output constants to mirror those of PHP */ const OID_OUTPUT_NUMERIC = SNMP_OID_OUTPUT_NUMERIC; /** * Definition of an SNMP return type 'TruthValue' * @var Definition of an SNMP return type 'TruthValue' */ const SNMP_TRUTHVALUE_TRUE = 1; /** * Definition of an SNMP return type 'TruthValue' * @var Definition of an SNMP return type 'TruthValue' */ const SNMP_TRUTHVALUE_FALSE = 2; /** * PHP equivalents of SNMP return type TruthValue * @var array PHP equivalents of SNMP return type TruthValue */ public static $SNMP_TRUTHVALUES = array( self::SNMP_TRUTHVALUE_TRUE => true, self::SNMP_TRUTHVALUE_FALSE => false ); /** * The constructor. * * @param string $host The target host for SNMP queries. * @param string $community The community to use for SNMP queries. * @return FiberlinkBundle\SNMP\SNMP An instance of $this (for fluent interfaces) */ public function __construct( $host = '127.0.0.1', $community = 'public' ) { return $this->setHost( $host ) ->setCommunity( $community ) ->setOidOutputFormat( self::OID_OUTPUT_NUMERIC ); } /** * Proxy to the snmp2_real_walk command * * @param string $oid The OID to walk * @return array The results of the walk */ public function realWalk( $oid ) { return $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); } /** * Get a single SNMP value * * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown * @param string $oid The OID to get * @return mixed The resultant value */ public function get( $oid ) { if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null ) return $rtn; $this->_lastResult = @snmp2_get( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); if( $this->_lastResult === false ) throw new Exception( 'Cound not perform walk for OID ' . $oid ); return $this->getCache()->save( $oid, $this->parseSnmpValue( $this->_lastResult ) ); } /** * Get indexed SNMP values (first degree) * * Walks the SNMP tree returning an array of key => value pairs. * * This is a first degree walk and it will throw an exception if there is more that one degree of values. * * I.e. the following query with sample results: * * walk1d( '.1.0.8802.1.1.2.1.3.7.1.4' ) * * .1.0.8802.1.1.2.1.3.7.1.4.1 = STRING: "GigabitEthernet1/0/1" * .1.0.8802.1.1.2.1.3.7.1.4.2 = STRING: "GigabitEthernet1/0/2" * .1.0.8802.1.1.2.1.3.7.1.4.3 = STRING: "GigabitEthernet1/0/3" * ..... * * would yield an array: * * 1 => GigabitEthernet1/0/1 * 2 => GigabitEthernet1/0/2 * 3 => GigabitEthernet1/0/3 * * @param string $oid The OID to walk * @return array The resultant values * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown */ public function walk1d( $oid ) { if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null ) return $rtn; $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); if( $this->_lastResult === false ) throw new Exception( 'Cound not perform walk for OID ' . $oid ); $result = array(); $oidPrefix = null; foreach( $this->_lastResult as $_oid => $value ) { if( $oidPrefix !== null && $oidPrefix != substr( $_oid, 0, strrpos( $_oid, '.' ) ) ) throw new Exception( 'Requested OID tree is not a first degree indexed SNMP value' ); else $oidPrefix = substr( $_oid, 0, strrpos( $_oid, '.' ) ); $result[ substr( $_oid, strrpos( $_oid, '.' ) + 1 ) ] = $this->parseSnmpValue( $value ); } return $this->getCache()->save( $oid, $result ); } /** * Get indexed SNMP values where the array key is the given position of the OID * * I.e. the following query with sample results: * * subOidWalk( '.1.3.6.1.4.1.9.9.23.1.2.1.1.9', 15 ) * * * .1.3.6.1.4.1.9.9.23.1.2.1.1.9.10101.5 = Hex-STRING: 00 00 00 01 * .1.3.6.1.4.1.9.9.23.1.2.1.1.9.10105.2 = Hex-STRING: 00 00 00 01 * .1.3.6.1.4.1.9.9.23.1.2.1.1.9.10108.4 = Hex-STRING: 00 00 00 01 * * would yield an array: * * 10101 => Hex-STRING: 00 00 00 01 * 10105 => Hex-STRING: 00 00 00 01 * 10108 => Hex-STRING: 00 00 00 01 * * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown * @param string $oid The OID to walk * @param int $position The position of the OID to use as the key * @return array The resultant values */ public function subOidWalk( $oid, $position ) { if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null ) return $rtn; $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); if( $this->_lastResult === false ) throw new Exception( 'Cound not perform walk for OID ' . $oid ); $result = array(); foreach( $this->_lastResult as $_oid => $value ) { $oids = explode( '.', $_oid ); $result[ $oids[ $position] ] = $this->parseSnmpValue( $value ); } return $this->getCache()->save( $oid, $result ); } /** * Get indexed SNMP values where they are indexed by IPv4 addresses * * I.e. the following query with sample results: * * subOidWalk( '.1.3.6.1.2.1.15.3.1.1. ) * * * .1.3.6.1.2.1.15.3.1.1.10.20.30.4 = IpAddress: 192.168.10.10 * ... * * would yield an array: * * [10.20.30.4] => "192.168.10.10" * .... * * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown * @param string $oid The OID to walk * @return array The resultant values */ public function walkIPv4( $oid ) { if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null ) return $rtn; $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); if( $this->_lastResult === false ) throw new Exception( 'Cound not perform walk for OID ' . $oid ); $result = array(); foreach( $this->_lastResult as $_oid => $value ) { $oids = explode( '.', $_oid ); $len = count( $oids ); $result[ $oids[ $len - 4 ] . '.' . $oids[ $len - 3 ] . '.' . $oids[ $len - 2 ] . '.' . $oids[ $len - 1 ] ] = $this->parseSnmpValue( $value ); } return $this->getCache()->save( $oid, $result ); } /** * Parse the result of an SNMP query into a PHP type * * For example, [STRING: "blah"] is parsed to a PHP string containing: blah * * @param string $v The value to parse * @return mixed The parsed value * @throws Exception */ public function parseSnmpValue( $v ) { // first, rule out an empty string if( $v == '""' || $v == '' ) return ""; $type = substr( $v, 0, strpos( $v, ':' ) ); $value = trim( substr( $v, strpos( $v, ':' ) + 1 ) ); switch( $type ) { case 'STRING': if($value == '"-"') return ""; if( substr( $value, 0, 1 ) == '"' ) $rtn = (string)trim( substr( substr( $value, 1 ), 0, -1 ) ); else $rtn = (string)$value; break; case 'INTEGER': //case : INTEGER : someText(intValue) // INTEGER : -3.15 Unidad if( strpos( $value, '(' ) !== false and substr($value, 0,1) != '-'){ $rtn = (float)substr( substr( $value, strpos( $value, '(' ) + 1 ), 0); }else{ $rtn = (float)$value; } if($rtn == (int)$rtn) $rtn = (int) $rtn; break; case 'Counter32': case 'Counter64': $rtn = (int)$value; break; case 'Gauge32': case 'Gauge64': $rtn = (int)$value; break; case 'Hex-STRING': $rtn = (string)implode( '', explode( ' ', $value ) ); break; case 'IpAddress': $rtn = (string)$value; break; case 'Timeticks': $rtn = (int)substr( $value, 1, strrpos( $value, ')' ) - 1 ); break; default: throw new Exception( "ERR: Unhandled SNMP return type: $type\n" ); } return $rtn; } /** * Utility function to convert TruthValue SNMP responses to true / false * * @param integer $value The TruthValue ( 1 => true, 2 => false) to convert * @return boolean */ public static function ppTruthValue( $value ) { if( is_array( $value ) ) foreach( $value as $k => $v ) $value[$k] = self::$SNMP_TRUTHVALUES[ $v ]; else $value = self::$SNMP_TRUTHVALUES[ $value ]; return $value; } /** * Utility function to translate one value(s) to another via an associated array * * I.e. all elements '$value' will be replaced with $translator( $value ) where * $translator is an associated array. * * Huh? Just read the code below! * * @param mixed $values A scalar or array or values to translate * @param array $translator An associated array to use to translate the values * @return mixed The translated scalar or array */ public static function translate( $values, $translator ) { if( !is_array( $values ) ) { if( isset( $translator[ $values ] ) ) return $translator[ $values ]; else return "*** UNKNOWN ***"; } foreach( $values as $k => $v ) { if( isset( $translator[ $v ] ) ) $values[$k] = $translator[ $v ]; else $values[$k] = "*** UNKNOWN ***"; } return $values; } /** * Sets the output format for SNMP queries. * * Should be one of the class OID_OUTPUT_* constants * * @param int $f The fomat to use * @return FiberlinkBundle\SNMP\SNMP An instance of $this (for fluent interfaces) */ public function setOidOutputFormat( $f ) { snmp_set_oid_output_format( $f ); return $this; } /** * Sets the target host for SNMP queries. * * @param string $h The target host for SNMP queries. * @return FiberlinkBundle\SNMP\SNMP An instance of $this (for fluent interfaces) */ public function setHost( $h ) { $this->_host = $h; // clear the temporary result cache and last result $this->_lastResult = null; unset( $this->_resultCache ); $this->_resultCache = array(); return $this; } /** * Returns the target host as currently configured for SNMP queries * * @return string The target host as currently configured for SNMP queries */ public function getHost() { return $this->_host; } /** * Sets the community string to use for SNMP queries. * * @param string $c The community to use for SNMP queries. * @return FiberlinkBundle\SNMP\SNMP An instance of $this (for fluent interfaces) */ public function setCommunity( $c ) { $this->_community = $c; return $this; } /** * Returns the community string currently in use. * * @return string The community string currently in use. */ public function getCommunity() { return $this->_community; } /** * Sets the timeout to use for SNMP queries (microseconds). * * @param int $t The timeout to use for SNMP queries (microseconds). * @return FiberlinkBundle\SNMP\SNMP An instance of $this (for fluent interfaces) */ public function setTimeout( $t ) { $this->_timeout = $t; return $this; } /** * Returns the SNMP query timeout (microseconds). * * @return int The the SNMP query timeout (microseconds) */ public function getTimeout() { return $this->_timeout; } /** * Sets the SNMP query retry count. * * @param int $r The SNMP query retry count * @return FiberlinkBundle\SNMP\SNMP An instance of $this (for fluent interfaces) */ public function setRetry( $r ) { $this->_retry = $r; return $this; } /** * Returns the SNMP query retry count * * @return string The SNMP query retry count */ public function getRetry() { return $this->_retry; } /** * Returns the unaltered original last SNMP result * * @return mixed The unaltered original last SNMP result */ public function getLastResult() { return $this->_lastResult; } /** * Returns the internal result cache * * @return array The internal result cache */ public function getResultCache() { return $this->_resultCache; } /** * Disable lookups of the local cache * * @return SNMP An instance of this for fluent interfaces */ public function disableCache() { $this->_disableCache = true; return $this; } /** * Enable lookups of the local cache * * @return SNMP An instance of this for fluent interfaces */ public function enableCache() { $this->_disableCache = false; return $this; } /** * Query whether we are using the cache or not * * @return boolean True of the local lookup cache is enabled. Otherwise false. */ public function cache() { return !$this->_disableCache; } /** * Set the cache to use * * @param \OSS_SNMP\Cache $c The cache to use * @return FiberlinkBundle\SNMP\SNMP For fluent interfaces */ public function setCache( $c ) { $this->_cache = $c; return $this; } /** * Get the cache in use (or create a Cache\Basic instance * * We kind of mandate the use of a cache as the code is written with a cache in mind. * You are free to disable it via disableCache() but your machines may be hammered! * * We would suggest disableCache() / enableCache() used in pairs only when really needed. * * @return \OSS_SNMP\Cache The cache object */ public function getCache() { if( $this->_cache === null ) $this->_cache = new \OSS_SNMP\Cache\Basic(); return $this->_cache; } /** * Magic method for generic function calls * * @param string $method * @param array $args * @throws Exception */ public function __call( $method, $args ) { if( substr( $method, 0, 3 ) == 'use' ) return $this->useExtension( substr( $method, 3 ), $args ); throw new Exception( "ERR: Unknown method requested in magic __call(): $method\n" ); } /** * This is the MIB Extension magic * * Calling $this->useXXX_YYY_ZZZ()->fn() will instantiate * an extension MIB class is the given name and this $this SNMP * instance and then call fn(). * * See the examples for more information. * * @param string $mib The extension class to use * @param array $args * @return FiberlinkBundle\MIBS */ public function useExtension( $mib, $args ) { $mib = 'FiberlinkBundle\\SNMP\\MIBS\\' . str_replace( '_', '\\', $mib ); $m = new $mib(); $m->setSNMP( $this ); return $m; } /** * Retorna la Ășltima parte del oid, iniciando desde $position * * I.e. the following query with sample results: * * lastOidWalk( '1.3.6.1.4.1.13464.1.11.3.1.1.2', 14 ) * * tener en cuenta que retorna con . por delante y realiza explode por . * * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.1 2 * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.2 2 * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.3 2 * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.4 2 * * Posiciones: * . 1 . 3 . 6 . 1 . 4 . 1 . 13464 . 1 . 11 . 3 . 1 . 1 . 2 . 0 . 4 2 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 value * * Would yield an array: * * [0.1] => 2 * [0.2] => 2 * [0.3] => 2 * [0.4] => 2 * * * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown * @param string $oid The OID to walk * @param int $position The position of the OID to use as the key * @return array The resultant values */ public function lastOidWalk( $oid, $position) { if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null ) return $rtn; $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); if( $this->_lastResult === false ) throw new Exception( 'Cound not perform walk for OID ' . $oid ); $result = array(); foreach( $this->_lastResult as $_oid => $value ) { $oids = explode( '.', $_oid ); $_oids = array_slice($oids, $position); $oid = implode(".", $_oids); $result[ $oid ] = $this->parseSnmpValue( $value ); } return $this->getCache()->save( $oid, $result ); } /** * Proxy to the snmprealwalk command * * @param string $oid The OID to walk * @return array The results of the walk */ public function realWalkV1( $oid ) { return $this->_lastResult = @snmprealwalk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); } public function lastOidWalkV1( $oid, $position ) { if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null ) return $rtn; $this->_lastResult = @snmprealwalk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() ); if( $this->_lastResult === false ) throw new Exception( 'Cound not perform walk for OID ' . $oid ); $result = array(); foreach( $this->_lastResult as $_oid => $value ) { $oids = explode( '.', $_oid ); $_oids = array_slice($oids, $position); $oid = implode(".", $_oids); $result[ $oid ] = $this->parseSnmpValue( $value ); } return $this->getCache()->save( $oid, $result ); } }