Community discussions

MikroTik App
 
rubence1975
just joined
Topic Author
Posts: 5
Joined: Wed Jan 25, 2017 2:56 pm

Help on php api

Wed Jan 25, 2017 3:17 pm

can anyone help me to write a php api ? from my php page i want to disable a nat rule with specific comment . or simply how can i invoke following cli command from php page

/ip firewall nat disable [/ip firewall nat find comment=1234]



thanks in advance
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Help on php api

Wed Jan 25, 2017 5:27 pm

With the API client from my signature:
<?php
use PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b5.phar';

$util = new RouterOS\Util($client = new RouterOS\Client('192.168.88.1', 'admin', 'password'));

$util->setMenu('/ip firewall nat')->disable(RouterOS\Query::where('comment', '1234')); 
 
rubence1975
just joined
Topic Author
Posts: 5
Joined: Wed Jan 25, 2017 2:56 pm

Re: Help on php api

Thu Jan 26, 2017 6:41 am

Thanks a lot . its working . can you help me on another thing . i want to show about the status of the nat rule . like if the rule with comment "1234" is disabled , on my php page it'll show " your rule is disabled" and if enabled it will show "your rule is enabled"

thanks again for your help
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Help on php api

Thu Jan 26, 2017 1:00 pm

If it's just one rule, you can use the get() method (equivalent to a CLI "get"). If you want to get all rules that match the criteria, you can use getAll() (equivalent to a CLI "print"; I could not call the PHP method "print", because that's a reserved word in PHP).

So either
$isDisabled = 'true' === $util->setMenu('/ip firewall nat')->get(
    $util->find(RouterOS\Query::where('comment', '1234')),
    'disabled'
);
if ($isDisabled) {
    echo 'Rule is disabled';
} else {
    echo 'Rule is enabled';
} 
or
$rules = $util->setMenu('/ip firewall nat')->getAll(array(), RouterOS\Query::where('comment', '1234'));
foreach ($rules as $rule) {
    $isDisabled = 'true' === $rule('disabled');
    if ($isDisabled) {
        echo "Rule is disabled\n";
    } else {
        echo "Rule is enabled\n";
    }
} 
 
rubence1975
just joined
Topic Author
Posts: 5
Joined: Wed Jan 25, 2017 2:56 pm

Re: Help on php api

Thu Jan 26, 2017 10:15 pm

thanks a lot :)
 
rubence1975
just joined
Topic Author
Posts: 5
Joined: Wed Jan 25, 2017 2:56 pm

Re: Help on php api

Sat Mar 11, 2017 8:19 pm

hello again,

with your API Client i played a lot for last few weeks . thanks for that great thing . but i stucked again .

i want to to reduce or increase the max limit in simple queue for an specific target ipaddress by 2 times . like if in simple queue for ip address 192.168.100.2 the maxlimits target upload is 10M and target download is 20M , from api i want to make the upload 5M and download 10M .......... and vice versa

is it possible ??

thanks in advance
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Help on php api

Sat Mar 11, 2017 9:42 pm

The max-limit value in a queue contains the limit in the form of "upload/download". IIRC, you get the number as bits per second, so doubling an existing limit should be as simple as separating by the "/", doing the multiplication on the two parts, and setting the two new values in a string concatenated with "/" again.

e.g.
$util->setMenu('/queue simple');
$queueId = $util->find(RouterOS\Query::where('target', '192.168.100.2/32'));
$maxLimit = $util->get($queueId, 'max-limit');
list($maxUp, $maxDown) = explode('/', $maxLimit, 2);
$maxUp *= 2;
$maxDown *= 2;
$util->set(
    $queueId,
    array(
        'max-limit' => "{$maxUp}/{$maxDown}"
    )
); 
(same for halving it, except you divide by 2 instead of multiplying, and round the result to remove fractions)
 
rubence1975
just joined
Topic Author
Posts: 5
Joined: Wed Jan 25, 2017 2:56 pm

Re: Help on php api

Sat Mar 11, 2017 10:26 pm

thanks for your quick reply .

its great bro . heads up !!
 
chenashop
just joined
Posts: 6
Joined: Mon Apr 03, 2017 9:42 pm

Re: Help on php api

Mon Apr 03, 2017 9:46 pm

hello,

I am also using your client. I want to edit pppoe password from php page, so that user can edit his own password


$name = "user1";
$password = "password1";
$service=pppoe

can u help us on this ... ?
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Help on php api

Tue Apr 04, 2017 11:27 am

$util->setMenu('/ppp secret')->set($name, array('password' => $password, 'service' => $service)); 
would be the equivalent of the command line
/ppp secret set numbers="user1" password="password1" service="pppoe"
 
evandromac
just joined
Posts: 12
Joined: Thu Sep 01, 2016 3:19 am

Re: Help on php api

Thu Jan 10, 2019 2:26 am

Boen,

Can you help me?

I was able to do several (good stuff) with your api. But now I'm tired, my neck is on fire (I spent all day here in front of the computer).

If I send a script with script::prepare and then run it from the router, it can perform network test (ping) to verify the connection.

If I execute the very same script with util->exec, it cannot ping anything outside.

The policy is the same for both scenarios: read,write,test

Now I have to take some medicine for my neck and wait for your help.

Thanks in advance!
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Help on php api

Thu Jan 10, 2019 11:42 am

You run it from the router how?

Util::exec() uses "/system script run". If you're using f.e. scheduler, or /import a file, that's different.

Also, Util::exec() prepends the current menu, while Script::prepare() doesn't (since it has no notion of a menu). If your script says "ping" rather than "/ping" or "/tool ping", you may be running it from the wrong menu. With Script::prepare(), you're definitely running it from root.

