Advertisement
Guest User

test.php

a guest
Jun 12th, 2019
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.79 KB | None | 0 0
  1. <?php
  2. /*****************************
  3. *
  4. * RouterOS PHP API class v1.6
  5. * Author: Denis Basta
  6. * Contributors:
  7. * Nick Barnes
  8. * Ben Menking (ben [at] infotechsc [dot] com)
  9. * Jeremy Jefferson (http://jeremyj.com)
  10. * Cristian Deluxe (djcristiandeluxe [at] gmail [dot] com)
  11. * Mikhail Moskalev (mmv.rus [at] gmail [dot] com)
  12. *
  13. * http://www.mikrotik.com
  14. * http://wiki.mikrotik.com/wiki/API_PHP_class
  15. *
  16. ******************************/
  17. class RouterosAPI
  18. {
  19. var $debug = false; // Show debug information
  20. var $connected = false; // Connection state
  21. var $port = 8728; // Port to connect to (default 8729 for ssl)
  22. var $ssl = false; // Connect using SSL (must enable api-ssl in IP/Services)
  23. var $timeout = 3; // Connection attempt timeout and data read timeout
  24. var $attempts = 5; // Connection attempt count
  25. var $delay = 3; // Delay between connection attempts in seconds
  26. var $socket; // Variable for storing socket resource
  27. var $error_no; // Variable for storing connection error number, if any
  28. var $error_str; // Variable for storing connection error text, if any
  29. /* Check, can be var used in foreach */
  30. public function isIterable($var)
  31. {
  32. return $var !== null
  33. && (is_array($var)
  34. || $var instanceof Traversable
  35. || $var instanceof Iterator
  36. || $var instanceof IteratorAggregate
  37. );
  38. }
  39. /**
  40. * Print text for debug purposes
  41. *
  42. * @param string $text Text to print
  43. *
  44. * @return void
  45. */
  46. public function debug($text)
  47. {
  48. if ($this->debug) {
  49. echo $text . "\n";
  50. }
  51. }
  52. /**
  53. *
  54. *
  55. * @param string $length
  56. *
  57. * @return void
  58. */
  59. public function encodeLength($length)
  60. {
  61. if ($length < 0x80) {
  62. $length = chr($length);
  63. } elseif ($length < 0x4000) {
  64. $length |= 0x8000;
  65. $length = chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
  66. } elseif ($length < 0x200000) {
  67. $length |= 0xC00000;
  68. $length = chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
  69. } elseif ($length < 0x10000000) {
  70. $length |= 0xE0000000;
  71. $length = chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
  72. } elseif ($length >= 0x10000000) {
  73. $length = chr(0xF0) . chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
  74. }
  75. return $length;
  76. }
  77. /**
  78. * Login to RouterOS
  79. *
  80. * @param string $ip Hostname (IP or domain) of the RouterOS server
  81. * @param string $login The RouterOS username
  82. * @param string $password The RouterOS password
  83. *
  84. * @return boolean If we are connected or not
  85. */
  86. public function connect($ip, $login, $password)
  87. {
  88. for ($ATTEMPT = 1; $ATTEMPT <= $this->attempts; $ATTEMPT++) {
  89. $this->connected = false;
  90. $PROTOCOL = ($this->ssl ? 'ssl://' : '' );
  91. $context = stream_context_create(array('ssl' => array('ciphers' => 'ADH:ALL', 'verify_peer' => false, 'verify_peer_name' => false)));
  92. $this->debug('Connection attempt #' . $ATTEMPT . ' to ' . $PROTOCOL . $ip . ':' . $this->port . '...');
  93. $this->socket = @stream_socket_client($PROTOCOL . $ip.':'. $this->port, $this->error_no, $this->error_str, $this->timeout, STREAM_CLIENT_CONNECT,$context);
  94. if ($this->socket) {
  95. socket_set_timeout($this->socket, $this->timeout);
  96. $this->write('/login', false);
  97. $this->write('=name=' . $login, false);
  98. $this->write('=password=' . $password);
  99. $RESPONSE = $this->read(false);
  100. if (isset($RESPONSE[0])) {
  101. if ($RESPONSE[0] == '!done') {
  102. if (!isset($RESPONSE[1])) {
  103. // Login method post-v6.43
  104. $this->connected = true;
  105. break;
  106. } else {
  107. // Login method pre-v6.43
  108. $MATCHES = array();
  109. if (preg_match_all('/[^=]+/i', $RESPONSE[1], $MATCHES)) {
  110. if ($MATCHES[0][0] == 'ret' && strlen($MATCHES[0][1]) == 32) {
  111. $this->write('/login', false);
  112. $this->write('=name=' . $login, false);
  113. $this->write('=response=00' . md5(chr(0) . $password . pack('H*', $MATCHES[0][1])));
  114. $RESPONSE = $this->read(false);
  115. if (isset($RESPONSE[0]) && $RESPONSE[0] == '!done') {
  116. $this->connected = true;
  117. break;
  118. }
  119. }
  120. }
  121. }
  122. }
  123. }
  124. fclose($this->socket);
  125. }
  126. sleep($this->delay);
  127. }
  128. if ($this->connected) {
  129. $this->debug('Connected...');
  130. } else {
  131. $this->debug('Error...');
  132. }
  133. return $this->connected;
  134. }
  135. /**
  136. * Disconnect from RouterOS
  137. *
  138. * @return void
  139. */
  140. public function disconnect()
  141. {
  142. // let's make sure this socket is still valid. it may have been closed by something else
  143. if( is_resource($this->socket) ) {
  144. fclose($this->socket);
  145. }
  146. $this->connected = false;
  147. $this->debug('Disconnected...');
  148. }
  149. /**
  150. * Parse response from Router OS
  151. *
  152. * @param array $response Response data
  153. *
  154. * @return array Array with parsed data
  155. */
  156. public function parseResponse($response)
  157. {
  158. if (is_array($response)) {
  159. $PARSED = array();
  160. $CURRENT = null;
  161. $singlevalue = null;
  162. foreach ($response as $x) {
  163. if (in_array($x, array('!fatal','!re','!trap'))) {
  164. if ($x == '!re') {
  165. $CURRENT =& $PARSED[];
  166. } else {
  167. $CURRENT =& $PARSED[$x][];
  168. }
  169. } elseif ($x != '!done') {
  170. $MATCHES = array();
  171. if (preg_match_all('/[^=]+/i', $x, $MATCHES)) {
  172. if ($MATCHES[0][0] == 'ret') {
  173. $singlevalue = $MATCHES[0][1];
  174. }
  175. $CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : '');
  176. }
  177. }
  178. }
  179. if (empty($PARSED) && !is_null($singlevalue)) {
  180. $PARSED = $singlevalue;
  181. }
  182. return $PARSED;
  183. } else {
  184. return array();
  185. }
  186. }
  187. /**
  188. * Parse response from Router OS
  189. *
  190. * @param array $response Response data
  191. *
  192. * @return array Array with parsed data
  193. */
  194. public function parseResponse4Smarty($response)
  195. {
  196. if (is_array($response)) {
  197. $PARSED = array();
  198. $CURRENT = null;
  199. $singlevalue = null;
  200. foreach ($response as $x) {
  201. if (in_array($x, array('!fatal','!re','!trap'))) {
  202. if ($x == '!re') {
  203. $CURRENT =& $PARSED[];
  204. } else {
  205. $CURRENT =& $PARSED[$x][];
  206. }
  207. } elseif ($x != '!done') {
  208. $MATCHES = array();
  209. if (preg_match_all('/[^=]+/i', $x, $MATCHES)) {
  210. if ($MATCHES[0][0] == 'ret') {
  211. $singlevalue = $MATCHES[0][1];
  212. }
  213. $CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : '');
  214. }
  215. }
  216. }
  217. foreach ($PARSED as $key => $value) {
  218. $PARSED[$key] = $this->arrayChangeKeyName($value);
  219. }
  220. return $PARSED;
  221. if (empty($PARSED) && !is_null($singlevalue)) {
  222. $PARSED = $singlevalue;
  223. }
  224. } else {
  225. return array();
  226. }
  227. }
  228. /**
  229. * Change "-" and "/" from array key to "_"
  230. *
  231. * @param array $array Input array
  232. *
  233. * @return array Array with changed key names
  234. */
  235. public function arrayChangeKeyName(&$array)
  236. {
  237. if (is_array($array)) {
  238. foreach ($array as $k => $v) {
  239. $tmp = str_replace("-", "_", $k);
  240. $tmp = str_replace("/", "_", $tmp);
  241. if ($tmp) {
  242. $array_new[$tmp] = $v;
  243. } else {
  244. $array_new[$k] = $v;
  245. }
  246. }
  247. return $array_new;
  248. } else {
  249. return $array;
  250. }
  251. }
  252. /**
  253. * Read data from Router OS
  254. *
  255. * @param boolean $parse Parse the data? default: true
  256. *
  257. * @return array Array with parsed or unparsed data
  258. */
  259. public function read($parse = true)
  260. {
  261. $RESPONSE = array();
  262. $receiveddone = false;
  263. while (true) {
  264. // Read the first byte of input which gives us some or all of the length
  265. // of the remaining reply.
  266. $BYTE = ord(fread($this->socket, 1));
  267. $LENGTH = 0;
  268. // If the first bit is set then we need to remove the first four bits, shift left 8
  269. // and then read another byte in.
  270. // We repeat this for the second and third bits.
  271. // If the fourth bit is set, we need to remove anything left in the first byte
  272. // and then read in yet another byte.
  273. if ($BYTE & 128) {
  274. if (($BYTE & 192) == 128) {
  275. $LENGTH = (($BYTE & 63) << 8) + ord(fread($this->socket, 1));
  276. } else {
  277. if (($BYTE & 224) == 192) {
  278. $LENGTH = (($BYTE & 31) << 8) + ord(fread($this->socket, 1));
  279. $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
  280. } else {
  281. if (($BYTE & 240) == 224) {
  282. $LENGTH = (($BYTE & 15) << 8) + ord(fread($this->socket, 1));
  283. $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
  284. $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
  285. } else {
  286. $LENGTH = ord(fread($this->socket, 1));
  287. $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
  288. $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
  289. $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
  290. }
  291. }
  292. }
  293. } else {
  294. $LENGTH = $BYTE;
  295. }
  296. $_ = "";
  297. // If we have got more characters to read, read them in.
  298. if ($LENGTH > 0) {
  299. $_ = "";
  300. $retlen = 0;
  301. while ($retlen < $LENGTH) {
  302. $toread = $LENGTH - $retlen;
  303. $_ .= fread($this->socket, $toread);
  304. $retlen = strlen($_);
  305. }
  306. $RESPONSE[] = $_;
  307. $this->debug('>>> [' . $retlen . '/' . $LENGTH . '] bytes read.');
  308. }
  309. // If we get a !done, make a note of it.
  310. if ($_ == "!done") {
  311. $receiveddone = true;
  312. }
  313. $STATUS = socket_get_status($this->socket);
  314. if ($LENGTH > 0) {
  315. $this->debug('>>> [' . $LENGTH . ', ' . $STATUS['unread_bytes'] . ']' . $_);
  316. }
  317. if ((!$this->connected && !$STATUS['unread_bytes']) || ($this->connected && !$STATUS['unread_bytes'] && $receiveddone)) {
  318. break;
  319. }
  320. }
  321. if ($parse) {
  322. $RESPONSE = $this->parseResponse($RESPONSE);
  323. }
  324. return $RESPONSE;
  325. }
  326. /**
  327. * Write (send) data to Router OS
  328. *
  329. * @param string $command A string with the command to send
  330. * @param mixed $param2 If we set an integer, the command will send this data as a "tag"
  331. * If we set it to boolean true, the funcion will send the comand and finish
  332. * If we set it to boolean false, the funcion will send the comand and wait for next command
  333. * Default: true
  334. *
  335. * @return boolean Return false if no command especified
  336. */
  337. public function write($command, $param2 = true)
  338. {
  339. if ($command) {
  340. $data = explode("\n", $command);
  341. foreach ($data as $com) {
  342. $com = trim($com);
  343. fwrite($this->socket, $this->encodeLength(strlen($com)) . $com);
  344. $this->debug('<<< [' . strlen($com) . '] ' . $com);
  345. }
  346. if (gettype($param2) == 'integer') {
  347. fwrite($this->socket, $this->encodeLength(strlen('.tag=' . $param2)) . '.tag=' . $param2 . chr(0));
  348. $this->debug('<<< [' . strlen('.tag=' . $param2) . '] .tag=' . $param2);
  349. } elseif (gettype($param2) == 'boolean') {
  350. fwrite($this->socket, ($param2 ? chr(0) : ''));
  351. }
  352. return true;
  353. } else {
  354. return false;
  355. }
  356. }
  357. /**
  358. * Write (send) data to Router OS
  359. *
  360. * @param string $com A string with the command to send
  361. * @param array $arr An array with arguments or queries
  362. *
  363. * @return array Array with parsed
  364. */
  365. public function comm($com, $arr = array())
  366. {
  367. $count = count($arr);
  368. $this->write($com, !$arr);
  369. $i = 0;
  370. if ($this->isIterable($arr)) {
  371. foreach ($arr as $k => $v) {
  372. switch ($k[0]) {
  373. case "?":
  374. $el = "$k=$v";
  375. break;
  376. case "~":
  377. $el = "$k~$v";
  378. break;
  379. default:
  380. $el = "=$k=$v";
  381. break;
  382. }
  383. $last = ($i++ == $count - 1);
  384. $this->write($el, $last);
  385. }
  386. }
  387. return $this->read();
  388. }
  389. /**
  390. * Standard destructor
  391. *
  392. * @return void
  393. */
  394. public function __destruct()
  395. {
  396. $this->disconnect();
  397. }
  398. }
  399. ?>
  400. <pre>
  401. <?php
  402.  
  403. require('routeros_api.class.php');
  404.  
  405. $API = new RouterosAPI();
  406.  
  407. // biar muncul proses nya
  408. $API->debug = true;
  409.  
  410. // klo pake port beda
  411. $API->port = 6847;
  412.  
  413. // setting host / user / pass mikrotik
  414. $host = 'us-1.hostddns.us';
  415. $user = 'adminsm';
  416. $pass = 'adminsm25';
  417.  
  418. // action
  419. if ($API->connect($host, $user, $pass)) {
  420.  
  421. $API->write('/interface/getall');
  422.  
  423. $READ = $API->read(false);
  424. $ARRAY = $API->parseResponse($READ);
  425.  
  426. print_r($ARRAY);
  427.  
  428. $API->disconnect();
  429.  
  430. }
  431. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement