![]() |
LM and Mikrotik routers - Printable Version +- Logic Machine Forum (https://forum.logicmachine.net) +-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1) +--- Forum: General (https://forum.logicmachine.net/forumdisplay.php?fid=2) +--- Thread: LM and Mikrotik routers (/showthread.php?tid=836) Pages:
1
2
|
LM and Mikrotik routers - AlexLV - 13.06.2017 Mikrotik network devices more and more popular. I used it more than 2 years.. Know that Mikrotk has API. Can we integrate it with LM? Possible use - try to swith WiFi On/Off by deep night over LAN from LM, if Mobile device registered at home Wifi - you can start scripts on LM, - Home automatics works you are just comming closer to home... : ![]() Have link to some info (russian) : http://asp24.com.ua/blog/mikrotik-router-os-api-connect/ https://tugibaev.ru/2014/04/dhcp-lease-mikrotik-notify-sms/ RE: LM and Mikrotik routers - AEK - 14.06.2017 (13.06.2017, 19:41)AlexLV Wrote: Mikrotik network devices more and more popular. I used it more than 2 years.. Know that Mikrotk has API. Can we integrate it with LM? Hi, AlexLV! It's time to start russian threads on forum ![]() you could try to send http request from microtic to LM and then do some logic operations on microtic. I found some links that might help you (Russian too) https://toster.ru/q/196163 https://wiki.mikrotik.com/wiki/Manual:Tools/Fetch in LM you should use remote services http://openrb.com/docs/remote-new.htm - for 2016 FW and newer http://openrb.com/docs/remote.htm - for pre 2016 FW RE: LM and Mikrotik routers - gjniewenhuijse - 14.06.2017 interesting RE: LM and Mikrotik routers - AlexLV - 16.09.2017 Hello, just yesterday started to use API from Mikrotik on one other system - now can see my devices connecting and disconnecting to my Wi-Fi, can add action to this, it is working fine. Will try to test more, but want use such functionality with LM... Is possible implement this Mikrotik API to LM?? <?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 = false; // 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(); } } ?> Script used in other system with this API: a:1:{i:0;a:7:{s:5:"TITLE";s:10:"WiFiDevice";s:5:"NOLOG";s:1:"0";s:11:"DESCRIPTION";s:51:"WIFI device monitoring";s:8:"TEMPLATE";N;s:7:"METHODS";a:2:{i:0;a:7:{s:5:"TITLE";s:5:"Found";s:11:"DESCRIPTION";s:0:"";s:4:"CODE";s:389:"$n=$this->getProperty('notify'); if (strlen($n)==2) { switch(substr($n, 0, 1)) { case 0: $s=-1; break; case 1: $s=0; break; case 2: $s=1; break; default: $s=0; } say($this->getProperty('name').' Connected to WiFi.', $s); if ($this->getProperty('name') == 'Not Known Device') { say($this->getProperty('MAC'), -1); } }";s:11:"CALL_PARENT";s:1:"0";s:9:"SCRIPT_ID";s:1:"0";s:8:"EXECUTED";s:19:"2017-09-12 22:44:01";s:15:"EXECUTED_PARAMS";s:50:"{"ORIGINAL_OBJECT_TITLE":"wifi_10:08:C1:0D:14:1B"}";}i:1;a:7:{s:5:"TITLE";s:4:"Lost";s:11:"DESCRIPTION";s:0:"";s:4:"CODE";s:262:"$n=$this->getProperty('notify'); if (strlen($n)==2) { switch (substr($n, -1, 1)) { case 0: $s=-1; break; case 1: $s=0; break; case 2: $s=1; break; default: $s=0; } say($this->getProperty('name').' Disconnected from WiFI.', $s); }";s:11:"CALL_PARENT";s:1:"0";s:9:"SCRIPT_ID";s:1:"0";s:8:"EXECUTED";s:19:"2017-09-12 23:33:01";s:15:"EXECUTED_PARAMS";s:50:"{"ORIGINAL_OBJECT_TITLE":"wifi_A0:F3:C1:81:A6 ![]() May be Guru of LM can adapt API and script and we can use LM with Mikrotik routers?? FOr usage this script I also need enter Mikrotik IP, login and pass. After that my mikrotik showed me list of all connected device's MAC addresses and system wrote - device not recognized. Later I entered for every MAC name of device I want to see and started monitoring of my devices in my WiFI... Can we do such possibilities?? RE: LM and Mikrotik routers - edgars - 09.03.2018 Hi guys, here is a Scheduled script for Mikrotik RouterOS (v6.41.2) which will monitor WiFi registration table and if one of both MACs appear it will send 1 to grp address 1/1/1 on LogicMachine (192.168.1.13) via HTTP POST command. If both of MACs disappear from the list, it will send 0 to 1/1/1. You can adjust Scheduled script run interval and list of MAC addresses. Or you can send different POST commands for different MAC addresses. Code: { Here is detailed example. RE: LM and Mikrotik routers - gjniewenhuijse - 12.03.2018 (09.03.2018, 13:41)edgars Wrote: Hi guys, This script only works if you don't use capsman i think. RE: LM and Mikrotik routers - gjniewenhuijse - 12.03.2018 i you use mikrotik capsman for wifi management change: /int wire reg find mac-address= to /caps-man reg find mac-address= RE: LM and Mikrotik routers - DGrandes - 09.11.2019 Hi, I used this script in my mikrotik to know if a mac was connected to the wifi and works perfectly. Code: { Is there any way to know witch MAC are connected to DHCP server to use an external Acces Point.. Thanks RE: LM and Mikrotik routers - edgars - 11.11.2019 Hi! do you want to check on Mikrotik DHCP server lease list either it has specific MAC or not? If yes, here is the script: Code: :local exists [/ip dhcp-server lease find mac-address="78:02:F8:7A:96:01"]; RE: LM and Mikrotik routers - DGrandes - 11.11.2019 (11.11.2019, 07:54)edgars Wrote: Hi! do you want to check on Mikrotik DHCP server lease list either it has specific MAC or not? Hi, it works perfectly but it doesn't work for what i whant because dhcp server keep MAC address even if i disconect from the network. I've seen that ARP lease change DC to C when disconect from network. Do you know the best option to know conected MAC address to network in real time? Thanks RE: LM and Mikrotik routers - edgars - 11.11.2019 I just tried with ARP table. It changes from DC to D if the client is disconnected. In this case you should use the following command: Code: :local exists [/ip arp find mac-address="78:02:F8:7A:96:01" and complete=yes]; RE: LM and Mikrotik routers - DGrandes - 11.11.2019 (11.11.2019, 12:39)edgars Wrote: I just tried with ARP table. It changes from DC to D if disconnect client. In this case you should use following command: Ok, i'll tri it! Thanks RE: LM and Mikrotik routers - DGrandes - 30.08.2020 Hi! I have a question about http post with mikrotik. I have this code to write value on LM: Code: /tool fetch url="http://remote:remote@192.168.2.205/scada-remote" http-data="m=json&r=grp&fn=write&alias=33/1/41&value=1" http-method=post; But I see that it´s posible getvalue from LM. I´ve tried this: Code: { But I cant´t get value. Is there something wrong? Thanks RE: LM and Mikrotik routers - admin - 30.08.2020 Try using post instead of get RE: LM and Mikrotik routers - DGrandes - 30.08.2020 (30.08.2020, 17:25)admin Wrote: Try using post instead of get The same, i can´t get value RE: LM and Mikrotik routers - admin - 30.08.2020 I think you're also missing / before tool, it should be: Code: :local value [/tool fetch url="http://remote:remote@192.168.2.205/scada-remote" http-data="m=json&r=grp&fn=getvalue&alias=33/1/241" http-method=get]; RE: LM and Mikrotik routers - DGrandes - 30.08.2020 Yes, I just see this mistake but it´s not the problem. I try with / (with post and get) and nothing. RE: LM and Mikrotik routers - admin - 31.08.2020 See this example and make sure that you have RouterOS v6.43 or newer: https://wiki.mikrotik.com/wiki/Manual:Tools/Fetch#Return_value_to_a_variable RE: LM and Mikrotik routers - DGrandes - 31.08.2020 (31.08.2020, 11:36)admin Wrote: See this example and make sure that you have RouterOS v6.43 or newer: https://wiki.mikrotik.com/wiki/Manual:Tools/Fetch#Return_value_to_a_variable I have routeros v6.44.5. But I don´t know what´s wrong in my code... RE: LM and Mikrotik routers - edgars - 01.09.2020 Hi DGrandes, this works fine on RouterOS 6.43.4 and LM 20200720 (you can paste these commands directly in Mikrotik's Terminal) Read value: Code: /tool fetch url="http://remote:yourPassword111@192.168.1.13/scada-remote" http-data="m=json&r=grp&fn=getvalue&alias=1/0/1" http-content-type="application/json" http-method=post; You should see something like this in Terminal: Code: status: finished By default output = file and the file scada-remote is created (in Files section). You can see object's 1/0/1 value in this file. Note! In latest LM version there is IP blocker enabled in case of 5 unsuccessful login attempts. It's related to FTP, SSH, Remote services. The quickest remedy is to reboot your LM5. If this happens, you will see something like this: Code: status: failed Write value: Code: /tool fetch url="http://remote:yourPassword111@192.168.1.13/scada-remote" http-data="m=json&r=grp&fn=write&alias=1/0/1&value=1" http-content-type="application/json" http-method=post; |