Order Simple Queue by IP Addresses

Any have a script to order a Simple queue by ip adrresses?

Any help about that ? :smiley:

What do you mean by “order”?
You mean you want to print them sorted by IP address? Why?

Order by IP, you can move or sorted by IP but we want order by IP

I still don’t know what you mean.
What do you mean by “order”?
What are you trying to get?

I don’t believe there is a way to sort an array, unless you write a script to do so yourself.

I think he means “order” as in “move around”. A queue may have a different effect based on whether it comes first or second in the list.

There’s no built in way of sorting items, but you could implement one yourself. Once you have the proper sorting order, you can do the moves by looping over the IDs, and call “move” for each. Calling “move” without a second argument puts it at the bottom of the list, so the end result is that your actual list matches the sorted one.

I’m not entirely sure about how the implementation would go though… I mean, because I’m lazy, I’d just use the API to get all queues, extract the IPs and IDs into an array (with the IP as an array key), do the sort with a single function call (present in most languages; certainly in PHP), and then loop over the array, and call “move” with the associated ID.

Exactly that, any have this script in the API and PHP or the script to the MK ?

Considering that queues have masks and interfaces, and that multiple targets may be present in a single queue, this turned out to be a bit more complicated than I thought, but still relatively easy.

Here’s using my API client:

<?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('/queue simple');
$queues = $util->getAll(array('.proplist' => '.id,target'))->orderBy(
        array(
            'target' => function ($a, $b) {
                //If the queues compared contain multiple targets, sort based on the first ones
                if (strpos($a, ',') !== false) {
                    $a = explode(',', $a, 1);
                    $a = $a[0];
                }
                if (strpos($b, ',') !== false) {
                    $b = explode(',', $b, 1);
                    $b = $b[0];
                }

                //If there are no mask parts, this is an interface queue - sort alphabetically
                if (strpos($a, '/') === false && strpos($b, '/') === false) {
                    return strcmp($a, $b);
                }

                //If one of the queues is an interface queue, it goes before the IP one
                if (strpos($a, '/') === false || strpos($b, '/') === false) {
                    return strpos($a, '/') === false ? -1 : 1;
                }

                //Separate the IP/Mask
                $a = explode('/', $a, 2);
                $b = explode('/', $b, 2);

                //Convert to integer representation
                $ipA = ip2long($a[0]);
                $ipB = ip2long($b[0]);
                $maskA = (int)$a[1];
                $maskB = (int)$b[1];

                //Get network address
                $netA = $ipA >> $maskA;
                $netB = $ipB >> $maskB;

                //Sort based on the network address; Bigger mask = smaller network = later in the list
                if ($netA < $netB) {
                    return 1;
                } elseif ($netA > $netB) {
                    return -1;
                } else {//Sort based on the address within the network
                    $a = ($netA << $maskA) ^ $ipA;
                    $b = ($netB << $maskB) ^ $ipB;
                    return $a < $b ? -1 : (int) $a > $b;
                }
            }
        )
);

$moveRequest = new RouterOS\Request('/queue simple move');
foreach ($queues as $queue) {
    $client->sendSync($moveRequest->setArgument('numbers', $queue->getProperty('.id')));
} 

(Side note: I found a bug with my $util->move() implementation… doesn’t support NULL destination… That’s why I’m using $client for the move part; I’ll be sure to fix this soon, at which point $util->move($queue(‘.id’), null) would be a thing, equivalent of $util->move($queue(‘.id’)) in fact)

I never run a API but I think can we use this script with XAMP or any Linux with PHP?, let me now please.

Yes.

You need to save this file with a “.php” extension. If you have XAMPP, you’d have to place it in the “htdocs” folder inside XAMPP’s folder.

For this particular script, you can also just download only PHP itself from php.net, and run the file from the command line with “php script.php”.