api.snmphelper.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. <?php
  2. /**
  3. * Ubilling SNMP abstraction class
  4. */
  5. class SNMPHelper {
  6. /**
  7. * System-wide alter.ini config as array
  8. * @var array
  9. */
  10. protected $altCfg = array();
  11. /**
  12. * Pre-configured SNMP work mode - system/native/class
  13. * @var string
  14. */
  15. protected $mode = '';
  16. /**
  17. * System snmpwalk background multi-threaded mode
  18. * @var bool
  19. */
  20. protected $background = false;
  21. /**
  22. * SNMP raw data caching timeout in minutes
  23. * @var int
  24. */
  25. protected $cacheTime = 60;
  26. /**
  27. * System snmpwalk binary path with -On and version params
  28. * @var string
  29. */
  30. protected $pathWalk = '';
  31. /**
  32. * System snmpset binary path with -On and version params
  33. * @var string
  34. */
  35. protected $pathSet = '';
  36. /**
  37. * Native PHP snmp functions retries
  38. * @var int
  39. */
  40. protected $retriesNative = 1;
  41. /**
  42. * Debugging mode flag
  43. *
  44. * @var bool
  45. */
  46. protected $debug = false;
  47. /**
  48. * Native PHP snmp functions timeout
  49. * @var int
  50. */
  51. protected $timeoutNative = 1000000;
  52. /**
  53. * some predefined constants, paths, exceptiongs etc
  54. */
  55. const CACHE_PATH = 'exports/'; //raw SNMP data cache path
  56. const EX_NOT_IMPL = 'NOT_IMPLEMENTED_MODE'; //not yet implemented SNMP mode exception
  57. const EX_WRONG_DATA = 'WRONG_DATA_FORMAT_RECEIVED';
  58. const OPTION_DEBUG = 'SNMP_DEBUG_MODE';
  59. const LOG_OIDS = 'exports/snmpdebug_oids.log';
  60. const LOG_COMMANDS = 'exports/snmpdebug_commands.log';
  61. /**
  62. * Creates new SNMPHelper instance
  63. *
  64. * @param bool $debugMode
  65. */
  66. public function __construct($debugMode = false) {
  67. $this->loadAlter();
  68. $this->setOptions();
  69. //overrides system debug option state if declared obviously in constructor
  70. $this->setDebug($debugMode);
  71. }
  72. /**
  73. * Loads system alter config at startup
  74. *
  75. * @global object $ubillingConfig
  76. *
  77. * @return void
  78. */
  79. protected function loadAlter() {
  80. global $ubillingConfig;
  81. $this->altCfg = $ubillingConfig->getAlter();
  82. }
  83. /**
  84. * Sets all needed options to protected props
  85. *
  86. * @return void
  87. */
  88. protected function setOptions() {
  89. if (!empty($this->altCfg)) {
  90. $this->mode = $this->altCfg['SNMP_MODE'];
  91. $this->background = ($this->altCfg['SNMPWALK_BACKGROUND']) ? true : false;
  92. $this->cacheTime = ($this->altCfg['SNMPCACHE_TIME'] * 60); //in minutes
  93. $this->pathWalk = $this->altCfg['SNMPWALK_PATH'];
  94. $this->pathSet = $this->altCfg['SNMPSET_PATH'];
  95. if (isset($this->altCfg[self::OPTION_DEBUG])) {
  96. if ($this->altCfg[self::OPTION_DEBUG]) {
  97. $this->setDebug(true);
  98. }
  99. }
  100. }
  101. }
  102. /**
  103. * Sets instance debug mode state
  104. *
  105. * @param bool $state
  106. *
  107. * @return void
  108. */
  109. protected function setDebug($state) {
  110. if ($state) {
  111. $this->debug = $state;
  112. }
  113. }
  114. /**
  115. * Public background mode setter
  116. *
  117. * @param bool $value
  118. *
  119. * @return void
  120. */
  121. public function setBackground($value) {
  122. $this->background = ($value) ? true : false;
  123. }
  124. /**
  125. * Public getter of background mode
  126. *
  127. * @return bool
  128. */
  129. public function getBackground() {
  130. return ($this->background);
  131. }
  132. /**
  133. * Set SNMP run mode (system/native/class)
  134. *
  135. * @param string $value
  136. *
  137. * @return void
  138. */
  139. public function setMode($value) {
  140. $this->mode = $value;
  141. }
  142. /**
  143. * Public getter of SNMP run mode
  144. *
  145. * @return bool
  146. */
  147. public function getMode() {
  148. return ($this->mode);
  149. }
  150. /**
  151. * Executes system SNMP walk interface
  152. *
  153. * @param string $ip
  154. * @param string $community
  155. * @param string $oid
  156. * @param bool $cache
  157. * @param bool $nowait
  158. * @return string
  159. */
  160. protected function snmpWalkSystem($ip, $community, $oid, $cache = true) {
  161. $command = $this->pathWalk . ' -c ' . $community . ' -Cc ' . $ip . ' ' . $oid;
  162. $cachetime = time() - $this->cacheTime;
  163. $cachepath = self::CACHE_PATH;
  164. $cacheFile = $cachepath . $ip . '_' . $oid;
  165. $updateCache = true;
  166. $result = '';
  167. if ($this->background) {
  168. $command = $command . ' > ' . $cacheFile . '&';
  169. }
  170. //cache handling
  171. if (file_exists($cacheFile)) {
  172. //cache not expired
  173. if ((filemtime($cacheFile) > $cachetime) AND ( $cache == true)) {
  174. $updateCache = false;
  175. } else {
  176. //cache expired - refresh data
  177. $updateCache = true;
  178. }
  179. } else {
  180. //no cached file exists
  181. $updateCache = true;
  182. }
  183. //getting some results
  184. if ($updateCache) {
  185. //getting fresh data
  186. $result = shell_exec($command);
  187. if ($this->debug) {
  188. //writing some log
  189. $date = date("Y-m-d H:i:s");
  190. $commandLog = '# ' . $date . PHP_EOL;
  191. $commandLog .= $command . PHP_EOL;
  192. file_put_contents(self::LOG_COMMANDS, $commandLog, FILE_APPEND);
  193. }
  194. if (!$this->background) {
  195. @file_put_contents($cacheFile, $result);
  196. }
  197. } else {
  198. //getting data from cache
  199. $result = file_get_contents($cacheFile);
  200. }
  201. return ($result);
  202. }
  203. /**
  204. * Executes native SNMP walk interface
  205. *
  206. * @param string $ip
  207. * @param string $community
  208. * @param string $oid
  209. * @param bool $cache
  210. * @param bool $nowait
  211. * @return string
  212. */
  213. protected function snmpWalkNative($ip, $community, $oid, $cache = true) {
  214. $cachetime = time() - $this->cacheTime;
  215. $cachepath = self::CACHE_PATH;
  216. $cacheFile = $cachepath . $ip . '_' . $oid;
  217. $result = '';
  218. //cache handling
  219. if (file_exists($cacheFile)) {
  220. //cache not expired
  221. if ((filemtime($cacheFile) > $cachetime) AND ( $cache == true)) {
  222. $result = file_get_contents($cacheFile);
  223. } else {
  224. //cache expired - refresh data
  225. snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC);
  226. @$raw = snmpwalkoid($ip, $community, $oid, $this->timeoutNative, $this->retriesNative);
  227. if (!empty($raw)) {
  228. foreach ($raw as $oid => $value) {
  229. $result .= $oid . ' = ' . $value . "\n";
  230. }
  231. } else {
  232. @$value = snmpget($ip, $community, $oid, $this->timeoutNative, $this->retriesNative);
  233. $result = $oid . ' = ' . $value;
  234. }
  235. file_put_contents($cacheFile, $result);
  236. }
  237. } else {
  238. //no cached file exists
  239. snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC);
  240. @$raw = snmprealwalk($ip, $community, $oid, $this->timeoutNative, $this->retriesNative);
  241. if (!empty($raw)) {
  242. foreach ($raw as $oid => $value) {
  243. $result .= $oid . ' = ' . $value . "\n";
  244. }
  245. } else {
  246. @$value = snmpget($ip, $community, $oid, $this->timeoutNative, $this->retriesNative);
  247. $result = $oid . ' = ' . $value;
  248. }
  249. file_put_contents($cacheFile, $result);
  250. }
  251. return ($result);
  252. }
  253. /**
  254. * Executes php 5.4 SNMP class walk interface
  255. *
  256. * @param string $ip
  257. * @param string $community
  258. * @param string $oid
  259. * @param bool $cache
  260. * @param bool $nowait
  261. * @return string
  262. */
  263. protected function snmpWalkClass($ip, $community, $oid, $cache = true) {
  264. $cachetime = time() - $this->cacheTime;
  265. $cachepath = self::CACHE_PATH;
  266. $cacheFile = $cachepath . $ip . '_' . $oid;
  267. $result = '';
  268. //cache handling
  269. if (file_exists($cacheFile)) {
  270. //cache not expired
  271. if ((filemtime($cacheFile) > $cachetime) AND ( $cache == true)) {
  272. $result = file_get_contents($cacheFile);
  273. } else {
  274. //cache expired - refresh data
  275. snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC);
  276. $session = new SNMP(SNMP::VERSION_1, $ip, $community, $this->timeoutNative, $this->retriesNative);
  277. $session->oid_increasing_check = false;
  278. $raw = $session->walk($oid);
  279. $session->close();
  280. if (!empty($raw)) {
  281. foreach ($raw as $oid => $value) {
  282. $result .= $oid . ' = ' . $value . "\n";
  283. }
  284. }
  285. file_put_contents($cacheFile, $result);
  286. }
  287. } else {
  288. //no cached file exists
  289. snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC);
  290. $session = new SNMP(SNMP::VERSION_1, $ip, $community, $this->timeoutNative, $this->retriesNative);
  291. $raw = $session->walk($oid);
  292. $session->close();
  293. if (!empty($raw)) {
  294. foreach ($raw as $oid => $value) {
  295. $result .= $oid . ' = ' . $value . "\n";
  296. }
  297. }
  298. file_put_contents($cacheFile, $result);
  299. }
  300. return ($result);
  301. }
  302. /**
  303. * Executes native SNMP set interface
  304. *
  305. * @param string $ip
  306. * @param string $community
  307. * @param array $data
  308. * @return string
  309. */
  310. protected function snmpSetSystem($ip, $community, $data) {
  311. $result = '';
  312. if (!empty($data)) {
  313. if (is_array($data)) {
  314. $command = $this->pathSet . ' -c ' . $community . ' ' . $ip . ' ';
  315. foreach ($data as $io => $each) {
  316. if (isset($each['oid']) AND ( isset($each['type']) AND ( isset($each['value'])))) {
  317. $command .= ' ' . $each['oid'] . ' ' . $each['type'] . ' ' . $each['value'];
  318. } else {
  319. throw new Exception(self::EX_WRONG_DATA);
  320. }
  321. }
  322. $result .= shell_exec($command);
  323. } else {
  324. throw new Exception(self::EX_WRONG_DATA);
  325. }
  326. }
  327. return ($result);
  328. }
  329. /**
  330. * Executes native SNMP set interface
  331. *
  332. * @param string $ip
  333. * @param string $community
  334. * @param array $data
  335. * @return string
  336. */
  337. protected function snmpSetNative($ip, $community, $data) {
  338. $result = '';
  339. if (!empty($data)) {
  340. if (is_array($data)) {
  341. foreach ($data as $io => $each) {
  342. if (isset($each['oid']) AND ( isset($each['type']) AND ( isset($each['value'])))) {
  343. @$pushResult = snmp2_set($ip, $community, $each['oid'], $each['type'], $each['value'], $this->timeoutNative, $this->retriesNative);
  344. if ($pushResult) {
  345. $result .= trim($this->snmpWalkNative($ip, $community, $each['oid'], false)) . "\n";
  346. }
  347. } else {
  348. throw new Exception(self::EX_WRONG_DATA);
  349. }
  350. }
  351. } else {
  352. throw new Exception(self::EX_WRONG_DATA);
  353. }
  354. }
  355. return ($result);
  356. }
  357. /**
  358. * Executes PHP 5.4 SNMP set interface
  359. *
  360. * @param string $ip
  361. * @param string $community
  362. * @param array $data
  363. * @return string
  364. */
  365. protected function snmpSetClass($ip, $community, $data) {
  366. $result = '';
  367. if (!empty($data)) {
  368. if (is_array($data)) {
  369. foreach ($data as $io => $each) {
  370. if (isset($each['oid']) AND ( isset($each['type']) AND ( isset($each['value'])))) {
  371. $session = new SNMP(SNMP::VERSION_2c, $ip, $community, $this->timeoutNative, $this->retriesNative);
  372. @$pushResult = $session->set($each['oid'], $each['type'], $each['value']);
  373. $session->close();
  374. if ($pushResult) {
  375. $result .= trim($this->snmpWalkClass($ip, $community, $each['oid'], false)) . "\n";
  376. }
  377. } else {
  378. throw new Exception(self::EX_WRONG_DATA);
  379. }
  380. }
  381. } else {
  382. throw new Exception(self::EX_WRONG_DATA);
  383. }
  384. }
  385. return ($result);
  386. }
  387. /**
  388. * Put some messages to logs if debug mode is enabled
  389. *
  390. * @param string $ip
  391. * @param string $community
  392. * @param string $oid
  393. * @param string $type
  394. *
  395. * @return void
  396. */
  397. protected function oidLog($ip, $community, $oid, $type = 'walk') {
  398. if ($this->debug) {
  399. $date = date("Y-m-d H:i:s");
  400. $oidLog = $date . ' snmp' . $type . ' host: ' . $ip . ' community: ' . $community . ' OID: ' . $oid . PHP_EOL;
  401. file_put_contents(self::LOG_OIDS, $oidLog, FILE_APPEND);
  402. }
  403. }
  404. /**
  405. * Public SNMP walk interface
  406. *
  407. * @param string $ip
  408. * @param string $community
  409. * @param string $oid
  410. * @param bool $cache
  411. * @param bool $nowait
  412. * @return string
  413. */
  414. public function walk($ip, $community, $oid, $cache = true) {
  415. switch ($this->mode) {
  416. case 'system':
  417. $result = $this->snmpWalkSystem($ip, $community, $oid, $cache);
  418. break;
  419. case 'native':
  420. $result = $this->snmpWalkNative($ip, $community, $oid, $cache);
  421. break;
  422. case 'class':
  423. $result = $this->snmpWalkClass($ip, $community, $oid, $cache);
  424. break;
  425. default :
  426. throw new Exception(self::EX_NOT_IMPL);
  427. }
  428. $this->oidLog($ip, $community, $oid);
  429. return ($result);
  430. }
  431. /**
  432. * Public SNMP set interface
  433. *
  434. * data format example:
  435. * $data[]=array(
  436. * 'oid' => '.1.3.6.1.2.1.1.6.0',
  437. * 'type' => 's',
  438. * 'value' => 'some location'
  439. * );
  440. *
  441. * @param string $ip
  442. * @param string $community
  443. * @param array $data
  444. * @return string
  445. */
  446. public function set($ip, $community, $data) {
  447. switch ($this->mode) {
  448. case 'system':
  449. $result = $this->snmpSetSystem($ip, $community, $data);
  450. break;
  451. case 'native':
  452. $result = $this->snmpSetNative($ip, $community, $data);
  453. break;
  454. case 'class':
  455. $result = $this->snmpSetClass($ip, $community, $data);
  456. break;
  457. default :
  458. throw new Exception(self::EX_NOT_IMPL);
  459. }
  460. $this->oidLog($ip, $community, print_r($data, true), 'set');
  461. return ($result);
  462. }
  463. }