denisovvsh Posted February 18, 2016 · Report post Уважаемые форумчане, подскажите пожалуйста! Как на встроенном языке, при помощи любого оператора цикла, перебрать массив? Который получаем командой /ip hotspot ip-binding и при каждой итерации выполнить команду /ip hotspot ip-binding> remove 0 . Тем самым удалить всех пользователей, при помощи запуска скрипта. Или может быть, кто нибудь подскажет, как это сделать одной командой? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
AciDSAS Posted February 19, 2016 · Report post /ip hotspot ip-binding remove [find server=all] Удалит всех у кого server = all. /ip hotspot ip-binding remove [find address=11.22.33.44] Удалит пользователя с адресом 11.22.33.44 По аналогии можете свое условие подставить. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 19, 2016 (edited) · Report post /ip hotspot ip-binding remove [find server=all] Удалит всех у кого server = all. /ip hotspot ip-binding remove [find address=11.22.33.44] Удалит пользователя с адресом 11.22.33.44 По аналогии можете свое условие подставить. А если нужно удалить всех у кого idle time более 1-го дня, в /ip hotspot host? Edited February 19, 2016 by denisovvsh Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
AciDSAS Posted February 19, 2016 (edited) · Report post Элементарно :) /ip hotspot host remove [find idle-time>1d] запихиваем это в scheduler, интервал исполнения указать по вкусу :) /system scheduler add interval=2m name=hotspot-idle-remove on-event="/ip hotspot host remove [find idle-time>1d]" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive start-time=startup Edited February 19, 2016 by AciDSAS Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 19, 2016 · Report post Элементарно :) /ip hotspot host remove [find idle-time>1d] запихиваем это в scheduler, интервал исполнения указать по вкусу :) /system scheduler add interval=2m name=hotspot-idle-remove on-event="/ip hotspot host remove [find idle-time>1d]" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive start-time=startup А если условие проверки в /ip hotspot host а удалить нужно в /ip hotspot ip-binding Т.к. в /ip hotspot ip-binding нет idle-time Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
AciDSAS Posted February 19, 2016 · Report post Такое попробуйте, должно выполнить задачу. Сам не проверял. /ip hotspot ip-binding remove [find [/ip hotspot host find idle-time>1d] Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 20, 2016 · Report post Такое попробуйте, должно выполнить задачу. Сам не проверял. /ip hotspot ip-binding remove [find [/ip hotspot host find idle-time>1d] не работает Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 28, 2016 · Report post Вот PHP класс для работы с RouterOS через API <?php /***************************** * * RouterOS PHP API class v1.5 * Author: Denis Basta * Contributors: * Nick Barnes * Ben Menking (ben [at] infotechsc [dot] com) * Jeremy Jefferson (http://jeremyj.com) * Cristian Deluxe (djcristiandeluxe [at] gmail [dot] com) * * http://www.mikrotik.com * http://wiki.mikrotik.com/wiki/API_PHP_class * ******************************/ class routeros_api { var $debug = false; // Show debug information var $error_no; // Variable for storing connection error number, if any var $error_str; // Variable for storing connection error text, if any var $attempts = 5; // Connection attempt count var $connected = true; // Connection state var $delay = 3; // Delay between connection attempts in seconds var $port = 8728; // Port to connect to var $timeout = 3; // Connection attempt timeout and data read timeout var $socket; // Variable for storing socket resource /** * Print text for debug purposes * * @param string $text Text to print * * @return void */ function debug($text) { if ($this->debug) echo $text . "\n"; } /** * * * @param string $length * * @return void */ function encode_length($length) { if ($length < 0x80) { $length = chr($length); } else if ($length < 0x4000) { $length |= 0x8000; $length = chr(($length >> 8) & 0xFF) . chr($length & 0xFF); } else if ($length < 0x200000) { $length |= 0xC00000; $length = chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF); } else if ($length < 0x10000000) { $length |= 0xE0000000; $length = chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF); } else if ($length >= 0x10000000) $length = chr(0xF0) . chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF); return $length; } /** * Login to RouterOS * * @param string $ip Hostname (IP or domain) of the RouterOS server * @param string $login The RouterOS username * @param string $password The RouterOS password * * @return boolean If we are connected or not */ function connect($ip, $login, $password) { for ($ATTEMPT = 1; $ATTEMPT <= $this->attempts; $ATTEMPT++) { $this->connected = false; $this->debug('Connection attempt #' . $ATTEMPT . ' to ' . $ip . ':' . $this->port . '...'); $this->socket = @fsockopen($ip, $this->port, $this->error_no, $this->error_str, $this->timeout); if ($this->socket) { socket_set_timeout($this->socket, $this->timeout); $this->write('/login'); $RESPONSE = $this->read(false); if ($RESPONSE[0] == '!done') { $MATCHES = array(); if (preg_match_all('/[^=]+/i', $RESPONSE[1], $MATCHES)) { if ($MATCHES[0][0] == 'ret' && strlen($MATCHES[0][1]) == 32) { $this->write('/login', false); $this->write('=name=' . $login, false); $this->write('=response=00' . md5(chr(0) . $password . pack('H*', $MATCHES[0][1]))); $RESPONSE = $this->read(false); if ($RESPONSE[0] == '!done') { $this->connected = true; break; } } } } fclose($this->socket); } sleep($this->delay); } if ($this->connected) $this->debug('Connected...'); else $this->debug('Error...'); return $this->connected; } /** * Disconnect from RouterOS * * @return void */ function disconnect() { fclose($this->socket); $this->connected = false; $this->debug('Disconnected...'); } /** * Parse response from Router OS * * @param array $response Response data * * @return array Array with parsed data */ function parse_response($response) { if (is_array($response)) { $PARSED = array(); $CURRENT = null; $singlevalue = null; foreach ($response as $x) { if (in_array($x, array( '!fatal', '!re', '!trap' ))) { if ($x == '!re') { $CURRENT =& $PARSED[]; } else $CURRENT =& $PARSED[$x][]; } else if ($x != '!done') { $MATCHES = array(); if (preg_match_all('/[^=]+/i', $x, $MATCHES)) { if ($MATCHES[0][0] == 'ret') { $singlevalue = $MATCHES[0][1]; } $CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : ''); } } } if (empty($PARSED) && !is_null($singlevalue)) { $PARSED = $singlevalue; } return $PARSED; } else return array(); } /** * Parse response from Router OS * * @param array $response Response data * * @return array Array with parsed data */ function parse_response4smarty($response) { if (is_array($response)) { $PARSED = array(); $CURRENT = null; $singlevalue = null; foreach ($response as $x) { if (in_array($x, array( '!fatal', '!re', '!trap' ))) { if ($x == '!re') $CURRENT =& $PARSED[]; else $CURRENT =& $PARSED[$x][]; } else if ($x != '!done') { $MATCHES = array(); if (preg_match_all('/[^=]+/i', $x, $MATCHES)) { if ($MATCHES[0][0] == 'ret') { $singlevalue = $MATCHES[0][1]; } $CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : ''); } } } foreach ($PARSED as $key => $value) { $PARSED[$key] = $this->array_change_key_name($value); } return $PARSED; if (empty($PARSED) && !is_null($singlevalue)) { $PARSED = $singlevalue; } } else { return array(); } } /** * Change "-" and "/" from array key to "_" * * @param array $array Input array * * @return array Array with changed key names */ function array_change_key_name(&$array) { if (is_array($array)) { foreach ($array as $k => $v) { $tmp = str_replace("-", "_", $k); $tmp = str_replace("/", "_", $tmp); if ($tmp) { $array_new[$tmp] = $v; } else { $array_new[$k] = $v; } } return $array_new; } else { return $array; } } /** * Read data from Router OS * * @param boolean $parse Parse the data? default: true * * @return array Array with parsed or unparsed data */ function read($parse = true) { $RESPONSE = array(); $receiveddone = false; while (true) { // Read the first byte of input which gives us some or all of the length // of the remaining reply. $BYTE = ord(fread($this->socket, 1)); $LENGTH = 0; // If the first bit is set then we need to remove the first four bits, shift left 8 // and then read another byte in. // We repeat this for the second and third bits. // If the fourth bit is set, we need to remove anything left in the first byte // and then read in yet another byte. if ($BYTE & 128) { if (($BYTE & 192) == 128) { $LENGTH = (($BYTE & 63) << 8) + ord(fread($this->socket, 1)); } else { if (($BYTE & 224) == 192) { $LENGTH = (($BYTE & 31) << 8) + ord(fread($this->socket, 1)); $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1)); } else { if (($BYTE & 240) == 224) { $LENGTH = (($BYTE & 15) << 8) + ord(fread($this->socket, 1)); $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1)); $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1)); } else { $LENGTH = ord(fread($this->socket, 1)); $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1)); $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1)); $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1)); } } } } else { $LENGTH = $BYTE; } // If we have got more characters to read, read them in. if ($LENGTH > 0) { $_ = ""; $retlen = 0; while ($retlen < $LENGTH) { $toread = $LENGTH - $retlen; $_ .= fread($this->socket, $toread); $retlen = strlen($_); } $RESPONSE[] = $_; $this->debug('>>> [' . $retlen . '/' . $LENGTH . '] bytes read.'); } // If we get a !done, make a note of it. if ($_ == "!done") $receiveddone = true; $STATUS = socket_get_status($this->socket); if ($LENGTH > 0) $this->debug('>>> [' . $LENGTH . ', ' . $STATUS['unread_bytes'] . ']' . $_); if ((!$this->connected && !$STATUS['unread_bytes']) || ($this->connected && !$STATUS['unread_bytes'] && $receiveddone)) break; } if ($parse) $RESPONSE = $this->parse_response($RESPONSE); return $RESPONSE; } /** * Write (send) data to Router OS * * @param string $command A string with the command to send * @param mixed $param2 If we set an integer, the command will send this data as a "tag" * If we set it to boolean true, the funcion will send the comand and finish * If we set it to boolean false, the funcion will send the comand and wait for next command * Default: true * * @return boolean Return false if no command especified */ function write($command, $param2 = true) { if ($command) { $data = explode("\n", $command); foreach ($data as $com) { $com = trim($com); fwrite($this->socket, $this->encode_length(strlen($com)) . $com); $this->debug('<<< [' . strlen($com) . '] ' . $com); } if (gettype($param2) == 'integer') { fwrite($this->socket, $this->encode_length(strlen('.tag=' . $param2)) . '.tag=' . $param2 . chr(0)); $this->debug('<<< [' . strlen('.tag=' . $param2) . '] .tag=' . $param2); } else if (gettype($param2) == 'boolean') fwrite($this->socket, ($param2 ? chr(0) : '')); return true; } else return false; } /** * Write (send) data to Router OS * * @param string $com A string with the command to send * @param array $arr An array with arguments or queries * * @return array Array with parsed */ function comm($com, $arr = array()) { $count = count($arr); $this->write($com, !$arr); $i = 0; foreach ($arr as $k => $v) { switch ($k[0]) { case "?": $el = "$k=$v"; break; case "~": $el = "$k~$v"; break; default: $el = "=$k=$v"; break; } $last = ($i++ == $count - 1); $this->write($el, $last); } return $this->read(); } } ?> Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 28, 2016 (edited) · Report post А вот как, извращенно решить многие задачи, одна из них, это удаление пассивных пользователей hotspot, если они не проявляли активности, заданное, в функции, время. //Используя класс выше, создаем дочерний класс. <?php class routeros_api_oversize extends routeros_api{ var $timeMask; function routeros_api_oversize(){ //конструктор $this->timeMask = '1d'; //сколько времени бездействует пользователь } function parseArrHotspotHost($routerArray){ $resultParseArrHotspot = array(); $client = array(); foreach($routerArray as $a => $b){ $val_arr = substr($b,1); $val_arr = substr($val_arr,strpos($val_arr,'=')+1); $sum_str = strlen($val_arr); $sum_str = "-".$sum_str - 1; $key_arr = substr($b, 1, $sum_str); if($key_arr == ".id"){$client[$key_arr] = $val_arr;} if($key_arr == "to-address"){$client[$key_arr] = $val_arr;} if($key_arr == "idle-time"){ $client[$key_arr] = $val_arr; array_push($resultParseArrHotspot, $client); } } return $resultParseArrHotspot; } } ?> //запускаем, на каком нибудь сервере(хостинге), скрипт который будет выполнять проверку пользователей hotspot //которые имеют статус bypassed и бездействуют 2 дня //удаляем их при обнаружении <?php $RAO = new routeros_api_oversize(); //создаем экземпляр класса $ipRouter = 'ip маршрутизатора микротик с включенным хотспот'; $usRouter = 'имя пользователя с правами на запись и чтение и выполнение'; $pasRouter = 'пароль'; if($RAO->connect($ipRouter, $usRouter, $pasRouter)){ //если подключение к маршрутизатору вернуло true $RAO->write('/ip/hotspot/host/print'); //отправляем команду $routerArr = $RAO->read(false); //получаем массив данных с пользователями hotspot $list_info = $RAO->parseArrHotspotHost($routerArr); //парсим полученный массив и получаем нужный нам массив пользователей на борту hotspot $k = 0; while(isset($list_info[$k])){ //проходим по массиву циклом и одновременно ищем пользователя среди пассивных //извлекаем данные о пользователе и присваиваем их переменным $ip = $list_info[$k]['to-address']; $idle = $list_info[$k]['idle-time']; //формат времени 1w1d1h1m1s $pos = strstr($idle, $RAO->timeMask); // ищем вхождение подстроки маски в строку времени простоя if($pos != false){ // если поиск вернул TRUE $RAO->write('/ip/hotspot/ip-binding/print'); // запрашиваем данные о пассивных пользователях $routerArr2 = $RAO->read(false); // получаем массив $list_info2 = $RAO->parseArrHotspotHost($routerArr2); // парсим $k2 = 0; while(isset($list_info2[$k2])){ // цикл прохождения по массиву для поиска по ip адресу $ip2 = $list_info2[$k2]['to-address']; if($ip2 == $ip){ // находим пользователя $id_ip = $k2; $RAO->comm('/ip/hotspot/ip-binding/remove', array('.id' => $id_ip,)); // удаляем пользователя из пассивных пользователей хотспота $k2++; break; } else{ $k2++; continue; } } $k++; continue; } else{ $k++; continue; // продолжаем проверять остальных пользователей hotspot } } $RAO->disconnect(); // отключаемся от маршрутизатора } ?> Edited February 28, 2016 by denisovvsh Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...