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... : If somebody try to connect to home Wifi - Mikrotik and LM can try to inform you... API works with no problem with .php, but I don't know LM possibilities.. 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:A6B"}";}}s:10:"PROPERTIES";a:7:{i:0;a:7:{s:5:"TITLE";s:10:"holdCycles";s:11:"DESCRIPTION";s:52:"Quantity of controlling cicles";s:12:"KEEP_HISTORY";s:1:"0";s:8:"ONCHANGE";s:0:"";s:6:"SYSTEM";s:0:"";s:8:"DATA_KEY";s:1:"0";s:9:"DATA_TYPE";s:1:"0";}i:1;a:7:{s:5:"TITLE";s:3:"MAC";s:11:"DESCRIPTION";s:35:"Device's MAC address";s:12:"KEEP_HISTORY";s:1:"0";s:8:"ONCHANGE";s:0:"";s:6:"SYSTEM";s:0:"";s:8:"DATA_KEY";s:1:"0";s:9:"DATA_TYPE";s:1:"0";}i:2;a:7:{s:5:"TITLE";s:4:"name";s:11:"DESCRIPTION";s:42:"Example - May be Daniel phone (name of registered device)";s:12:"KEEP_HISTORY";s:1:"0";s:8:"ONCHANGE";s:0:"";s:6:"SYSTEM";s:0:"";s:8:"DATA_KEY";s:1:"0";s:9:"DATA_TYPE";s:1:"0";}i:3;a:7:{s:5:"TITLE";s:6:"notify";s:11:"DESCRIPTION";s:107:"inform: 0-no, 1-daytime, 2-always. 1 come, 2 away";s:12:"KEEP_HISTORY";s:1:"0";s:8:"ONCHANGE";s:0:"";s:6:"SYSTEM";s:0:"";s:8:"DATA_KEY";s:1:"0";s:9:"DATA_TYPE";s:1:"0";}i:4;a:7:{s:5:"TITLE";s:10:"lastActive";s:11:"DESCRIPTION";s:59:"Time and date of last visit";s:12:"KEEP_HISTORY";s:1:"0";s:8:"ONCHANGE";s:0:"";s:6:"SYSTEM";s:0:"";s:8:"DATA_KEY";s:1:"0";s:9:"DATA_TYPE";s:1:"0";}i:5;a:7:{s:5:"TITLE";s:6:"online";s:11:"DESCRIPTION";s:24:"Now connected to WiFi";s:12:"KEEP_HISTORY";s:1:"0";s:8:"ONCHANGE";s:0:"";s:6:"SYSTEM";s:0:"";s:8:"DATA_KEY";s:1:"0";s:9:"DATA_TYPE";s:1:"0";}i:6;a:7:{s:5:"TITLE";s:6:"status";s:11:"DESCRIPTION";s:0:"";s:12:"KEEP_HISTORY";s:1:"0";s:8:"ONCHANGE";s:0:"";s:6:"SYSTEM";s:0:"";s:8:"DATA_KEY";s:1:"0";s:9:"DATA_TYPE";s:1:"0";}}s:7:"OBJECTS";a:0:{}}} 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; |