Skip to content

When using 32-bit OS, automation errors can be seen due to subnet mask calculations #3310

@panlinux

Description

@panlinux

Describe the bug
Function automation_get_valid_mask() fails in in https://github.com/Cacti/cacti/blob/develop/lib/api_automation.php#L3029 when converting a binary string to integer on a 32bit architecture like armhf.

This results in errors like these in the logs:

02/27/2020 03:15:08 - ERROR PHP WARNING: long2ip() expects parameter 1 to be int, float given in file: /usr/share/cacti/site/lib/api_automation.php  on line: 3006
02/27/2020 03:15:08 - CMDPHP PHP ERROR WARNING Backtrace:  (/poller_automation.php[272]:automation_primeIPAddressTable(), /lib/api_automation.php[3179]:automation_calculate_total_ips(), /lib/api_automation.php[3128]:automation_get_network_info(), /lib/api_automation.php[3034]:automation_get_valid_mask(), /lib/api_automation.php[3006]:long2ip(), CactiErrorHandler())
02/27/2020 03:15:08 - ERROR PHP WARNING: long2ip() expects parameter 1 to be int, float given in file: /usr/share/cacti/site/lib/api_automation.php  on line: 3006
02/27/2020 03:15:08 - CMDPHP PHP ERROR WARNING Backtrace:  (/poller_automation.php[272]:automation_primeIPAddressTable(), /lib/api_automation.php[3182]:automation_calculate_start(), /lib/api_automation.php[3116]:automation_get_network_info(), /lib/api_automation.php[3034]:automation_get_valid_mask(), /lib/api_automation.php[3006]:long2ip(), CactiErrorHandler())

To Reproduce
The error is showing up in the DEP8 Ubuntu tests at http://autopkgtest.ubuntu.com/packages/cacti. One can see they are failing for armhf: http://autopkgtest.ubuntu.com/packages/cacti/focal/armhf

A simple way to reproduce it is to call the automation_get_valid_mask() function with any argument between 0 and 33. For example, 24, on an amd64 machine returns this (with some debugging of mine):

$ php ./automation_get_valid_mask.php 24

bindec(11111111111111111111111100000000):
4294967040
Array
(
    [cidr] => 24
    [subnet] => 255.255.255.0
    [count] => 255
)

On armhf, however:

$ php ./automation_get_valid_mask.php 24

bindec(11111111111111111111111100000000):
4294967040PHP Warning:  long2ip() expects parameter 1 to be int, float given in /home/ubuntu/automation_get_valid_mask.php on line 13

Array
(
    [cidr] => 24
    [subnet] => 
    [count] => 255
)

There are warnings about issues with 32bit architectures on https://www.php.net/manual/en/function.bindec.php and https://www.php.net/manual/en/function.long2ip.php

Expected behavior
On armhf 32bit, automation_get_valid_mask() should work properly. For example, return "255.255.255.0" for "subnet" when called with a range == 24.

Cacti server

  • OS: Ubuntu 20.04 Focal Fossa (development release)
  • php 7.3.15
  • architecture: armhf (32bits)

Misc
This is the script I used. I copied the function from lib/api_automation.php and added some debugging:

<?php
function automation_get_valid_mask($range) {
    $cidr = false;
    if (is_numeric($range)) {
        if ($range > 0 && $range < 33) {
            $cidr = $range;
	    $ones = str_repeat('1',$range);
	    $zeroes = str_repeat('0',32-$range);
	    echo "\nbindec(" . $ones . $zeroes . "):\n";
	    print_r(bindec($ones . $zeroes));
            $mask = array(
                'cidr' => $cidr,
                'subnet' => long2ip(bindec($ones . $zeroes)));
        } else {
            $mask = false;
        }
    } else {
        $mask = automation_get_valid_subnet_cidr($range);
    }

    if ($mask !== false) {
        $mask['count'] = bindec(str_repeat('0',$mask['cidr']) . str_repeat('1',32-$mask['cidr']));
        if ($mask['count'] == 0) {
            $mask['count'] = 1;
        }
    }
    return $mask;
}

$bits = strval($argv[1]);
$mask = automation_get_valid_mask($bits);
echo "\n";
print_r($mask);
?>

Metadata

Metadata

Assignees

Labels

apiAPI related issuesbugUndesired behaviourresolvedA fixed issue

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions