Mikrotik -> PHP

I get this error:

Connection attempt #1 to 123.123.123.123:8728… <<< [6] /login >>> [5/5 bytes read. >>> [5, 39] !done >>> [37/37 bytes read. >>> [37, 1] =ret=a58048c26a26d61fde722fce4750f34f <<< [6] /login <<< [11] =name=admin <<< [44] =response=00b54e6533572cc9a3992c023e24fddfd8 >>> [5/5 bytes read. >>> [5, 1] !done Connected… <<< [24] /ip/firewall/filter/edit <<< [10] =.id=00001 <<< [26] =src-address=12.34.12.34 <<< [17] =src-mac-address= >>> [5/5 bytes read. >>> [5, 35] !trap >>> [26/26 bytes read. >>> [26, 8] =message=unknown parameter >>> [5/5 bytes read. >>> [5, 1] !done Array ( [!trap] => Array ( [0] => Array ( [message] => unknown parameter ) ) ) Disconnected…

I cant understand what is mistake

<<< [10] =.id=00001

this is the problem. attribute .id value is hexadecimal number without leading zeros prefixed with *

for example =.id=*BEEF

that is the problem why you cannot do what you require.

I understand that I need hex, but I do not know hex coding,

ex. I want need to edit user 1234
What can I make?

$API->write('/ip/firewall/filter/edit',false);
$API->write("=.id=1234",false);
$API->write("=src-address=$ip",false);
$API->write("=src-mac-address=$mac");

Thank you

There’s PHP’s dechex() function to help you out with this. Just remember to prefix the number with a *, i.e.

$API->write('/ip/firewall/filter/edit',false);
$API->write("=.id=*" . dechex(1234), false);
$API->write("=src-address=$ip",false);
$API->write("=src-mac-address=$mac"); 

However, the hex IDs are not necesarily the same decimal IDs you see in Winbox’s “#” column. If you don’t have some other sort of a unique identifier, you’ll have to first print all entries, and then hardcode the ID you wish to edit. If you do have some sort of a unique identifier (e.g. if the full properties of the filter have their old values only in that one rule), you can print the ID of that directly as you’re about to edit it.

That last one is done much easier with my client than with this one, but it’s completely doable with this one too.

BTW, on a side note… have you considered using address lists instead of creating actual rules? You can have one rule for enabled users, and perhaps one for disabled users. For MAC address protection, there’s the “reply-only” option you can set on your local interface’s “ARP” setting, and then add the user’s IP/MAC combos into your ARP list. With that setup, once you create a user, enabling and disabling them is a matter of moving a user from the list of enabled to the list of disabled users.

Thank you boen_robot!

I make this

   $API->write('/ip/firewall/filter/edit',false);
   $API->write("=.id=*" . dechex(3015), false);
   $API->write("=src-address=$ip",false);
   $API->write("=src-mac-address=$maci");

But I get some error:

Connection attempt #1 to 123.1.1.1:8728… <<< [6] /login >>> [5/5 bytes read. >>> [5, 39] !done >>> [37/37 bytes read. >>> [37, 1] =ret=ebab08056bea7de07c8ced7c4853c44c <<< [6] /login <<< [11] =name=admin <<< [44] =response=00c4a05c93495a60d067f7e8520ff3659d >>> [5/5 bytes read. >>> [5, 1] !done Connected… <<< [24] /ip/firewall/filter/edit <<< [9] =.id=*bc7 <<< [26] =src-address=172.31.247.40 <<< [17] =src-mac-address= >>> [5/5 bytes read. >>> [5, 35] !trap >>> [26/26 bytes read. >>> [26, 8] =message=unknown parameter >>> [5/5 bytes read. >>> [5, 1] !done Array ( [!trap] => Array ( [0] => Array ( [message] => unknown parameter ) ) ) Disconnected…

I want to edit IP address:
http://s008.radikal.ru/i304/1111/d4/ca619f5995b9.png
Sorry and thank you again.

use set instead of_edit_ as that is interactive and interactive stuff does not work in API.

So anything that in CLI asks for user input will not work properly if at all.

In addition to janisk’s note, I’m not sure about your ID, as I already said in my last post. 3015 is definetly not it though… that’s a comment, not an ID.

With the client from my signature, you should be able to do what you want with something like:

<?php
namespace PEAR2\Net\RouterOS;//This must remain at the top of your PHP file!
require_once 'PEAR2/Net/RouterOS/Autoload.php';

//The rest of your PHP script here... particularly important is that you define $ip and $mac

$client = new Client('123.123.123.123', 'admin', 'root'));

//The key bit... getting the correct ID by printing it
$id = $client->sendSync(new Request('/ip/firewall/filter/print .proplist=.id', null, Query::where('comment', '3015')))->getArgument('.id');

$setRequest = new Request('/ip/firewall/filter/set');
$setRequest->setArgument('numbers', $id);
$setRequest->setArgument('src-address', $ip);
$setRequest->setArgument('src-mac-address', $mac);

$client->sendSync($setRequest);
//And you're done.
 

Hello,
Thank you boen_robot and janisk for answers.

boen_robot, I see your script, but I need this modification

require('routeros_api.class.php'); // RouterOS API class
$API = new routeros_api();
$API->debug = true;
include "router_config.php"; // router username and password

{

$abonentiAPI = $API->connect(new Request('/ip/firewall/filter/print .proplist=.id', null, Query::where('comment', "$abonenti")))->getArgument('.id');

  
$setRequest = new Request('/ip/firewall/filter/set');
$setRequest->setArgument('numbers', $abonentiAPI);
$setRequest->setArgument('src-address', $ip);
$setRequest->setArgument('src-mac-address', $maci);
$client->sendSync($setRequest);

}
   
