Help writing a PHP function to parse a long hex array

Hello all,

I’m trying to add support for Avaya ERS vlan discovery.

The ERS switches report VLAN port memebers using a long hex string, much like the Q-Bridge MIB, but longer.
Since you can have a stack of upto 8 50 port switches, the hex string is always 64 octets, even if you just have a single 24 port switch.
Example output for one VLAN on a 26 port switch:
7F FF FF E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

There is already a function in includes\functions.php that will take a bitmask like this and return an array of port ids, q_bridge_bits2indices()
But this does not return anything if I send the above mask to it.
I think this is likely to be down to the length.

That mask is really 8 x 8 octets, each set of 8 octets being a single switch in the stack

I don’t really know any PHP, so I’m looking for help in creating a new function to return an array of port indexes from the above bitmask.

The sticky bit is this, if I have 2 x 26 port switches in a stack with all ports in the VLAN, I will get this output:
7F FF FF E0 00 00 00 00 7F FF FF E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
And would need an array returning with ports 1-52 in it.
But if I had 1 x 50 port and 1 x 26 port switch I would get this output:
‭7F FF FF FF FF FF E0 00‬ 7F FF FF E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
And would need an array returning with ports 1-76 in it.

I hope that all makes sense.

This seems to work for me:

$result =  q_bridge_bits2indices('7F FF FF E0 00 00 00 00 7F FF FF E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00');
print_r($result);

Array
(
    [0] => 2
    [1] => 3
    [2] => 4
    [3] => 5
    [4] => 6
    [5] => 7
    [6] => 8
    [7] => 9
    [8] => 10
    [9] => 11
    [10] => 12
    [11] => 13
    [12] => 14
    [13] => 15
    [14] => 16
    [15] => 17
    [16] => 18
    [17] => 19
    [18] => 20
    [19] => 21
    [20] => 22
    [21] => 23
    [22] => 24
    [23] => 25
    [24] => 26
    [25] => 27
    [26] => 66
    [27] => 67
    [28] => 68
    [29] => 69
    [30] => 70
    [31] => 71
    [32] => 72
    [33] => 73
    [34] => 74
    [35] => 75
    [36] => 76
    [37] => 77
    [38] => 78
    [39] => 79
    [40] => 80
    [41] => 81
    [42] => 82
    [43] => 83
    [44] => 84
    [45] => 85
    [46] => 86
    [47] => 87
    [48] => 88
    [49] => 89
    [50] => 90
    [51] => 91
)

Hmm, @murrant how are you testing that?
If there is an easy way of just testing that function I’ll have a play.

Also, the result is wrong.
It should be:

[0] => 1
[1] => 2
[2] => 3
...
[49] => 50
[50] => 51
[51] => 52

You can just do:

<?php

$init_modules = array();
require __DIR__ . '/includes/init.php';

$result =  q_bridge_bits2indices('7F FF FF E0 00 00 00 00 7F FF FF E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00');
print_r($result);

thanks @murrant and @laf, it helps being able to easily play around with the code.

So there is an off by one error, but I can easily fix that. (this is because the MSB is always 0, port 1 is represented by the 2nd MSB)

I’m trying to work out how to sort the untagged VLAN.

The avaya reports this differently.
Instead of a bit mask, it returns a list of ports with the PVID (or default) vlan, like this:

SNMP[/usr/bin/snmpbulkwalk -v2c -c COMMUNITY -OQUs -m RC-VLAN-MIB -M /opt/librenms/mibs:/opt/librenms/mibs/nortel udp:HOSTNAME:161 rcVlanPortDefaultVlanId]
rcVlanPortDefaultVlanId.1 = 350
rcVlanPortDefaultVlanId.2 = 350
rcVlanPortDefaultVlanId.3 = 350
rcVlanPortDefaultVlanId.4 = 350

So the PVID of ports 1-4 is 350.

If I do this:

$untagged_ids = snmpwalk_cache_oid($device, 'rcVlanPortDefaultVlanId', array(), 'RC-VLAN-MIB');
  echo "printing result...";
  print_r($untagged_ids);

I get this back:

printing result...Array
(
    [1] =>  Array
        (
            [rcVlanPortDefaultVlanId] => 350
        )

    [2] => Array
        (
            [rcVlanPortDefaultVlanId] => 350
        )

    [3] => Array
        (
            [rcVlanPortDefaultVlanId] => 350
        )

    [4] => Array
        (
            [rcVlanPortDefaultVlanId] => 350
        )

)

I need to flatten this to an array like this:

Array
(
    [1] => 350
    [2] => 350
    [3] => 350
    [4] => 350
)

Then I can write a function to build a list of untagged ports for each vlan.

Is there already a function for this? Or am I approaching this wrong?

thanks

I’m not aware of any function, why not just loop through the array to get what you want?

yea, it was obvious how to do it once I had read a bit more about PHP.

Done and PR sent: 7098.

I’ll apologise now for the code…