Community discussions

MikroTik App
 
cheesegrits
just joined
Topic Author
Posts: 16
Joined: Fri Jun 01, 2007 11:17 pm

perl API client

Mon Mar 24, 2008 6:01 pm

[New version uploaded 3/26/2008. Fixed a bug which caused command output to hang sometimes, and added simple command line client]

Attached should be a ZIP with three files:

Mtik.pm - a simple perl client for the Mtik API. Pretty much a perl port of the python client from the Wiki, with an extra routine or two for formatting the returned data.

mtik_api_example.pl - an example of how to use the API. Provides some useful wireless ACL control routines. I've included enough comments so you should be able to work out how it all hangs together.

mtik_tty.pl - a simple command line client for testing API commands with. Use -h switch for usage info.

This code is very much a first cut. I intend to make the Mtik.pm stuff object oriented, so it can support more than one open Mtik connection at a time, but for now it is purely function driven. I needed it in a hurry!

Please feel free to feed back comments, suggestions, bug reports or light bulb jokes. Also feel free to modify, redistribute and generally do what you will with the code.

Share And Enjoy.

-- hugh

edit:
some other user added SSL functionality to this code. You can see it here (on this thread):
http://forum.mikrotik.com/viewtopic.php ... 84#p457584
You do not have the required permissions to view the files attached to this post.
Last edited by cheesegrits on Wed Mar 26, 2008 11:12 pm, edited 1 time in total.
 
cheesegrits
just joined
Topic Author
Posts: 16
Joined: Fri Jun 01, 2007 11:17 pm

Re: perl API client

Tue Mar 25, 2008 8:46 pm

I think I've tracked down the reason it hangs occasionally on the socket recv. A misunderstanding on my part on how recv works with regards to specified read lengths.

I'm testing the new version, I'll post it when I'm sure it's fixed.

-- hugh
 
cheesegrits
just joined
Topic Author
Posts: 16
Joined: Fri Jun 01, 2007 11:17 pm

Re: perl API client

Wed Mar 26, 2008 11:13 pm

New version uploaded. Bug described in previous post is fixed.

-- hugh
 
gacopl
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Sun Jul 29, 2007 5:11 pm
Location: Poland

Re: perl API client

Fri Apr 18, 2008 10:57 am

Hello

Thank you for doing this wrap for perl, however i cannot get it to run it gives me no socket: Connection refused :/

Please help

Michal
 
gacopl
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Sun Jul 29, 2007 5:11 pm
Location: Poland

Re: perl API client

Fri Apr 18, 2008 11:28 am

ok i solved i had to enable api service on MT

B/R
Michal
 
adamx
just joined
Posts: 1
Joined: Tue Jun 12, 2007 8:46 am

Re: perl API client

Thu May 01, 2008 12:54 pm

Much appreciated. I'll have some additional contributions to this soon.
 
cheesegrits
just joined
Topic Author
Posts: 16
Joined: Fri Jun 01, 2007 11:17 pm

Re: perl API client

Fri May 09, 2008 10:23 pm

Glad it helps you out.

I've now built a fairly comprehensive provisioning system for our Mtik based wireless networks using it, and so far haven't had to update the main mtik_api.pl core.

If you feel adventurous, feel free to turn it into an actual package ... :)

-- hugh
 
ran_talbott
just joined
Posts: 2
Joined: Thu Apr 10, 2008 6:51 pm

Re: perl API client and non-keyword operands

Tue May 20, 2008 2:54 pm

Hugh,

Thanks for making this available: it has been a big help.

One mistake I made that other people who want to use it should avoid is the assumption that you can use the "talk" function just like you would a telnet connection. E.g., I tried something like:
@cmd = ("/category/command", "keyword1=value1", "keyword2=value2");
($rc, @response) = Mtik::talk(\@cmd);
Mtik::talk works fine for commands with no operands, but, if you're sending a command with keyword-based operands, you need to use the "mtik_cmd" function, and supply the operands in a hash, like the main loop in the example does. I think this is because mtik_cmd is doing the special formatting (like adding a leading "=" to operands) that's different between the terminal interface and the API.

The problem I'm having right now, though, is that I'm using the API to fiddle the firewall tables to provide temporary access to certain servers for users who've logged in through a web interface. I can add entries okay, now that I'm using mtik_cmd. But, when I try to remove entries with:
    my @cmd = ("/ip/firewall/filter/remove", "$rowno");
    my($retval,@results) = Mtik::talk(\@cmd);

The debug output says that the code is sending the command and operand, and I get a "!done" response. But the command doesn't remove the entry.

I'd kinda like to find out why this doesn't work, for future reference. Has anyone worked out a general-purpose method for sending commands with positional parameters?

Meanwhile, I found a hint in another posting that enabled me to make it work. It was about another command that takes a "row number" as a positional parameter in the telnet interface. In the API, the row is identified using the ".id" value passed back when listing the table (notthe row number that you'd use in the telnet interface), and a keyword of "numbers".

I have a function that uses the "talk" function to build an array of hashes containing the current firewall table, and another that will find the entry to be deleted. So the code to remove an entry looks like this:
# Remove a camera/IPA pair from the firewall list.
# Returns 0 if it was removed, or a negative number if it wasn't.
# Inputs:
#		The camera resource name (which is also used as the name of
#			its chain in the firewall)
#		The source (i.e.,  user's) IP address
sub mtik_access_remove
{
    my($chain) = shift;
    my($ipa) = shift;

		# First see whether it's already in the list
    my($rc, @firewall) = mtik_get_firewall;
	if ($rc) {
		return $rc;
		}
	my($rowno) = mtik_find_entry_in_firewall(\@firewall, $chain, $ipa);
	if ($rowno < 0) {
		print "IPA $ipa not found in chain $chain\n";
		return -1;
		}
    	# It's there, so try to remove it
#	my @cmd = ("/ip", "firewall", "filter", "remove", "$rowno");
    my %operands;
	$operands{'numbers'} = $firewall[$rowno]{".id"};
	my($retval,@results) = Mtik::mtik_cmd("/ip/firewall/filter/remove", \%operands);
	if ($retval != 1) {
		print "removal of IPA $ipa from $chain failed. RC = $retval\n$Mtik::error_msg\n";
		return $retval;
		}

	return 0;
}
[code]

Note the way I test $retval for a value of 1 (instead of 0) for "success".  I translate it to 0 for code calling my functions,  since I'm used to the convention of "0 for success,  non-zero for failure".

Thanks again for sharing.  I hope others find this record of my mistakes useful in avoiding repeating them.

Ran
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Tue May 27, 2008 4:10 pm

use .id to remove entries, in this case, do print and get a list of rules with .id numbers, then parse the result and get what rules you want to remove.

also when you add a rule, you get the .id number of the rule, so if in the same session you want to remove the rule you can use returned .id number of the rule to remove it in the end
 
User avatar
normis
MikroTik Support
MikroTik Support
Posts: 26912
Joined: Fri May 28, 2004 11:04 am
Location: Riga, Latvia
Contact:

Re: perl API client

Mon Jun 02, 2008 8:41 am

To cheesegrits: If you will add this info to the wiki, I will give you a free RouterOS license!
 
cfernandes_io
just joined
Posts: 2
Joined: Fri May 30, 2008 5:22 pm

Re: perl API client

Tue Jun 03, 2008 12:30 am

is possible to get a queue simple rate ?
 
k3dt
newbie
Posts: 29
Joined: Tue Jul 17, 2007 3:37 pm
Location: Czech Republic

Re: perl API client

Fri Jun 06, 2008 6:28 pm

Thank you very much for this scripts! Btw can somebody make php class for MT api?
 
lagosta
just joined
Posts: 21
Joined: Sun May 11, 2008 10:02 pm

Re: perl API client

Wed Jul 09, 2008 1:02 am

Where should i put the pm file?
I'm running a kubuntu 7.10 distro.
 
gacopl
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Sun Jul 29, 2007 5:11 pm
Location: Poland

Re: perl API client

Tue Aug 26, 2008 1:56 am

use .id to remove entries, in this case, do print and get a list of rules with .id numbers, then parse the result and get what rules you want to remove.

also when you add a rule, you get the .id number of the rule, so if in the same session you want to remove the rule you can use returned .id number of the rule to remove it in the end

yes try to filter out a table of 1000 firewall rules, another 1000 of queues and another one of mangles, 1st your MT must be really fast, same as the machine you're running this script. It takes ages otherwise.

Also i checked, that id that you get returned when you add a rule, persist the same even after reboot, it only changes when you of course remove it ;). So if your doing some script for handling qos etc. It is good to keep those id's on some database such as Mysql then you just refer to id's you need, instead of parsing of hundreds of lines. besides that even if you have fast machines, such huge comunication (printing 5000 rules, and all ACKs in comunication) takes a lot of bandwidth. I'm doing such a database, and i always have at my hand script that when something goes wrong just does it in oldstyle way, removes all rules and add them again.

