api.junbgp.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <?php
  2. /**
  3. * This class is responsible for getting Juniper BGP peers stats using SNMP.
  4. */
  5. class JunBGP {
  6. /**
  7. * Contains system SNMP Helper instance
  8. *
  9. * @var object
  10. */
  11. protected $snmp = '';
  12. /**
  13. * Determines whether to use raw SNMP cache
  14. *
  15. * @var bool
  16. */
  17. protected $rawCache = false;
  18. /**
  19. * Mapping of BGP state codes to state names
  20. *
  21. * @var array
  22. */
  23. protected $statesNames = array(
  24. 1 => 'idle',
  25. 2 => 'connect',
  26. 3 => 'active',
  27. 4 => 'opensent',
  28. 5 => 'openconfirm',
  29. 6 => 'established'
  30. );
  31. /**
  32. * Mapping of BGP status codes to status names
  33. *
  34. * @var array
  35. */
  36. protected $statusNames = array(
  37. 1 => 'halted',
  38. 2 => 'running'
  39. );
  40. /**
  41. * IP address of the BGP peer
  42. *
  43. * @var string
  44. */
  45. protected $ip = '';
  46. /**
  47. * SNMP community string
  48. *
  49. * @var string
  50. */
  51. protected $community = '';
  52. /**
  53. * Some predefined stuff here
  54. */
  55. const OID_PEER_TABLE = '.1.3.6.1.4.1.2636.5.1.1.2';
  56. const OID_INDEX = '.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.14';
  57. const OID_REMOTEIP = '.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.11.0.1';
  58. const OID_AS = '.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.13';
  59. const OID_STATE = '.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.2';
  60. const OID_STATUS = '1.3.6.1.4.1.2636.5.1.1.2.1.1.1.3';
  61. const OID_TIMERS = '.1.3.6.1.4.1.2636.5.1.1.2.4.1.1.1';
  62. const OID_PREF_IN = '.1.3.6.1.4.1.2636.5.1.1.2.6.2.1.7';
  63. const OID_PREF_OUT = '.1.3.6.1.4.1.2636.5.1.1.2.6.2.1.10';
  64. /**
  65. * Quidquid latine dictum sit, altum sonatur
  66. *
  67. * @param string $ip IP address of the BGP peer
  68. * @param string $community SNMP community string
  69. */
  70. public function __construct($ip, $community) {
  71. $this->setIp($ip);
  72. $this->setCommunity($community);
  73. $this->initSNMP();
  74. }
  75. /**
  76. * Sets the IP address of the BGP peer
  77. *
  78. * @param string $ip IP address
  79. *
  80. * @return void
  81. */
  82. protected function setIp($ip) {
  83. $this->ip = $ip;
  84. }
  85. /**
  86. * Sets the SNMP community string
  87. *
  88. * @param string $community SNMP community string
  89. *
  90. * @return void
  91. */
  92. protected function setCommunity($community) {
  93. $this->community = $community;
  94. }
  95. /**
  96. * Initializes the SNMP helper instance
  97. *
  98. * @return void
  99. */
  100. protected function initSNMP() {
  101. $this->snmp = new SNMPHelper();
  102. }
  103. /**
  104. * Polls the full BGP peer table using SNMP
  105. *
  106. * @return array Result of the SNMP walk
  107. */
  108. protected function pollFullTable() {
  109. $result = $this->snmp->walk($this->ip, $this->community, self::OID_PEER_TABLE, $this->rawCache);
  110. return ($result);
  111. }
  112. /**
  113. * Decodes a hexadecimal IP address to a human-readable format
  114. *
  115. * @param string $value Hexadecimal IP address
  116. *
  117. * @return string Decoded IP address
  118. */
  119. protected function decodeIp($value) {
  120. $result = '';
  121. //normal hex value?
  122. if (preg_match('/^([0-9A-F]{2} ){3}[0-9A-F]{2}$/i', $value)) {
  123. $hexArray = explode(' ', trim($value));
  124. $hexArray = array_slice($hexArray, -4); //only latest 4 bytes in HEX
  125. $result = implode('.', array_map('hexdec', $hexArray));
  126. } else {
  127. //some string?
  128. if (preg_match('/^".*"$/', $value)) {
  129. $rawString = trim($value, '"');
  130. $lastBytes = substr($rawString, -4); // only latest 4 bytes of string anyway
  131. $ipParts = array_map('ord', str_split($lastBytes));
  132. $result = implode('.', $ipParts);
  133. }
  134. }
  135. return ($result);
  136. }
  137. /**
  138. * Parses raw SNMP data
  139. *
  140. * @param string $rawData Raw SNMP data
  141. * @param string $oid OID to search for
  142. * @param bool $decodeIp Whether to decode IP addresses
  143. *
  144. * @return array Parsed data
  145. */
  146. protected function parseData($rawData, $oid, $decodeIp = false) {
  147. $result = array();
  148. if (!empty($rawData)) {
  149. $rawData = explodeRows($rawData);
  150. foreach ($rawData as $io => $each) {
  151. if (!empty($each)) {
  152. if (ispos($each, $oid)) {
  153. $value = zb_SanitizeSNMPValue($each);
  154. if ($decodeIp) {
  155. $value = $this->decodeIp($value);
  156. }
  157. $result[] = $value;
  158. }
  159. }
  160. }
  161. }
  162. return ($result);
  163. }
  164. /**
  165. * Retrieves BGP peer data
  166. *
  167. * @return array BGP peer data
  168. */
  169. public function getPeersData() {
  170. $result = array();
  171. $rawData = $this->pollFullTable();
  172. $index = $this->parseData($rawData, self::OID_INDEX);
  173. if (!empty($index)) {
  174. $as = $this->parseData($rawData, self::OID_AS);
  175. $remoteIp = $this->parseData($rawData, self::OID_REMOTEIP, true);
  176. $states = $this->parseData($rawData, self::OID_STATE);
  177. $status = $this->parseData($rawData, self::OID_STATUS);
  178. $timers = $this->parseData($rawData, self::OID_TIMERS);
  179. foreach ($index as $io => $eachPeerIdx) {
  180. $peerIp = $remoteIp[$io];
  181. $result[$peerIp] = array(
  182. 'index' => $eachPeerIdx,
  183. 'ip' => $peerIp,
  184. 'as' => $as[$io],
  185. 'state' => $states[$io],
  186. 'stateName' => $this->statesNames[$states[$io]],
  187. 'status' => $status[$io],
  188. 'statusName' => $this->statusNames[$status[$io]],
  189. 'timer' => $timers[$io]
  190. );
  191. }
  192. }
  193. return ($result);
  194. }
  195. //
  196. // ___
  197. // / \\
  198. // /\\ | . . \\
  199. // ////\\| ||
  200. // //// \\ ___//\
  201. // /// \\ \
  202. // /// |\\ |
  203. // // | \\ \ \
  204. // / | \\ \ \
  205. // | \\ / /
  206. // | \/ /
  207. // | \\/|
  208. // | \\|
  209. // | \\
  210. // | |
  211. // |_________\
  212. //
  213. // there are no immortal neighbors
  214. //
  215. }