$READ = $API->read(false);
$ARRAY = $API->parse_response($READ);
print_r($ARRAY);
$API->disconnect();
 

This won’t work. Denis’ class doesn’t have any of my features. The two packages are completely incompatible with each other. You must forget about these lines:

require('routeros_api.class.php'); // RouterOS API class
$API = new routeros_api();
$API->debug = true;
include "router_config.php"; // router username and password
 

in favor of

<?php
namespace PEAR2\Net\RouterOS;//This must remain at the top of your PHP file!
require_once 'PEAR2/Net/RouterOS/Autoload.php';
 

If you wish to keep using Denis’ class, you’ll have to rewrite the whole communication flow accordingly. The basic idea is the same - use query words to print the entry you’re about to edit, get its ID, and feed it into the “numbers” argument of a new set command. You must do this in a “raw” fashion though (i.e. read the API page in the MikroTik Wiki, and write the words accordingly).

My package tries to discourage this (in favor of classes and methods with self descriptive purposes chained in a fashion that should be intuitive to an average PHP developer), while Denis’ class only allows for raw kind of flow. I’d rather help you set up my class and do any raw-to-method rewrites than help you with the method-to-raw rewrite.

boen_robot
Can you upload all files?

They’re already uploaded at GitHub and SourceForge. See my signature or the bottom of the API page. On both sites, the files are equivalent.


I mean… look
|
|
V

I get some error and I delete this “namespace PEAR2\Net\RouterOS;”

but now have this error:

Fatal error: Uncaught exception ‘LogicException’ with message ‘Function ‘NAMESPACE\autoload’ not found’ in /home/fastnetg/public_html/baza/api/PEAR2/Net/RouterOS/Autoload.php:56 Stack trace: #0 /home/f/public_html/test/api/PEAR2/Net/RouterOS/Autoload.php(56): spl_autoload_register() #1 /home/f/public_html/test/api/callback-and-loop.php(2): require_once(‘/home/fastnetg/…’) #2 {main} thrown in /home/f/public_html/test/api/PEAR2/Net/RouterOS/Autoload.php on line 56

You need to have PHP 5.3.0 or later. The error you first saw can only mean that you have an earlier version (e.g. 5.2.*).

If you’re doing this on your own machine, upgrade your PHP. If you’re using a host, ask your host to upgrade the PHP version for your site.

Don’t forget to add back the “namespace PEAR2\Net\RouterOS;” line once that is done.

How can I show the $ARRAY[0][.id] value? The .id make error because the “.” character is invalid.

Quote the key, i.e.

$ARRAY[0]['.id'] 

This is a common requirement for ALL strings (i.e. text) in PHP. You can use either single quotes (apostrophes) as above, or double quotes, although I’d personally reccomend single, because they are interpreted literally (as opposed to double quoted strings, with which variables are expanded). That would in turn save you some trouble later on.

BTW, next time, you might want to make a new topic instead of snatching another user’s topic… your issues are not really related anyway.

boen_robot

You need to have PHP 5.3.0 or later. The error you first saw can only mean that you have an earlier version (e.g. 5.2.*).

If you’re doing this on your own machine, upgrade your PHP. If you’re using a host, ask your host to upgrade the PHP version for your site.

Don’t forget to add back the “namespace PEAR2\Net\RouterOS;” line once that is done.

Thank you, I’ll try PHP 5.3

Thank you your answer! Your say right, I had to make a new topic. Sorry for all users! :frowning:

Hello,

I need graphic statistic on my billing system, example:
http://i054.radikal.ru/1203/2a/07edab5ca9cc.png

also I need ping from router, example:
http://s019.radikal.ru/i608/1203/fa/84757663d338.png

Is it possible from API? or what is alternative way?

Pinging from router is trivial. You just use the “/ping” command, with arguments equivalent to those you’d use from terminal (address, timeout, etc.).

As for the stats… depends on the kind of stats you want, but either way, you can only get the data for the stats, not a graphic. You need to use a separate charting library that would take the data and generate a graphic out of it, which isn’t exactly trivial, but could be made easier if you use a specialized library. Here’s a tutorial on pChart for example.

Hello,

Now I’m rewriting billing and making for boen_robot API client.

<?php
namespace PEAR2\Net\RouterOS;

require_once 'PEAR2/Net/RouterOS/Autoload.php';

$client = new Client('1.2.3.4', 'admin', '123456');

$addRequest = new Request('/ip/firewall/filter/add');
$addRequest->setArgument('chain', 'forward');
$addRequest->setArgument('src-address', "$ip");
$addRequest->setArgument('action', 'accept');
$addRequest->setArgument('comment', "$abonenti");
$addRequest->setArgument('src-mac-address', "$mac");
$addRequest->setArgument('disabled', 'no');
$addRequest->setTag('arp1');
$client->sendAsync($addRequest);

$addRequest = new Request('/ip/firewall/filter/add');
$addRequest->setArgument('chain', 'forward');
$addRequest->setArgument('dst-address', "$ip");
$addRequest->setArgument('action', 'accept');
$addRequest->setArgument('comment', '$abonenti - 2');
$addRequest->setArgument('disabled', 'no');
$addRequest->setTag('arp2');

$client->sendAsync($addRequest);

$client->loop();
?>

Now I need choices position,
Now I have this:
http://s019.radikal.ru/i635/1204/d5/7cd18fe79787.png
last added want up to “123456789”