BTW. I saw that in ROUTEROS 3.13 something has changed becuase, usually my script worked but in this version the communication seems to be unregular, it looses some rules (in debug it shows "traped" instead of done). It runs smoothly on 3.10. There had to be some change. This what makes me always nervous at RouterOS, unpredictable changes.... that are not presented in changelog.

B/R

Michal

BTW thx a lot for this perl wrap!!!
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Mon Sep 01, 2008 3:21 pm

would be nice if you wrote what exactly is failing, and how large outputs you are getting.
 
gacopl
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Sun Jul 29, 2007 5:11 pm
Location: Poland

Re: perl API client

Tue Dec 23, 2008 12:01 am

okay i've made an effort and debugged it, it seems that api dosen't accept src-port=445-65535, in fact it doesn't accept any range of ports for dst-port and src-port, this happens in ROS 3.11 and above... if I hashout directives with port-ranges my script works fine...

now it's your turn to fix or guide me how to overcome this ;)

B/R
Michal
 
gacopl
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Sun Jul 29, 2007 5:11 pm
Location: Poland

Re: perl API client

Tue Dec 23, 2008 12:13 am

okay i have to give you back your honor, the problem was that MT got smarter in newer versions and can accept port ranges only for tcp and udp as far as i recall, and not giving parameter of protocol=tcp was the cause... and as far as i recall you mentioned this new behavior in changelog, soo I APOLOGIZE.

you never know how much frustating administrating can be ... ;)

merry christmas
 
gacopl
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Sun Jul 29, 2007 5:11 pm
Location: Poland

Re: perl API client

Tue Dec 23, 2008 12:56 am

NO, unfortunately i was assuming things too quickly, i was right it itsn't accepting port ranges correctly:

root@ns1:/etc/lms# ./mtik_tty.pl -m 10.255.0.2 -u admin -p xxxxx
<<< /ip/firewall/mangle/add
<<< =chain=forward
<<< =protocol=tcp
<<< =src-port=445-460
<<<
>>> !trap
>>> =category=1
>>> =message=invalid value for argument range

like i said logging into 3.10 this works flawlessly, and in my script i have protocol=tcp directive so everything is fine from my side

B/R
Michal
 
gacopl
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Sun Jul 29, 2007 5:11 pm
Location: Poland

Re: perl API client

Fri Jan 30, 2009 4:55 pm

again it's not surprise to not get an answer here

shall i forward this to support?
 
dada
Member Candidate
Member Candidate
Posts: 245
Joined: Tue Feb 21, 2006 1:44 pm

Re: perl API client

Mon Feb 23, 2009 1:32 pm

[New version uploaded 3/26/2008. Fixed a bug which caused command output to hang sometimes, and added simple command line client]

Attached should be a ZIP with three files:

Mtik.pm - a simple perl client for the Mtik API. Pretty much a perl port of the python client from the Wiki, with an extra routine or two for formatting the returned data.

mtik_api_example.pl - an example of how to use the API. Provides some useful wireless ACL control routines. I've included enough comments so you should be able to work out how it all hangs together.

mtik_tty.pl - a simple command line client for testing API commands with. Use -h switch for usage info.

This code is very much a first cut. I intend to make the Mtik.pm stuff object oriented, so it can support more than one open Mtik connection at a time, but for now it is purely function driven. I needed it in a hurry!

Please feel free to feed back comments, suggestions, bug reports or light bulb jokes. Also feel free to modify, redistribute and generally do what you will with the code.

Share And Enjoy.

-- hugh
Thanks for the code - but I would like to write that the read_len() function in mtapi.pl is completely wrong. For one byte lengths it works (but only by accident - the initial IF statement is not correct).

- the bitwise negation operator is not "!" but "~". If you use ! all nonzero values are repleced by zero and zero is replaced by 1
- bitwise AND has lower precedence than comparation (==). In original code two constants were compared and the result (mostly zero) was anded with $len
- you have to read the subsequent bytes of block length using recv() not recursivelly calling read_len() again

This is the code which works for one and two byte lengths. I tried to correct others too but no checks/tests were made for them.

sub readbyte {
my $line;
$sock->recv($line,1);
if ($debug > 4)
{
printf "readbyte:received: %x\n",ord($line);
}
return ord($line);
};

sub read_len {
if ($debug > 4)
{
print "start read_len\n";
}
my $line;
my $len = readbyte();
if (($len & 0x80) == 0x00)
{
return $len;
}
elsif (($len & 0xC0) == 0x80)
{
$len &= ~0xC0;
$len <<= 8;
$len += readbyte();
}
elsif (($len & 0xE0) == 0xC0)
{
$len &= ~0xE0;
$len <<= 8;
$len += readbyte();
$len <<=8;
$len += readbyte();
}
elsif (($len & 0xF0) == 0xE0)
{
$len &= ~0xF0;
$len <<= 8;
$len += readbyte();
$len <<=8;
$len += readbyte();
$len <<=8;
$len += readbyte();
}
elsif (($len & 0xF8) == 0xF0)
{
$len = readbyte();
$len <<= 8;
$len += readbyte();
$len <<=8;
$len += readbyte();
$len <<=8;
$len += readbyte();
}
if ($debug > 4)
{
print "read_len got $len\n";
}
return $len;
}

Regards
Dalibor Toman
 
nodeny
just joined
Posts: 4
Joined: Sun May 03, 2009 4:06 am

Re: perl API client

Sun May 03, 2009 4:22 am

cheesegrits did you tested len>=0x200000?

I think
print $sock chr(($len >> 8) & 0xFF);
print $sock chr(($len >> 8) & 0xFF);
print $sock chr(($len >> 8) & 0xFF);
...
will print one value. Maybe you mean
print $sock chr(($len >> 24) & 0xFF);
print $sock chr(($len >> 16) & 0xFF);
print $sock chr(($len >> 8) & 0xFF);
yeah?

Then I read wiki.mikrotik.com/wiki/API:
len >= 0x10000000
0xF0 and len as four bytes
so your code is
 elsif ($len < 0x10000000)
    {
        $len |= 0xE0000000;
0xE0000000 != 0xF000000000

and better elsif ($len < 0x10000000) -> else

The formula is seems simple. My code:
$bytes=$len < 0x80? 1 : $len < 0x4000? 2 : $len < 0x200000? 3 : $len < 0x10000000? 4 : 5;
$len|=(0x0F >> (5-$bytes)) << ($bytes*8-$bytes+1);
while ($bytes--)
   {
    $str.=chr($len & 0xFF);
    $len>>=8;
   }
$str - rezult
 
nodeny
just joined
Posts: 4
Joined: Sun May 03, 2009 4:06 am

Re: perl API client

Sun May 03, 2009 4:27 am

I mean
elsif ($len < 0x10000000)
...
elsif ($len < 0x10000000)
2 Identical conditions
 
nodeny
just joined
Posts: 4
Joined: Sun May 03, 2009 4:06 am

Re: perl API client

Sun May 03, 2009 11:38 am

sub read_len
{
 my ($len,$c,$bytes);
 $sock->recv($c,1);
 $c=ord($c);
 $bytes=$c<0x80? 0 : $c<0xC0? 1 : $c<0xE0? 2 : $c<0xF0? 3 : 4;
 $len=$c & (0xFF >> $bytes);
 $bytes or return $len;
 while ($bytes--)
 { 
    $sock->recv($c,1);
    $len=($len << 8) + ord($c);
 }
 return $len;
}
 
nodeny
just joined
Posts: 4
Joined: Sun May 03, 2009 4:06 am

Re: perl API client

Wed May 06, 2009 12:03 pm

if ($word =~ /!done/)
{
    $retval = 1;
}
->
if ($word =~ /^!done/)
{
    $retval = 1;
}
imagine a reply like that:
=name=system!done
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Wed May 27, 2009 12:21 am

in API, you can use shortened value names, like in CLI; e.g.

/ip/route/print
=n=*1
=val=routing-mark

instead of

/ip/route/print
=numbers=*1
=value-name=routing-mark

isn't it a bit dangerous? maybe it should be forbidden, to avoid possible future problems? API is not CLI for humans...
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Mon Jun 01, 2009 11:07 am

users have to use full command/attribute names when writing API command. Shortened names will not be allowed in 3.25+ versions
 
User avatar
normis
MikroTik Support
MikroTik Support
Posts: 26912
Joined: Fri May 28, 2004 11:04 am
Location: Riga, Latvia
Contact:

Re: perl API client

Mon Jun 01, 2009 11:09 am

What's new in 3.25:

*) api - do not accept truncated property names;
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Mon Jun 01, 2009 11:31 am

