API address-list add or remove

Hi all,

with this API command i send ip to address-list to my router
/ip/firewall/address-list/add =list=kesik =address=1.2.3.4 =disabled=no
and i cant remove it with API command.

Can any one help me please about send this command with api?

/ip firewall address-list remove [/ip firewall address-list find address=1.2.3.4]



i try lots of time but i cant do it.

thanks.

there are two commands (find, then remove). so, you should first execute

/ip/firewall/address-list/print
?address=1.2.3.4
=.proplist=.id

and then use that .id to remove the entry:

/ip/firewall/address-list/remove
=.id=<result_of_previous_query>

and for the command below ?

/ip firewall address-list remove [/ip firewall address-list find list=ssh-accept]

let me guess… just replace

?address=1.2.3.4

with

?list=ssh-accept

? :smiley:

If there is more than one entry, you can include all IDs by separating them with a comma. I don’t know if =.id= supports this, but last I checked, =numbers= does.

i receive the error : !trap=message=unkown parameter

My code is:

            mikrotik.Send("/ip/firewall/address-list/print");
            mikrotik.Send("?list=ssh-accept");
            mikrotik.Send("=.proplist=.id");

            mikrotik.Send("/ip/firewall/address-list/remove");
            mikrotik.Send("=.id=");

You need to actually store the ID into a variable (by using the Read() method, and analyze the returned data appropriately), and then concatenate the returned ID as part of the next command. What you’re instead doing is just sending a print command, following by a remove command that misses the actual ID to remove.

That, plus the C# client in the wiki is… ergh… have you considered using mikrotik4net (the C# client in the “elsewhere” section)?

hm…
i have array with ip, which need to remove from address list

$ros_list=mylist;
foreach ($removeiparray as $remove)
{
echo "Remove IP: " . $remove . "\n";

$API->write("/ip/firewall/address-list/print",false);
   $API->write("?list=$ros_list",false);
   $API->write("?address=$remove",false);
   $API->write("=.proplist=.id");
   $READ = $API->read();
   $i=0;
   foreach   ($READ as $x) {
           $line=$READ[$i];
           $id=$line['.id'];
           sleep(1);
           $API->write("/ip/firewall/address-list/remove",false);
           $API->write("=.id=$id",true);
           $i++;
#           usleep(5000);
}}}

i create ip - 2.2.2.2
in debug i see:

We removing next ip: 2.2.2.2
<<< [31] /ip/firewall/address-list/print
<<< [14] ?list=mylist
<<< [16] ?address=2.2.2.2
<<< [14] =.proplist=.id
>>> [3/3] bytes read.
>>> [3, 19]!re
>>> [10/10] bytes read.
>>> [10, 8]=.id=*1ED6
>>> [5/5] bytes read.
>>> [5, 1]!done
<<< [32] /ip/firewall/address-list/remove
<<< [10] =.id=*1ED6
Disconnected...

But he still stay in address-list

I got a similar bug report about my client… It seems despite what the API spec says (that processing starts when the end of a sentence is received), processing actually only starts when RouterOS is about to send you back a response. But unless you actually demand such a response, i.e. if you just disconnect, RouterOS is not going to do a thing.

To fix this, simply do a read() after the write, i.e.

           $API->write("/ip/firewall/address-list/remove",false);
           $API->write("=.id=$id",true);
           $API->read();
           $i++; 

BTW, it will be SIGNIFICANTLY more efficient to get all the IDs with a single print, and then pass all IDs (separated with commas) to the remove command. And what’s with all the sleeps? Are you trying to make the code slow?

thanks, i inserted $API->read();
code is work

how can i optimize code ?

if (count($removeiparray) > 0)
{
foreach ($removeiparray as $remove)
{
echo "We removing next ip: " . $remove . "\n";

$API->write("/ip/firewall/address-list/print",false);
   $API->write("?list=$ros_list",false);
   $API->write("?address=$remove",false);
   $API->write("=.proplist=.id");
   $READ = $API->read();
   $i=0;
   foreach   ($READ as $x) {
           $line=$READ[$i];
           $id=$line['.id'];
           sleep(1);

        $API->write("/ip/firewall/address-list/remove",false);
        $API->write("=.id=$id",true);
        $API->read();
        $i++;
}}}

