SNMP.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. <?php
  2. namespace FiberhomeBundle\SNMP;
  3. use \Exception;
  4. use \Cache;
  5. class SNMP
  6. {
  7. /**
  8. * The SNMP community to use when polling SNMP services. Defaults to 'public' by the constructor.
  9. *
  10. * @var string The SNMP community to use when polling SNMP services. Defaults to 'public' by the constructor.
  11. */
  12. protected $_community;
  13. /**
  14. * The SNMP host to query. Defaults to '127.0.0.1'
  15. * @var string The SNMP host to query. Defaults to '127.0.0.1' by the constructor.
  16. */
  17. protected $_host;
  18. /**
  19. * The SNMP query timeout value (microseconds). Default: 1000000
  20. * @var int The SNMP query timeout value (microseconds). Default: 1000000
  21. */
  22. protected $_timeout = 100000000;
  23. /**
  24. * The SNMP query retry count. Default: 5
  25. * @var int The SNMP query retry count. Default: 5
  26. */
  27. protected $_retry = 5;
  28. /**
  29. * A variable to hold the last unaltered result of an SNMP query
  30. * @var mixed The last unaltered result of an SNMP query
  31. */
  32. protected $_lastResult = null;
  33. /**
  34. * The cache object to use as the cache
  35. * @var \Cache The cache object to use
  36. */
  37. protected $_cache = null;
  38. /**
  39. * Set to true to disable local cache lookup and force SNMP queries
  40. *
  41. * Results are still stored. If you need to force a SNMP query, you can:
  42. *
  43. * $snmp = new OSS_SNMP( ... )'
  44. * ...
  45. * $snmp->disableCache();
  46. * $snmp->get( ... );
  47. * $snmp->enableCache();
  48. */
  49. protected $_disableCache = false;
  50. /**
  51. * SNMP output constants to mirror those of PHP
  52. * @var SNMP output constants to mirror those of PHP
  53. */
  54. const OID_OUTPUT_FULL = SNMP_OID_OUTPUT_FULL;
  55. /**
  56. * SNMP output constants to mirror those of PHP
  57. * @var SNMP output constants to mirror those of PHP
  58. */
  59. const OID_OUTPUT_NUMERIC = SNMP_OID_OUTPUT_NUMERIC;
  60. /**
  61. * Definition of an SNMP return type 'TruthValue'
  62. * @var Definition of an SNMP return type 'TruthValue'
  63. */
  64. const SNMP_TRUTHVALUE_TRUE = 1;
  65. /**
  66. * Definition of an SNMP return type 'TruthValue'
  67. * @var Definition of an SNMP return type 'TruthValue'
  68. */
  69. const SNMP_TRUTHVALUE_FALSE = 2;
  70. /**
  71. * PHP equivalents of SNMP return type TruthValue
  72. * @var array PHP equivalents of SNMP return type TruthValue
  73. */
  74. public static $SNMP_TRUTHVALUES = array(
  75. self::SNMP_TRUTHVALUE_TRUE => true,
  76. self::SNMP_TRUTHVALUE_FALSE => false
  77. );
  78. /**
  79. * The constructor.
  80. *
  81. * @param string $host The target host for SNMP queries.
  82. * @param string $community The community to use for SNMP queries.
  83. * @return FiberhomeBundle\SNMP\SNMP An instance of $this (for fluent interfaces)
  84. */
  85. public function __construct( $host = '127.0.0.1', $community = 'public' )
  86. {
  87. return $this->setHost( $host )
  88. ->setCommunity( $community )
  89. ->setOidOutputFormat( self::OID_OUTPUT_NUMERIC );
  90. }
  91. /**
  92. * Proxy to the snmp2_real_walk command
  93. *
  94. * @param string $oid The OID to walk
  95. * @return array The results of the walk
  96. */
  97. public function realWalk( $oid )
  98. {
  99. return $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  100. }
  101. /**
  102. * Get a single SNMP value
  103. *
  104. * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown
  105. * @param string $oid The OID to get
  106. * @return mixed The resultant value
  107. */
  108. public function get( $oid )
  109. {
  110. if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null )
  111. return $rtn;
  112. $this->_lastResult = @snmp2_get( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  113. if( $this->_lastResult === false )
  114. throw new Exception( 'Cound not perform walk for OID ' . $oid );
  115. return $this->getCache()->save( $oid, $this->parseSnmpValue( $this->_lastResult ) );
  116. }
  117. /**
  118. * Get indexed SNMP values (first degree)
  119. *
  120. * Walks the SNMP tree returning an array of key => value pairs.
  121. *
  122. * This is a first degree walk and it will throw an exception if there is more that one degree of values.
  123. *
  124. * I.e. the following query with sample results:
  125. *
  126. * walk1d( '.1.0.8802.1.1.2.1.3.7.1.4' )
  127. *
  128. * .1.0.8802.1.1.2.1.3.7.1.4.1 = STRING: "GigabitEthernet1/0/1"
  129. * .1.0.8802.1.1.2.1.3.7.1.4.2 = STRING: "GigabitEthernet1/0/2"
  130. * .1.0.8802.1.1.2.1.3.7.1.4.3 = STRING: "GigabitEthernet1/0/3"
  131. * .....
  132. *
  133. * would yield an array:
  134. *
  135. * 1 => GigabitEthernet1/0/1
  136. * 2 => GigabitEthernet1/0/2
  137. * 3 => GigabitEthernet1/0/3
  138. *
  139. * @param string $oid The OID to walk
  140. * @return array The resultant values
  141. * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown
  142. */
  143. public function walk1d( $oid )
  144. {
  145. if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null )
  146. return $rtn;
  147. $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  148. if( $this->_lastResult === false )
  149. throw new Exception( 'Cound not perform walk for OID ' . $oid );
  150. $result = array();
  151. $oidPrefix = null;
  152. foreach( $this->_lastResult as $_oid => $value )
  153. {
  154. if( $oidPrefix !== null && $oidPrefix != substr( $_oid, 0, strrpos( $_oid, '.' ) ) )
  155. throw new Exception( 'Requested OID tree is not a first degree indexed SNMP value' );
  156. else
  157. $oidPrefix = substr( $_oid, 0, strrpos( $_oid, '.' ) );
  158. $result[ substr( $_oid, strrpos( $_oid, '.' ) + 1 ) ] = $this->parseSnmpValue( $value );
  159. }
  160. return $this->getCache()->save( $oid, $result );
  161. }
  162. /**
  163. * Get indexed SNMP values where the array key is the given position of the OID
  164. *
  165. * I.e. the following query with sample results:
  166. *
  167. * subOidWalk( '.1.3.6.1.4.1.9.9.23.1.2.1.1.9', 15 )
  168. *
  169. *
  170. * .1.3.6.1.4.1.9.9.23.1.2.1.1.9.10101.5 = Hex-STRING: 00 00 00 01
  171. * .1.3.6.1.4.1.9.9.23.1.2.1.1.9.10105.2 = Hex-STRING: 00 00 00 01
  172. * .1.3.6.1.4.1.9.9.23.1.2.1.1.9.10108.4 = Hex-STRING: 00 00 00 01
  173. *
  174. * would yield an array:
  175. *
  176. * 10101 => Hex-STRING: 00 00 00 01
  177. * 10105 => Hex-STRING: 00 00 00 01
  178. * 10108 => Hex-STRING: 00 00 00 01
  179. *
  180. * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown
  181. * @param string $oid The OID to walk
  182. * @param int $position The position of the OID to use as the key
  183. * @return array The resultant values
  184. */
  185. public function subOidWalk( $oid, $position )
  186. {
  187. if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null )
  188. return $rtn;
  189. $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  190. if( $this->_lastResult === false )
  191. throw new Exception( 'Cound not perform walk for OID ' . $oid );
  192. $result = array();
  193. foreach( $this->_lastResult as $_oid => $value )
  194. {
  195. $oids = explode( '.', $_oid );
  196. $result[ $oids[ $position] ] = $this->parseSnmpValue( $value );
  197. }
  198. return $this->getCache()->save( $oid, $result );
  199. }
  200. /**
  201. * Get indexed SNMP values where they are indexed by IPv4 addresses
  202. *
  203. * I.e. the following query with sample results:
  204. *
  205. * subOidWalk( '.1.3.6.1.2.1.15.3.1.1. )
  206. *
  207. *
  208. * .1.3.6.1.2.1.15.3.1.1.10.20.30.4 = IpAddress: 192.168.10.10
  209. * ...
  210. *
  211. * would yield an array:
  212. *
  213. * [10.20.30.4] => "192.168.10.10"
  214. * ....
  215. *
  216. * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown
  217. * @param string $oid The OID to walk
  218. * @return array The resultant values
  219. */
  220. public function walkIPv4( $oid )
  221. {
  222. if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null )
  223. return $rtn;
  224. $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  225. if( $this->_lastResult === false )
  226. throw new Exception( 'Cound not perform walk for OID ' . $oid );
  227. $result = array();
  228. foreach( $this->_lastResult as $_oid => $value )
  229. {
  230. $oids = explode( '.', $_oid );
  231. $len = count( $oids );
  232. $result[ $oids[ $len - 4 ] . '.' . $oids[ $len - 3 ] . '.' . $oids[ $len - 2 ] . '.' . $oids[ $len - 1 ] ] = $this->parseSnmpValue( $value );
  233. }
  234. return $this->getCache()->save( $oid, $result );
  235. }
  236. /**
  237. * Parse the result of an SNMP query into a PHP type
  238. *
  239. * For example, [STRING: "blah"] is parsed to a PHP string containing: blah
  240. *
  241. * @param string $v The value to parse
  242. * @return mixed The parsed value
  243. * @throws Exception
  244. */
  245. public function parseSnmpValue( $v )
  246. {
  247. // first, rule out an empty string
  248. if( $v == '""' || $v == '' )
  249. return "";
  250. $type = substr( $v, 0, strpos( $v, ':' ) );
  251. $value = trim( substr( $v, strpos( $v, ':' ) + 1 ) );
  252. switch( $type )
  253. {
  254. case 'STRING':
  255. if($value == '"-"') return "";
  256. if( substr( $value, 0, 1 ) == '"' )
  257. $rtn = (string)trim( substr( substr( $value, 1 ), 0, -1 ) );
  258. else
  259. $rtn = (string)$value;
  260. break;
  261. case 'INTEGER': //case : INTEGER : someText(intValue) // INTEGER : -3.15 Unidad
  262. if( strpos( $value, '(' ) !== false and substr($value, 0,1) != '-'){
  263. $rtn = (float)substr( substr( $value, strpos( $value, '(' ) + 1 ), 0);
  264. }else{
  265. $rtn = (float)$value;
  266. }
  267. if($rtn == (int)$rtn) $rtn = (int) $rtn;
  268. break;
  269. case 'Counter32':
  270. case 'Counter64':
  271. $rtn = (int)$value;
  272. break;
  273. case 'Gauge32':
  274. case 'Gauge64':
  275. $rtn = (int)$value;
  276. break;
  277. case 'Hex-STRING':
  278. $rtn = (string)implode( '', explode( ' ', $value ) );
  279. break;
  280. case 'IpAddress':
  281. $rtn = (string)$value;
  282. break;
  283. case 'Timeticks':
  284. $rtn = (int)substr( $value, 1, strrpos( $value, ')' ) - 1 );
  285. break;
  286. default:
  287. throw new Exception( "ERR: Unhandled SNMP return type: $type\n" );
  288. }
  289. return $rtn;
  290. }
  291. /**
  292. * Utility function to convert TruthValue SNMP responses to true / false
  293. *
  294. * @param integer $value The TruthValue ( 1 => true, 2 => false) to convert
  295. * @return boolean
  296. */
  297. public static function ppTruthValue( $value )
  298. {
  299. if( is_array( $value ) )
  300. foreach( $value as $k => $v )
  301. $value[$k] = self::$SNMP_TRUTHVALUES[ $v ];
  302. else
  303. $value = self::$SNMP_TRUTHVALUES[ $value ];
  304. return $value;
  305. }
  306. /**
  307. * Utility function to translate one value(s) to another via an associated array
  308. *
  309. * I.e. all elements '$value' will be replaced with $translator( $value ) where
  310. * $translator is an associated array.
  311. *
  312. * Huh? Just read the code below!
  313. *
  314. * @param mixed $values A scalar or array or values to translate
  315. * @param array $translator An associated array to use to translate the values
  316. * @return mixed The translated scalar or array
  317. */
  318. public static function translate( $values, $translator )
  319. {
  320. if( !is_array( $values ) )
  321. {
  322. if( isset( $translator[ $values ] ) )
  323. return $translator[ $values ];
  324. else
  325. return "*** UNKNOWN ***";
  326. }
  327. foreach( $values as $k => $v )
  328. {
  329. if( isset( $translator[ $v ] ) )
  330. $values[$k] = $translator[ $v ];
  331. else
  332. $values[$k] = "*** UNKNOWN ***";
  333. }
  334. return $values;
  335. }
  336. /**
  337. * Sets the output format for SNMP queries.
  338. *
  339. * Should be one of the class OID_OUTPUT_* constants
  340. *
  341. * @param int $f The fomat to use
  342. * @return FiberhomeBundle\SNMP\SNMP An instance of $this (for fluent interfaces)
  343. */
  344. public function setOidOutputFormat( $f )
  345. {
  346. snmp_set_oid_output_format( $f );
  347. return $this;
  348. }
  349. /**
  350. * Sets the target host for SNMP queries.
  351. *
  352. * @param string $h The target host for SNMP queries.
  353. * @return FiberhomeBundle\SNMP\SNMP An instance of $this (for fluent interfaces)
  354. */
  355. public function setHost( $h )
  356. {
  357. $this->_host = $h;
  358. // clear the temporary result cache and last result
  359. $this->_lastResult = null;
  360. unset( $this->_resultCache );
  361. $this->_resultCache = array();
  362. return $this;
  363. }
  364. /**
  365. * Returns the target host as currently configured for SNMP queries
  366. *
  367. * @return string The target host as currently configured for SNMP queries
  368. */
  369. public function getHost()
  370. {
  371. return $this->_host;
  372. }
  373. /**
  374. * Sets the community string to use for SNMP queries.
  375. *
  376. * @param string $c The community to use for SNMP queries.
  377. * @return FiberhomeBundle\SNMP\SNMP An instance of $this (for fluent interfaces)
  378. */
  379. public function setCommunity( $c )
  380. {
  381. $this->_community = $c;
  382. return $this;
  383. }
  384. /**
  385. * Returns the community string currently in use.
  386. *
  387. * @return string The community string currently in use.
  388. */
  389. public function getCommunity()
  390. {
  391. return $this->_community;
  392. }
  393. /**
  394. * Sets the timeout to use for SNMP queries (microseconds).
  395. *
  396. * @param int $t The timeout to use for SNMP queries (microseconds).
  397. * @return FiberhomeBundle\SNMP\SNMP An instance of $this (for fluent interfaces)
  398. */
  399. public function setTimeout( $t )
  400. {
  401. $this->_timeout = $t;
  402. return $this;
  403. }
  404. /**
  405. * Returns the SNMP query timeout (microseconds).
  406. *
  407. * @return int The the SNMP query timeout (microseconds)
  408. */
  409. public function getTimeout()
  410. {
  411. return $this->_timeout;
  412. }
  413. /**
  414. * Sets the SNMP query retry count.
  415. *
  416. * @param int $r The SNMP query retry count
  417. * @return FiberhomeBundle\SNMP\SNMP An instance of $this (for fluent interfaces)
  418. */
  419. public function setRetry( $r )
  420. {
  421. $this->_retry = $r;
  422. return $this;
  423. }
  424. /**
  425. * Returns the SNMP query retry count
  426. *
  427. * @return string The SNMP query retry count
  428. */
  429. public function getRetry()
  430. {
  431. return $this->_retry;
  432. }
  433. /**
  434. * Returns the unaltered original last SNMP result
  435. *
  436. * @return mixed The unaltered original last SNMP result
  437. */
  438. public function getLastResult()
  439. {
  440. return $this->_lastResult;
  441. }
  442. /**
  443. * Returns the internal result cache
  444. *
  445. * @return array The internal result cache
  446. */
  447. public function getResultCache()
  448. {
  449. return $this->_resultCache;
  450. }
  451. /**
  452. * Disable lookups of the local cache
  453. *
  454. * @return SNMP An instance of this for fluent interfaces
  455. */
  456. public function disableCache()
  457. {
  458. $this->_disableCache = true;
  459. return $this;
  460. }
  461. /**
  462. * Enable lookups of the local cache
  463. *
  464. * @return SNMP An instance of this for fluent interfaces
  465. */
  466. public function enableCache()
  467. {
  468. $this->_disableCache = false;
  469. return $this;
  470. }
  471. /**
  472. * Query whether we are using the cache or not
  473. *
  474. * @return boolean True of the local lookup cache is enabled. Otherwise false.
  475. */
  476. public function cache()
  477. {
  478. return !$this->_disableCache;
  479. }
  480. /**
  481. * Set the cache to use
  482. *
  483. * @param \OSS_SNMP\Cache $c The cache to use
  484. * @return FiberhomeBundle\SNMP\SNMP For fluent interfaces
  485. */
  486. public function setCache( $c )
  487. {
  488. $this->_cache = $c;
  489. return $this;
  490. }
  491. /**
  492. * Get the cache in use (or create a Cache\Basic instance
  493. *
  494. * We kind of mandate the use of a cache as the code is written with a cache in mind.
  495. * You are free to disable it via disableCache() but your machines may be hammered!
  496. *
  497. * We would suggest disableCache() / enableCache() used in pairs only when really needed.
  498. *
  499. * @return \OSS_SNMP\Cache The cache object
  500. */
  501. public function getCache()
  502. {
  503. if( $this->_cache === null )
  504. $this->_cache = new \OSS_SNMP\Cache\Basic();
  505. return $this->_cache;
  506. }
  507. /**
  508. * Magic method for generic function calls
  509. *
  510. * @param string $method
  511. * @param array $args
  512. * @throws Exception
  513. */
  514. public function __call( $method, $args )
  515. {
  516. if( substr( $method, 0, 3 ) == 'use' )
  517. return $this->useExtension( substr( $method, 3 ), $args );
  518. throw new Exception( "ERR: Unknown method requested in magic __call(): $method\n" );
  519. }
  520. /**
  521. * This is the MIB Extension magic
  522. *
  523. * Calling $this->useXXX_YYY_ZZZ()->fn() will instantiate
  524. * an extension MIB class is the given name and this $this SNMP
  525. * instance and then call fn().
  526. *
  527. * See the examples for more information.
  528. *
  529. * @param string $mib The extension class to use
  530. * @param array $args
  531. * @return FiberhomeBundle\MIBS
  532. */
  533. public function useExtension( $mib, $args )
  534. {
  535. $mib = 'FiberhomeBundle\\SNMP\\MIBS\\' . str_replace( '_', '\\', $mib );
  536. $m = new $mib();
  537. $m->setSNMP( $this );
  538. return $m;
  539. }
  540. /**
  541. * Retorna la última parte del oid, iniciando desde $position
  542. *
  543. * I.e. the following query with sample results:
  544. *
  545. * lastOidWalk( '1.3.6.1.4.1.13464.1.11.3.1.1.2', 14 )
  546. *
  547. * tener en cuenta que retorna con . por delante y realiza explode por .
  548. *
  549. * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.1 2
  550. * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.2 2
  551. * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.3 2
  552. * .1.3.6.1.4.1.13464.1.11.3.1.1.2.0.4 2
  553. *
  554. * Posiciones:
  555. * . 1 . 3 . 6 . 1 . 4 . 1 . 13464 . 1 . 11 . 3 . 1 . 1 . 2 . 0 . 4 2
  556. * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 value
  557. *
  558. * Would yield an array:
  559. *
  560. * [0.1] => 2
  561. * [0.2] => 2
  562. * [0.3] => 2
  563. * [0.4] => 2
  564. *
  565. *
  566. * @throws \Exception On *any* SNMP error, warnings are supressed and a generic exception is thrown
  567. * @param string $oid The OID to walk
  568. * @param int $position The position of the OID to use as the key
  569. * @return array The resultant values
  570. */
  571. public function lastOidWalk( $oid, $position)
  572. {
  573. if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null )
  574. return $rtn;
  575. $this->_lastResult = @snmp2_real_walk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  576. if( $this->_lastResult === false )
  577. throw new Exception( 'Cound not perform walk for OID ' . $oid );
  578. $result = array();
  579. foreach( $this->_lastResult as $_oid => $value )
  580. {
  581. $oids = explode( '.', $_oid );
  582. $_oids = array_slice($oids, $position);
  583. $oid = implode(".", $_oids);
  584. $result[ $oid ] = $this->parseSnmpValue( $value );
  585. }
  586. return $this->getCache()->save( $oid, $result );
  587. }
  588. /**
  589. * Proxy to the snmprealwalk command
  590. *
  591. * @param string $oid The OID to walk
  592. * @return array The results of the walk
  593. */
  594. public function realWalkV1( $oid )
  595. {
  596. return $this->_lastResult = @snmprealwalk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  597. }
  598. public function lastOidWalkV1( $oid, $position )
  599. {
  600. if( $this->cache() && ( $rtn = $this->getCache()->load( $oid ) ) !== null )
  601. return $rtn;
  602. $this->_lastResult = @snmprealwalk( $this->getHost(), $this->getCommunity(), $oid, $this->getTimeout(), $this->getRetry() );
  603. if( $this->_lastResult === false )
  604. throw new Exception( 'Cound not perform walk for OID ' . $oid );
  605. $result = array();
  606. foreach( $this->_lastResult as $_oid => $value )
  607. {
  608. $oids = explode( '.', $_oid );
  609. $_oids = array_slice($oids, $position);
  610. $oid = implode(".", $_oids);
  611. $result[ $oid ] = $this->parseSnmpValue( $value );
  612. }
  613. return $this->getCache()->save( $oid, $result );
  614. }
  615. }