coool =)
 
User avatar
normis
MikroTik Support
MikroTik Support
Posts: 26912
Joined: Fri May 28, 2004 11:04 am
Location: Riga, Latvia
Contact:

Re: perl API client

Mon Jun 01, 2009 11:33 am

yes, thank you very much for the report :) will you come to MUM in USA?
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Mon Jun 01, 2009 11:46 am

unfortunately, no - it's too expensive for me =(
I'll wait for the next MUM in Europe, CZ MUM was the best ))

during your MUM in USA I'll be looking for such issues with API here, in Minsk :D
 
Pikoro
Frequent Visitor
Frequent Visitor
Posts: 63
Joined: Fri Mar 14, 2008 10:43 am

Re: perl API client

Sat Jul 11, 2009 6:47 am

When are you guys going to have a MUM in Japan?
 
User avatar
ema
just joined
Posts: 21
Joined: Mon Apr 14, 2008 5:13 pm
Location: Poland, Warsaw

Re: perl API client

Wed Jul 15, 2009 11:58 am

This perl api need to be rewritten.
It has also errors in general getting answer where !done= !trap= !fatal,
-> sub talk and and sub read_sentence

I would like to thanks to the author.
All my networks works managed using API Perl + PHP.
api.perl gets statistics, signals, macs
ap.php manage users,queues

sub read_sentence {
    my ($word);
    my ($i) = 0;
    my (@reply);
    my($retval) = 0;
    my($done) = 0;
    # tu trzeba dopisać obsluga trap
    while ($word = &read_word())
    {
            if ($word =~ /^!done/)
            {
                $retval = 1;
                $done=1;
            }
            elsif ($word =~ /^!trap/)
            {
                $retval = 2;
            }
            elsif ($word =~ /^!fatal/)
            {
                $retval = 3;
            }
        $reply[$i++] = $word;
        if ($debug > 2)
        {
            print STDERR "MT: $word\n"
        }
    }
    return ($done,$retval,@reply);
}

######## PUBLIC FUNCTIONS ############

sub talk
{
    #my(@sentence) = shift;
    my($sentence_ref) = shift;
    my(@sentence) = @$sentence_ref;
    &write_sentence(\@sentence);
    my(@reply);
    my(@attrs);
    my($i) = 0;
    my($retval) = 0;
    my($done) = 0;
    while (($done,$retval,@reply) = &read_sentence())
    {
        foreach my $line (@reply)
        {
            if ($line =~ /^=(\S+)=(.*)/)
            {
                $attrs[$i]{$1} = $2;
            }
        }
        if ($retval > 0 && $done>0)
        {
            last;
        }
        
        $i++;
    }
    return ($retval, @attrs);
}

 
gumis78
just joined
Posts: 2
Joined: Thu Sep 17, 2009 2:23 pm

Re: perl API client

Thu Sep 17, 2009 2:30 pm

HELP ... i update all RB from 3.20 to 3.28 and some scripts in perl stops
settings parameters - OK
/interface/print - OK
/interface/wireless/accesslist/print - OK

but

/interface/wireless/registration-table/print - CRASH

what is wrong ??

help me ...
Krzys
 
User avatar
ema
just joined
Posts: 21
Joined: Mon Apr 14, 2008 5:13 pm
Location: Poland, Warsaw

Re: perl API client

Sun Sep 20, 2009 11:02 pm

How many client stations is connected to this mikrotik?
There is a bug which losts data when you try to get more then 1KB data.
Try to change first doanloaded perl api and apply all canges on forum site in this thread.
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Tue Sep 22, 2009 12:16 pm

if i remember correctly then first releases of Perl API lacked support for long responses. Do as ema said
 
gumis78
just joined
Posts: 2
Joined: Thu Sep 17, 2009 2:23 pm

Re: perl API client

Tue Sep 22, 2009 2:48 pm

How many client stations is connected to this mikrotik?
There is a bug which losts data when you try to get more then 1KB data.
Try to change first doanloaded perl api and apply all canges on forum site in this thread.

hmm .. many connected stations ... sometimes show 6 stations (maybe it is 1kB)

I try changed perl api but does't work fine - sometimes show 6 stations - sometimes crash
 
zlyZwierz
newbie
Posts: 33
Joined: Tue Jun 19, 2007 2:37 pm
Location: Poland

Re: perl API client

Tue Sep 22, 2009 5:00 pm

Maybe check mine perl API packege: http://zwierzu.zepsul.net/Mtik.pm.txt

sample code:
#!/usr/bin/perl

use strict;
use warnings;
use Mtik;
use Data::Dumper;


       my $mt = Mtik->new( host => 'host', user => 'admin', pass => 'pass');

        if ($mt->login()) {
            my $regtable_api = $mt->get_by_key('/interface/wireless/registration-table/print','=stats', 'mac-address');
            print Dumper $regtable_api;
        }

Works for me..
localhost sbin # perl dupa.pl

$VAR1 = {
          '00:15:6D:D0:0F:F5' => {
                                   'rx-ccq' => '17',
                                   'hw-frame-bytes' => '42100172,7240063',
                                   'packets' => '49461,38274',
                                   'nstreme' => 'false',
                                   'ack-timeout' => '28',
                                   'uptime' => '08:03:54',
                                   'interface' => 'wlan3',
                                   'last-activity' => '00:00:03.350',
                                   'frame-bytes' => '40615897,6306238',
                                   'mac-address' => '00:15:6D:D0:0F:F5',
                                   'framing-mode' => 'none',
                                   '802.1x-port-enabled' => 'true',
                                   'routeros-version' => '3.2',
                                   'ap' => 'false',
                                   'bytes' => '40910305,6535882',
                                   'signal-to-noise' => '34',
                                   'tx-ccq' => '97',
                                   'radio-name' => 'Motozbyt',
                                   'frames' => '49461,38274',
                                   'hw-frames' => '49738,38665',
                                   'tx-frames-timed-out' => '0',
                                   'compression' => 'false',
                                   'wmm-enabled' => 'false',
                                   'p-throughput' => '18146',
                                   'tx-signal-strength' => '-67',
                                   'wds' => 'false',
                                   'signal-strength' => '-70dBm@6Mbps',
                                   'comment' => '',
                                   '.id' => '*4',
                                   'rx-rate' => '12Mbps',
                                   'strength-at-rates' => '-70dBm@6Mbps 1s350ms,-70dBm@9Mbps 18s380ms,-71dBm@12Mbps 3s350ms,-71dBm@18Mbps 3m39s750ms,-72dBm@24Mbps 3m43s620ms',
                                   'tx-rate' => '24Mbps'
                                 },
 
grealish
just joined
Posts: 10
Joined: Tue Apr 07, 2009 6:43 pm

Re: perl API client

Tue Sep 29, 2009 11:38 am

Hi I've been playing around allot with the perl API client, and have been testing a few commands on the TTY wrapper, however I'm having trouble trying to enable a defined queue in the simple queues table
/queue/simple-table/print
#lists queues
>>> !re
>>> =.id=*2
>>> =name=limit-vlan3-tc
>>> =target-addresses=192.168.192.0/22
>>> =dst-address=0.0.0.0/0
>>> =interface=vlan3-192.168.192.0/22 VM TC
>>> =parent=none
>>> =direction=both
>>> =priority=8
>>> =queue=default-small/default-small
>>> =limit-at=0/0
>>> =max-limit=2M/2M
>>> =burst-limit=0/0
>>> =burst-threshold=0/0
>>> =burst-time=0s/0s
>>> =total-queue=default-small
>>> =bytes=0/0
>>> =total-bytes=0
>>> =packets=0/0
>>> =total-packets=0
>>> =dropped=0/0
>>> =total-dropped=0
>>> =rate=0/0
>>> =total-rate=0
>>> =packet-rate=0/0
>>> =total-packet-rate=0
>>> =queued-packets=0/0
>>> =total-queued-packets=0
>>> =queued-bytes=0/0
>>> =total-queued-bytes=0
>>> =lends=0/0
>>> =total-lends=0
>>> =borrows=0/0
>>> =total-borrows=0
>>> =pcq-queues=0/0
>>> =total-pcq-queues=0
>>> =disabled=true
>>> =invalid=false
>>> =dynamic=false
>>> !done
When I specify the =.id=*2 and then =disable=false it returns
>>> !done
<<<
>>> !trap
>>> =message=no such command prefix

And i'm unsure if i'm specifying this right
Thanks in advance
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Tue Sep 29, 2009 12:22 pm

/queue/simple-table ?..

what exact command do you try to set 'disabled' to false?..
 
grealish
just joined
Posts: 10
Joined: Tue Apr 07, 2009 6:43 pm

Re: perl API client

Tue Sep 29, 2009 12:31 pm

/queue/simple-table ?..

what exact command do you try to set 'disabled' to false?..
I have a list of simple queue's that I wish to be able to disable and enable from a perl script using the API,
/queue/simple-table/print will list the table of simple scripts, but my question is how do I enable the predefined scripts?
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Tue Sep 29, 2009 12:45 pm

at first, '/queue/simple-table/print' gets
no such command prefix
trap =) you should use '/queue/simple/print'