May I first ask why you chose that client?*

Using my client (see my signature), you can do it like that (and if you do measurements, you’ll also see it’s a lot more efficient):

<?php
namespace PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b3.phar';

$client = new Client('192.168.0.1', 'admin', 'password');

$responses = $client->sendSync(
    new Request('/ip/firewall/address-list/print .proplist=.id', Query::where('list', 'mylist'))
)->getAllOfType(Response::TYPE_DATA);

$idList = '';
foreach ($responses as $response) {
    $idList .= $response->getArgument('.id') . ',';
}

if ('' !== $idList) {
    $removeRequest = new Request('/ip/firewall/address-list/remove');
    $removeRequest->setArgument('numbers', rtrim($idList, ','));
    $client->sendSync($removeRequest);
} 

It’s the same idea with Denis’ client.

(the code above can be shortened further - especially if you have PHP 5.4 - but I’m keeping it verbose for clarity’s sake)

  • No. Honestly… I’m not criticizing or anything, I’m genuinely curious. Every time I ask this question, people either insist on using Denis’ class without giving a reason or switch to my client without saying why they previously used the other one, leaving me to wonder what I’m doing wrong in terms of “PR”, even if “technically” it’s all good.

i used this client API:
http://wiki.mikrotik.com/wiki/API_PHP_class

because i don’t work with pear :slight_smile:

Ahhh… facepalm… I suspected that much…

Despite the name, PEAR(2) is not required. It’s not even an optional dependency in fact. Everything that is needed is included in the PHAR file which you can just include directly, as in the example above. In other words, you don’t need to work with PEAR to use this.


edit:

OK… I wrote MikroTik support to shave off the “using PEAR2” part, as that’s just misleading…

API states, that each successfully sent command will have a reply to it on the execution results. So generally it is a good idea to get the response if everything happened or not (!re or !trap in response)

ok, i will try it

I’m trying to do something similar using Python. However, the .id that I get back is not a decimal number, and I can’t pass it on to the remove command.

I want to kick PPPoE user #0:

[admin@BOMA_lab] > /ppp active print
Flags: R - radius
 #   NAME         SERVICE CALLER-ID         ADDRESS         UPTIME   ENCODING
 0 R andristhe... pppoe   D4:CA:6D:04:C0:14 0.0.0.0         18m40s

Here is what the API returns to me:

<<< /ppp/active/print
<<< =.proplist=.id
<<<
>>> !re
>>> =.id=*80000010

I can’t seem to do much with *80000010, e.g. */interface/pppoe-server/remove=.id=80000010 fails. /interface/pppoe-server/remove=.id=80000010 fails, etc.

*80000010 looks like a pointer to memory location to me, it doesn’t convert into a usable base 10 number.

Am I missing something obvious here? Thanks. This is router OS 6.20.

if you get .id from /ppp/active, then you must use it under /ppp/active, not /interface/ or something

the correct command is:

/ppp/active/remove
=.id=*80000010

Hi

I need help with the command to reset-counters. this is my code in c#:

var cmd= connection.CreateCommandAndParameters("/tool/user-manager/user/reset-counters ", “?=numbers”, txtreset.Text);

I tried using .id instead of numbers unfortunately I keep getting the same error message “no such command”

That means, “/tool/user-manager/user/reset-counters " command does not exist. Try without space symbol at the end of string (”…ters" instead of your "…ters ").

this works to me:

<?php 
    try {
        $client = new RouterOS\Client('192.168.88.1', 'admin', 'password');
    } catch (Exception $e) {
        echo "error : ".$e;
        die('Unable to connect to the router.');
        
    }
///ip firewall address-list remove [/ip firewall address-list find address=192.168.88.14]
$printRequest = new RouterOS\Request('/ip/firewall/address-list/print');
$printRequest->setArgument('.proplist', '.id');
$printRequest->setQuery(RouterOS\Query::where('address', '192.168.88.14'));
$id = $client->sendSync($printRequest)->getProperty('.id');
//$id now contains the ID of the entry we're targeting
$setRequest = new RouterOS\Request('/ip/firewall/address-list/remove');
$setRequest->setArgument('numbers', $id);
$client->sendSync($setRequest);
?>