denisovvsh Posted February 18, 2016 Уважаемые форумчане, подскажите пожалуйста! Как на встроенном языке, при помощи любого оператора цикла, перебрать массив? Который получаем командой /ip hotspot ip-binding и при каждой итерации выполнить команду /ip hotspot ip-binding> remove 0 . Тем самым удалить всех пользователей, при помощи запуска скрипта. Или может быть, кто нибудь подскажет, как это сделать одной командой? Share this post Link to post Share on other sites More sharing options...
AciDSAS Posted February 19, 2016 /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 По аналогии можете свое условие подставить. Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 19, 2016 (edited) /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 Share this post Link to post Share on other sites More sharing options...
AciDSAS Posted February 19, 2016 (edited) Элементарно :) /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 Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 19, 2016 Элементарно :) /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 Share this post Link to post Share on other sites More sharing options...
AciDSAS Posted February 19, 2016 Такое попробуйте, должно выполнить задачу. Сам не проверял. /ip hotspot ip-binding remove [find [/ip hotspot host find idle-time>1d] Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 20, 2016 Такое попробуйте, должно выполнить задачу. Сам не проверял. /ip hotspot ip-binding remove [find [/ip hotspot host find idle-time>1d] не работает Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 28, 2016 Вот 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(); } } ?> Share this post Link to post Share on other sites More sharing options...
denisovvsh Posted February 28, 2016 (edited) А вот как, извращенно решить многие задачи, одна из них, это удаление пассивных пользователей 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 Share this post Link to post Share on other sites More sharing options...