for enabling, use
/queue/simple/set
=.id=*2
=disabled=false
 
grealish
just joined
Posts: 10
Joined: Tue Apr 07, 2009 6:43 pm

Re: perl API client

Tue Sep 29, 2009 3:36 pm

at first, '/queue/simple-table/print' gets
no such command prefix
trap =) you should use '/queue/simple/print'

for enabling, use
/queue/simple/set
=.id=*2
=disabled=false
Cool Thanks, works now, however can I address the queue differently as in;
<<< /queue/simple/set
<<< =name=limit-vlan3-tc
<<< =disable=false
<<<
>>> !done
Basiclly i'm trying to setup a perl script that will enable a simple queue, then start the B/W server to create load on the link so I introduce latency on the link while I test an application communicating on a high latency link,
Is the API able to control the BW server settings as well?
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Tue Sep 29, 2009 4:08 pm

Cool Thanks, works now, however can I address the queue differently as in;
<<< /queue/simple/set
<<< =name=limit-vlan3-tc
<<< =disable=false
<<<
>>> !done
no, you should first find necessary item, then disable it by id. like this:
/queue/simple/print
=.proplist=.id
?name=limit-vlan3-tc
and then
/queue/simple/set
=.id=*here's_your_id
=disabled=false
Is the API able to control the BW server settings as well?
basically, API can do anything you can do with CLI =) all exceptions you can get to know only after you try to do something unusual =)
 
grealish
just joined
Posts: 10
Joined: Tue Apr 07, 2009 6:43 pm

Re: perl API client

Tue Sep 29, 2009 6:45 pm

thanks, so I do as is, however it returns idone?? is it not to return the .id? of the name I passed?
<<< /queue/simple/print
<<< =.proplist=.id
<<< ?name=limit-vlan3=tc
<<<
>>> !done
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Tue Sep 29, 2009 9:09 pm

checked with 3.28: when that name exists, the request returns the following:
!re=
=.id=*1
 
grealish
just joined
Posts: 10
Joined: Tue Apr 07, 2009 6:43 pm

Re: perl API client

Tue Sep 29, 2009 9:17 pm

checked with 3.28: when that name exists, the request returns the following:
!re=
=.id=*1
Got it :)
<<< /queue/simple/print
<<< =.proplist=.id
<<< ?name=limit-vlan3-tc
<<<
>>> !re
>>> =.id=*2
>>> !done
<<<
Will try now to implement this in a perl script

I believe you have to enter the tree structure with the /cancel followed by two CR/LF before it will reset the state of the API?
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Tue Sep 29, 2009 9:31 pm

state? what state?..
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Thu Oct 01, 2009 10:48 am

/cancel is for commands that are continuous, and other way would not end ever, like:
/ip/address/print
=interval=1
if you add .tag to continuous command then youcing /cancle with tag, you can cancel just this one command with the tag, and not all commands that are launched.

Also, API have no states, you send in commands and get responses. If you send more commands, you get more answers, if you run continuous command you will get answers all the time, but that does not mean you cannot send it more commands to get more responses.

Virtually speaking, if you want states then there are 2 that matter - you are either logged in (one state) or not (second state)
 
milanc
just joined
Posts: 8
Joined: Sat May 22, 2010 5:20 pm

Re: perl API client

Sun Aug 21, 2011 4:58 pm

Hi, i have problem.
Is possible get via api UPS status? Command is /system ups monitor 0 once

This is ok...
my $ret = $mt->get_by_key('/system/ups/print');
print Dumper($ret);

$VAR1 = {
          '*3' => {
                    'nominal-battery-voltage' => '24',
                    'disabled' => 'false',
                    'manufacture-date' => '08/06/99',
                    'serial' => '************',
                    'version' => '50.11.I',
                    'model' => 'SMART-UPS 700',
                    'name' => 'ups1',
                    'alarm-setting' => 'immediate',
                    'port' => 'serial0',
                    'min-runtime' => '5m',
                    'on-line' => 'true',
                    '.id' => '*3',
                    'offline-time' => '00:05:00',
                    'load' => '5',
                    'invalid' => 'false'
                  }
        };

my $ret = $mt->get_by_key('/system/ups/monitor','=0','=once');
print Dumper($ret);

$VAR1 = {};
what is wrong? Thanks for help.
Milan
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Mon Aug 22, 2011 1:22 pm

try
my $ret = $mt->get_by_key('/system/ups/monitor','=.id=*3','=once=');
 
milanc
just joined
Posts: 8
Joined: Sat May 22, 2010 5:20 pm

Re: perl API client

Tue Aug 23, 2011 3:43 am

It works, thank you very much. Just the following warning is written...
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
Use of uninitialized value in hash element at /usr/local/lib/perl5/site_perl/5.10.1/Mtik.pm line 414.
$VAR1 = {
          '' => {
                  'rtc-running' => 'false',
                  'battery-voltage' => '2760',
                  'smart-boost' => 'false',
                  'on-battery' => 'false',
                  'overload' => 'false',
                  'runtime-left' => '02:31:00',
                  'transfer-cause' => 'Line voltage notch or spike',
                  'smart-trim' => 'false',
                  'replace-battery' => 'false',
                  'frequency' => '50',
                  'line-voltage' => '24050',
                  'on-line' => 'true',
                  'low-battery' => 'false',
                  'load' => '5',
                  'output-voltage' => '24050',
                  'temperature' => '5620',
                  'battery-charge' => '100'
                }
        };
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Wed Aug 24, 2011 1:50 am

and what's on line 414? =)
 
milanc
just joined
Posts: 8
Joined: Sat May 22, 2010 5:20 pm

Re: perl API client

Sun Aug 28, 2011 4:29 am

Hi, is in function get_by_key
    foreach (@results) {
        my $item = $_;

        foreach my $result_key (keys (%$item)) {
            if (exists($item->{$key})) {
                if ($key eq $result_key) {
                    $result_hash->{ $item->{$key} } = $item
                }
            }
            else {
                $result_hash->{ $item->{'.id'} } = $item  <--- HERE
            }
        }
    }
Thanks.
 
nightsnake
just joined
Posts: 1
Joined: Thu Jun 28, 2012 1:28 pm

Re: perl API client

Thu Jun 28, 2012 1:33 pm

Hello!

Download this module, but it's don't connect to my RB:
>>> /login
start read_len
read_len got 5
recv 5
<<< !done
start read_len
read_len got 37
recv 37
<<< =ret=5d6f57de5c78f9305a19e17e11ff47cf
start read_len
read_len got 0
Use of uninitialized value in pack at Mtik.pm line 292.
>>> /login
>>> =name=admin
>>> =response=0088d75a26cd50e9304521a8b0bba09a85
start read_len
read_len got 5
recv 5
<<< !trap
start read_len
read_len got 22
recv 22
<<< =message=cannot log in
start read_len
read_len got 0
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Mon Jul 02, 2012 11:50 am

Hello!

Download this module, but it's don't connect to my RB:
is API service enabled?
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Tue Jul 03, 2012 1:54 am

is API service enabled?
seems like it is:
=ret=5d6f57de5c78f9305a19e17e11ff47cf
 
mmino7
just joined
Posts: 1
Joined: Tue Aug 07, 2012 10:56 pm

Re: perl API client

Wed Sep 12, 2012 8:51 pm

Hi all,

where can I find last release of perl API.

:)
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Fri Sep 14, 2012 4:19 pm

check the first post of this thread. Also, if you check

http://wiki.mikrotik.com/wiki/Manual:API

it has link where the code/binaries can be found
 
savage
Forum Guru
Forum Guru
Posts: 1265
Joined: Mon Oct 18, 2004 12:07 am
Location: Cape Town, South Africa
Contact:

Re: perl API client

Fri May 10, 2013 4:15 pm

Hi,

I currently use telnet to (rather frequently) fetch /ip firewall connection print count-only where src-address~"x.x.x.x:" assured

How would I be sending this via the API? I'm not having much success... :?
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Thu May 16, 2013 4:33 pm

unfortunately, there's no 'regexp' query in API, so you cannot do this

MT Staff, a little feature request: split that 'src-address' to 'src-address' and 'src-port', so it be possible to make queries to /ip firewall connections via API :) or maybe some additional query operators to match '*-address' not only by address part but also by IP subnet.
 
User avatar
noyo
Member Candidate
Member Candidate
Posts: 124
Joined: Sat Jan 28, 2012 12:25 am
Location: Mazury - Poland
Contact:

Re: perl API client

Wed Aug 14, 2013 11:40 pm

how to incorporate timeout? / how to set timeout? in script api mt perl
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Thu Aug 15, 2013 11:44 am

what timeout?
 
User avatar
noyo
Member Candidate
Member Candidate
Posts: 124
Joined: Sat Jan 28, 2012 12:25 am
Location: Mazury - Poland
Contact:

Re: perl API client

Thu Aug 15, 2013 11:49 am

Timeout when no response from mikrotik.

I worked it out.

edit Mtik.pm end:
my $sock = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => $port,
Proto => 'tcp',
Timeout => 3);
it works
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Tue Aug 27, 2013 4:05 pm

Trying to get source from a script hangs... Anyone help? I am trying to get/set script source content from the API. Not sure if it is possible.

This Hangs:

perl code

my (%attrs);
$attrs{'.proplist'} = ".id,name,source";
	
my (%queries);
$queries{'name'} = "MyScript";

my($retval,@results) = Mtik::mtik_query('/system/script/print',\%attrs,\%queries);

print Dumper(\@results);
This Doesn't:

perl code

my (%attrs);
$attrs{'.proplist'} = ".id,name";
	
my (%queries);
$queries{'name'} = "MyScript";

my($retval,@results) = Mtik::mtik_query('/system/script/print',\%attrs,\%queries);

print Dumper(\@results);

Added to Mtik.pm:

perl code

sub mtik_query
{
    my($cmd) = shift;
    my(%attrs) = %{(shift)};
	my(%queries) = %{(shift)};
    $error_msg = '';
    my(@command);
    push(@command,$cmd);
    foreach my $attr (keys (%attrs))
    {
        push(@command,'=' . $attr . '=' . $attrs{$attr});
    }
    foreach my $query (keys (%queries))
    {
        push(@command,'?' . $query . '=' . $queries{$query});
    }
    my($retval,@results) = talk(\@command);
    if ($retval > 1)
    {
        $error_msg = $results[0]{'message'};
    }
    return ($retval,@results);
}
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Tue Aug 27, 2013 4:15 pm

using python (3) client:
/system/script/print

<<< /system/script/print
<<< 
>>> !re
>>> =.id=*1
>>> =name=script1
>>> =owner=admin
>>> =policy=ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api
>>> =run-count=0
>>> =source=asdfasdfasdfsadf
>>> =invalid=false
>>> 
>>> !done
>>> 
source is just fast example of error:
asdfasdfasdfsadf

so this is language specific.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Tue Aug 27, 2013 4:24 pm

using python (3) client:
/system/script/print

<<< /system/script/print
<<< 
>>> !re
>>> =.id=*1
>>> =name=script1
>>> =owner=admin
>>> =policy=ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api
>>> =run-count=0
>>> =source=asdfasdfasdfsadf
>>> =invalid=false
>>> 
>>> !done
>>> 
source is just fast example of error:
asdfasdfasdfsadf

so this is language specific.

Yeah... I think I narrowed it down. I am pretty sure there is an error in the reading of the line length somewhere.... So yes.. it is library specific. Now if I could find the bug.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: perl API client

Tue Aug 27, 2013 4:36 pm

Yeah... I think I narrowed it down. I am pretty sure there is an error in the reading of the line length somewhere.... So yes.. it is library specific. Now if I could find the bug.
Given that most words are read fine, and only the last one is the problem, length decoding is probably not the issue.

It appers the real culprit may be the lack of socket buffering, which most API clients don't do. In the vast majority of cases, this is a problem only when you have large words, but if the speed of your connection to the router is low enough, you can experience it even with just a few bytes, as the case here. I think other than my client, there was only one other which did such buffering, but I don't remember which one it was... I think maybe Ruby, or ActionScript.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Tue Aug 27, 2013 4:42 pm

Yeah... I think I narrowed it down. I am pretty sure there is an error in the reading of the line length somewhere.... So yes.. it is library specific. Now if I could find the bug.
Given that most words are read fine, and only the last one is the problem, length decoding is probably not the issue.

It appers the real culprit may be the lack of socket buffering, which most API clients don't do. In the vast majority of cases, this is a problem only when you have large words, but if the speed of your connection to the router is low enough, you can experience it even with just a few bytes, as the case here. I think other than my client, there was only one other which did such buffering, but I don't remember which one it was... I think maybe Ruby, or ActionScript.
Interesting.... I wonder the best way to fix it. It is getting to the last word... reading part of it... reading "!do" then reads the length of the next word as "ne" and is trying to read 111 bytes... only finds 2 and fails.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: perl API client

Tue Aug 27, 2013 4:44 pm

It needs to be fixed in a generic fashion - the procedure that reads words needs to try read some data, then check out how much data it ACTUALLY received, and substract THAT from the length, and retry the remaining bytes.

What most clients do instead is that they read the length as, say "5 bytes", then they ask for 5 bytes, and assume they got what they asked for, when in fact, they got just 3 bytes.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Tue Aug 27, 2013 4:47 pm

It needs to be fixed in a generic fashion - the procedure that reads words needs to try read some data, then check out how much data it ACTUALLY received, and substract THAT from the length, and retry the remaining bytes.

What most clients do instead is that they read the length as, say "5 bytes", then they ask for 5 bytes, and assume they got what they asked for, when in fact, they got just 3 bytes.
It is theoretically doing that....
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: perl API client

Tue Aug 27, 2013 4:51 pm

i really doubt that he is running out of TCP buffers set by OS. Unless perl uses something different. And usually TCP buffer is enough.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: perl API client

Tue Aug 27, 2013 5:01 pm

i really doubt that he is running out of TCP buffers set by OS. Unless perl uses something different. And usually TCP buffer is enough.
It's not about "runinng out" per se, but about not addressing how OS socket functions work - i.e. them being unreliable in terms of fetching what you ask for. People look at receivers like "give me N bytes", when in fact, they work as "give me all you've got, even if it's just 1 byte... just don't give me more than N bytes".

But after looking at the source, it appears efaden is right, and the Perl client is actually THE very other client which does such buffering, and I failed to remember (I'm terrible... I apologize).

The problem then seems to be in the recursive read_len calls - if you have a two byte length such as "10000001 100000000", instead of being decoded as "00000001 100000000" (384), it will be read as a three byte length, with the start of the second byte indicating a third length byte, which can become even more problematic if the next byte also starts with "1". Eventually, the client will start demanding more bytes then actually exist, and will hang because it will keep retrying for bytes that ultimately will never come. The problem would occur if ANY word in the stream has such sort of a length, which in this case is likely one of the scripts' source.

Within read_len, replace all read_len calls with a simple ord($sock->recv($line,1)), and things should be back to normal.

P.S. It's times like this that make me ask why aren't projects like this on GitHub. I would've made a pull request about this already by now.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Tue Aug 27, 2013 5:40 pm

There was a bug in read_len... I thought I fixed it, but there is still a bug. Fixing it... or trying to.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: perl API client

Tue Aug 27, 2013 5:45 pm

There was a bug in read_len... I thought I fixed it, but there is still a bug. Fixing it... or trying to.
I saw the source for the brief time you posted it - do the "<<= 8" first, and THEN "+=" the new byte, not the other way around.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Tue Aug 27, 2013 6:23 pm

FIXED, Any length > 128 was reading incorrectly. Basically I modified it to mirror the Python code. There were several issues. It works now.

See the next post for the updated PM file.
Last edited by efaden on Tue Aug 27, 2013 9:59 pm, edited 1 time in total.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Tue Aug 27, 2013 9:31 pm

Updated a few things....

Added the timeout parameter, fixed write_len for lengths > 0x80, fixed read_len for lengths > 0x80, and fixed allowing of newlines in the read_sentence.

I am now able to read and write scripts... woot!

I think I got all of my debugging out of the pm file. Let me know if you see anything else.

-Eric
You do not have the required permissions to view the files attached to this post.
 
farnsworth78
just joined
Posts: 1
Joined: Fri Oct 18, 2013 6:52 am

Re: perl API client

Fri Oct 18, 2013 7:36 am

Updated a few things....

Added the timeout parameter, fixed write_len for lengths > 0x80, fixed read_len for lengths > 0x80, and fixed allowing of newlines in the read_sentence.

I am now able to read and write scripts... woot!

I think I got all of my debugging out of the pm file. Let me know if you see anything else.

-Eric
Can you add $sock->autoflush(0) ?
I wrote test program (it add 250 ips to address-list "using Mtik::mtik_cmd('/ip/firewall/address-list/add',\%attr);")
with $sock->autoflush(1) it takes ~60 sec .
with $sock->autoflush(0) it takes ~27 sec .

==== some changes
sub mtik_connect
{
my($host) = shift;
my($port) = shift || 8728;
if (!($host))
{
print "no host!\n";
return 0;
}
my($sock) = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => $port,
Proto => 'tcp');
if (!($sock))
{
print "no socket :$!\n";
return 0;
}
$sock->autoflush(0); #<---- ADD THIS LINE
return $sock;
}
sub write_sentence {
my($sentence_ref) = shift;
my(@sentence) = @$sentence_ref;
foreach my $word (@sentence)
{
write_word($word);
if ($debug > 2)
{
print ">>> $word\n";
}
}
write_word('');
$sock->flush(); #<---- ADD THIS LINE
}

How to add ips to address list at once (like "enable/disable/remove" do )?
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Fri Oct 18, 2013 1:18 pm

Updated a few things....

Added the timeout parameter, fixed write_len for lengths > 0x80, fixed read_len for lengths > 0x80, and fixed allowing of newlines in the read_sentence.

I am now able to read and write scripts... woot!

I think I got all of my debugging out of the pm file. Let me know if you see anything else.

-Eric
Can you add $sock->autoflush(0) ?
I wrote test program (it add 250 ips to address-list "using Mtik::mtik_cmd('/ip/firewall/address-list/add',\%attr);")
with $sock->autoflush(1) it takes ~60 sec .
with $sock->autoflush(0) it takes ~27 sec .

==== some changes
sub mtik_connect
{
my($host) = shift;
my($port) = shift || 8728;
if (!($host))
{
print "no host!\n";
return 0;
}
my($sock) = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => $port,
Proto => 'tcp');
if (!($sock))
{
print "no socket :$!\n";
return 0;
}
$sock->autoflush(0); #<---- ADD THIS LINE
return $sock;
}
sub write_sentence {
my($sentence_ref) = shift;
my(@sentence) = @$sentence_ref;
foreach my $word (@sentence)
{
write_word($word);
if ($debug > 2)
{
print ">>> $word\n";
}
}
write_word('');
$sock->flush(); #<---- ADD THIS LINE
}

How to add ips to address list at once (like "enable/disable/remove" do )?
Feel free to add it. I don't actually maintain the thing. I just went to use it and found a bunch of errors in it, so I fixed them.

As for adding multiple IPs.... I'm not sure you can.
 
dahili
just joined
Posts: 7
Joined: Sun Feb 06, 2011 5:15 pm

Re: perl API client

Sun Nov 10, 2013 10:21 pm

To cheesegrits: If you will add this info to the wiki, I will give you a free RouterOS license!
To normis: Dear friend i am looking some one who able to make perl or php basic gui for few commands for me i will pay works! my email : atilla.o.ersoz [at] gmail.com please get in touch with me
 
dahili
just joined
Posts: 7
Joined: Sun Feb 06, 2011 5:15 pm

Re: perl API client

Sun Nov 10, 2013 10:43 pm

in API, you can use shortened value names, like in CLI; e.g.

/ip/route/print
=n=*1
=val=routing-mark

instead of

/ip/route/print
=numbers=*1
=value-name=routing-mark

isn't it a bit dangerous? maybe it should be forbidden, to avoid possible future problems? API is not CLI for humans...
To forum guru i am looking some one who are able to do it perl or php little gui for me only few commands please recomend me some one my email is atilla.o.erso [at] gmail.com i am sorry for this message hire
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: perl API client

Sun Nov 10, 2013 11:41 pm

in API, you can use shortened value names, like in CLI; e.g.
Really? Since which version? Last I checked (right now, with 6.5), that's not the case, protocol wise at least.
To forum guru i am looking some one who are able to do it perl or php little gui for me only few commands please recomend me some one my email is atilla.o.erso [at] gmail.com i am sorry for this message hire
The next version of my client (in PHP, from my signature) will provide an interactive command line utility that you can type raw commands in. You can get the current state from its develop branch on GitHub if you can't wait for a tagged release (which is held up for a few reasons, one of which is that for the console, you need to also get the current untagged PEAR2_Console_CommandLine for it to work...).
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8712
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: perl API client

Wed Nov 20, 2013 4:10 pm

in API, you can use shortened value names, like in CLI; e.g.
Really? Since which version? Last I checked (right now, with 6.5), that's not the case, protocol wise at least.
it was 4,5 years ago ;) read the next message: "Shortened names will not be allowed in 3.25+ versions"
 
akschu
Frequent Visitor
Frequent Visitor
Posts: 59
Joined: Thu Mar 15, 2012 2:09 am

Re: perl API client

Sat Nov 22, 2014 12:54 am

This is a bit of a hack, but I needed something in perl so I extended this code to use ssl. Attached is the module.
You do not have the required permissions to view the files attached to this post.
 
User avatar
noyo
Member Candidate
Member Candidate
Posts: 124
Joined: Sat Jan 28, 2012 12:25 am
Location: Mazury - Poland
Contact:

Re: perl API client

Sat Jan 10, 2015 2:11 pm

Why if you accidentally give ssh port is a connection. Do not hang up just waiting for something.
Contribution to IO::Socket::INET Timeout but it does not work.
 
davestahr
just joined
Posts: 12
Joined: Wed May 04, 2011 3:33 pm

Re: perl API client

Sun Feb 15, 2015 7:26 pm

Updated a few things....
Thanks! This fixed a problem I've been having with perl API for years.
 
camlost
just joined
Posts: 9
Joined: Tue Feb 17, 2009 4:50 pm

Re: perl API client

Thu May 07, 2015 10:31 am

Finally found this repo on github

Unfortunately, it's based on original cheesegrits module, withoud efaden modifications, so I created pull-request.

Maybe, we finally can maintain and download fresh and bug-free module from github.
 
davestahr
just joined
Posts: 12
Joined: Wed May 04, 2011 3:33 pm

Re: perl API client

Thu May 07, 2015 2:48 pm

I know there's sometimes a financial nudge that can be given to people developing and maintaining open-source software. I'd like to offer that nudge to an individual or group who might be interested in further developing and refining this perl API. Anyone interested? I'm a perl programmer, but some of the API stuff is a bit beyond the scope of my talents.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Mon May 25, 2015 12:54 pm

What needs fixing? I'm still around. I'm happy to try to fix some bugs, especially if there is money involved.
 
davestahr
just joined
Posts: 12
Joined: Wed May 04, 2011 3:33 pm

Re: perl API client

Mon May 25, 2015 6:08 pm

Thanks for the reply, I'm glad to hear someone with more skills than me is around on here! It might not be anything more than poor implementation of code on my part, or perhaps the the information simply isn't available from the API, but I'm having difficulty getting some of the hardware stats from system->resources, such as uptime. I don't have time at the moment to go dig up what I can't see, but I'll look into it and post back here when I've got the time.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Mon May 25, 2015 7:11 pm

Let's set up a repository somewhere... Then make sure we get the latest code on there (that I fixed)... then I can start to work on it again.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: perl API client

Mon May 25, 2015 7:13 pm

Let's set up a repository somewhere... Then make sure we get the latest code on there (that I fixed)... then I can start to work on it again.
As camlost said above, there is a repo on GitHub, but without your modifications.

Maybe you could fork it, apply your mod, and keep maintaining it from that point (no PRs to the "original")?
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Mon May 25, 2015 8:35 pm

Set up a new repository with my changes in it... https://github.com/efaden/MikroTikPerl

Let me know if you want access.
 
akschu
Frequent Visitor
Frequent Visitor
Posts: 59
Joined: Thu Mar 15, 2012 2:09 am

Re: perl API client

Thu Aug 27, 2015 9:54 pm

I think the code that Efaden put on github is probably the best bet since it fixes the length issue, as well as gives us a place to track change, but it didn't have port or ssl support. I forked his code and added those featuers:

https://github.com/akschu/MikroTikPerl

Efaden, please consider merging my pull request.
 
User avatar
noyo
Member Candidate
Member Candidate
Posts: 124
Joined: Sat Jan 28, 2012 12:25 am
Location: Mazury - Poland
Contact:

Re: perl API client

Thu Aug 27, 2015 10:01 pm

I think the code that Efaden put on github is probably the best bet since it fixes the length issue, as well as gives us a place to track change, but it didn't have port or ssl support. I forked his code and added those featuers:

https://github.com/akschu/MikroTikPerl

Efaden, please consider merging my pull request.
I modified it because some things were missing. Also, I added ssl. This can be done simply by reviewing client @akschu.
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Thu Aug 27, 2015 11:25 pm

Merged. And added you as a collaborator.
 
camlost
just joined
Posts: 9
Joined: Tue Feb 17, 2009 4:50 pm

Re: perl API client

Mon Sep 28, 2015 4:27 pm

I have plans and time to add object-oriented interface to module and publish it in CPAN.

2 efaden:
Will you accept PR which implelents it?
 
