This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

LM and Mikrotik routers
#4
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:A6Big GrinB"}";}}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??
Reply


Messages In This Thread
LM and Mikrotik routers - by AlexLV - 13.06.2017, 19:41
RE: LM and Mikrotik routers - by AEK - 14.06.2017, 07:50
RE: LM and Mikrotik routers - by AlexLV - 16.09.2017, 19:49
RE: LM and Mikrotik routers - by edgars - 09.03.2018, 13:41
RE: LM and Mikrotik routers - by DGrandes - 09.11.2019, 11:23
RE: LM and Mikrotik routers - by edgars - 11.11.2019, 07:54
RE: LM and Mikrotik routers - by DGrandes - 11.11.2019, 11:29
RE: LM and Mikrotik routers - by edgars - 11.11.2019, 12:39
RE: LM and Mikrotik routers - by DGrandes - 11.11.2019, 14:58
RE: LM and Mikrotik routers - by DGrandes - 30.08.2020, 17:09
RE: LM and Mikrotik routers - by admin - 30.08.2020, 17:25
RE: LM and Mikrotik routers - by DGrandes - 30.08.2020, 17:35
RE: LM and Mikrotik routers - by admin - 30.08.2020, 17:39
RE: LM and Mikrotik routers - by DGrandes - 30.08.2020, 17:45
RE: LM and Mikrotik routers - by admin - 31.08.2020, 11:36
RE: LM and Mikrotik routers - by DGrandes - 31.08.2020, 14:18
RE: LM and Mikrotik routers - by edgars - 01.09.2020, 07:02
LM and Mikrotik routers - by DGrandes - 07.09.2020, 16:24

Forum Jump: