2009-09-07 11:07:59 +00:00
< ? php
2015-06-14 08:00:21 +00:00
/*
* LibreNMS - Common Functions
*
* Original Observium version by : Adam Armstrong , Tom Laermans
* Copyright ( c ) 2009 - 2012 Adam Armstrong .
*
* Additions for LibreNMS by : Neil Lathwood , Paul Gear , Tim DuFrane
* Copyright ( c ) 2014 - 2015 Neil Lathwood < http :// www . lathwood . co . uk >
* Copyright ( c ) 2014 - 2015 Gear Consulting Pty Ltd < http :// libertysys . com . au />
*
* This program is free software : you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation , either version 3 of the License , or ( at your
* option ) any later version . Please see LICENSE . txt at the top level of
* the source code distribution for details .
*/
2009-05-07 13:47:51 +00:00
2017-08-08 19:14:58 +00:00
use LibreNMS\Config ;
2023-08-05 17:12:36 +00:00
use LibreNMS\Enum\Severity ;
2017-08-08 19:14:58 +00:00
use LibreNMS\Exceptions\InvalidIpException ;
2021-04-30 03:42:18 +00:00
use LibreNMS\Util\Debug ;
2017-08-08 19:14:58 +00:00
use LibreNMS\Util\IP ;
2021-05-13 18:00:56 +00:00
use LibreNMS\Util\Laravel ;
2020-10-29 18:02:26 +00:00
use Symfony\Component\Process\Process ;
2017-08-08 19:14:58 +00:00
2018-12-16 13:42:50 +00:00
/**
* Execute and snmp command , filter debug output unless - v is specified
*
2021-09-08 21:35:56 +00:00
* @ param array $command
2018-12-16 13:42:50 +00:00
* @ return null | string
*/
2016-08-28 17:32:58 +00:00
function external_exec ( $command )
{
2020-10-29 18:02:26 +00:00
$device = DeviceCache :: getPrimary ();
$proc = new Process ( $command );
2019-01-10 17:18:34 +00:00
$proc -> setTimeout ( Config :: get ( 'snmp.exec_timeout' , 1200 ));
2016-09-22 16:36:33 +00:00
2021-04-30 03:42:18 +00:00
if ( Debug :: isEnabled () && ! Debug :: isVerbose ()) {
2018-12-16 13:42:50 +00:00
$patterns = [
2019-01-28 21:41:50 +00:00
'/-c\' \'[\S]+\'/' ,
'/-u\' \'[\S]+\'/' ,
'/-U\' \'[\S]+\'/' ,
'/-A\' \'[\S]+\'/' ,
'/-X\' \'[\S]+\'/' ,
'/-P\' \'[\S]+\'/' ,
'/-H\' \'[\S]+\'/' ,
2022-03-13 21:51:55 +00:00
'/-y\' \'[\S]+\'/' ,
2018-12-16 13:42:50 +00:00
'/(udp|udp6|tcp|tcp6):([^:]+):([\d]+)/' ,
];
$replacements = [
2019-01-28 21:41:50 +00:00
'-c\' \'COMMUNITY\'' ,
'-u\' \'USER\'' ,
2019-01-29 13:40:15 +00:00
'-U\' \'USER\'' ,
2019-01-28 21:41:50 +00:00
'-A\' \'PASSWORD\'' ,
'-X\' \'PASSWORD\'' ,
'-P\' \'PASSWORD\'' ,
'-H\' \'HOSTNAME\'' ,
2022-03-13 21:51:55 +00:00
'-y\' \'KG_KEY\'' ,
2018-12-16 13:42:50 +00:00
'\1:HOSTNAME:\3' ,
];
$debug_command = preg_replace ( $patterns , $replacements , $proc -> getCommandLine ());
2016-09-22 16:36:33 +00:00
c_echo ( 'SNMP[%c' . $debug_command . " %n] \n " );
2021-04-30 03:42:18 +00:00
} elseif ( Debug :: isVerbose ()) {
2018-12-16 13:42:50 +00:00
c_echo ( 'SNMP[%c' . $proc -> getCommandLine () . " %n] \n " );
2016-01-17 14:39:17 +00:00
}
2018-12-16 13:42:50 +00:00
$proc -> run ();
$output = $proc -> getOutput ();
2016-01-17 14:39:17 +00:00
2020-10-29 18:02:26 +00:00
if ( $proc -> getExitCode ()) {
2020-10-30 10:14:33 +00:00
if ( Str :: startsWith ( $proc -> getErrorOutput (), 'Invalid authentication protocol specified' )) {
2023-08-05 17:12:36 +00:00
\App\Models\Eventlog :: log ( 'Unsupported SNMP authentication algorithm - ' . $proc -> getExitCode (), optional ( $device ) -> device_id , 'poller' , Severity :: Error );
2020-10-30 10:14:33 +00:00
} elseif ( Str :: startsWith ( $proc -> getErrorOutput (), 'Invalid privacy protocol specified' )) {
2023-08-05 17:12:36 +00:00
\App\Models\Eventlog :: log ( 'Unsupported SNMP privacy algorithm - ' . $proc -> getExitCode (), optional ( $device ) -> device_id , 'poller' , Severity :: Error );
2020-10-30 10:14:33 +00:00
}
2020-10-29 18:02:26 +00:00
d_echo ( 'Exitcode: ' . $proc -> getExitCode ());
d_echo ( $proc -> getErrorOutput ());
}
2021-04-30 03:42:18 +00:00
if ( Debug :: isEnabled () && ! Debug :: isVerbose ()) {
2016-09-22 16:36:33 +00:00
$ip_regex = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/' ;
$debug_output = preg_replace ( $ip_regex , '*' , $output );
d_echo ( $debug_output . PHP_EOL );
2021-04-30 03:42:18 +00:00
} elseif ( Debug :: isVerbose ()) {
2016-09-22 16:36:33 +00:00
d_echo ( $output . PHP_EOL );
2016-01-17 14:39:17 +00:00
}
2018-12-16 13:42:50 +00:00
d_echo ( $proc -> getErrorOutput ());
2011-09-22 18:28:00 +00:00
return $output ;
}
2016-08-28 17:32:58 +00:00
function shorthost ( $hostname , $len = 12 )
{
2014-03-28 17:05:39 +00:00
// IP addresses should not be shortened
2016-08-28 17:32:58 +00:00
if ( filter_var ( $hostname , FILTER_VALIDATE_IP )) {
2014-03-28 17:04:44 +00:00
return $hostname ;
2016-08-28 17:32:58 +00:00
}
2017-11-09 20:47:52 +00:00
$len = Config :: get ( 'shorthost_target_length' , $len );
2015-07-13 18:10:26 +00:00
2011-09-22 15:54:16 +00:00
$parts = explode ( '.' , $hostname );
$shorthost = $parts [ 0 ];
$i = 1 ;
while ( $i < count ( $parts ) && strlen ( $shorthost . '.' . $parts [ $i ]) < $len ) {
$shorthost = $shorthost . '.' . $parts [ $i ];
$i ++ ;
}
2020-09-21 13:40:17 +00:00
2011-09-22 15:54:16 +00:00
return $shorthost ;
}
2015-07-13 18:10:26 +00:00
2016-08-28 17:32:58 +00:00
function print_error ( $text )
{
2021-05-13 18:00:56 +00:00
if ( Laravel :: isCli ()) {
2016-08-17 00:52:36 +00:00
c_echo ( '%r' . $text . " %n \n " );
2016-08-28 17:32:58 +00:00
} else {
2016-09-21 19:00:17 +00:00
echo '<div class="alert alert-danger"><i class="fa fa-fw fa-exclamation-circle" aria-hidden="true"></i> ' . $text . '</div>' ;
2011-09-08 12:24:18 +00:00
}
}
2016-08-28 17:32:58 +00:00
function print_message ( $text )
{
2021-05-13 18:00:56 +00:00
if ( Laravel :: isCli ()) {
2016-08-17 00:52:36 +00:00
c_echo ( '%g' . $text . " %n \n " );
2016-08-28 17:32:58 +00:00
} else {
2016-09-22 12:09:31 +00:00
echo '<div class="alert alert-success"><i class="fa fa-fw fa-check-circle" aria-hidden="true"></i> ' . $text . '</div>' ;
2011-09-08 12:24:18 +00:00
}
}
2016-07-09 03:58:36 +00:00
function get_sensor_rrd ( $device , $sensor )
{
2021-03-28 22:25:30 +00:00
return Rrd :: name ( $device [ 'hostname' ], get_sensor_rrd_name ( $device , $sensor ));
2016-07-09 03:58:36 +00:00
}
2016-08-28 17:32:58 +00:00
function get_sensor_rrd_name ( $device , $sensor )
{
2011-04-28 21:12:16 +00:00
// For IPMI, sensors tend to change order, and there is no index, so we prefer to use the description as key here.
2019-06-23 05:29:12 +00:00
if ( Config :: getOsSetting ( $device [ 'os' ], 'sensor_descr' ) || $sensor [ 'poller_type' ] == 'ipmi' ) {
2016-07-09 03:58:36 +00:00
return [ 'sensor' , $sensor [ 'sensor_class' ], $sensor [ 'sensor_type' ], $sensor [ 'sensor_descr' ]];
2016-07-07 06:33:43 +00:00
} else {
2016-07-09 03:58:36 +00:00
return [ 'sensor' , $sensor [ 'sensor_class' ], $sensor [ 'sensor_type' ], $sensor [ 'sensor_index' ]];
2011-04-26 15:07:52 +00:00
}
2016-07-07 06:33:43 +00:00
}
2016-08-28 17:32:58 +00:00
function get_port_rrdfile_path ( $hostname , $port_id , $suffix = '' )
{
2021-03-28 22:25:30 +00:00
return Rrd :: name ( $hostname , Rrd :: portName ( $port_id , $suffix ));
2016-01-26 12:49:30 +00:00
}
2016-08-28 17:32:58 +00:00
function get_port_by_index_cache ( $device_id , $ifIndex )
{
2011-05-19 10:02:55 +00:00
global $port_index_cache ;
if ( isset ( $port_index_cache [ $device_id ][ $ifIndex ]) && is_array ( $port_index_cache [ $device_id ][ $ifIndex ])) {
$port = $port_index_cache [ $device_id ][ $ifIndex ];
2016-08-28 17:32:58 +00:00
} else {
2011-05-19 10:02:55 +00:00
$port = get_port_by_ifIndex ( $device_id , $ifIndex );
$port_index_cache [ $device_id ][ $ifIndex ] = $port ;
}
return $port ;
}
2016-08-28 17:32:58 +00:00
function get_port_by_ifIndex ( $device_id , $ifIndex )
{
2011-05-19 10:02:55 +00:00
return dbFetchRow ( 'SELECT * FROM `ports` WHERE `device_id` = ? AND `ifIndex` = ?' , [ $device_id , $ifIndex ]);
}
2016-08-28 17:32:58 +00:00
function table_from_entity_type ( $type )
{
2011-05-19 10:02:55 +00:00
// Fuck you, english pluralisation.
if ( $type == 'storage' ) {
2012-05-16 13:25:50 +00:00
return $type ;
2016-08-28 17:32:58 +00:00
} else {
2012-05-16 13:25:50 +00:00
return $type . 's' ;
2015-07-13 18:10:26 +00:00
}
2012-05-16 13:25:50 +00:00
}
2011-05-19 10:02:55 +00:00
2016-08-28 17:32:58 +00:00
function get_entity_by_id_cache ( $type , $id )
{
2012-05-16 13:25:50 +00:00
global $entity_cache ;
$table = table_from_entity_type ( $type );
if ( is_array ( $entity_cache [ $type ][ $id ])) {
$entity = $entity_cache [ $type ][ $id ];
2016-08-28 17:32:58 +00:00
} else {
2012-05-16 13:25:50 +00:00
$entity = dbFetchRow ( 'SELECT * FROM `' . $table . '` WHERE `' . $type . '_id` = ?' , [ $id ]);
$entity_cache [ $type ][ $id ] = $entity ;
2015-07-13 18:10:26 +00:00
}
2020-09-21 13:40:17 +00:00
2012-05-16 13:25:50 +00:00
return $entity ;
2015-07-13 18:10:26 +00:00
}
2012-05-16 13:25:50 +00:00
2016-08-28 17:32:58 +00:00
function get_port_by_id ( $port_id )
{
2012-05-16 13:25:50 +00:00
if ( is_numeric ( $port_id )) {
2012-05-16 16:24:43 +00:00
$port = dbFetchRow ( 'SELECT * FROM `ports` WHERE `port_id` = ?' , [ $port_id ]);
2015-02-22 19:28:09 +00:00
if ( is_array ( $port )) {
2012-05-16 13:25:50 +00:00
return $port ;
2016-08-28 17:32:58 +00:00
} else {
return false ;
2015-07-13 18:10:26 +00:00
}
}
2011-05-19 10:02:55 +00:00
}
2016-08-28 17:32:58 +00:00
function get_sensor_by_id ( $sensor_id )
{
2011-03-23 09:54:56 +00:00
if ( is_numeric ( $sensor_id )) {
2011-05-12 17:59:00 +00:00
$sensor = dbFetchRow ( 'SELECT * FROM `sensors` WHERE `sensor_id` = ?' , [ $sensor_id ]);
2015-02-22 19:28:09 +00:00
if ( is_array ( $sensor )) {
return $sensor ;
2016-08-28 17:32:58 +00:00
} else {
return false ;
2015-07-13 18:10:26 +00:00
}
2015-02-22 19:28:09 +00:00
}
2010-08-01 14:17:06 +00:00
}
2016-08-28 17:32:58 +00:00
function get_device_id_by_port_id ( $port_id )
{
2011-03-23 09:54:56 +00:00
if ( is_numeric ( $port_id )) {
2011-05-12 17:59:00 +00:00
$device_id = dbFetchCell ( 'SELECT `device_id` FROM `ports` WHERE `port_id` = ?' , [ $port_id ]);
2015-02-22 19:28:09 +00:00
if ( is_numeric ( $device_id )) {
return $device_id ;
2016-08-28 17:32:58 +00:00
} else {
return false ;
2015-07-13 18:10:26 +00:00
}
2015-02-22 19:28:09 +00:00
}
2010-08-01 14:17:06 +00:00
}
2016-08-28 17:32:58 +00:00
function ifclass ( $ifOperStatus , $ifAdminStatus )
{
2018-12-07 22:24:53 +00:00
// fake a port model
return \LibreNMS\Util\Url :: portLinkDisplayClass (( object ) [ 'ifOperStatus' => $ifOperStatus , 'ifAdminStatus' => $ifAdminStatus ]);
2010-07-28 19:43:02 +00:00
}
2015-07-13 18:10:26 +00:00
2019-11-14 21:56:06 +00:00
function device_by_name ( $name )
2016-08-28 17:32:58 +00:00
{
2019-11-14 21:56:06 +00:00
return device_by_id_cache ( getidbyname ( $name ));
2011-10-03 13:40:37 +00:00
}
2016-08-28 17:32:58 +00:00
function accesspoint_by_id ( $ap_id , $refresh = '0' )
{
2015-02-18 21:31:01 +00:00
$ap = dbFetchRow ( 'SELECT * FROM `access_points` WHERE `accesspoint_id` = ?' , [ $ap_id ]);
2012-05-21 18:17:23 +00:00
return $ap ;
}
2017-12-20 14:36:49 +00:00
function device_by_id_cache ( $device_id , $refresh = false )
2016-08-28 17:32:58 +00:00
{
2020-09-11 12:28:46 +00:00
$model = $refresh ? DeviceCache :: refresh (( int ) $device_id ) : DeviceCache :: get (( int ) $device_id );
2011-03-11 18:03:49 +00:00
2019-11-14 21:56:06 +00:00
$device = $model -> toArray ();
2020-09-11 12:28:46 +00:00
$device [ 'location' ] = $model -> location -> location ? ? null ;
$device [ 'lat' ] = $model -> location -> lat ? ? null ;
$device [ 'lng' ] = $model -> location -> lng ? ? null ;
2019-11-14 21:56:06 +00:00
$device [ 'attribs' ] = $model -> getAttribs ();
2016-08-28 17:32:58 +00:00
2011-03-23 09:54:56 +00:00
return $device ;
2010-04-20 15:46:17 +00:00
}
2016-08-28 17:32:58 +00:00
function truncate ( $substring , $max = 50 , $rep = '...' )
{
2011-09-20 14:37:54 +00:00
if ( strlen ( $substring ) < 1 ) {
$string = $rep ;
2016-08-28 17:32:58 +00:00
} else {
2011-09-20 14:37:54 +00:00
$string = $substring ;
}
2016-08-28 17:32:58 +00:00
$leave = $max - strlen ( $rep );
2011-09-20 14:37:54 +00:00
if ( strlen ( $string ) > $max ) {
return substr_replace ( $string , $rep , $leave );
2016-08-28 17:32:58 +00:00
} else {
2011-09-20 14:37:54 +00:00
return $string ;
}
2009-10-28 13:49:37 +00:00
}
2019-11-14 21:56:06 +00:00
function gethostbyid ( $device_id )
2016-08-28 17:32:58 +00:00
{
2020-09-11 12:28:46 +00:00
return DeviceCache :: get (( int ) $device_id ) -> hostname ;
2009-05-07 13:47:51 +00:00
}
2016-08-28 17:32:58 +00:00
function strgen ( $length = 16 )
{
2011-03-23 09:54:56 +00:00
$entropy = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 'a' , 'A' , 'b' , 'B' , 'c' , 'C' , 'd' , 'D' , 'e' ,
'E' , 'f' , 'F' , 'g' , 'G' , 'h' , 'H' , 'i' , 'I' , 'j' , 'J' , 'k' , 'K' , 'l' , 'L' , 'm' , 'M' , 'n' ,
'N' , 'o' , 'O' , 'p' , 'P' , 'q' , 'Q' , 'r' , 'R' , 's' , 'S' , 't' , 'T' , 'u' , 'U' , 'v' , 'V' , 'w' ,
'W' , 'x' , 'X' , 'y' , 'Y' , 'z' , 'Z' , ];
$string = '' ;
2011-03-11 18:03:49 +00:00
2011-03-23 09:54:56 +00:00
for ( $i = 0 ; $i < $length ; $i ++ ) {
2016-08-28 17:32:58 +00:00
$key = mt_rand ( 0 , 61 );
2011-03-23 09:54:56 +00:00
$string .= $entropy [ $key ];
}
2011-03-11 18:03:49 +00:00
2011-03-23 09:54:56 +00:00
return $string ;
2009-05-07 13:47:51 +00:00
}
2016-08-28 17:32:58 +00:00
function getpeerhost ( $id )
{
2011-05-12 17:59:00 +00:00
return dbFetchCell ( 'SELECT `device_id` from `bgpPeers` WHERE `bgpPeer_id` = ?' , [ $id ]);
2009-05-07 13:47:51 +00:00
}
2016-08-28 17:32:58 +00:00
function getifindexbyid ( $id )
{
2012-05-16 13:25:50 +00:00
return dbFetchCell ( 'SELECT `ifIndex` FROM `ports` WHERE `port_id` = ?' , [ $id ]);
2009-05-07 13:47:51 +00:00
}
2016-08-28 17:32:58 +00:00
function getifbyid ( $id )
{
2012-05-16 13:25:50 +00:00
return dbFetchRow ( 'SELECT * FROM `ports` WHERE `port_id` = ?' , [ $id ]);
2010-01-08 23:09:25 +00:00
}
2016-08-28 17:32:58 +00:00
function getifdescrbyid ( $id )
{
2012-05-16 13:25:50 +00:00
return dbFetchCell ( 'SELECT `ifDescr` FROM `ports` WHERE `port_id` = ?' , [ $id ]);
2009-05-07 13:47:51 +00:00
}
2016-08-28 17:32:58 +00:00
function getidbyname ( $hostname )
{
2019-11-14 21:56:06 +00:00
return DeviceCache :: getByHostname ( $hostname ) -> device_id ;
2009-05-07 13:47:51 +00:00
}
2016-08-28 17:32:58 +00:00
function zeropad ( $num , $length = 2 )
{
2017-08-08 19:14:58 +00:00
return str_pad ( $num , $length , '0' , STR_PAD_LEFT );
2011-03-28 20:29:34 +00:00
}
2016-08-28 17:32:58 +00:00
function set_dev_attrib ( $device , $attrib_type , $attrib_value )
{
2020-09-11 12:28:46 +00:00
return DeviceCache :: get (( int ) $device [ 'device_id' ]) -> setAttrib ( $attrib_type , $attrib_value );
2011-03-31 17:19:54 +00:00
}
2019-11-14 21:56:06 +00:00
function get_dev_attribs ( $device_id )
2016-08-28 17:32:58 +00:00
{
2020-09-11 12:28:46 +00:00
return DeviceCache :: get (( int ) $device_id ) -> getAttribs ();
2011-05-03 20:13:15 +00:00
}
2016-08-28 17:32:58 +00:00
function get_dev_entity_state ( $device )
{
2011-11-14 18:28:00 +00:00
$state = [];
foreach ( dbFetchRows ( 'SELECT * FROM entPhysical_state WHERE `device_id` = ?' , [ $device ]) as $entity ) {
$state [ 'group' ][ $entity [ 'group' ]][ $entity [ 'entPhysicalIndex' ]][ $entity [ 'subindex' ]][ $entity [ 'key' ]] = $entity [ 'value' ];
$state [ 'index' ][ $entity [ 'entPhysicalIndex' ]][ $entity [ 'subindex' ]][ $entity [ 'group' ]][ $entity [ 'key' ]] = $entity [ 'value' ];
}
2020-09-21 13:40:17 +00:00
2011-11-14 18:28:00 +00:00
return $state ;
}
2019-11-14 21:56:06 +00:00
function get_dev_attrib ( $device , $attrib_type )
2016-08-28 17:32:58 +00:00
{
2020-09-11 12:28:46 +00:00
return DeviceCache :: get (( int ) $device [ 'device_id' ]) -> getAttrib ( $attrib_type );
2015-06-12 23:26:26 +00:00
}
2016-08-28 17:32:58 +00:00
function del_dev_attrib ( $device , $attrib_type )
{
2020-09-11 12:28:46 +00:00
return DeviceCache :: get (( int ) $device [ 'device_id' ]) -> forgetAttrib ( $attrib_type );
2011-03-31 17:19:54 +00:00
}
2011-03-28 20:29:34 +00:00
2016-08-17 00:52:36 +00:00
/**
* Output using console color if possible
* https :// github . com / pear / Console_Color2 / blob / master / examples / documentation
*
2021-09-08 21:35:56 +00:00
* @ param string $string the string to print with console color
* @ param bool $enabled if set to false , this function does nothing
2016-08-17 00:52:36 +00:00
*/
2016-08-17 21:00:43 +00:00
function c_echo ( $string , $enabled = true )
2016-08-17 00:52:36 +00:00
{
2016-08-28 17:32:58 +00:00
if ( ! $enabled ) {
2016-08-17 21:00:43 +00:00
return ;
}
2016-08-17 00:52:36 +00:00
2021-05-13 18:00:56 +00:00
if ( Laravel :: isCli ()) {
2017-07-17 18:02:28 +00:00
global $console_color ;
if ( $console_color ) {
echo $console_color -> convert ( $string );
} else {
// limited functionality for validate.php
$search = [
'/%n/' ,
'/%g/' ,
'/%R/' ,
'/%Y/' ,
'/%B/' ,
'/%((%)|.)/' , // anything left over replace with empty string
];
$replace = [
" \ e[0m " ,
" \ e[32m " ,
" \ e[1;31m " ,
" \ e[1;33m " ,
" \ e[1;34m " ,
'' ,
];
echo preg_replace ( $search , $replace , $string );
}
2016-08-17 00:52:36 +00:00
} else {
echo preg_replace ( '/%((%)|.)/' , '' , $string );
}
}
2015-06-13 12:50:37 +00:00
/*
* @ return true if client IP address is authorized to access graphs
*/
2016-08-28 17:32:58 +00:00
function is_client_authorized ( $clientip )
{
2017-08-08 19:14:58 +00:00
if ( Config :: get ( 'allow_unauth_graphs' , false )) {
2015-06-13 12:50:37 +00:00
d_echo ( " Unauthorized graphs allowed \n " );
2020-09-21 13:40:17 +00:00
2015-06-13 12:50:37 +00:00
return true ;
}
2017-08-08 19:14:58 +00:00
foreach ( Config :: get ( 'allow_unauth_graphs_cidr' , []) as $range ) {
try {
if ( IP :: parse ( $clientip ) -> inNetwork ( $range )) {
2015-06-13 12:50:37 +00:00
d_echo ( " Unauthorized graphs allowed from $range\n " );
2020-09-21 13:40:17 +00:00
2015-06-13 12:50:37 +00:00
return true ;
}
2017-08-08 19:14:58 +00:00
} catch ( InvalidIpException $e ) {
d_echo ( " Client IP ( $clientip ) is invalid. \n " );
2015-06-13 12:50:37 +00:00
}
}
return false ;
2015-11-15 08:18:13 +00:00
} // is_client_authorized
2015-06-13 12:55:18 +00:00
/*
* @ return an array of all graph subtypes for the given type
*/
2016-01-17 05:00:15 +00:00
function get_graph_subtypes ( $type , $device = null )
{
2019-04-12 04:26:42 +00:00
$type = basename ( $type );
2015-06-13 12:55:18 +00:00
$types = [];
// find the subtypes defined in files
2019-06-23 05:29:12 +00:00
if ( $handle = opendir ( Config :: get ( 'install_dir' ) . " /includes/html/graphs/ $type / " )) {
2015-06-13 12:55:18 +00:00
while ( false !== ( $file = readdir ( $handle ))) {
if ( $file != '.' && $file != '..' && $file != 'auth.inc.php' && strstr ( $file , '.inc.php' )) {
$types [] = str_replace ( '.inc.php' , '' , $file );
}
}
closedir ( $handle );
}
sort ( $types );
2020-09-21 13:40:17 +00:00
2015-06-13 12:55:18 +00:00
return $types ;
2015-11-15 08:18:13 +00:00
} // get_graph_subtypes
2016-08-28 17:32:58 +00:00
function get_smokeping_files ( $device )
{
2020-09-11 12:28:46 +00:00
$smokeping = new \LibreNMS\Util\Smokeping ( DeviceCache :: get (( int ) $device [ 'device_id' ]));
2020-09-21 13:40:17 +00:00
2020-04-29 12:25:13 +00:00
return $smokeping -> findFiles ();
}
2015-07-10 15:10:35 +00:00
2016-08-28 17:32:58 +00:00
function generate_smokeping_file ( $device , $file = '' )
{
2020-09-11 12:28:46 +00:00
$smokeping = new \LibreNMS\Util\Smokeping ( DeviceCache :: get (( int ) $device [ 'device_id' ]));
2020-09-21 13:40:17 +00:00
2020-04-29 12:25:13 +00:00
return $smokeping -> generateFileName ( $file );
}
2015-11-15 08:18:13 +00:00
2015-07-21 15:08:09 +00:00
/*
* @ return rounded value to 10 th / 100 th / 1000 th depending on input ( valid : 10 , 100 , 1000 )
*/
2016-08-28 17:32:58 +00:00
function round_Nth ( $val , $round_to )
{
2015-07-21 15:08:09 +00:00
if (( $round_to == '10' ) || ( $round_to == '100' ) || ( $round_to == '1000' )) {
$diff = $val % $round_to ;
if ( $diff >= ( $round_to / 2 )) {
$ret = $val + ( $round_to - $diff );
} else {
$ret = $val - $diff ;
}
2020-09-21 13:40:17 +00:00
2015-07-21 15:08:09 +00:00
return $ret ;
}
2016-08-28 17:32:58 +00:00
} // end round_Nth
2015-07-21 15:08:09 +00:00
2019-12-19 00:17:21 +00:00
function is_customoid_graph ( $type , $subtype )
{
if ( ! empty ( $subtype ) && $type == 'customoid' ) {
return true ;
}
2020-09-21 13:40:17 +00:00
2019-12-19 00:17:21 +00:00
return false ;
} // is_customoid_graph
2015-06-30 22:14:23 +00:00
2015-07-20 04:02:16 +00:00
//
// maintain a simple cache of objects
//
function object_add_cache ( $section , $obj )
{
global $object_cache ;
$object_cache [ $section ][ $obj ] = true ;
2015-11-15 08:18:13 +00:00
} // object_add_cache
2015-07-20 04:02:16 +00:00
function object_is_cached ( $section , $obj )
{
global $object_cache ;
2022-08-24 22:37:40 +00:00
if ( is_array ( $object_cache ) && array_key_exists ( $obj , $object_cache )) {
2015-12-06 08:07:51 +00:00
return $object_cache [ $section ][ $obj ];
2016-08-28 17:32:58 +00:00
} else {
2015-07-20 04:02:16 +00:00
return false ;
}
2015-11-15 08:18:13 +00:00
} // object_is_cached
2015-12-06 08:07:51 +00:00
function search_phrase_column ( $c )
{
global $searchPhrase ;
2020-09-21 13:40:17 +00:00
2015-12-06 08:07:51 +00:00
return " $c LIKE '% $searchPhrase %' " ;
} // search_phrase_column
2015-11-17 02:50:52 +00:00
/**
* Parse location field for coordinates
2021-09-10 18:09:53 +00:00
*
2015-11-17 02:50:52 +00:00
* @ param string location The location field to look for coords in .
Refactored and update Location Geocoding (#9359)
- Fix location so it is a regular database relation (this allows multiple devices to be accurately linked to one location and saves api calls)
- Parse coordinates from the location more consistently
- Add settings to webui
- ~~Used [PHP Geocoder](http://geocoder-php.org/), which has lots of backends and is well tested. (also includes reverse and geoip)~~
- Google Maps, Bing, Mapquest, and OpenStreetMap supported initially.
- Default to OpenStreetMap, which doesn't require a key. They will liberally hand out bans if you exceed 1 query per second though.
- All other Geocoding APIs require an API key. (Google requires a credit card on file, but seems to be the most accurate)
- Update all (I think) sql queries to handle the new structure
- Remove final vestiges of override_sysLocation as a device attribute
- Update existing device groups and rules in DB
- Tested all APIs with good/bad location, no/bad/good key, and no connection.
- Cannot fix advanced queries that use location
This blocks #8868
DO NOT DELETE THIS TEXT
#### Please note
> Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting.
- [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/)
#### Testers
If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926`
After you are done testing, you can remove the changes with `./scripts/github-remove`. If there are schema changes, you can ask on discord how to revert.
2018-11-28 22:49:18 +00:00
* @ return array | bool Containing the lat and lng coords
2018-08-05 08:50:13 +00:00
**/
2016-08-28 17:32:58 +00:00
function parse_location ( $location )
{
Refactored and update Location Geocoding (#9359)
- Fix location so it is a regular database relation (this allows multiple devices to be accurately linked to one location and saves api calls)
- Parse coordinates from the location more consistently
- Add settings to webui
- ~~Used [PHP Geocoder](http://geocoder-php.org/), which has lots of backends and is well tested. (also includes reverse and geoip)~~
- Google Maps, Bing, Mapquest, and OpenStreetMap supported initially.
- Default to OpenStreetMap, which doesn't require a key. They will liberally hand out bans if you exceed 1 query per second though.
- All other Geocoding APIs require an API key. (Google requires a credit card on file, but seems to be the most accurate)
- Update all (I think) sql queries to handle the new structure
- Remove final vestiges of override_sysLocation as a device attribute
- Update existing device groups and rules in DB
- Tested all APIs with good/bad location, no/bad/good key, and no connection.
- Cannot fix advanced queries that use location
This blocks #8868
DO NOT DELETE THIS TEXT
#### Please note
> Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting.
- [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/)
#### Testers
If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926`
After you are done testing, you can remove the changes with `./scripts/github-remove`. If there are schema changes, you can ask on discord how to revert.
2018-11-28 22:49:18 +00:00
preg_match ( '/\[(-?[0-9. ]+), *(-?[0-9. ]+)\]/' , $location , $tmp_loc );
if ( is_numeric ( $tmp_loc [ 1 ]) && is_numeric ( $tmp_loc [ 2 ])) {
return [ 'lat' => $tmp_loc [ 1 ], 'lng' => $tmp_loc [ 2 ]];
2015-11-17 02:50:52 +00:00
}
Refactored and update Location Geocoding (#9359)
- Fix location so it is a regular database relation (this allows multiple devices to be accurately linked to one location and saves api calls)
- Parse coordinates from the location more consistently
- Add settings to webui
- ~~Used [PHP Geocoder](http://geocoder-php.org/), which has lots of backends and is well tested. (also includes reverse and geoip)~~
- Google Maps, Bing, Mapquest, and OpenStreetMap supported initially.
- Default to OpenStreetMap, which doesn't require a key. They will liberally hand out bans if you exceed 1 query per second though.
- All other Geocoding APIs require an API key. (Google requires a credit card on file, but seems to be the most accurate)
- Update all (I think) sql queries to handle the new structure
- Remove final vestiges of override_sysLocation as a device attribute
- Update existing device groups and rules in DB
- Tested all APIs with good/bad location, no/bad/good key, and no connection.
- Cannot fix advanced queries that use location
This blocks #8868
DO NOT DELETE THIS TEXT
#### Please note
> Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting.
- [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/)
#### Testers
If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926`
After you are done testing, you can remove the changes with `./scripts/github-remove`. If there are schema changes, you can ask on discord how to revert.
2018-11-28 22:49:18 +00:00
return false ;
2015-11-17 02:50:52 +00:00
} //end parse_location()
2016-01-06 00:14:35 +00:00
2016-01-17 23:59:51 +00:00
/**
2018-08-05 08:50:13 +00:00
* Convert a MySQL binary v4 ( 4 - byte ) or v6 ( 16 - byte ) IP address to a printable string .
2021-09-10 18:09:53 +00:00
*
2021-09-08 21:35:56 +00:00
* @ param string $ip A binary string containing an IP address , as returned from MySQL ' s INET6_ATON function
2018-08-05 08:50:13 +00:00
* @ return string Empty if not valid .
*/
2021-02-08 23:29:04 +00:00
// Fuction is from https://php.net/manual/en/function.inet-ntop.php
2016-08-28 17:32:58 +00:00
function inet6_ntop ( $ip )
{
2016-01-17 23:59:51 +00:00
$l = strlen ( $ip );
if ( $l == 4 or $l == 16 ) {
return inet_ntop ( pack ( 'A' . $l , $ip ));
}
2020-09-21 13:40:17 +00:00
2016-01-17 23:59:51 +00:00
return '' ;
}
2016-01-19 09:00:18 +00:00
2016-01-17 22:01:09 +00:00
/**
2017-05-05 11:25:58 +00:00
* If hostname is an ip , use return sysName
2021-09-10 18:09:53 +00:00
*
2021-09-08 21:35:56 +00:00
* @ param array $device ( uses hostname and sysName fields )
2016-01-17 22:01:09 +00:00
* @ return string
2018-07-02 13:23:09 +00:00
*/
2021-11-18 21:46:22 +00:00
function format_hostname ( $device ) : string
{
$hostname = $device [ 'hostname' ] ? ? 'invalid hostname' ;
$hostname_is_ip = IP :: isValid ( $hostname );
$sysName = empty ( $device [ 'sysName' ]) ? $hostname : $device [ 'sysName' ];
return \App\View\SimpleTemplate :: parse ( empty ( $device [ 'display' ]) ? Config :: get ( 'device_display_default' , '{{ $hostname }}' ) : $device [ 'display' ], [
'hostname' => $hostname ,
'sysName' => $sysName ,
'sysName_fallback' => $hostname_is_ip ? $sysName : $hostname ,
'ip' => empty ( $device [ 'overwrite_ip' ]) ? ( $hostname_is_ip ? $device [ 'hostname' ] : $device [ 'ip' ] ? ? '' ) : $device [ 'overwrite_ip' ],
]);
2018-07-02 13:23:09 +00:00
}
2016-01-26 12:49:30 +00:00
/**
* Query all ports of the given device ( by ID ) and build port array and
* port association maps for ifIndex , ifName , ifDescr . Query port stats
* if told to do so , too .
2021-09-10 18:09:53 +00:00
*
2021-09-08 21:35:56 +00:00
* @ param int $device_id ID of device to query ports for
* @ param bool $with_statistics Query port statistics , too . ( optional , default false )
2016-01-26 12:49:30 +00:00
* @ return array
*/
2016-08-28 17:32:58 +00:00
function get_ports_mapped ( $device_id , $with_statistics = false )
{
2016-01-30 10:05:46 +00:00
$ports = [];
2016-01-30 10:10:16 +00:00
$maps = [
2016-01-30 10:05:46 +00:00
'ifIndex' => [],
'ifName' => [],
'ifDescr' => [],
];
2016-01-26 12:49:30 +00:00
if ( $with_statistics ) {
/* ... including any related ports_statistics if requested */
$query = 'SELECT *, `ports_statistics`.`port_id` AS `ports_statistics_port_id`, `ports`.`port_id` AS `port_id` FROM `ports` LEFT OUTER JOIN `ports_statistics` ON `ports`.`port_id` = `ports_statistics`.`port_id` WHERE `ports`.`device_id` = ? ORDER BY ports.port_id' ;
2016-10-15 01:03:26 +00:00
} else {
/* Query all information available for ports for this device ... */
$query = 'SELECT * FROM `ports` WHERE `device_id` = ? ORDER BY port_id' ;
2016-01-26 12:49:30 +00:00
}
// Query known ports in order of discovery to make sure the latest
// discoverd/polled port is in the mapping tables.
2016-08-28 17:32:58 +00:00
foreach ( dbFetchRows ( $query , [ $device_id ]) as $port ) {
2016-01-26 12:49:30 +00:00
// Store port information by ports port_id from DB
$ports [ $port [ 'port_id' ]] = $port ;
// Build maps from ifIndex, ifName, ifDescr to port_id
$maps [ 'ifIndex' ][ $port [ 'ifIndex' ]] = $port [ 'port_id' ];
$maps [ 'ifName' ][ $port [ 'ifName' ]] = $port [ 'port_id' ];
$maps [ 'ifDescr' ][ $port [ 'ifDescr' ]] = $port [ 'port_id' ];
}
2016-01-30 10:05:46 +00:00
return [
2016-01-26 12:49:30 +00:00
'ports' => $ports ,
'maps' => $maps ,
2016-01-30 10:05:46 +00:00
];
2016-01-26 12:49:30 +00:00
}
/**
* Calculate port_id of given port using given devices port information and port association mode
2021-09-10 18:09:53 +00:00
*
2021-09-08 21:35:56 +00:00
* @ param array $ports_mapped Port information of device queried by get_ports_mapped ()
* @ param array $port Port information as fetched from DB
* @ param string $port_association_mode Port association mode to use for mapping
2016-01-26 12:49:30 +00:00
* @ return int port_id ( or Null )
*/
2016-08-28 17:32:58 +00:00
function get_port_id ( $ports_mapped , $port , $port_association_mode )
{
2016-01-26 12:49:30 +00:00
// Get port_id according to port_association_mode used for this device
2016-08-28 17:32:58 +00:00
$port_id = null ;
2016-01-26 12:49:30 +00:00
/*
* Information an all ports is available through $ports_mapped [ 'ports' ]
* This might come in handy sometime in the future to add you nifty new
* port mapping schema :
*
* $ports = $ports_mapped [ 'ports' ];
*/
$maps = $ports_mapped [ 'maps' ];
2016-08-28 17:32:58 +00:00
if ( in_array ( $port_association_mode , [ 'ifIndex' , 'ifName' , 'ifDescr' , 'ifAlias' ])) {
2022-10-25 17:27:28 +00:00
$port_id = $maps [ $port_association_mode ][ $port [ $port_association_mode ]] ? ? null ;
2016-01-26 12:49:30 +00:00
}
return $port_id ;
}
2016-06-22 08:42:48 +00:00
/**
* Create a glue - chain
2021-09-10 18:09:53 +00:00
*
2021-09-08 21:35:56 +00:00
* @ param array $tables Initial Tables to construct glue - chain
* @ param string $target Glue to find ( usual device_id )
* @ param int $x Recursion Anchor
* @ param array $hist History of processed tables
* @ param array $last Glues on the fringe
2017-12-02 23:03:36 +00:00
* @ return array | false
2016-06-22 08:42:48 +00:00
*/
2016-08-28 17:32:58 +00:00
function ResolveGlues ( $tables , $target , $x = 0 , $hist = [], $last = [])
{
if ( sizeof ( $tables ) == 1 && $x != 0 ) {
if ( dbFetchCell ( 'SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_NAME = ? && COLUMN_NAME = ?' , [ $tables [ 0 ], $target ]) == 1 ) {
return array_merge ( $last , [ $tables [ 0 ] . '.' . $target ]);
} else {
2016-06-22 08:42:48 +00:00
return false ;
}
2016-08-28 17:32:58 +00:00
} else {
2016-06-22 08:42:48 +00:00
$x ++ ;
2016-08-28 17:32:58 +00:00
if ( $x > 30 ) {
2016-06-22 08:42:48 +00:00
//Too much recursion. Abort.
return false ;
}
2016-08-28 17:32:58 +00:00
foreach ( $tables as $table ) {
2017-12-02 23:03:36 +00:00
if ( $table == 'state_translations' && ( $target == 'device_id' || $target == 'sensor_id' )) {
// workaround for state_translations
2017-12-06 22:13:10 +00:00
return array_merge ( $last , [
2017-12-02 23:03:36 +00:00
'state_translations.state_index_id' ,
'sensors_to_state_indexes.sensor_id' ,
" sensors. $target " ,
2017-12-06 22:13:10 +00:00
]);
Refactored and update Location Geocoding (#9359)
- Fix location so it is a regular database relation (this allows multiple devices to be accurately linked to one location and saves api calls)
- Parse coordinates from the location more consistently
- Add settings to webui
- ~~Used [PHP Geocoder](http://geocoder-php.org/), which has lots of backends and is well tested. (also includes reverse and geoip)~~
- Google Maps, Bing, Mapquest, and OpenStreetMap supported initially.
- Default to OpenStreetMap, which doesn't require a key. They will liberally hand out bans if you exceed 1 query per second though.
- All other Geocoding APIs require an API key. (Google requires a credit card on file, but seems to be the most accurate)
- Update all (I think) sql queries to handle the new structure
- Remove final vestiges of override_sysLocation as a device attribute
- Update existing device groups and rules in DB
- Tested all APIs with good/bad location, no/bad/good key, and no connection.
- Cannot fix advanced queries that use location
This blocks #8868
DO NOT DELETE THIS TEXT
#### Please note
> Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting.
- [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/)
#### Testers
If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926`
After you are done testing, you can remove the changes with `./scripts/github-remove`. If there are schema changes, you can ask on discord how to revert.
2018-11-28 22:49:18 +00:00
} elseif ( $table == 'application_metrics' && $target == 'device_id' ) {
2017-12-06 22:13:10 +00:00
return array_merge ( $last , [
'application_metrics.app_id' ,
" applications. $target " ,
]);
Refactored and update Location Geocoding (#9359)
- Fix location so it is a regular database relation (this allows multiple devices to be accurately linked to one location and saves api calls)
- Parse coordinates from the location more consistently
- Add settings to webui
- ~~Used [PHP Geocoder](http://geocoder-php.org/), which has lots of backends and is well tested. (also includes reverse and geoip)~~
- Google Maps, Bing, Mapquest, and OpenStreetMap supported initially.
- Default to OpenStreetMap, which doesn't require a key. They will liberally hand out bans if you exceed 1 query per second though.
- All other Geocoding APIs require an API key. (Google requires a credit card on file, but seems to be the most accurate)
- Update all (I think) sql queries to handle the new structure
- Remove final vestiges of override_sysLocation as a device attribute
- Update existing device groups and rules in DB
- Tested all APIs with good/bad location, no/bad/good key, and no connection.
- Cannot fix advanced queries that use location
This blocks #8868
DO NOT DELETE THIS TEXT
#### Please note
> Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting.
- [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/)
#### Testers
If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926`
After you are done testing, you can remove the changes with `./scripts/github-remove`. If there are schema changes, you can ask on discord how to revert.
2018-11-28 22:49:18 +00:00
} elseif ( $table == 'locations' && $target == 'device_id' ) {
return array_merge ( $last , [
'locations.id' ,
'devices.device_id.location_id' ,
]);
2017-12-02 23:03:36 +00:00
}
2016-08-28 17:32:58 +00:00
$glues = dbFetchRows ( 'SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = ? && COLUMN_NAME LIKE "%\_id"' , [ $table ]);
if ( sizeof ( $glues ) == 1 && $glues [ 0 ][ 'COLUMN_NAME' ] != $target ) {
2016-06-22 08:42:48 +00:00
//Search for new candidates to expand
$ntables = [];
2020-05-19 19:35:32 +00:00
[ $tmp ] = explode ( '_' , $glues [ 0 ][ 'COLUMN_NAME' ], 2 );
2016-06-22 08:42:48 +00:00
$ntables [] = $tmp ;
$ntables [] = $tmp . 's' ;
2016-08-28 17:32:58 +00:00
$tmp = dbFetchRows ( 'SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME LIKE "' . substr ( $table , 0 , - 1 ) . '_%" && TABLE_NAME != "' . $table . '"' );
foreach ( $tmp as $expand ) {
2016-06-22 08:42:48 +00:00
$ntables [] = $expand [ 'TABLE_NAME' ];
}
2016-08-28 17:32:58 +00:00
$tmp = ResolveGlues ( $ntables , $target , $x ++ , array_merge ( $tables , $ntables ), array_merge ( $last , [ $table . '.' . $glues [ 0 ][ 'COLUMN_NAME' ]]));
if ( is_array ( $tmp )) {
2016-06-22 08:42:48 +00:00
return $tmp ;
}
2016-08-28 17:32:58 +00:00
} else {
foreach ( $glues as $glue ) {
if ( $glue [ 'COLUMN_NAME' ] == $target ) {
return array_merge ( $last , [ $table . '.' . $target ]);
} else {
2020-05-19 19:35:32 +00:00
[ $tmp ] = explode ( '_' , $glue [ 'COLUMN_NAME' ]);
2016-06-22 08:42:48 +00:00
$tmp .= 's' ;
2016-08-28 17:32:58 +00:00
if ( ! in_array ( $tmp , $tables ) && ! in_array ( $tmp , $hist )) {
2016-06-22 08:42:48 +00:00
//Expand table
2016-08-28 17:32:58 +00:00
$tmp = ResolveGlues ([ $tmp ], $target , $x ++ , array_merge ( $tables , [ $tmp ]), array_merge ( $last , [ $table . '.' . $glue [ 'COLUMN_NAME' ]]));
if ( is_array ( $tmp )) {
2016-06-22 08:42:48 +00:00
return $tmp ;
}
}
}
}
}
}
}
//You should never get here.
return false ;
}
2016-08-19 19:57:08 +00:00
/**
2018-01-29 21:58:21 +00:00
* Determine if a given string contains a given substring .
2016-08-19 19:57:08 +00:00
*
2021-09-08 21:35:56 +00:00
* @ param string $haystack
* @ param string | array $needles
2016-08-19 19:57:08 +00:00
* @ return bool
*/
2018-01-29 21:58:21 +00:00
function str_i_contains ( $haystack , $needles )
2016-08-19 19:57:08 +00:00
{
2018-01-29 21:58:21 +00:00
foreach (( array ) $needles as $needle ) {
if ( $needle != '' && stripos ( $haystack , $needle ) !== false ) {
return true ;
2016-08-19 19:57:08 +00:00
}
}
2020-09-21 13:40:17 +00:00
2016-08-19 19:57:08 +00:00
return false ;
}
2019-12-16 22:58:54 +00:00
/**
* Get alert_rules sql filter by minimal severity
*
2021-09-08 21:35:56 +00:00
* @ param string | int $min_severity
* @ param string $alert_rules_name
2019-12-16 22:58:54 +00:00
* @ return string
*/
function get_sql_filter_min_severity ( $min_severity , $alert_rules_name )
{
$alert_severities = [
// alert_rules.status is enum('ok','warning','critical')
'ok' => 1 ,
'warning' => 2 ,
'critical' => 3 ,
'ok only' => 4 ,
'warning only' => 5 ,
'critical only' => 6 ,
];
if ( is_numeric ( $min_severity )) {
$min_severity_id = $min_severity ;
} elseif ( ! empty ( $min_severity )) {
$min_severity_id = $alert_severities [ $min_severity ];
}
if ( isset ( $min_severity_id )) {
return " AND ` $alert_rules_name `.`severity` " . ( $min_severity_id > 3 ? '' : '>' ) . '= ' . ( $min_severity_id > 3 ? $min_severity_id - 3 : $min_severity_id );
}
2020-09-21 13:40:17 +00:00
2019-12-16 22:58:54 +00:00
return '' ;
}
2017-01-13 12:47:16 +00:00
/**
2017-08-28 17:57:23 +00:00
* Converts fahrenheit to celsius ( with 2 decimal places )
* if $scale is not fahrenheit , it assumes celsius and returns the value
*
2021-09-08 21:35:56 +00:00
* @ param float $value
* @ param string $scale fahrenheit or celsius
2017-08-28 17:57:23 +00:00
* @ return string ( containing a float )
2017-01-18 08:48:33 +00:00
*/
2017-08-28 17:57:23 +00:00
function fahrenheit_to_celsius ( $value , $scale = 'fahrenheit' )
2017-01-18 08:48:33 +00:00
{
if ( $scale === 'fahrenheit' ) {
$value = ( $value - 32 ) / 1.8 ;
}
2020-09-21 13:40:17 +00:00
2017-01-18 08:48:33 +00:00
return sprintf ( '%.02f' , $value );
}
2017-08-19 19:22:23 +00:00
2019-12-19 00:17:21 +00:00
/**
* Converts celsius to fahrenheit ( with 2 decimal places )
* if $scale is not celsius , it assumes celsius and returns the value
*
2021-09-08 21:35:56 +00:00
* @ param float $value
* @ param string $scale fahrenheit or celsius
2019-12-19 00:17:21 +00:00
* @ return string ( containing a float )
*/
function celsius_to_fahrenheit ( $value , $scale = 'celsius' )
{
if ( $scale === 'celsius' ) {
$value = ( $value * 1.8 ) + 32 ;
}
2020-09-21 13:40:17 +00:00
2019-12-19 00:17:21 +00:00
return sprintf ( '%.02f' , $value );
}
2020-09-13 21:03:35 +00:00
/**
* Converts string to float
*/
function string_to_float ( $value )
{
return sprintf ( '%.02f' , $value );
}
2018-09-19 15:00:11 +00:00
/**
* Converts uW to dBm
* $value must be positive
*/
2017-01-19 16:42:57 +00:00
function uw_to_dbm ( $value )
{
2023-03-15 13:07:46 +00:00
return $value == 0 ? - 60 : 10 * log10 ( $value / 1000 );
2017-01-19 16:42:57 +00:00
}
2018-09-19 15:00:11 +00:00
2020-09-08 13:07:04 +00:00
/**
* Converts mW to dBm
* $value must be positive
*/
function mw_to_dbm ( $value )
{
2023-03-15 13:07:46 +00:00
return $value == 0 ? - 60 : 10 * log10 ( $value );
2020-09-08 13:07:04 +00:00
}
2017-01-18 08:48:33 +00:00
/**
2023-06-13 11:35:00 +00:00
* @ param $value
2021-09-08 21:35:56 +00:00
* @ param null $default
* @ param int $min
2017-01-18 08:48:33 +00:00
* @ return null
*/
2017-03-08 04:15:22 +00:00
function set_null ( $value , $default = null , $min = null )
2017-01-18 08:48:33 +00:00
{
2018-07-13 22:08:00 +00:00
if ( ! is_numeric ( $value )) {
2017-09-07 13:49:32 +00:00
return $default ;
2018-07-13 22:08:00 +00:00
} elseif ( is_nan ( $value )) {
2017-09-07 13:49:32 +00:00
return $default ;
2018-07-13 22:08:00 +00:00
} elseif ( is_infinite ( $value )) {
2017-03-08 04:15:22 +00:00
return $default ;
} elseif ( isset ( $min ) && $value < $min ) {
return $default ;
2017-01-18 08:48:33 +00:00
}
2020-09-21 13:40:17 +00:00
2017-01-18 08:48:33 +00:00
return $value ;
}
/*
2017-01-13 12:47:16 +00:00
* @ param $value
* @ param int $default
* @ return int
*/
function set_numeric ( $value , $default = 0 )
{
2018-07-13 22:08:00 +00:00
if ( ! is_numeric ( $value ) ||
is_nan ( $value ) ||
is_infinite ( $value )
2017-09-07 13:49:32 +00:00
) {
2017-01-13 12:47:16 +00:00
$value = $default ;
}
2020-09-21 13:40:17 +00:00
2017-01-13 12:47:16 +00:00
return $value ;
}
2017-01-26 22:38:43 +00:00
function get_vm_parent_id ( $device )
{
if ( empty ( $device [ 'hostname' ])) {
return false ;
}
2019-06-23 05:29:12 +00:00
return dbFetchCell ( 'SELECT `device_id` FROM `vminfo` WHERE `vmwVmDisplayName` = ? OR `vmwVmDisplayName` = ?' , [ $device [ 'hostname' ], $device [ 'hostname' ] . '.' . Config :: get ( 'mydomain' )]);
2017-01-26 22:38:43 +00:00
}
2017-03-05 03:25:06 +00:00
feature: Wireless Sensors Overhaul (#6471)
* feature: Wireless Sensors
Includes client counts for ios and unifi
Graphing could use some improvement.
Alerting and threshold ui not implemented
WIP: starting OO based wireless sensors.
Class based functionality working
remove old functional files
add schema file
discovery needs to be enabled, not polling
fix up schema
fix Unifi discovery not returning an array
Add some debug when discovering a sensor.
Fix style.
Add missing semicolin
Add a null object (Generic) for OS.
Fill out some phpdocs
Re-organized code
Each sensor type now has it's own discovery and polling interface
Custom polling tested with Unifi CCQ
Left to do:
Implement UI (Graphs and Custom thresholds)
Alerting
Testing
Fix event message text
Remove runDiscovery and runPolling from OS, they are unused and don't belong there.
Cleanups/docs
Missed this file.
Remove the requirement to fetch the current value to check validity.
Do that automatically if current is not specified
A few cleanups here and there
First pass at graphing.
device_ and wireless_ graphs added.
Add RouterOS support
Singleton OS instance isn't required right now.
Remove that to allow some memory to be freed.
Add wireless to the device list metrics.
Make all metrics clickable
Tweak graphs a bit
Implement limit configuration page.
Use sensors page as common code instead of duplicating.
Clean up some javascript interactions: Allow enter on values to save. Cancel if update is not needed. Enable the clear custom button after setting a custom value.
Add some wireless alert rules to the library.
Add documentation.
Add unifi client counts by ssid in addition to radio.
Optimize Sensor polling a bit.
Add HP MSM clients support (for full controller)
Fix function accessibility
Formalize the discovery and poller interfaces.
Add Xirrus clients and noise floor
move module interfaces to a more appropriate place.
push caching code up to os, unsure about this do to the limitations
No point in selectively enabling wireless discovery. We only discover if the device supports something.
Add RSSI, Power, and Rate.
Add these sensors for Ubnt Airos.
Clean up some copyrights.
Reduce the amount of files need to add new types.
Leave graph files for consistency and to allow customization.
Remove the old wifi clients graph completely.
ciscowlc should have improved counts (total and per-ssid)
Schema didn't get added.
Impelement the rest of the AirOS sensors
Reformat and re-organize the Airos.php class.
Add several UBNT AirFiber sensors
A few fixes add links to the section headers
Add HP MSM mibs.
* Schema file got dropped in rebase.
* Add wireless menu to view sensors across all devices.
Icons in the menu need help :/
* Add HeliOS, Mimosa, and Siklu support
Sensors added SNR + Noise
* Add power and utilization to Unifi
* Update polling to prefetch all sensor data in a few snmp requests as possible
* Add Extendair: tx+rx power, aggregate rate, frequency
* Add a check for duplicate sensors in discovery. Just print an error for now.
* Add Bit Error Ratio (named error-ratio to allow for bit error rate to be added if needed)
Fix an incorrect link in the wireless sensors table
* Add error rate and change all bps and Hz to use si units
* Fixes to limits and frequency display
* Fix overview graph frequency display
A few decimal place tweaks
* Don't allow switching sensor and wireless-sensor graphs, it doesn't work.
Change individual distance graphs to use si units
* Go through the OS and make sure I got all the sensors I can (probably missed some still)
Because pollWirelessChannelAsFrequency() is generic and a little complex, so pull it up to OS.
Message to help developers adding supports that don't return an array from discover functions.
* Fix some issues
* Remove noise and signal for now at least
A couple more fixes
Add a notification
* Oopsie
* Bonus AirFiber sensors
2017-05-02 04:49:11 +00:00
/**
* Generate a class name from a lowercase string containing - or _
* Remove - and _ and camel case words
*
2021-09-08 21:35:56 +00:00
* @ param string $name The string to convert to a class name
* @ param string $namespace namespace to prepend to the name for example : LibreNMS\
* @ return string Class name
feature: Wireless Sensors Overhaul (#6471)
* feature: Wireless Sensors
Includes client counts for ios and unifi
Graphing could use some improvement.
Alerting and threshold ui not implemented
WIP: starting OO based wireless sensors.
Class based functionality working
remove old functional files
add schema file
discovery needs to be enabled, not polling
fix up schema
fix Unifi discovery not returning an array
Add some debug when discovering a sensor.
Fix style.
Add missing semicolin
Add a null object (Generic) for OS.
Fill out some phpdocs
Re-organized code
Each sensor type now has it's own discovery and polling interface
Custom polling tested with Unifi CCQ
Left to do:
Implement UI (Graphs and Custom thresholds)
Alerting
Testing
Fix event message text
Remove runDiscovery and runPolling from OS, they are unused and don't belong there.
Cleanups/docs
Missed this file.
Remove the requirement to fetch the current value to check validity.
Do that automatically if current is not specified
A few cleanups here and there
First pass at graphing.
device_ and wireless_ graphs added.
Add RouterOS support
Singleton OS instance isn't required right now.
Remove that to allow some memory to be freed.
Add wireless to the device list metrics.
Make all metrics clickable
Tweak graphs a bit
Implement limit configuration page.
Use sensors page as common code instead of duplicating.
Clean up some javascript interactions: Allow enter on values to save. Cancel if update is not needed. Enable the clear custom button after setting a custom value.
Add some wireless alert rules to the library.
Add documentation.
Add unifi client counts by ssid in addition to radio.
Optimize Sensor polling a bit.
Add HP MSM clients support (for full controller)
Fix function accessibility
Formalize the discovery and poller interfaces.
Add Xirrus clients and noise floor
move module interfaces to a more appropriate place.
push caching code up to os, unsure about this do to the limitations
No point in selectively enabling wireless discovery. We only discover if the device supports something.
Add RSSI, Power, and Rate.
Add these sensors for Ubnt Airos.
Clean up some copyrights.
Reduce the amount of files need to add new types.
Leave graph files for consistency and to allow customization.
Remove the old wifi clients graph completely.
ciscowlc should have improved counts (total and per-ssid)
Schema didn't get added.
Impelement the rest of the AirOS sensors
Reformat and re-organize the Airos.php class.
Add several UBNT AirFiber sensors
A few fixes add links to the section headers
Add HP MSM mibs.
* Schema file got dropped in rebase.
* Add wireless menu to view sensors across all devices.
Icons in the menu need help :/
* Add HeliOS, Mimosa, and Siklu support
Sensors added SNR + Noise
* Add power and utilization to Unifi
* Update polling to prefetch all sensor data in a few snmp requests as possible
* Add Extendair: tx+rx power, aggregate rate, frequency
* Add a check for duplicate sensors in discovery. Just print an error for now.
* Add Bit Error Ratio (named error-ratio to allow for bit error rate to be added if needed)
Fix an incorrect link in the wireless sensors table
* Add error rate and change all bps and Hz to use si units
* Fixes to limits and frequency display
* Fix overview graph frequency display
A few decimal place tweaks
* Don't allow switching sensor and wireless-sensor graphs, it doesn't work.
Change individual distance graphs to use si units
* Go through the OS and make sure I got all the sensors I can (probably missed some still)
Because pollWirelessChannelAsFrequency() is generic and a little complex, so pull it up to OS.
Message to help developers adding supports that don't return an array from discover functions.
* Fix some issues
* Remove noise and signal for now at least
A couple more fixes
Add a notification
* Oopsie
* Bonus AirFiber sensors
2017-05-02 04:49:11 +00:00
*/
function str_to_class ( $name , $namespace = null )
{
2021-10-19 20:43:43 +00:00
return \LibreNMS\Util\StringHelpers :: toClass ( $name , $namespace );
feature: Wireless Sensors Overhaul (#6471)
* feature: Wireless Sensors
Includes client counts for ios and unifi
Graphing could use some improvement.
Alerting and threshold ui not implemented
WIP: starting OO based wireless sensors.
Class based functionality working
remove old functional files
add schema file
discovery needs to be enabled, not polling
fix up schema
fix Unifi discovery not returning an array
Add some debug when discovering a sensor.
Fix style.
Add missing semicolin
Add a null object (Generic) for OS.
Fill out some phpdocs
Re-organized code
Each sensor type now has it's own discovery and polling interface
Custom polling tested with Unifi CCQ
Left to do:
Implement UI (Graphs and Custom thresholds)
Alerting
Testing
Fix event message text
Remove runDiscovery and runPolling from OS, they are unused and don't belong there.
Cleanups/docs
Missed this file.
Remove the requirement to fetch the current value to check validity.
Do that automatically if current is not specified
A few cleanups here and there
First pass at graphing.
device_ and wireless_ graphs added.
Add RouterOS support
Singleton OS instance isn't required right now.
Remove that to allow some memory to be freed.
Add wireless to the device list metrics.
Make all metrics clickable
Tweak graphs a bit
Implement limit configuration page.
Use sensors page as common code instead of duplicating.
Clean up some javascript interactions: Allow enter on values to save. Cancel if update is not needed. Enable the clear custom button after setting a custom value.
Add some wireless alert rules to the library.
Add documentation.
Add unifi client counts by ssid in addition to radio.
Optimize Sensor polling a bit.
Add HP MSM clients support (for full controller)
Fix function accessibility
Formalize the discovery and poller interfaces.
Add Xirrus clients and noise floor
move module interfaces to a more appropriate place.
push caching code up to os, unsure about this do to the limitations
No point in selectively enabling wireless discovery. We only discover if the device supports something.
Add RSSI, Power, and Rate.
Add these sensors for Ubnt Airos.
Clean up some copyrights.
Reduce the amount of files need to add new types.
Leave graph files for consistency and to allow customization.
Remove the old wifi clients graph completely.
ciscowlc should have improved counts (total and per-ssid)
Schema didn't get added.
Impelement the rest of the AirOS sensors
Reformat and re-organize the Airos.php class.
Add several UBNT AirFiber sensors
A few fixes add links to the section headers
Add HP MSM mibs.
* Schema file got dropped in rebase.
* Add wireless menu to view sensors across all devices.
Icons in the menu need help :/
* Add HeliOS, Mimosa, and Siklu support
Sensors added SNR + Noise
* Add power and utilization to Unifi
* Update polling to prefetch all sensor data in a few snmp requests as possible
* Add Extendair: tx+rx power, aggregate rate, frequency
* Add a check for duplicate sensors in discovery. Just print an error for now.
* Add Bit Error Ratio (named error-ratio to allow for bit error rate to be added if needed)
Fix an incorrect link in the wireless sensors table
* Add error rate and change all bps and Hz to use si units
* Fixes to limits and frequency display
* Fix overview graph frequency display
A few decimal place tweaks
* Don't allow switching sensor and wireless-sensor graphs, it doesn't work.
Change individual distance graphs to use si units
* Go through the OS and make sure I got all the sensors I can (probably missed some still)
Because pollWirelessChannelAsFrequency() is generic and a little complex, so pull it up to OS.
Message to help developers adding supports that don't return an array from discover functions.
* Fix some issues
* Remove noise and signal for now at least
A couple more fixes
Add a notification
* Oopsie
* Bonus AirFiber sensors
2017-05-02 04:49:11 +00:00
}
2017-11-23 08:29:10 +00:00
2017-12-01 07:53:26 +00:00
/**
* Index an array by a column
*
2021-09-08 21:35:56 +00:00
* @ param array $array
* @ param string | int $column
2017-12-01 07:53:26 +00:00
* @ return array
*/
function array_by_column ( $array , $column )
{
return array_combine ( array_column ( $array , $column ), $array );
}