Are there any errors on the PHP side, or does the script work without errors, it's just that you don't see any results from the ping? If the former - what is the error? If the latter... Maybe try to write the results to a global variable, and check the global variable afterwards?
 
evandromac
just joined
Posts: 12
Joined: Thu Sep 01, 2016 3:19 am

Re: Help on php api

Thu Jan 10, 2019 2:35 pm

You run it from the router how?

Util::exec() uses "/system script run". If you're using f.e. scheduler, or /import a file, that's different.

Also, Util::exec() prepends the current menu, while Script::prepare() doesn't (since it has no notion of a menu). If your script says "ping" rather than "/ping" or "/tool ping", you may be running it from the wrong menu. With Script::prepare(), you're definitely running it from root.

Are there any errors on the PHP side, or does the script work without errors, it's just that you don't see any results from the ping? If the former - what is the error? If the latter... Maybe try to write the results to a global variable, and check the global variable afterwards?
I run it on router opening the script and clicking "run". To be honest, I tried to run the script I sent with ::prepare from browser with PHP and didn't succeed, and as I am against the clock, I used the util->exec instead. But if you know how I can run the script that I previously sent using ::prepare, any help is very appreciated. I tried several combinations of setCommand, request, setArgument (passing the name of the script) and nothing, no error, and no script running in that way.

About your second question: my script uses /tool ping, as you can see here:
:global pingPPPoE do={
:return [/tool ping $1 src-address=$2 count=$3];
}
It receives the following parameters:

$1 = ping destination
$2 = ping origin
$3 = how many pings the router should send

And returns how many replies it received.

I didn't tried yet to store the ping count in a global variable, as I was convinced that was some kind of permission issue.

And about your third question: there's no error on any side. Just it receives 0 (zero) packets in return.

EDIT: I tried using just "/ping" instead of "/tool ping" and, yet, no packets.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Help on php api

Thu Jan 10, 2019 3:28 pm

What about running the actual ping from the API?

If the results are important for later in the script, you can pass the relevant parts of the result as parameters in Util::exec(), and act accordingly.

You can run the actual ping with
$pingResults = $client->sendSync(
    $util->setMenu('/tool')->newRequest('ping', ['address' => $ip, 'src-address' => $src, 'count' => $count])
)->getAllOfType(RouterOS\Response::TYPE_DATA);
Util::exec() uses Script::prepare() under the hood (well... Script::append() to be exact, but that's also what Script::prepare() uses), so it should be pretty much the same.

The only differences between the two are that exec() prepends the menu, and it adds the script in "/system script" with a random name, runs it, and removes it afterwards. You can do those same steps manually around Script::prepare() or part of them.

You could try to use Script::prepare(), then add the resulting script to scheduler, scheduled to run after a second or so. You'll still need to write your results into global variables or log if you want PHP to be able to access them though.
 
evandromac
just joined
Posts: 12
Joined: Thu Sep 01, 2016 3:19 am

Re: Help on php api

Thu Jan 10, 2019 4:37 pm

Thanks again, Boen.

In fact, the ping and another checkings have to be made inside the script. I can't use PHP to check it for development reasons (it's part of a larger script).

I'll try using your hint: use ::prepare and adding to a scheduler to run 1s later. I'll return here with the info.
 
evandromac
just joined
Posts: 12
Joined: Thu Sep 01, 2016 3:19 am

Re: Help on php api

Sat Jan 12, 2019 9:12 pm

You could try to use Script::prepare(), then add the resulting script to scheduler, scheduled to run after a second or so. You'll still need to write your results into global variables or log if you want PHP to be able to access them though.
Yeah, Boen!

Only today (16:47 saturday in Brazil) I managed to allocate time to return to this project. And your hint work exactly as you said.

To read the ping count back from routerOS context, I simply stored the value in the "comment" of the script. In my case I only need the result code of whole operation (on my original script), but it's a simple and effective solution. For people who need more values, the same solution applies. Several values can be stored and using delimitators, it's easy to break apart later and read individual values.

To illustrate better and help others, I wrote the small piece of code below:
<?php
use PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b6.phar';

# variable declarations

$device_ip		= '<x.x.x.x>';
$device_login		= '<login>';
$device_password	= '<password>';
$script_name 		= '<script_name>';
$where_to_ping		= '<ip_to_ping>';
$how_many_packets	= <ping_count>;

try {
    $util = new RouterOS\Util(
		$client = new RouterOS\Client($device_ip, $device_login, $device_password));
} catch (Exception $e) {
    die('Unable to connect to device at '.$device_ip.'.');
}

// First, we send the script to the router using script::prepare
// It only stores the script, but will not execute it

$util->setMenu('/system script')->add(
	array(
		'name' 			=> $script_name,
		'comment'		=> 'Test script execution from Boen Mikrotik PHP API',
		'policy'		=> 'read,write,test',
		'source'		=> RouterOS\Script::prepare(
									'
:local pingcount [/ping $where count=$packets]
/system script set [find name=$mynameis] comment="pingcount=$pingcount"

								',
								array(
									'mynameis' => $script_name,
									'where' => $where_to_ping,
									'packets' => $how_many_packets
								)
							)
		)
);

// Now we set the same script in a scheduler to run 2 seconds later

$util->setMenu('/system scheduler')->add(
	array(
		'name' => 'big_test',
		'start-time' => date_add($util->getCurrentTime(),date_interval_create_from_date_string("2 seconds"))->format('H:i:s'),
		'on-event' => $script_name
	)
);

?>
I choosed to run the script 2 seconds later it's insertion.

I'll create a topic for other people find this example.

Again, thank you, Boen, for helping me!

Who is online

Users browsing this forum: No registered users and 30 guests