marting
Member Candidate
Member Candidate
Posts: 172
Joined: Thu Aug 21, 2014 2:07 pm

Re: perl API client

Mon Dec 07, 2015 4:02 pm

Hi camlost,
did you make any progress and are you willing to share it?
I will have to do the same, the current version is nearly unusable in larger projects.
Regards
Martin
 
marting
Member Candidate
Member Candidate
Posts: 172
Joined: Thu Aug 21, 2014 2:07 pm

Re: perl API client

Wed Dec 09, 2015 8:07 pm

I reworked it to OO and published it at github. See http://forum.mikrotik.com/viewtopic.php?f=9&t=102923 for more details.
 
User avatar
hknet
Member Candidate
Member Candidate
Posts: 128
Joined: Sun Jul 17, 2016 6:05 pm
Location: Vienna, Austria
Contact:

Re: perl API client

Fri Aug 05, 2016 11:46 pm

well, I'm a bit lost, anyone knowing which perl API might be maintained?
it seems the later "MikroTik.pm" is no more working for scripts originally based on the "Mtik.pm" by Hugh.

our nagios checks use the older lib.

now I ran into a problem - I'm trying to implement something like:
/ip/route/print count where routing-mark=VRF
so we could alert if we loose routes or get a lot more than planned for :)

the printing works with our old-style Mtik.pm programming, but options like count and where?

any lead appreciated.

regards,
hk
 
efaden
Forum Guru
Forum Guru
Posts: 1708
Joined: Sat Mar 30, 2013 1:55 am
Location: New York, USA

Re: perl API client

Sat Aug 06, 2016 12:07 am

I haven't updated it in a while.... but

https://github.com/efaden/MikroTikPerl

was working last time I looked.
 
bbs2web
Member Candidate
Member Candidate
Posts: 234
Joined: Sun Apr 22, 2012 6:25 pm
Location: Johannesburg, South Africa
Contact:

Re: perl API client

Mon Jan 29, 2018 2:47 pm

Many thanks to all that have contributed to the MikroTik Perl API.

We previously used the ported OO version, as it had the nicest interface and was in CPAN (Comprehensive Perl Archive Network). We however needed to reduce overheads as the OO version utilises the Perl Moose library and subsequently retrieved the version the efaden posted and applied minimal changes from the OO ported version.

Perl OO version, in CPAN: https://metacpan.org/release/MikroTik-API
Latest patched version (efaden): https://github.com/efaden/MikroTikPerl

Herewith our version, which essentially makes minor changes to efaden's version:
API2.zip

Changes:
  • 3 second timeout on connections
  • specify whether or not you want SSL (efaden's would switch to SSL when port was 8729)
  • custom port specification (efaden's version couldn't use any port other than 8729 for SSL)
  • return '$retval' when not '!done', '!trap' or '!fatal'

Performance comparison:
  • OO version from CPAN (primarily due to it including the 'Moose' library):
    Total Elapsed Time = 2.998272 Seconds
      User+System Time = 0.508272 Seconds
  • efaden's version:
    Total Elapsed Time = 0.077465 Seconds
      User+System Time = 0.077465 Seconds

To install, create a directory such as '/usr/local/share/perl5/MikroTik' and place API2.pm in that directory. Then simply include 'use MikroTik::API2;' in your script.

For those converting from the OO version of the MikroTik API on CPAN to efaden's one, herewith a sample diff:
--- /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_old.pl      2017-04-04 05:53:43.547467546 +0200
+++ /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status.pl  2018-01-28 08:50:56.437834735 +0200
@@ -1,10 +1,11 @@
 #!/usr/bin/perl
 use strict;
 use warnings;
-use MikroTik::API;     # http://search.cpan.org/~martingo/MikroTik-API/lib/MikroTik/API/Examples.pm
+use MikroTik::API2;    # https://github.com/efaden/MikroTikPerl/blob/master/MikroTik.pm
 use Fcntl qw(:flock);
 use Storable qw(lock_store lock_nstore lock_retrieve);

+my $use_ssl = 1;
 my ($router, $api_user, $api_passwd, $command, $peer, $key) = @ARGV;
 if (not defined $router) { print STDERR "Need router FQDN or IP, as first parameter.\n"; exit 3 };
 if (not defined $api_user) { print STDERR "Need MikroTik API username, as second parameter.\n"; exit 4 };
@@ -25,16 +26,6 @@
   return ($years*31536000)+($weeks*604800)+($days*86400)+($hours*3600)+($minutes*60)+$seconds;
 }

-my $api = MikroTik::API->new (
-  {
-    host        => $router,
-    username    => $api_user,
-    password    => $api_passwd,
-    use_ssl     => 1,
-    autoconnect => 0,
-  }
-);
-
 my %bgp_peer;
 my $cached = 0;
 my $modified = (stat($cachefile))[9];
@@ -46,10 +37,9 @@
 }
 if ($cached == 0) {
   if (!flock $lockfile, LOCK_EX | LOCK_NB) { print STDERR "Another process is already using MikroTik API.\n"; exit 6 };
-  $api->connect();
-  $api->login();
-  %bgp_peer = $api->get_by_key('/routing/bgp/peer/print', 'name');
-  $api->logout();
+  MikroTik::login($router, $api_user, $api_passwd, $use_ssl);
+  %bgp_peer = MikroTik::get_by_key('/routing/bgp/peer/print', 'name');
+  MikroTik::logout;
   lock_nstore \%bgp_peer, $cachefile;
   chmod 0660, $cachefile;
   flock $lockfile, LOCK_UN;
You do not have the required permissions to view the files attached to this post.
 
bbs2web
Member Candidate
Member Candidate
Posts: 234
Joined: Sun Apr 22, 2012 6:25 pm
Location: Johannesburg, South Africa
Contact:

Re: perl API client

Tue Jan 30, 2018 10:29 pm

The following is however again much faster:
real    0m0.003s
user    0m0.003s
sys     0m0.001s

An improvement of over 7700%.

We work around Perl's compilation overheads:
  • Convert script to TCP server which compiles once, listens on port 7890 and then forks children
  • Replace existing script with simple netcat wrapper:
    [root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -d; echo $?
    {
            "data": [
                    { "{#BGPPEER}": "iOnline" }
            ]
    }
    0
    [root@zabbix ~]# cat /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh
    #!/bin/sh
    echo "'$1'" "'$2'" "'$3'" "'$4'" "'$5'" "'$6'" | /usr/bin/nc -w 3 127.0.0.1 7890;
    exit $?;


Changes to convert script itself to a standalone tcp server:
  • Alter all print statements (eg 'print', 'print STDERR', and 'printf') to output to '$client'
    -print STDERR "Another ...
    +print $client "Another ...
    -printf ("%-25.25s ...
    +printf $client ("%-25.25s ...
    
  • Encapsulate script's previous main section by starting with the following subroutine definition and appending '}'. These changes result in the tcp server reading up to 250 characters worth of commands, instead of them being supplied directly as script arguments:
    sub handle_client {
      my $client = shift;
      my $msg;
      $client->recv($msg, 250);
      my ($router, $api_user, $api_passwd, $command, $peer, $key) = quotewords('\s+', 0, $msg);
      #my ($router, $api_user, $api_passwd, $command, $peer, $key) = @ARGV;
  • New main body listens for tcp connections on port 7890 on the loopback adapter and forks child for each connection:
    use IO::Socket::INET;
    use Text::ParseWords;
    
    $SIG{CHLD} = 'IGNORE';
    STDOUT->autoflush(1);
    my $server = IO::Socket::INET->new(
      LocalAddr => '127.0.0.1',
      LocalPort => '7890',
      Listen    => SOMAXCONN,
      Type      => SOCK_STREAM,
      Reuse     => 1) or die "could not open port: $!";
    while (my $client = $server->accept) {
      next if my $pid = fork;
      die "fork: $!" unless defined $pid;
      $client->autoflush(1);
      close $server;
      handle_client($client);
    } continue {
      close $client;
    }
    


mikrotik-api-bgp-status.zip
Contains:
  • init.d launch script for tcp server
  • perl tcp server which listens on port 7890 and connects to MikroTik using API to retrieve BGP peer status information. Information is cached for 55 seconds so speed up subsequent queries
  • client app which is really simply a netcat wrapper

Available commands:
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd'
Missing or invalid command. Usage /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh <router> <api username> <api password> <command> [<peer>] :
  -d|--discover         Zabbix LLD (low level discovery). In JSON format.
  -c|--croak            Dumps all available data. Usable as $bgp_peer{'$peer'}->{'key'}
  -t|--table            Displays tabled overview
  -g|--get <peer> <key> example: -g "Syrex - Primary" state

  Examples:
    Discovery   : /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms "FakeP@ssw0rd" -d
    Sample      : {
                    "data": [
                      { "{#BGPPEER}": "Syrex - Primary" },
                      { "{#BGPPEER}": "Syrex - Secondary" }
                    ]
                  }

    Get item    : /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms "FakeP@ssw0rd" "Syrex - Primary" state
    Sample      : established

Zabbix low level item discovery:
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -d
{
        "data": [
                { "{#BGPPEER}": "iOnline" }
        ]
}

Tabled output:
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -t
Peer                      Active   Prefixes       Remote IP Remote AS             Uptime State
iOnline                   yes             2     172.18.0.17    327909       4w1d12h20m3s established

Dump all values (croak):
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -c
peer: iOnline

=
  .id=*0
  address-families=ip
  as-override=false
  as4-capability=true
  default-originate=if-installed
  disabled=false
  established=true
  hold-time=3m
  in-filter=ionline-in
  instance=mpls
  local-address=172.18.0.20
  multihop=false
  name=iOnline
  nexthop-choice=default
  out-filter=ionline-out
  passive=false
  prefix-count=2
  refresh-capability=true
  remote-address=172.18.0.17
  remote-as=329709
  remote-hold-time=3m
  remote-id=145.23.110.26
  remove-private-as=false
  route-reflect=false
  state=established
  tcp-md5-key=secret123
  ttl=default
  updates-received=6
  updates-sent=1
  uptime=4w1d12h21m3s
  use-bfd=false
  used-hold-time=3m
  used-keepalive-time=1m
  withdrawn-received=0
  withdrawn-sent=0

Retrieve specific item value (uptime in MikroTik format is converted to uptime seconds):
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -g iOnline uptime
2550183


Sample BGP peer uptime graph:
zabbix_bgp_uptime_sample.jpg
Sample BGP prefix activity graph:
zabbix_bgp_activity_sample.jpg
Sample BGP status graph:
zabbix_bgp_status_sample.jpg
You do not have the required permissions to view the files attached to this post.
 
rafaelbarboza
just joined
Posts: 1
Joined: Thu Oct 19, 2017 7:24 pm

Re: perl API client

Thu Apr 12, 2018 3:14 pm

@bbs2web, thank you!

It's possible to share this Zabbix Template for use?
 
savage
Forum Guru
Forum Guru
Posts: 1265
Joined: Mon Oct 18, 2004 12:07 am
Location: Cape Town, South Africa
Contact:

Re: perl API client

Thu Oct 31, 2019 10:16 am

Can we get these libs updated please?

They no longer work after the recent changes made by Mikrotik.
 
useopenid
just joined
Posts: 12
Joined: Mon Oct 04, 2010 12:02 am

Re: perl API client

Thu Mar 05, 2020 12:49 am

According to the docs, the challenge/response login mechanism is no longer available after 6.45.1, however, 6.45.8 returns a challenge after sending the new username/password style parameters, and sending the md5 response results in "invalid username or password". Given that the connection is not encrypted, deprecating the challenge/response login is unfortunate.
 
Longsdale
just joined
Posts: 6
Joined: Thu Jan 02, 2020 8:19 am

Re: perl API client

Thu Mar 05, 2020 3:08 am

According to the docs, the challenge/response login mechanism is no longer available after 6.45.1, however, 6.45.8 returns a challenge after sending the new username/password style parameters, and sending the md5 response results in "invalid username or password". Given that the connection is not encrypted, deprecating the challenge/response login is unfortunate.
The legacy challenge-response authentication is not a measure of good protection. You can set the router to encrypt the connection.
 
useopenid
just joined
Posts: 12
Joined: Mon Oct 04, 2010 12:02 am

Re: perl API client

Thu Mar 05, 2020 3:18 am

OK, that's good to hear, now if the plain login actually worked...
 
abatie
just joined
Posts: 23
Joined: Sat Feb 20, 2016 2:17 am

Re: perl API client

Fri Mar 06, 2020 2:36 am

Never mind, I found a bug in the parameters I was passing...
 
User avatar
webasdf
Frequent Visitor
Frequent Visitor
Posts: 87
Joined: Mon Jan 26, 2009 6:37 pm

Re: perl API client

Tue Mar 02, 2021 9:57 pm

Not sure if anyone needs this or if it's already been done, but I fixed it.

https://pastebin.com/fUSxZkC3
 
bbs2web
Member Candidate
Member Candidate
Posts: 234
Joined: Sun Apr 22, 2012 6:25 pm
Location: Johannesburg, South Africa
Contact:

Re: perl API client

Tue Oct 11, 2022 3:44 pm

Just some information for anyone that comes across this, after upgrading our Zabbix server and subsequently updating to the latest perl MikroTik API (v2.0.1) available here:
https://metacpan.org/pod/MikroTik::API

We utilise API-SSL but do not deploy certificates to all monitored routers, using anonymous ciphers to secure the connections. Debian 11 ships with SECLEVEL=2 which prevents these connections from establishing, validated via openssl client on the CLI:
[admin@zabbix ~]# openssl s_client -host router1.domain.com -port 8729
CONNECTED(00000003)
140139476116800:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1543:SSL alert number 40
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 317 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

Solution is to allow the client to use SECLEVEL=0, which then allows anonymous ciphers, whilst still encrypting the connection. This does not offer verification of any kind so deploying certificates is still highly recommended!

Herewith a subsequent test where one can validate that the connection negotiates TLS v1.2 by allowing anonymous ciphers:
[admin@zabbix ~]# openssl s_client -host router1.domain.com -port 8729 -cipher HIGH:@SECLEVEL=0
CONNECTED(00000003)
---
no peer certificate available
---
No client certificate CA names sent
Server Temp Key: DH, 2048 bits
---
SSL handshake has read 853 bytes and written 753 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ADH-AES256-GCM-SHA384
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ADH-AES256-GCM-SHA384
    Session-ID: 935F72E228A4CEA71F519C4F3B9A55F75E027483F0992538D2ACB0CB64038438
    Session-ID-ctx:
    Master-Key: 273B26E476DDA0E4ADCD85816518118256EC129D742640433553F92C0F6D867AD362BACC90625284A1B6181CE0C737F0
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 37 d0 be 7a e1 80 57 0f-bb 39 35 a4 88 ad c9 1a   7..z..W..95.....
    0010 - 96 4c 04 98 44 23 11 92-28 53 56 47 a5 69 d4 d7   .L..D#..(SVG.i..
    0020 - b3 e4 f5 c7 f8 e4 9b 4f-2b 0b 30 c0 83 0a e5 75   .......O+.0....u
    0030 - dc aa 74 7a 2c d3 c9 dd-57 67 47 3c 8b a9 09 86   ..tz,...WgG<....
    0040 - 41 b3 56 50 33 25 51 fa-a9 a8 97 b8 e5 1c 4c 42   A.VP3%Q.......LB
    0050 - 30 fb 7b 9b 09 5b 52 4c-53 a8 9f 45 9b 55 32 ea   0.{..[RLS..E.U2.
    0060 - da 4a 51 d6 02 bb d0 b8-9e d2 45 b5 b1 e8 28 07   .JQ.......E...(.
    0070 - ac 77 e3 65 cb af c9 67-57 a8 57 db 07 55 5c 8e   .w.e...gW.W..U\.
    0080 - 17 5a e2 76 b7 7a a4 b6-b4 97 03 e9 d1 69 83 e4   .Z.v.z.......i..
    0090 - c2 64 87 54 86 e7 d2 b7-fc 97 56 3d 3d 40 8d 65   .d.T......V==@.e
    00a0 - 35 19 9a da a1 10 94 dd-e6 8a 25 42 cb 7c 02 95   5.........%B.|..
    00b0 - 7b d3 fb d0 a6 21 3b 74-5c 01 3b 9c ae 1a e6 60   {....!;t\.;....`

    Start Time: 1665492017
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

Herewith the code change to the API.pm perl library, to allow 'anonymous API-SSL':
[admin@zabbix ~]# diff -uNr /usr/share/perl5/MikroTik/API.pm_v2.0.1.orig /usr/share/perl5/MikroTik/API.pm
--- /usr/share/perl5/MikroTik/API.pm_v2.0.1.orig        2022-10-10 21:35:36.261712950 +0200
+++ /usr/share/perl5/MikroTik/API.pm    2022-10-10 23:09:32.948755784 +0200
@@ -110,7 +110,7 @@
                     PeerHost        => $self->get_host,
                     PeerPort        => $self->get_port,
                     Proto           => 'tcp',
-                    SSL_cipher_list => 'HIGH',
+                    SSL_cipher_list => 'HIGH:@SECLEVEL=0',
                     SSL_verify_mode => $self->get_ssl_verify(),
                     Timeout         => $self->get_timeout,
                 );
                 

Who is online

Users browsing this forum: ohilton576 and 6 guests