2010-02-15 01:26:50 +00:00
<? php
2010-08-11 17:08:56 +00:00
2011-09-15 15:03:42 +00:00
/*
2016-09-08 14:12:23 +01:00
* LibreNMS Network Management and Monitoring System
2011-09-15 15:03:42 +00:00
* Copyright (C) 2006-2011, Observium Developers - http://www.observium.org
*
* 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.
*
* See COPYING for more details.
*/
2021-12-02 05:52:37 +01:00
use App\Models\Ipv6Address ;
use App\Models\Ipv6Network ;
use App\Models\Port ;
2020-04-17 17:37:56 -05:00
use Illuminate\Support\Str ;
2017-09-11 15:26:41 -05:00
use LibreNMS\Config ;
2018-12-05 19:40:29 +01:00
use LibreNMS\Device\YamlDiscovery ;
2021-11-23 02:52:52 -06:00
use LibreNMS\Enum\Alert ;
2016-08-21 08:07:14 -05:00
use LibreNMS\Exceptions\HostExistsException ;
2017-10-04 02:16:23 -05:00
use LibreNMS\Exceptions\InvalidIpException ;
2021-10-08 14:04:11 -05:00
use LibreNMS\OS ;
2017-08-08 14:14:58 -05:00
use LibreNMS\Util\IP ;
use LibreNMS\Util\IPv6 ;
2016-08-21 08:07:14 -05:00
2021-03-28 17:25:30 -05:00
function discover_new_device ( $hostname , $device = [], $method = '' , $interface = '' )
2016-08-28 12:32:58 -05:00
{
2017-01-24 15:56:51 -06:00
d_echo ( "discovering $hostname \n " );
2015-07-13 20:10:26 +02:00
2017-10-04 02:16:23 -05:00
if ( IP :: isValid ( $hostname )) {
$ip = $hostname ;
2017-09-11 15:26:41 -05:00
if ( ! Config :: get ( 'discovery_by_ip' , false )) {
2017-01-24 15:56:51 -06:00
d_echo ( 'Discovery by IP disabled, skipping ' . $hostname );
2017-02-14 00:32:02 +02:00
log_event ( " $method discovery of " . $hostname . ' failed - Discovery by IP disabled' , $device [ 'device_id' ], 'discovery' , 4 );
2017-06-29 15:12:51 -05:00
2015-10-20 16:12:03 +00:00
return false ;
}
2021-03-28 17:25:30 -05:00
} elseif ( \LibreNMS\Util\Validate :: hostname ( $hostname )) {
2017-10-04 02:16:23 -05:00
if ( $mydomain = Config :: get ( 'mydomain' )) {
$full_host = rtrim ( $hostname , '.' ) . '.' . $mydomain ;
if ( isDomainResolves ( $full_host )) {
$hostname = $full_host ;
}
}
$ip = gethostbyname ( $hostname );
if ( $ip == $hostname ) {
d_echo ( "name lookup of $hostname failed \n " );
log_event ( " $method discovery of " . $hostname . ' failed - Check name lookup' , $device [ 'device_id' ], 'discovery' , 5 );
return false ;
}
} else {
d_echo ( "Discovery failed: ' $hostname ' is not a valid ip or dns name \n " );
2020-09-21 15:40:17 +02:00
2017-10-04 02:16:23 -05:00
return false ;
2015-10-20 16:12:03 +00:00
}
2011-09-15 15:03:42 +00:00
2015-08-20 15:59:43 +02:00
d_echo ( "ip lookup result: $ip \n " );
2013-10-28 15:55:57 +10:00
2017-10-04 02:16:23 -05:00
$hostname = rtrim ( $hostname , '.' ); // remove trailing dot
2015-07-13 20:10:26 +02:00
2017-10-04 02:16:23 -05:00
$ip = IP :: parse ( $ip , true );
if ( $ip -> inNetworks ( Config :: get ( 'autodiscovery.nets-exclude' ))) {
d_echo ( " $ip in an excluded network - skipping \n " );
2020-09-21 15:40:17 +02:00
2013-10-28 15:55:57 +10:00
return false ;
2011-09-15 15:03:42 +00:00
}
2017-10-04 02:16:23 -05:00
if ( ! $ip -> inNetworks ( Config :: get ( 'nets' ))) {
d_echo ( " $ip not in a matched network - skipping \n " );
2020-09-21 15:40:17 +02:00
2017-10-04 02:16:23 -05:00
return false ;
}
2015-07-13 20:10:26 +02:00
2017-10-04 02:16:23 -05:00
try {
2022-08-19 03:30:57 +02:00
$remote_device_id = addHost ( $hostname , '' , '161' , 'udp' , $device [ 'poller_group' ]); // discover with actual poller group
2017-10-04 02:16:23 -05:00
$remote_device = device_by_id_cache ( $remote_device_id , 1 );
echo '+[' . $remote_device [ 'hostname' ] . '(' . $remote_device [ 'device_id' ] . ')]' ;
discover_device ( $remote_device );
device_by_id_cache ( $remote_device_id , 1 );
2020-05-25 00:55:11 +02:00
2017-10-04 02:16:23 -05:00
if ( $remote_device_id && is_array ( $device ) && ! empty ( $method )) {
2022-08-19 03:30:57 +02:00
$extra_log = is_array ( $interface ) ? ' (port ' . cleanPort ( $interface )[ 'label' ] . ') ' : '' ;
2011-09-15 15:03:42 +00:00
2017-10-04 02:16:23 -05:00
log_event ( 'Device ' . $remote_device [ 'hostname' ] . " ( $ip ) $extra_log autodiscovered through $method on " . $device [ 'hostname' ], $remote_device_id , 'discovery' , 1 );
} else {
log_event ( " $method discovery of " . $remote_device [ 'hostname' ] . " ( $ip ) failed - Check ping and SNMP access" , $device [ 'device_id' ], 'discovery' , 5 );
2015-07-13 20:10:26 +02:00
}
2017-10-04 02:16:23 -05:00
return $remote_device_id ;
} catch ( HostExistsException $e ) {
// already have this device
} catch ( Exception $e ) {
log_event ( " $method discovery of " . $hostname . " ( $ip ) failed - " . $e -> getMessage (), $device [ 'device_id' ], 'discovery' , 5 );
}
return false ;
2016-02-02 12:21:45 +01:00
}
//end discover_new_device()
2011-09-15 15:03:42 +00:00
2018-07-12 15:30:39 -05:00
/**
2021-09-08 23:35:56 +02:00
* @param array $device The device to poll
* @param bool $force_module Ignore device module overrides
2018-07-12 15:30:39 -05:00
* @return bool if the device was discovered or skipped
*/
function discover_device ( & $device , $force_module = false )
2016-08-28 12:32:58 -05:00
{
2017-10-31 14:26:25 +01:00
if ( $device [ 'snmp_disable' ] == '1' ) {
2021-09-08 11:15:08 -05:00
return true ;
2017-10-31 14:26:25 +01:00
}
2017-09-11 15:26:41 -05:00
global $valid ;
2011-09-15 15:03:42 +00:00
$valid = [];
// Reset $valid array
2021-10-25 14:35:18 -05:00
$device [ 'attribs' ] = DeviceCache :: getPrimary () -> getAttribs ();
2011-09-15 15:03:42 +00:00
2016-01-08 13:33:32 +01:00
$device_start = microtime ( true );
2011-09-15 15:03:42 +00:00
// Start counting device poll time
2016-02-02 12:21:45 +01:00
echo $device [ 'hostname' ] . ' ' . $device [ 'device_id' ] . ' ' . $device [ 'os' ] . ' ' ;
2011-09-15 15:03:42 +00:00
2021-10-03 22:45:10 -05:00
$helper = new \LibreNMS\Polling\ConnectivityHelper ( DeviceCache :: getPrimary ());
2017-02-15 15:22:09 +00:00
2021-10-03 22:45:10 -05:00
if ( ! $helper -> isUp ()) {
2018-07-12 15:30:39 -05:00
return false ;
2017-02-15 15:22:09 +00:00
}
2018-01-07 05:00:47 +00:00
$discovery_devices = Config :: get ( 'discovery_modules' , []);
$discovery_devices = [ 'core' => true ] + $discovery_devices ;
2021-10-06 17:09:54 -05:00
/** @var \App\Polling\Measure\MeasurementManager $measurements */
$measurements = app ( \App\Polling\Measure\MeasurementManager :: class );
$measurements -> checkpoint (); // don't count previous stats
2018-01-07 05:00:47 +00:00
foreach ( $discovery_devices as $module => $module_status ) {
2017-09-14 00:43:14 -05:00
$os_module_status = Config :: getOsSetting ( $device [ 'os' ], "discovery_modules. $module " );
2016-11-13 20:46:05 +01:00
d_echo ( 'Modules status: Global' . ( isset ( $module_status ) ? ( $module_status ? '+ ' : '- ' ) : ' ' ));
d_echo ( 'OS' . ( isset ( $os_module_status ) ? ( $os_module_status ? '+ ' : '- ' ) : ' ' ));
2021-10-25 14:35:18 -05:00
d_echo ( 'Device' . ( isset ( $device [ 'attribs' ][ 'discover_' . $module ]) ? ( $device [ 'attribs' ][ 'discover_' . $module ] ? '+ ' : '- ' ) : ' ' ));
2016-11-13 20:46:05 +01:00
if ( $force_module === true ||
2021-10-25 14:35:18 -05:00
! empty ( $device [ 'attribs' ][ 'discover_' . $module ]) ||
( $os_module_status && ! isset ( $device [ 'attribs' ][ 'discover_' . $module ])) ||
( $module_status && ! isset ( $os_module_status ) && ! isset ( $device [ 'attribs' ][ 'discover_' . $module ]))
2017-02-15 15:22:09 +00:00
) {
2016-06-24 15:32:19 +01:00
$module_start = microtime ( true );
2017-02-08 04:54:30 +00:00
$start_memory = memory_get_usage ();
2016-11-13 20:46:05 +01:00
echo " \n #### Load disco module $module #### \n " ;
2018-08-25 15:00:03 -05:00
try {
include "includes/discovery/ $module .inc.php" ;
2021-11-23 02:52:52 -06:00
} catch ( Throwable $e ) {
2018-08-25 15:00:03 -05:00
// isolate module exceptions so they don't disrupt the polling process
2022-04-09 14:21:10 -05:00
Log :: error ( "%rError discovering $module module for { $device [ 'hostname' ] } .%n $e " , [ 'color' => true ]);
2021-11-23 02:52:52 -06:00
Log :: event ( "Error discovering $module module. Check log file for more details." , $device [ 'device_id' ], 'discovery' , Alert :: ERROR );
2022-08-24 00:33:28 +02:00
report ( $e );
2018-08-25 15:00:03 -05:00
}
2016-06-24 15:32:19 +01:00
$module_time = microtime ( true ) - $module_start ;
$module_time = substr ( $module_time , 0 , 5 );
2017-02-15 15:22:09 +00:00
$module_mem = ( memory_get_usage () - $start_memory );
2017-02-08 04:54:30 +00:00
printf ( " \n >> Runtime for discovery module '%s': %.4f seconds with %s bytes \n " , $module , $module_time , $module_mem );
2021-10-06 17:09:54 -05:00
$measurements -> printChangedStats ();
2016-06-24 15:32:19 +01:00
echo "#### Unload disco module $module #### \n\n " ;
2021-10-25 14:35:18 -05:00
} elseif ( isset ( $device [ 'attribs' ][ 'discover_' . $module ]) && $device [ 'attribs' ][ 'discover_' . $module ] == '0' ) {
2016-06-24 15:32:19 +01:00
echo "Module [ $module ] disabled on host. \n\n " ;
2016-11-13 20:46:05 +01:00
} elseif ( isset ( $os_module_status ) && $os_module_status == '0' ) {
echo "Module [ $module ] disabled on os. \n\n " ;
2016-06-24 15:32:19 +01:00
} else {
echo "Module [ $module ] disabled globally. \n\n " ;
2015-07-13 20:10:26 +02:00
}
2011-09-15 15:03:42 +00:00
}
2017-07-21 17:01:59 -05:00
$device_time = round ( microtime ( true ) - $device_start , 3 );
2011-09-15 15:03:42 +00:00
2017-01-11 16:36:04 +00:00
dbUpdate ([ 'last_discovered' => [ 'NOW()' ], 'last_discovered_timetaken' => $device_time ], 'devices' , '`device_id` = ?' , [ $device [ 'device_id' ]]);
2011-09-15 15:03:42 +00:00
2012-05-20 18:23:40 +00:00
echo "Discovered in $device_time seconds \n " ;
2015-07-13 20:10:26 +02:00
2018-06-30 06:19:49 -05:00
echo PHP_EOL ;
2020-09-21 15:40:17 +02:00
2018-07-12 15:30:39 -05:00
return true ;
2016-02-02 12:21:45 +01:00
}
//end discover_device()
2011-05-17 19:21:20 +00:00
2017-06-26 23:27:57 +01:00
// Discover sensors
2019-01-11 16:42:56 -06:00
function discover_sensor ( & $valid , $class , $device , $oid , $index , $type , $descr , $divisor = 1 , $multiplier = 1 , $low_limit = null , $low_warn_limit = null , $warn_limit = null , $high_limit = null , $current = null , $poller_type = 'snmp' , $entPhysicalIndex = null , $entPhysicalIndex_measured = null , $user_func = null , $group = null )
2016-08-28 12:32:58 -05:00
{
2019-03-16 11:51:09 +01:00
$guess_limits = Config :: get ( 'sensors.guess_limits' , true );
2017-01-18 08:48:33 +00:00
$low_limit = set_null ( $low_limit );
$low_warn_limit = set_null ( $low_warn_limit );
$warn_limit = set_null ( $warn_limit );
$high_limit = set_null ( $high_limit );
2021-03-12 18:10:14 -06:00
$current = cast_number ( $current );
2017-01-18 08:48:33 +00:00
2017-01-13 12:47:16 +00:00
if ( ! is_numeric ( $divisor )) {
$divisor = 1 ;
}
2020-05-15 04:06:50 +02:00
if ( can_skip_sensor ( $device , $class , $descr )) {
2019-08-08 03:01:58 +02:00
return false ;
}
2017-01-13 12:47:16 +00:00
2019-03-18 03:42:47 +01:00
d_echo ( "Discover sensor: $oid , $index , $type , $descr , $poller_type , $divisor , $multiplier , $entPhysicalIndex , $current , (limits: LL: $low_limit , LW: $low_warn_limit , W: $warn_limit , H: $high_limit ) \n " );
2010-08-11 17:08:56 +00:00
2019-01-10 19:48:37 -06:00
if ( isset ( $warn_limit , $low_warn_limit ) && $low_warn_limit > $warn_limit ) {
2012-04-09 12:57:02 +00:00
// Fix high/low thresholds (i.e. on negative numbers)
2019-01-10 19:48:37 -06:00
[ $warn_limit , $low_warn_limit ] = [ $low_warn_limit , $warn_limit ];
2012-04-09 12:57:02 +00:00
}
2018-09-01 17:55:20 +02:00
if ( dbFetchCell ( 'SELECT COUNT(sensor_id) FROM `sensors` WHERE `poller_type`= ? AND `sensor_class` = ? AND `device_id` = ? AND sensor_type = ? AND `sensor_index` = ?' , [ $poller_type , $class , $device [ 'device_id' ], $type , ( string ) $index ]) == '0' ) {
2019-03-16 11:51:09 +01:00
if ( $guess_limits && is_null ( $high_limit )) {
2011-04-03 19:36:32 +00:00
$high_limit = sensor_limit ( $class , $current );
2010-08-11 12:46:07 +00:00
}
2019-03-16 11:51:09 +01:00
if ( $guess_limits && is_null ( $low_limit )) {
2012-04-09 12:57:02 +00:00
$low_limit = sensor_low_limit ( $class , $current );
}
2017-03-12 09:56:56 -05:00
if ( ! is_null ( $high_limit ) && $low_limit > $high_limit ) {
2012-04-09 12:57:02 +00:00
// Fix high/low thresholds (i.e. on negative numbers)
[ $high_limit , $low_limit ] = [ $low_limit , $high_limit ];
}
2011-05-17 22:10:23 +00:00
$insert = [
2016-02-02 12:21:45 +01:00
'poller_type' => $poller_type ,
'sensor_class' => $class ,
'device_id' => $device [ 'device_id' ],
'sensor_oid' => $oid ,
'sensor_index' => $index ,
'sensor_type' => $type ,
'sensor_descr' => $descr ,
'sensor_divisor' => $divisor ,
'sensor_multiplier' => $multiplier ,
'sensor_limit' => $high_limit ,
'sensor_limit_warn' => $warn_limit ,
'sensor_limit_low' => $low_limit ,
'sensor_limit_low_warn' => $low_warn_limit ,
'sensor_current' => $current ,
'entPhysicalIndex' => $entPhysicalIndex ,
2011-05-17 22:10:23 +00:00
'entPhysicalIndex_measured' => $entPhysicalIndex_measured ,
2017-05-17 22:41:53 +01:00
'user_func' => $user_func ,
2019-01-16 03:56:30 +01:00
'group' => $group ,
2011-05-17 22:10:23 +00:00
];
2015-07-13 20:10:26 +02:00
2011-05-17 22:21:02 +00:00
foreach ( $insert as $key => $val_check ) {
if ( ! isset ( $val_check )) {
unset ( $insert [ $key ]);
2015-07-13 20:10:26 +02:00
}
}
2011-05-17 22:21:02 +00:00
$inserted = dbInsert ( $insert , 'sensors' );
2015-07-13 20:10:26 +02:00
2015-08-20 15:59:43 +02:00
d_echo ( "( $inserted inserted ) \n " );
2015-07-13 20:10:26 +02:00
2011-05-17 19:21:20 +00:00
echo '+' ;
2018-09-01 17:55:20 +02:00
log_event ( 'Sensor Added: ' . $class . ' ' . $type . ' ' . $index . ' ' . $descr , $device , 'sensor' , 3 , $inserted );
2016-02-02 12:21:45 +01:00
} else {
2018-09-01 17:55:20 +02:00
$sensor_entry = dbFetchRow ( 'SELECT * FROM `sensors` WHERE `sensor_class` = ? AND `device_id` = ? AND `sensor_type` = ? AND `sensor_index` = ?' , [ $class , $device [ 'device_id' ], $type , ( string ) $index ]);
2015-07-13 20:10:26 +02:00
2011-09-28 14:30:24 +00:00
if ( ! isset ( $high_limit )) {
2019-03-16 11:51:09 +01:00
if ( $guess_limits && ! $sensor_entry [ 'sensor_limit' ]) {
2011-05-04 13:22:41 +00:00
// Calculate a reasonable limit
2011-03-15 11:24:35 +00:00
$high_limit = sensor_limit ( $class , $current );
2016-02-02 12:21:45 +01:00
} else {
2012-04-09 12:57:02 +00:00
// Use existing limit
2010-08-11 17:08:56 +00:00
$high_limit = $sensor_entry [ 'sensor_limit' ];
2010-07-07 14:55:21 +00:00
}
2015-07-13 20:10:26 +02:00
}
2010-02-28 22:04:15 +00:00
2011-03-15 11:24:35 +00:00
if ( ! isset ( $low_limit )) {
2019-03-16 11:51:09 +01:00
if ( $guess_limits && ! $sensor_entry [ 'sensor_limit_low' ]) {
2011-03-15 11:24:35 +00:00
// Calculate a reasonable limit
$low_limit = sensor_low_limit ( $class , $current );
2016-02-02 12:21:45 +01:00
} else {
2012-04-09 12:57:02 +00:00
// Use existing limit
2010-08-11 17:08:56 +00:00
$low_limit = $sensor_entry [ 'sensor_limit_low' ];
2015-07-13 20:10:26 +02:00
}
}
2011-03-15 11:24:35 +00:00
// Fix high/low thresholds (i.e. on negative numbers)
2020-05-25 13:53:38 +02:00
if ( isset ( $high_limit ) && $low_limit > $high_limit ) {
2012-04-09 12:57:02 +00:00
[ $high_limit , $low_limit ] = [ $low_limit , $high_limit ];
2015-07-13 20:10:26 +02:00
}
2022-08-05 01:01:51 +02:00
if (( string ) $high_limit != ( string ) $sensor_entry [ 'sensor_limit' ] && $sensor_entry [ 'sensor_custom' ] == 'No' ) {
2016-02-02 12:21:45 +01:00
$update = [ 'sensor_limit' => ( $high_limit == null ? [ 'NULL' ] : $high_limit )];
2012-04-09 12:57:02 +00:00
$updated = dbUpdate ( $update , 'sensors' , '`sensor_id` = ?' , [ $sensor_entry [ 'sensor_id' ]]);
2015-08-20 15:59:43 +02:00
d_echo ( "( $updated updated ) \n " );
2015-07-13 20:10:26 +02:00
echo 'H' ;
2021-03-22 16:41:20 +01:00
log_event ( 'Sensor High Limit Updated: ' . $class . ' ' . $type . ' ' . $index . ' ' . $descr . ' (' . $high_limit . ')' , $device , 'sensor' , 3 , $sensor_entry [ 'sensor_id' ]);
2015-07-13 20:10:26 +02:00
}
2022-08-05 01:01:51 +02:00
if (( string ) $sensor_entry [ 'sensor_limit_low' ] != ( string ) $low_limit && $sensor_entry [ 'sensor_custom' ] == 'No' ) {
2016-02-02 12:21:45 +01:00
$update = [ 'sensor_limit_low' => ( $low_limit == null ? [ 'NULL' ] : $low_limit )];
2012-04-09 12:57:02 +00:00
$updated = dbUpdate ( $update , 'sensors' , '`sensor_id` = ?' , [ $sensor_entry [ 'sensor_id' ]]);
2015-08-20 15:59:43 +02:00
d_echo ( "( $updated updated ) \n " );
2015-07-13 20:10:26 +02:00
echo 'L' ;
2021-03-22 16:41:20 +01:00
log_event ( 'Sensor Low Limit Updated: ' . $class . ' ' . $type . ' ' . $index . ' ' . $descr . ' (' . $low_limit . ')' , $device , 'sensor' , 3 , $sensor_entry [ 'sensor_id' ]);
2015-07-13 20:10:26 +02:00
}
2022-08-05 01:01:51 +02:00
if (( string ) $warn_limit != ( string ) $sensor_entry [ 'sensor_limit_warn' ] && $sensor_entry [ 'sensor_custom' ] == 'No' ) {
2016-02-02 12:21:45 +01:00
$update = [ 'sensor_limit_warn' => ( $warn_limit == null ? [ 'NULL' ] : $warn_limit )];
2012-04-09 12:57:02 +00:00
$updated = dbUpdate ( $update , 'sensors' , '`sensor_id` = ?' , [ $sensor_entry [ 'sensor_id' ]]);
2015-08-20 15:59:43 +02:00
d_echo ( "( $updated updated ) \n " );
2015-07-13 20:10:26 +02:00
echo 'WH' ;
2021-03-22 16:41:20 +01:00
log_event ( 'Sensor Warn High Limit Updated: ' . $class . ' ' . $type . ' ' . $index . ' ' . $descr . ' (' . $warn_limit . ')' , $device , 'sensor' , 3 , $sensor_entry [ 'sensor_id' ]);
2015-07-13 20:10:26 +02:00
}
2022-08-05 01:01:51 +02:00
if (( string ) $sensor_entry [ 'sensor_limit_low_warn' ] != ( string ) $low_warn_limit && $sensor_entry [ 'sensor_custom' ] == 'No' ) {
2016-02-02 12:21:45 +01:00
$update = [ 'sensor_limit_low_warn' => ( $low_warn_limit == null ? [ 'NULL' ] : $low_warn_limit )];
2012-04-09 12:57:02 +00:00
$updated = dbUpdate ( $update , 'sensors' , '`sensor_id` = ?' , [ $sensor_entry [ 'sensor_id' ]]);
2015-08-20 15:59:43 +02:00
d_echo ( "( $updated updated ) \n " );
2015-07-13 20:10:26 +02:00
echo 'WL' ;
2021-03-22 16:41:20 +01:00
log_event ( 'Sensor Warn Low Limit Updated: ' . $class . ' ' . $type . ' ' . $index . ' ' . $descr . ' (' . $low_warn_limit . ')' , $device , 'sensor' , 3 , $sensor_entry [ 'sensor_id' ]);
2015-07-13 20:10:26 +02:00
}
2017-04-13 04:52:07 -05:00
if ( $oid == $sensor_entry [ 'sensor_oid' ] &&
$descr == $sensor_entry [ 'sensor_descr' ] &&
$multiplier == $sensor_entry [ 'sensor_multiplier' ] &&
$divisor == $sensor_entry [ 'sensor_divisor' ] &&
$entPhysicalIndex_measured == $sensor_entry [ 'entPhysicalIndex_measured' ] &&
2017-05-17 22:41:53 +01:00
$entPhysicalIndex == $sensor_entry [ 'entPhysicalIndex' ] &&
2019-01-11 16:42:56 -06:00
$user_func == $sensor_entry [ 'user_func' ] &&
$group == $sensor_entry [ 'group' ]
2017-08-28 19:44:24 +01:00
2017-04-13 04:52:07 -05:00
) {
2015-07-13 20:10:26 +02:00
echo '.' ;
2016-02-02 12:21:45 +01:00
} else {
$update = [
'sensor_oid' => $oid ,
'sensor_descr' => $descr ,
'sensor_multiplier' => $multiplier ,
'sensor_divisor' => $divisor ,
'entPhysicalIndex' => $entPhysicalIndex ,
2015-02-18 08:39:05 -07:00
'entPhysicalIndex_measured' => $entPhysicalIndex_measured ,
2017-05-17 22:41:53 +01:00
'user_func' => $user_func ,
2019-01-11 16:42:56 -06:00
'group' => $group ,
2015-07-13 20:10:26 +02:00
];
2012-04-09 12:57:02 +00:00
$updated = dbUpdate ( $update , 'sensors' , '`sensor_id` = ?' , [ $sensor_entry [ 'sensor_id' ]]);
2015-07-13 20:10:26 +02:00
echo 'U' ;
2021-03-22 16:41:20 +01:00
log_event ( 'Sensor Updated: ' . $class . ' ' . $type . ' ' . $index . ' ' . $descr , $device , 'sensor' , 3 , $sensor_entry [ 'sensor_id' ]);
2015-08-20 15:59:43 +02:00
d_echo ( "( $updated updated ) \n " );
2015-07-13 20:10:26 +02:00
}
} //end if
2011-05-04 13:22:41 +00:00
$valid [ $class ][ $type ][ $index ] = 1 ;
2016-02-02 12:21:45 +01:00
}
2015-07-13 20:10:26 +02:00
2016-02-02 12:21:45 +01:00
//end discover_sensor()
2015-07-13 20:10:26 +02:00
2016-08-28 12:32:58 -05:00
function sensor_low_limit ( $class , $current )
{
2019-06-21 16:03:27 +02:00
// matching an empty case executes code until a break is reached
2011-03-15 11:24:35 +00:00
switch ( $class ) {
2016-02-02 12:21:45 +01:00
case 'temperature' :
2017-11-17 06:07:50 -08:00
$limit = $current - 10 ;
2016-02-02 12:21:45 +01:00
break ;
case 'voltage' :
2019-06-21 16:03:27 +02:00
$limit = $current * 0.85 ;
2016-02-02 12:21:45 +01:00
break ;
case 'humidity' :
2019-01-10 19:48:37 -06:00
$limit = 30 ;
2016-02-02 12:21:45 +01:00
break ;
case 'fanspeed' :
2019-01-10 19:48:37 -06:00
$limit = $current * 0.80 ;
2016-02-02 12:21:45 +01:00
break ;
2019-01-20 19:24:11 +01:00
case 'power_factor' :
$limit = - 1 ;
break ;
2016-03-22 10:37:07 -04:00
case 'signal' :
2016-04-06 08:20:10 -04:00
$limit = - 80 ;
2016-03-22 10:37:07 -04:00
break ;
2017-04-30 17:32:39 +01:00
case 'airflow' :
2017-05-23 16:28:45 +01:00
case 'snr' :
2017-09-29 21:13:27 +01:00
case 'frequency' :
case 'pressure' :
case 'cooling' :
2019-01-10 19:48:37 -06:00
$limit = $current * 0.95 ;
2017-04-30 17:32:39 +01:00
break ;
2019-06-21 16:03:27 +02:00
default :
return null ;
2010-08-11 12:46:07 +00:00
} //end switch
2015-07-13 20:10:26 +02:00
2019-06-21 16:03:27 +02:00
return round ( $limit , 11 );
2016-02-02 12:21:45 +01:00
}
2015-07-13 20:10:26 +02:00
2016-02-02 12:21:45 +01:00
//end sensor_low_limit()
2015-07-13 20:10:26 +02:00
2016-08-28 12:32:58 -05:00
function sensor_limit ( $class , $current )
{
2019-06-21 16:03:27 +02:00
// matching an empty case executes code until a break is reached
2010-12-15 17:54:42 +00:00
switch ( $class ) {
2016-02-02 12:21:45 +01:00
case 'temperature' :
2017-11-17 06:07:50 -08:00
$limit = $current + 20 ;
2016-02-02 12:21:45 +01:00
break ;
case 'voltage' :
2019-01-10 19:48:37 -06:00
$limit = $current * 1.15 ;
2016-02-02 12:21:45 +01:00
break ;
case 'humidity' :
2019-01-10 19:48:37 -06:00
$limit = 70 ;
2016-02-02 12:21:45 +01:00
break ;
2019-06-21 16:03:27 +02:00
case 'fanspeed' :
$limit = $current * 1.80 ;
2016-02-02 12:21:45 +01:00
break ;
2019-01-20 19:24:11 +01:00
case 'power_factor' :
$limit = 1 ;
break ;
2016-08-28 12:32:58 -05:00
case 'signal' :
2016-04-06 08:20:10 -04:00
$limit = - 30 ;
2016-03-22 10:37:07 -04:00
break ;
2016-10-13 19:03:46 +03:00
case 'load' :
$limit = 80 ;
break ;
2017-04-30 17:32:39 +01:00
case 'airflow' :
2017-05-23 16:28:45 +01:00
case 'snr' :
2017-09-29 21:13:27 +01:00
case 'frequency' :
case 'pressure' :
case 'cooling' :
2019-01-10 19:48:37 -06:00
$limit = $current * 1.05 ;
2017-04-30 17:32:39 +01:00
break ;
2019-06-21 16:03:27 +02:00
default :
return null ;
2012-05-16 13:25:50 +00:00
} //end switch
2011-05-17 19:21:20 +00:00
2019-06-21 16:03:27 +02:00
return round ( $limit , 11 );
2016-02-02 12:21:45 +01:00
}
2011-05-17 19:21:20 +00:00
2016-02-02 12:21:45 +01:00
//end sensor_limit()
2015-07-13 20:10:26 +02:00
2016-08-28 12:32:58 -05:00
function check_valid_sensors ( $device , $class , $valid , $poller_type = 'snmp' )
{
2012-05-16 13:25:50 +00:00
$entries = dbFetchRows ( 'SELECT * FROM sensors AS S, devices AS D WHERE S.sensor_class=? AND S.device_id = D.device_id AND D.device_id = ? AND S.poller_type = ?' , [ $class , $device [ 'device_id' ], $poller_type ]);
2015-07-13 20:10:26 +02:00
2012-05-16 13:25:50 +00:00
if ( count ( $entries )) {
foreach ( $entries as $entry ) {
$index = $entry [ 'sensor_index' ];
2016-02-02 12:21:45 +01:00
$type = $entry [ 'sensor_type' ];
2016-03-12 23:27:21 +01:00
$class = $entry [ 'sensor_class' ];
2016-02-02 12:21:45 +01:00
d_echo ( $index . ' -> ' . $type . " \n " );
2015-07-13 20:10:26 +02:00
2015-03-28 14:05:40 +00:00
if ( ! $valid [ $class ][ $type ][ $index ]) {
2015-07-13 20:10:26 +02:00
echo '-' ;
2016-03-12 23:27:21 +01:00
if ( $class == 'state' ) {
dbDelete ( 'sensors_to_state_indexes' , '`sensor_id` = ?' , [ $entry [ 'sensor_id' ]]);
}
2015-03-28 14:05:40 +00:00
dbDelete ( 'sensors' , '`sensor_id` = ?' , [ $entry [ 'sensor_id' ]]);
2021-03-22 16:41:20 +01:00
log_event ( 'Sensor Deleted: ' . $entry [ 'sensor_class' ] . ' ' . $entry [ 'sensor_type' ] . ' ' . $entry [ 'sensor_index' ] . ' ' . $entry [ 'sensor_descr' ], $device , 'sensor' , 3 , $entry [ 'sensor_id' ]);
2015-07-13 20:10:26 +02:00
}
2010-03-11 19:09:19 +00:00
unset ( $oid );
2010-07-29 18:25:11 +00:00
unset ( $type );
2015-07-13 20:10:26 +02:00
}
2010-03-11 19:09:19 +00:00
}
2016-02-02 12:21:45 +01:00
}
2015-07-13 20:10:26 +02:00
2016-02-02 12:21:45 +01:00
//end check_valid_sensors()
2015-07-13 20:10:26 +02:00
2017-02-14 12:06:01 +00:00
function discover_juniAtmVp ( & $valid , $device , $port_id , $vp_id , $vp_descr )
2016-08-28 12:32:58 -05:00
{
2016-09-27 14:18:12 -05:00
d_echo ( "Discover Juniper ATM VP: $port_id , $vp_id , $vp_descr \n " );
2015-07-13 20:10:26 +02:00
2015-02-16 15:37:51 -07:00
if ( dbFetchCell ( 'SELECT COUNT(*) FROM `juniAtmVp` WHERE `port_id` = ? AND `vp_id` = ?' , [ $port_id , $vp_id ]) == '0' ) {
$inserted = dbInsert ([ 'port_id' => $port_id , 'vp_id' => $vp_id , 'vp_descr' => $vp_descr ], 'juniAtmVp' );
2015-08-20 15:59:43 +02:00
d_echo ( "( $inserted inserted ) \n " );
2015-07-13 20:10:26 +02:00
2011-04-03 19:36:32 +00:00
// FIXME vv no $device!
2018-09-01 17:55:20 +02:00
log_event ( 'Juniper ATM VP Added: port ' . $port_id . ' vp ' . $vp_id . ' descr' . $vp_descr , $device , 'juniAtmVp' , 3 , $inserted );
2016-02-02 12:21:45 +01:00
} else {
2010-03-11 19:09:19 +00:00
echo '.' ;
}
2015-07-13 20:10:26 +02:00
2011-05-17 19:21:20 +00:00
$valid [ $port_id ][ $vp_id ] = 1 ;
2016-02-02 12:21:45 +01:00
}
2015-07-13 20:10:26 +02:00
2016-02-02 12:21:45 +01:00
//end discover_juniAtmVp()
2015-07-13 20:10:26 +02:00
2016-08-28 12:32:58 -05:00
function discover_link ( $local_port_id , $protocol , $remote_port_id , $remote_hostname , $remote_port , $remote_platform , $remote_version , $local_device_id , $remote_device_id )
{
2016-09-27 14:18:12 -05:00
global $link_exists ;
2015-07-13 20:10:26 +02:00
2017-10-06 08:53:16 -05:00
d_echo ( "Discover link: $local_port_id , $protocol , $remote_port_id , $remote_hostname , $remote_port , $remote_platform , $remote_version , $remote_device_id \n " );
2015-07-13 20:10:26 +02:00
2011-05-04 13:22:41 +00:00
if ( dbFetchCell (
2016-08-28 12:32:58 -05:00
'SELECT COUNT(*) FROM `links` WHERE `remote_hostname` = ? AND `local_port_id` = ? AND `protocol` = ? AND `remote_port` = ?' ,
2020-09-21 15:40:17 +02:00
[
2016-02-02 12:21:45 +01:00
$remote_hostname ,
$local_port_id ,
$protocol ,
$remote_port ,
2020-09-21 15:40:17 +02:00
]
2016-08-28 12:32:58 -05:00
) == '0' ) {
2015-02-16 14:14:49 -07:00
$insert_data = [
2016-02-02 12:21:45 +01:00
'local_port_id' => $local_port_id ,
'local_device_id' => $local_device_id ,
'protocol' => $protocol ,
'remote_hostname' => $remote_hostname ,
2017-10-06 08:53:16 -05:00
'remote_device_id' => ( int ) $remote_device_id ,
2016-02-02 12:21:45 +01:00
'remote_port' => $remote_port ,
'remote_platform' => $remote_platform ,
'remote_version' => $remote_version ,
2015-02-16 14:14:49 -07:00
];
2015-07-13 20:10:26 +02:00
2015-02-16 14:14:49 -07:00
if ( ! empty ( $remote_port_id )) {
2017-10-06 08:53:16 -05:00
$insert_data [ 'remote_port_id' ] = ( int ) $remote_port_id ;
2015-02-16 14:14:49 -07:00
}
2015-07-13 20:10:26 +02:00
2015-02-16 14:14:49 -07:00
$inserted = dbInsert ( $insert_data , 'links' );
2015-07-13 20:10:26 +02:00
2010-03-11 19:09:19 +00:00
echo '+' ;
2015-08-20 15:59:43 +02:00
d_echo ( "( $inserted inserted )" );
2016-02-02 12:21:45 +01:00
} else {
2017-10-04 02:16:23 -05:00
$sql = 'SELECT `id`,`local_device_id`,`remote_platform`,`remote_version`,`remote_device_id`,`remote_port_id` FROM `links`' ;
$sql .= ' WHERE `remote_hostname` = ? AND `local_port_id` = ? AND `protocol` = ? AND `remote_port` = ?' ;
$data = dbFetchRow ( $sql , [ $remote_hostname , $local_port_id , $protocol , $remote_port ]);
2015-07-13 20:10:26 +02:00
2017-10-04 02:16:23 -05:00
$update_data = [
'local_device_id' => $local_device_id ,
'remote_platform' => $remote_platform ,
'remote_version' => $remote_version ,
2017-10-06 08:53:16 -05:00
'remote_device_id' => ( int ) $remote_device_id ,
'remote_port_id' => ( int ) $remote_port_id ,
2017-10-04 02:16:23 -05:00
];
2015-07-13 20:10:26 +02:00
2017-10-04 02:16:23 -05:00
$id = $data [ 'id' ];
unset ( $data [ 'id' ]);
if ( $data == $update_data ) {
echo '.' ;
} else {
$updated = dbUpdate ( $update_data , 'links' , '`id` = ?' , [ $id ]);
2015-07-13 20:10:26 +02:00
echo 'U' ;
2015-08-20 15:59:43 +02:00
d_echo ( "( $updated updated )" );
2015-07-13 20:10:26 +02:00
} //end if
} //end if
2012-05-16 13:25:50 +00:00
$link_exists [ $local_port_id ][ $remote_hostname ][ $remote_port ] = 1 ;
2016-02-02 12:21:45 +01:00
}
2015-07-13 20:10:26 +02:00
2016-02-02 12:21:45 +01:00
//end discover_link()
2015-07-13 20:10:26 +02:00
2016-08-28 12:32:58 -05:00
function discover_storage ( & $valid , $device , $index , $type , $mib , $descr , $size , $units , $used = null )
{
2018-01-05 15:24:06 +11:00
if ( ignore_storage ( $device [ 'os' ], $descr )) {
return ;
}
2016-09-27 14:18:12 -05:00
d_echo ( "Discover Storage: $index , $type , $mib , $descr , $size , $units , $used \n " );
2015-07-13 20:10:26 +02:00
2011-03-15 11:24:35 +00:00
if ( $descr && $size > '0' ) {
2011-05-17 19:21:20 +00:00
$storage = dbFetchRow ( 'SELECT * FROM `storage` WHERE `storage_index` = ? AND `device_id` = ? AND `storage_mib` = ?' , [ $index , $device [ 'device_id' ], $mib ]);
2021-03-12 18:10:14 -06:00
if ( empty ( $storage )) {
2019-03-16 23:53:05 +01:00
if ( Config :: getOsSetting ( $device [ 'os' ], 'storage_perc_warn' )) {
$perc_warn = Config :: getOsSetting ( $device [ 'os' ], 'storage_perc_warn' );
} else {
$perc_warn = Config :: get ( 'storage_perc_warn' , 60 );
}
2021-03-22 16:41:20 +01:00
dbInsert (
2020-09-21 15:40:17 +02:00
[
2016-09-27 14:18:12 -05:00
'device_id' => $device [ 'device_id' ],
'storage_descr' => $descr ,
'storage_index' => $index ,
'storage_mib' => $mib ,
'storage_type' => $type ,
'storage_units' => $units ,
'storage_size' => $size ,
'storage_used' => $used ,
2019-03-16 23:53:05 +01:00
'storage_perc_warn' => $perc_warn ,
2016-09-27 14:18:12 -05:00
],
2016-08-28 12:32:58 -05:00
'storage'
2015-07-13 20:10:26 +02:00
);
echo '+' ;
2016-02-02 12:21:45 +01:00
} else {
2011-05-17 19:21:20 +00:00
$updated = dbUpdate ([ 'storage_descr' => $descr , 'storage_type' => $type , 'storage_units' => $units , 'storage_size' => $size ], 'storage' , '`device_id` = ? AND `storage_index` = ? AND `storage_mib` = ?' , [ $device [ 'device_id' ], $index , $mib ]);
if ( $updated ) {
2015-07-13 20:10:26 +02:00
echo 'U' ;
2016-02-02 12:21:45 +01:00
} else {
2015-07-13 20:10:26 +02:00
echo '.' ;
}
} //end if
2011-05-04 13:22:41 +00:00
$valid [ $mib ][ $index ] = 1 ;
2015-07-13 20:10:26 +02:00
} //end if
2016-02-02 12:21:45 +01:00
}
2015-07-13 20:10:26 +02:00
2019-01-20 19:24:11 +01:00
function discover_entity_physical ( & $valid , $device , $entPhysicalIndex , $entPhysicalDescr , $entPhysicalClass , $entPhysicalName , $entPhysicalModelName , $entPhysicalSerialNum , $entPhysicalContainedIn , $entPhysicalMfgName , $entPhysicalParentRelPos , $entPhysicalVendorType , $entPhysicalHardwareRev , $entPhysicalFirmwareRev , $entPhysicalSoftwareRev , $entPhysicalIsFRU , $entPhysicalAlias , $entPhysicalAssetID , $ifIndex )
{
d_echo ( "Discover Inventory Item: $entPhysicalIndex , $entPhysicalDescr , $entPhysicalClass , $entPhysicalName , $entPhysicalModelName , $entPhysicalSerialNum , $entPhysicalContainedIn , $entPhysicalMfgName , $entPhysicalParentRelPos , $entPhysicalVendorType , $entPhysicalHardwareRev , $entPhysicalFirmwareRev , $entPhysicalSoftwareRev , $entPhysicalIsFRU , $entPhysicalAlias , $entPhysicalAssetID , $ifIndex \n " );
if ( $entPhysicalDescr || $entPhysicalName ) {
if ( dbFetchCell ( 'SELECT COUNT(entPhysical_id) FROM `entPhysical` WHERE `device_id` = ? AND `entPhysicalIndex` = ?' , [ $device [ 'device_id' ], $entPhysicalIndex ]) == '0' ) {
$insert_data = [
'device_id' => $device [ 'device_id' ],
'entPhysicalIndex' => $entPhysicalIndex ,
'entPhysicalDescr' => $entPhysicalDescr ,
'entPhysicalClass' => $entPhysicalClass ,
'entPhysicalName' => $entPhysicalName ,
'entPhysicalModelName' => $entPhysicalModelName ,
'entPhysicalSerialNum' => $entPhysicalSerialNum ,
'entPhysicalContainedIn' => $entPhysicalContainedIn ,
'entPhysicalMfgName' => $entPhysicalMfgName ,
'entPhysicalParentRelPos' => $entPhysicalParentRelPos ,
'entPhysicalVendorType' => $entPhysicalVendorType ,
'entPhysicalHardwareRev' => $entPhysicalHardwareRev ,
'entPhysicalFirmwareRev' => $entPhysicalFirmwareRev ,
'entPhysicalSoftwareRev' => $entPhysicalSoftwareRev ,
'entPhysicalIsFRU' => $entPhysicalIsFRU ,
'entPhysicalAlias' => $entPhysicalAlias ,
'entPhysicalAssetID' => $entPhysicalAssetID ,
];
if ( ! empty ( $ifIndex )) {
$insert_data [ 'ifIndex' ] = $ifIndex ;
}
$inserted = dbInsert ( $insert_data , 'entPhysical' );
echo '+' ;
log_event ( 'Inventory Item added: index ' . $entPhysicalIndex . ' descr ' . $entPhysicalDescr , $device , 'entity-physical' , 3 , $inserted );
} else {
echo '.' ;
$update_data = [
'entPhysicalIndex' => $entPhysicalIndex ,
'entPhysicalDescr' => $entPhysicalDescr ,
'entPhysicalClass' => $entPhysicalClass ,
'entPhysicalName' => $entPhysicalName ,
'entPhysicalModelName' => $entPhysicalModelName ,
'entPhysicalSerialNum' => $entPhysicalSerialNum ,
'entPhysicalContainedIn' => $entPhysicalContainedIn ,
'entPhysicalMfgName' => $entPhysicalMfgName ,
'entPhysicalParentRelPos' => $entPhysicalParentRelPos ,
'entPhysicalVendorType' => $entPhysicalVendorType ,
'entPhysicalHardwareRev' => $entPhysicalHardwareRev ,
'entPhysicalFirmwareRev' => $entPhysicalFirmwareRev ,
'entPhysicalSoftwareRev' => $entPhysicalSoftwareRev ,
'entPhysicalIsFRU' => $entPhysicalIsFRU ,
'entPhysicalAlias' => $entPhysicalAlias ,
'entPhysicalAssetID' => $entPhysicalAssetID ,
2019-07-15 01:37:01 +02:00
'ifIndex' => $ifIndex ,
2019-01-20 19:24:11 +01:00
];
dbUpdate ( $update_data , 'entPhysical' , '`device_id`=? AND `entPhysicalIndex`=?' , [ $device [ 'device_id' ], $entPhysicalIndex ]);
} //end if
$valid [ $entPhysicalIndex ] = 1 ;
} //end if
}
//end discover_entity_physical()
2016-08-28 12:32:58 -05:00
function discover_process_ipv6 ( & $valid , $ifIndex , $ipv6_address , $ipv6_prefixlen , $ipv6_origin , $context_name = '' )
{
2016-09-27 14:18:12 -05:00
global $device ;
2015-07-13 20:10:26 +02:00
2017-08-08 14:14:58 -05:00
if ( ! IPv6 :: isValid ( $ipv6_address , true )) {
2014-06-10 22:21:10 +01:00
// ignore link-locals (coming from IPV6-MIB)
return ;
2011-05-04 10:45:38 +00:00
}
2017-08-08 14:14:58 -05:00
$ipv6 = new IPv6 ( $ipv6_address );
$ipv6_network = $ipv6 -> getNetwork ( $ipv6_prefixlen );
$ipv6_compressed = $ipv6 -> compressed ();
2021-12-02 05:52:37 +01:00
$port_id = Port :: where ([
[ 'device_id' , $device [ 'device_id' ]],
[ 'ifIndex' , $ifIndex ],
]) -> value ( 'port_id' );
2015-07-13 20:10:26 +02:00
2021-12-02 05:52:37 +01:00
if ( $port_id && $ipv6_prefixlen > '0' && $ipv6_prefixlen < '129' && $ipv6_compressed != '::1' ) {
d_echo ( 'IPV6: Found port id: ' . $port_id );
2016-02-02 12:21:45 +01:00
2021-12-02 05:52:37 +01:00
$ipv6netDB = Ipv6Network :: updateOrCreate ([
'ipv6_network' => $ipv6_network ,
], [
'context_name' => $context_name ,
]);
if ( $ipv6netDB -> wasChanged ()) {
d_echo ( 'IPV6: Update DB ipv6_networks' );
}
$ipv6_network_id = Ipv6Network :: where ( 'ipv6_network' , $ipv6_network ) -> where ( 'context_name' , $context_name ) -> value ( 'ipv6_network_id' );
if ( $ipv6_network_id ) {
d_echo ( 'IPV6: Found network id: ' . $ipv6_network_id );
$ipv6adrDB = Ipv6Address :: updateOrCreate ([
'ipv6_address' => $ipv6_address ,
'ipv6_prefixlen' => $ipv6_prefixlen ,
'port_id' => $port_id ,
], [
'ipv6_compressed' => $ipv6_compressed ,
'ipv6_origin' => $ipv6_origin ,
'ipv6_network_id' => $ipv6_network_id ,
'context_name' => $context_name ,
]);
if ( $ipv6adrDB -> wasChanged ()) {
d_echo ( 'IPV6: Update DB ipv6_addresses' );
2017-04-25 21:28:25 +01:00
}
2011-05-04 10:45:38 +00:00
2017-04-25 21:28:25 +01:00
$full_address = " $ipv6_address / $ipv6_prefixlen " ;
$valid_address = $full_address . '-' . $port_id ;
$valid [ 'ipv6' ][ $valid_address ] = 1 ;
2021-12-02 05:52:37 +01:00
} //endif network_id
} //endif port_id && others
2011-05-04 13:22:41 +00:00
} //end discover_process_ipv6()
2016-01-25 22:37:38 +00:00
/*
* Check entity sensors to be excluded
2017-06-29 15:12:51 -05:00
*
2016-01-25 22:37:38 +00:00
* @param string value to check
* @param array device
*
* @return bool true if sensor is valid
* false if sensor is invalid
*/
2016-08-28 12:32:58 -05:00
function check_entity_sensor ( $string , $device )
{
2017-09-14 00:43:14 -05:00
$fringe = array_merge ( Config :: get ( 'bad_entity_sensor_regex' , []), Config :: getOsSetting ( $device [ 'os' ], 'bad_entity_sensor_regex' , []));
2017-09-11 15:26:41 -05:00
foreach ( $fringe as $bad ) {
if ( preg_match ( $bad . 'i' , $string )) {
d_echo ( "Ignored entity sensor: $bad : $string " );
2020-09-21 15:40:17 +02:00
2017-09-11 15:26:41 -05:00
return false ;
2016-01-25 22:37:38 +00:00
}
}
2017-09-11 15:26:41 -05:00
return true ;
2016-01-25 22:37:38 +00:00
}
2016-02-06 06:52:21 +01:00
2016-09-18 19:38:31 +01:00
/**
2017-03-10 04:47:58 +01:00
* Get the device divisor, account for device specific quirks
* The default divisor is 10
*
2021-09-08 23:35:56 +02:00
* @param array $device device array
* @param string $os_version firmware version poweralert quirks
* @param string $sensor_type the type of this sensor
* @param string $oid the OID of this sensor
2016-09-18 19:38:31 +01:00
* @return int
*/
2017-03-10 04:47:58 +01:00
function get_device_divisor ( $device , $os_version , $sensor_type , $oid )
2016-09-18 19:38:31 +01:00
{
2016-09-27 22:40:15 +03:00
if ( $device [ 'os' ] == 'poweralert' ) {
2017-03-11 18:03:04 -06:00
if ( $sensor_type == 'current' || $sensor_type == 'frequency' ) {
2017-03-10 04:47:58 +01:00
if ( version_compare ( $os_version , '12.06.0068' , '>=' )) {
return 10 ;
} elseif ( version_compare ( $os_version , '12.04.0055' , '=' )) {
return 10 ;
} elseif ( version_compare ( $os_version , '12.04.0056' , '>=' )) {
return 1 ;
2017-02-11 00:38:51 +00:00
}
2017-03-10 04:47:58 +01:00
} elseif ( $sensor_type == 'load' ) {
if ( version_compare ( $os_version , '12.06.0064' , '=' )) {
return 10 ;
2017-02-11 00:38:51 +00:00
} else {
2017-03-10 04:47:58 +01:00
return 1 ;
2016-09-27 22:40:15 +03:00
}
2016-09-18 19:38:31 +01:00
}
2017-07-13 12:09:56 -05:00
} elseif ( $device [ 'os' ] == 'huaweiups' ) {
if ( $sensor_type == 'frequency' ) {
2020-04-17 17:37:56 -05:00
if ( Str :: startsWith ( $device [ 'hardware' ], 'UPS2000' )) {
2019-12-17 09:08:12 +01:00
return 10 ;
}
2020-09-21 15:40:17 +02:00
2017-07-13 12:09:56 -05:00
return 100 ;
2017-05-03 23:38:43 +02:00
}
2017-05-16 22:42:10 +02:00
} elseif ( $device [ 'os' ] == 'hpe-rtups' ) {
2020-04-17 17:37:56 -05:00
if ( $sensor_type == 'voltage' && ! Str :: startsWith ( $oid , '.1.3.6.1.2.1.33.1.2.5.' ) && ! Str :: startsWith ( $oid , '.1.3.6.1.2.1.33.1.3.3.1.3' )) {
2017-05-16 22:42:10 +02:00
return 1 ;
}
2018-10-26 22:05:30 +02:00
} elseif ( $device [ 'os' ] == 'apc-mgeups' ) {
2018-10-17 18:03:51 +02:00
if ( $sensor_type == 'voltage' ) {
return 10 ;
}
2016-09-18 19:38:31 +01:00
}
2017-03-10 04:47:58 +01:00
2017-07-13 12:09:56 -05:00
// UPS-MIB Defaults
if ( $sensor_type == 'load' ) {
return 1 ;
}
2020-04-17 17:37:56 -05:00
if ( $sensor_type == 'voltage' && ! Str :: startsWith ( $oid , '.1.3.6.1.2.1.33.1.2.5.' )) {
2017-07-13 12:09:56 -05:00
return 1 ;
}
2017-09-14 15:55:07 -05:00
if ( $sensor_type == 'runtime' ) {
2020-04-17 17:37:56 -05:00
if ( Str :: startsWith ( $oid , '.1.3.6.1.2.1.33.1.2.2.' )) {
2017-09-14 15:55:07 -05:00
return 60 ;
}
2020-04-17 17:37:56 -05:00
if ( Str :: startsWith ( $oid , '.1.3.6.1.2.1.33.1.2.3.' )) {
2022-01-16 09:32:54 -05:00
if ( $device [ 'os' ] == 'routeros' && version_compare ( $device [ 'version' ], '6.47' , '<' )) {
2017-11-27 18:13:09 +01:00
return 60 ;
}
2021-11-02 06:23:56 -05:00
return 1 ;
2017-09-14 15:55:07 -05:00
}
}
2017-07-13 12:09:56 -05:00
return 10 ;
2016-09-18 19:38:31 +01:00
}
2016-10-03 19:49:23 +03:00
2016-11-30 20:50:29 +00:00
/**
2017-09-13 13:43:21 -05:00
* Should we ignore this storage device based on teh description? (usually the mount path or drive)
*
2021-09-08 23:35:56 +02:00
* @param string $os The OS of the device
* @param string $descr The description of the storage
2017-09-13 13:43:21 -05:00
* @return bool
2016-11-30 20:50:29 +00:00
*/
2017-09-13 13:43:21 -05:00
function ignore_storage ( $os , $descr )
2016-11-30 20:50:29 +00:00
{
2022-04-21 21:49:26 -05:00
foreach ( Config :: getCombined ( $os , 'ignore_mount' ) as $im ) {
2017-09-13 13:43:21 -05:00
if ( $im == $descr ) {
d_echo ( "ignored $descr (matched: $im ) \n " );
2020-09-21 15:40:17 +02:00
2017-09-11 15:26:41 -05:00
return true ;
2016-11-30 20:50:29 +00:00
}
}
2022-04-21 21:49:26 -05:00
foreach ( Config :: getCombined ( $os , 'ignore_mount_string' ) as $ims ) {
2020-04-17 17:37:56 -05:00
if ( Str :: contains ( $descr , $ims )) {
2017-09-13 13:43:21 -05:00
d_echo ( "ignored $descr (matched: $ims ) \n " );
2020-09-21 15:40:17 +02:00
2017-09-11 15:26:41 -05:00
return true ;
2016-11-30 20:50:29 +00:00
}
}
2022-04-21 21:49:26 -05:00
foreach ( Config :: getCombined ( $os , 'ignore_mount_regexp' ) as $imr ) {
2017-09-13 13:43:21 -05:00
if ( preg_match ( $imr , $descr )) {
d_echo ( "ignored $descr (matched: $imr ) \n " );
2020-09-21 15:40:17 +02:00
2017-09-11 15:26:41 -05:00
return true ;
2016-11-30 20:50:29 +00:00
}
}
2017-09-11 15:26:41 -05:00
return false ;
2016-11-30 20:50:29 +00:00
}
2017-02-03 12:39:38 +00:00
2017-07-10 22:27:46 +01:00
/**
* @param $valid
2021-10-08 14:04:11 -05:00
* @param OS $os
2017-07-10 22:27:46 +01:00
* @param $sensor_type
* @param $pre_cache
*/
2021-10-08 14:04:11 -05:00
function discovery_process ( & $valid , $os , $sensor_class , $pre_cache )
2017-06-26 23:27:57 +01:00
{
2021-10-08 14:04:11 -05:00
$discovery = $os -> getDiscovery ( 'sensors' );
$device = $os -> getDeviceArray ();
if ( ! empty ( $discovery [ $sensor_class ]) && ! can_skip_sensor ( $device , $sensor_class , '' )) {
2017-07-10 22:27:46 +01:00
$sensor_options = [];
2021-10-08 14:04:11 -05:00
if ( isset ( $discovery [ $sensor_class ][ 'options' ])) {
$sensor_options = $discovery [ $sensor_class ][ 'options' ];
2017-07-10 22:27:46 +01:00
}
2017-09-03 13:58:39 -05:00
2020-05-15 04:06:50 +02:00
d_echo ( "Dynamic Discovery ( $sensor_class ): " );
2021-10-08 14:04:11 -05:00
d_echo ( $discovery [ $sensor_class ]);
2017-09-03 13:58:39 -05:00
2021-10-08 14:04:11 -05:00
foreach ( $discovery [ $sensor_class ][ 'data' ] as $data ) {
2017-06-26 23:27:57 +01:00
$tmp_name = $data [ 'oid' ];
2017-09-03 13:58:39 -05:00
$raw_data = ( array ) $pre_cache [ $tmp_name ];
d_echo ( "Data $tmp_name : " );
d_echo ( $raw_data );
2017-06-26 23:27:57 +01:00
foreach ( $raw_data as $index => $snmp_data ) {
2017-11-28 20:30:24 -06:00
$user_function = null ;
2017-12-16 23:26:43 +01:00
if ( isset ( $data [ 'user_func' ])) {
$user_function = $data [ 'user_func' ];
2017-11-28 20:30:24 -06:00
}
2017-09-03 13:58:39 -05:00
// get the value for this sensor, check 'value' and 'oid', if state string, translate to a number
2021-04-22 21:40:45 +02:00
$data [ 'value' ] = isset ( $data [ 'value' ]) ? $data [ 'value' ] : $data [ 'oid' ]; // fallback to oid if value is not set
2017-10-25 14:10:02 +01:00
2021-04-22 21:40:45 +02:00
$snmp_value = $snmp_data [ $data [ 'value' ]];
2018-02-05 07:39:13 -06:00
if ( ! is_numeric ( $snmp_value )) {
2020-05-15 04:06:50 +02:00
if ( $sensor_class === 'temperature' ) {
2017-11-28 20:30:24 -06:00
// For temp sensors, try and detect fahrenheit values
2020-04-17 17:37:56 -05:00
if ( Str :: endsWith ( $snmp_value , [ 'f' , 'F' ])) {
2017-11-28 20:30:24 -06:00
$user_function = 'fahrenheit_to_celsius' ;
}
}
2018-02-05 07:39:13 -06:00
preg_match ( '/-?\d*\.?\d+/' , $snmp_value , $temp_response );
2017-10-25 14:10:02 +01:00
if ( ! empty ( $temp_response [ 0 ])) {
2018-02-05 07:39:13 -06:00
$snmp_value = $temp_response [ 0 ];
2017-10-25 14:10:02 +01:00
}
}
2018-02-05 07:39:13 -06:00
if ( is_numeric ( $snmp_value )) {
$value = $snmp_value ;
2020-05-15 04:06:50 +02:00
} elseif ( $sensor_class === 'state' ) {
2017-09-03 13:58:39 -05:00
// translate string states to values (poller does this as well)
$states = array_column ( $data [ 'states' ], 'value' , 'descr' );
2018-02-05 07:39:13 -06:00
$value = isset ( $states [ $snmp_value ]) ? $states [ $snmp_value ] : false ;
2017-09-03 13:58:39 -05:00
} else {
$value = false ;
}
2019-08-08 03:01:58 +02:00
$skippedFromYaml = YamlDiscovery :: canSkipItem ( $value , $index , $data , $sensor_options , $pre_cache );
2021-03-01 16:54:29 +01:00
// Check if we have a "num_oid" value. If not, we'll try to compute it from textual OIDs with snmptranslate.
if ( empty ( $data [ 'num_oid' ])) {
try {
2021-10-08 14:04:11 -05:00
$data [ 'num_oid' ] = YamlDiscovery :: computeNumericalOID ( $os , $data );
2021-03-01 16:54:29 +01:00
} catch ( \Exception $e ) {
2021-04-22 21:40:45 +02:00
d_echo ( 'Error: We cannot find a numerical OID for ' . $data [ 'value' ] . '. Skipping this one...' );
2021-03-01 16:54:29 +01:00
$skippedFromYaml = true ;
2021-04-22 21:40:45 +02:00
// Because we don't have a num_oid, we have no way to add this sensor.
2021-03-01 16:54:29 +01:00
}
}
2019-08-08 03:01:58 +02:00
if ( $skippedFromYaml === false && is_numeric ( $value )) {
2021-03-12 18:10:14 -06:00
d_echo ( "Sensor fetched value: $value \n " );
2018-11-10 17:45:24 -06:00
$oid = str_replace ( '{{ $index }}' , $index , $data [ 'num_oid' ]);
2019-08-21 10:04:16 +02:00
// if index is a string, we need to convert it to OID
// strlen($index) as first number, and each letter converted to a number, separated by dots
$oid = str_replace ( '{{ $index_string }}' , strlen ( $index ) . '.' . implode ( '.' , unpack ( 'c*' , $index )), $oid );
2017-11-04 16:25:13 -05:00
// process the description
2019-01-16 03:56:30 +01:00
$descr = YamlDiscovery :: replaceValues ( 'descr' , $index , null , $data , $pre_cache );
// process the group
2019-06-21 16:03:27 +02:00
$group = YamlDiscovery :: replaceValues ( 'group' , $index , null , $data , $pre_cache ) ?: null ;
2017-11-04 16:25:13 -05:00
2021-03-12 18:10:14 -06:00
$divisor = $data [ 'divisor' ] ?? ( $sensor_options [ 'divisor' ] ?? 1 );
$multiplier = $data [ 'multiplier' ] ?? ( $sensor_options [ 'multiplier' ] ?? 1 );
2018-05-07 15:17:45 -05:00
2018-04-14 03:43:40 +01:00
$limits = [ 'low_limit' , 'low_warn_limit' , 'warn_limit' , 'high_limit' ];
foreach ( $limits as $limit ) {
2021-03-12 18:10:14 -06:00
if ( isset ( $data [ $limit ]) && is_numeric ( $data [ $limit ])) {
2018-04-23 21:30:13 +01:00
$$limit = $data [ $limit ];
} else {
2020-02-01 23:28:03 +01:00
$$limit = YamlDiscovery :: getValueFromData ( $limit , $index , $data , $pre_cache , 'null' );
2018-04-23 21:30:13 +01:00
if ( is_numeric ( $$limit )) {
$$limit = ( $$limit / $divisor ) * $multiplier ;
}
2020-06-05 20:58:34 +02:00
if ( is_numeric ( $$limit ) && isset ( $user_function ) && is_callable ( $user_function )) {
$$limit = $user_function ( $$limit );
}
2018-04-14 03:43:40 +01:00
}
}
2017-09-03 13:58:39 -05:00
$sensor_name = $device [ 'os' ];
2017-11-28 20:30:24 -06:00
2020-05-15 04:06:50 +02:00
if ( $sensor_class === 'state' ) {
2022-08-21 16:23:43 -05:00
$sensor_name = $data [ 'state_name' ] ?? $data [ 'oid' ];
2017-09-03 13:58:39 -05:00
create_state_index ( $sensor_name , $data [ 'states' ]);
} else {
2019-02-04 15:55:31 +01:00
// We default to 1 for both divisors / multipliers so it should be safe to do the calculation using both.
2018-04-14 03:43:40 +01:00
$value = ( $value / $divisor ) * $multiplier ;
2017-06-26 23:27:57 +01:00
}
2017-09-03 13:58:39 -05:00
2021-03-08 22:50:34 -06:00
echo "Cur $value , Low: $low_limit , Low Warn: $low_warn_limit , Warn: $warn_limit , High: $high_limit " . PHP_EOL ;
$entPhysicalIndex = YamlDiscovery :: replaceValues ( 'entPhysicalIndex' , $index , null , $data , $pre_cache ) ?: null ;
$entPhysicalIndex_measured = isset ( $data [ 'entPhysicalIndex_measured' ]) ? $data [ 'entPhysicalIndex_measured' ] : null ;
2019-04-18 03:15:31 +02:00
//user_func must be applied after divisor/multiplier
2019-04-29 16:46:53 +02:00
if ( isset ( $user_function ) && is_callable ( $user_function )) {
2019-04-18 03:15:31 +02:00
$value = $user_function ( $value );
}
2018-12-28 20:11:24 -06:00
$uindex = str_replace ( '{{ $index }}' , $index , isset ( $data [ 'index' ]) ? $data [ 'index' ] : $index );
2020-05-15 04:06:50 +02:00
discover_sensor ( $valid [ 'sensor' ], $sensor_class , $device , $oid , $uindex , $sensor_name , $descr , $divisor , $multiplier , $low_limit , $low_warn_limit , $warn_limit , $high_limit , $value , 'snmp' , $entPhysicalIndex , $entPhysicalIndex_measured , $user_function , $group );
2017-09-03 13:58:39 -05:00
2020-05-15 04:06:50 +02:00
if ( $sensor_class === 'state' ) {
2017-09-03 13:58:39 -05:00
create_sensor_to_state_index ( $device , $sensor_name , $uindex );
2017-06-26 23:27:57 +01:00
}
}
}
}
}
}
2017-02-03 12:39:38 +00:00
/**
* @param $types
2021-10-08 14:04:11 -05:00
* @param OS $os
2021-09-08 23:35:56 +02:00
* @param array $pre_cache
2017-02-03 12:39:38 +00:00
*/
2021-10-08 14:04:11 -05:00
function sensors ( $types , $os , $valid , $pre_cache = [])
2017-02-03 12:39:38 +00:00
{
2021-10-08 14:04:11 -05:00
$device = & $os -> getDeviceArray ();
2019-09-18 14:29:58 +02:00
foreach (( array ) $types as $sensor_class ) {
echo ucfirst ( $sensor_class ) . ': ' ;
$dir = Config :: get ( 'install_dir' ) . '/includes/discovery/sensors/' . $sensor_class . '/' ;
2017-02-03 12:39:38 +00:00
2021-03-12 18:10:14 -06:00
if ( isset ( $device [ 'os_group' ]) && is_file ( $dir . $device [ 'os_group' ] . '.inc.php' )) {
2017-03-01 23:06:11 +00:00
include $dir . $device [ 'os_group' ] . '.inc.php' ;
2017-02-03 12:39:38 +00:00
}
if ( is_file ( $dir . $device [ 'os' ] . '.inc.php' )) {
2017-03-01 23:06:11 +00:00
include $dir . $device [ 'os' ] . '.inc.php' ;
2017-02-03 12:39:38 +00:00
}
2017-09-14 00:43:14 -05:00
if ( Config :: getOsSetting ( $device [ 'os' ], 'rfc1628_compat' , false )) {
2017-02-03 12:39:38 +00:00
if ( is_file ( $dir . '/rfc1628.inc.php' )) {
2017-03-01 23:06:11 +00:00
include $dir . '/rfc1628.inc.php' ;
2017-02-03 12:39:38 +00:00
}
}
2021-10-08 14:04:11 -05:00
discovery_process ( $valid , $os , $sensor_class , $pre_cache );
2021-03-08 22:50:34 -06:00
d_echo ( $valid [ 'sensor' ][ $sensor_class ] ?? []);
2019-09-18 14:29:58 +02:00
check_valid_sensors ( $device , $sensor_class , $valid [ 'sensor' ]);
2017-02-03 12:39:38 +00:00
echo " \n " ;
}
}
2017-03-11 23:16:49 +00:00
function build_bgp_peers ( $device , $data , $peer2 )
{
d_echo ( "Peers : $data \n " );
2018-01-18 14:54:38 -06:00
$remove = [
'ARISTA-BGP4V2-MIB::aristaBgp4V2PeerRemoteAs.1.' ,
2021-01-26 06:56:59 +02:00
'ALCATEL-IND1-BGP-MIB::alaBgpPeerAS.' ,
2018-01-18 14:54:38 -06:00
'CISCO-BGP4-MIB::cbgpPeer2RemoteAs.' ,
'BGP4-MIB::bgpPeerRemoteAs.' ,
2019-04-09 14:44:48 +02:00
'HUAWEI-BGP-VPN-MIB::hwBgpPeerRemoteAs.' ,
2021-04-08 14:57:17 +02:00
'.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.13.' ,
2018-01-18 14:54:38 -06:00
];
$peers = trim ( str_replace ( $remove , '' , $data ));
2017-03-11 23:16:49 +00:00
$peerlist = [];
$ver = '' ;
2022-08-21 16:23:43 -05:00
foreach ( $peers ? explode ( " \n " , $peers ) : [] as $peer ) {
2020-02-01 23:28:03 +01:00
$local_ip = null ;
2017-03-11 23:16:49 +00:00
if ( $peer2 === true ) {
[ $ver , $peer ] = explode ( '.' , $peer , 2 );
}
[ $peer_ip , $peer_as ] = explode ( ' ' , $peer );
if ( $device [ 'os' ] === 'junos' ) {
$ver = '' ;
2021-04-08 14:57:17 +02:00
$octets = count ( explode ( '.' , $peer_ip ));
if ( $octets > 11 ) {
// ipv6
$peer_ip = ( string ) IP :: parse ( snmp2ipv6 ( $peer_ip ), true );
} else {
// ipv4
$peer_ip = implode ( '.' , array_slice ( explode ( '.' , $peer_ip ), - 4 ));
2017-03-11 23:16:49 +00:00
}
} else {
if ( strstr ( $peer_ip , ':' )) {
$peer_ip_snmp = preg_replace ( '/:/' , ' ' , $peer_ip );
$peer_ip = preg_replace ( '/(\S+\s+\S+)\s/' , '$1:' , $peer_ip_snmp );
$peer_ip = str_replace ( '"' , '' , str_replace ( ' ' , '' , $peer_ip ));
}
}
2021-04-08 14:57:17 +02:00
if ( $peer && $peer_ip != '0.0.0.0' ) {
2020-11-07 16:12:09 +01:00
if ( $peer_as < 0 ) {
//if ASN is negative -> overflow int32 -> original number is max(INT32) - min(INT32) + 1 + value
$peer_as = 4294967296 + $peer_as ;
}
2017-03-11 23:16:49 +00:00
d_echo ( "Found peer $peer_ip (AS $peer_as ) \n " );
$peerlist [] = [
2020-02-01 23:28:03 +01:00
'ip' => $peer_ip ,
'as' => $peer_as ,
'localip' => $local_ip ?: '0.0.0.0' ,
'ver' => $ver ,
2017-03-11 23:16:49 +00:00
];
}
}
2020-09-21 15:40:17 +02:00
2017-03-11 23:16:49 +00:00
return $peerlist ;
}
function build_cbgp_peers ( $device , $peer , $af_data , $peer2 )
{
d_echo ( 'afi data :: ' );
d_echo ( $af_data );
$af_list = [];
foreach ( $af_data as $k => $v ) {
if ( $peer2 === true ) {
[, $k ] = explode ( '.' , $k , 2 );
}
d_echo ( "AFISAFI = $k \n " );
$afisafi_tmp = explode ( '.' , $k );
2019-04-09 14:44:48 +02:00
if ( $device [ 'os_group' ] === 'vrp' ) {
2020-02-11 20:54:12 +01:00
$vpninst_id = array_shift ( $afisafi_tmp );
2019-04-09 14:44:48 +02:00
$afi = array_shift ( $afisafi_tmp );
$safi = array_shift ( $afisafi_tmp );
2020-02-11 20:54:12 +01:00
$peertype = array_shift ( $afisafi_tmp );
2019-04-09 14:44:48 +02:00
$bgp_ip = implode ( '.' , $afisafi_tmp );
2021-01-26 06:56:59 +02:00
} elseif ( $device [ 'os' ] == 'aos7' ) {
$afi = 'ipv4' ;
$safi = 'unicast' ;
$bgp_ip = $k ;
2019-04-09 14:44:48 +02:00
} else {
$safi = array_pop ( $afisafi_tmp );
$afi = array_pop ( $afisafi_tmp );
$bgp_ip = str_replace ( ". $afi . $safi " , '' , $k );
if ( $device [ 'os_group' ] === 'arista' ) {
$bgp_ip = str_replace ( " $afi ." , '' , $bgp_ip );
}
2017-03-11 23:16:49 +00:00
}
$bgp_ip = preg_replace ( '/:/' , ' ' , $bgp_ip );
$bgp_ip = preg_replace ( '/(\S+\s+\S+)\s/' , '$1:' , $bgp_ip );
$bgp_ip = str_replace ( '"' , '' , str_replace ( ' ' , '' , $bgp_ip ));
if ( $afi && $safi && $bgp_ip == $peer [ 'ip' ]) {
$af_list [ $bgp_ip ][ $afi ][ $safi ] = 1 ;
add_cbgp_peer ( $device , $peer , $afi , $safi );
}
}
2020-09-21 15:40:17 +02:00
2017-03-11 23:16:49 +00:00
return $af_list ;
}
function add_bgp_peer ( $device , $peer )
{
if ( dbFetchCell ( 'SELECT COUNT(*) from `bgpPeers` WHERE device_id = ? AND bgpPeerIdentifier = ?' , [ $device [ 'device_id' ], $peer [ 'ip' ]]) < '1' ) {
$bgpPeers = [
'device_id' => $device [ 'device_id' ],
'bgpPeerIdentifier' => $peer [ 'ip' ],
'bgpPeerRemoteAs' => $peer [ 'as' ],
'context_name' => $device [ 'context_name' ],
'astext' => $peer [ 'astext' ],
'bgpPeerState' => 'idle' ,
'bgpPeerAdminStatus' => 'stop' ,
2020-02-01 23:28:03 +01:00
'bgpLocalAddr' => $peer [ 'localip' ] ?: '0.0.0.0' ,
2021-04-08 14:57:17 +02:00
'bgpPeerRemoteAddr' => '0.0.0.0' ,
2017-03-11 23:16:49 +00:00
'bgpPeerInUpdates' => 0 ,
'bgpPeerOutUpdates' => 0 ,
'bgpPeerInTotalMessages' => 0 ,
'bgpPeerOutTotalMessages' => 0 ,
'bgpPeerFsmEstablishedTime' => 0 ,
'bgpPeerInUpdateElapsedTime' => 0 ,
];
dbInsert ( $bgpPeers , 'bgpPeers' );
2017-09-11 15:26:41 -05:00
if ( Config :: get ( 'autodiscovery.bgp' )) {
$name = gethostbyaddr ( $peer [ 'ip' ]);
2017-03-11 23:16:49 +00:00
discover_new_device ( $name , $device , 'BGP' );
}
echo '+' ;
} else {
2018-09-01 17:55:20 +02:00
dbUpdate ([ 'bgpPeerRemoteAs' => $peer [ 'as' ], 'astext' => $peer [ 'astext' ]], 'bgpPeers' , 'device_id=? AND bgpPeerIdentifier=?' , [ $device [ 'device_id' ], $peer [ 'ip' ]]);
2017-03-11 23:16:49 +00:00
echo '.' ;
}
}
function add_cbgp_peer ( $device , $peer , $afi , $safi )
{
if ( dbFetchCell ( 'SELECT COUNT(*) from `bgpPeers_cbgp` WHERE device_id = ? AND bgpPeerIdentifier = ? AND afi=? AND safi=?' , [ $device [ 'device_id' ], $peer [ 'ip' ], $afi , $safi ]) == 0 ) {
$cbgp = [
'device_id' => $device [ 'device_id' ],
'bgpPeerIdentifier' => $peer [ 'ip' ],
'afi' => $afi ,
'safi' => $safi ,
'context_name' => $device [ 'context_name' ],
'AcceptedPrefixes' => 0 ,
'DeniedPrefixes' => 0 ,
'PrefixAdminLimit' => 0 ,
'PrefixThreshold' => 0 ,
'PrefixClearThreshold' => 0 ,
'AdvertisedPrefixes' => 0 ,
'SuppressedPrefixes' => 0 ,
'WithdrawnPrefixes' => 0 ,
'AcceptedPrefixes_delta' => 0 ,
'AcceptedPrefixes_prev' => 0 ,
'DeniedPrefixes_delta' => 0 ,
'DeniedPrefixes_prev' => 0 ,
'AdvertisedPrefixes_delta' => 0 ,
'AdvertisedPrefixes_prev' => 0 ,
'SuppressedPrefixes_delta' => 0 ,
'SuppressedPrefixes_prev' => 0 ,
'WithdrawnPrefixes_delta' => 0 ,
'WithdrawnPrefixes_prev' => 0 ,
];
dbInsert ( $cbgp , 'bgpPeers_cbgp' );
}
}
2017-10-04 02:16:23 -05:00
2019-08-08 03:01:58 +02:00
/**
* check if we should skip this sensor from discovery
2021-09-10 20:09:53 +02:00
*
2019-08-08 03:01:58 +02:00
* @param $device
2021-09-08 23:35:56 +02:00
* @param string $sensor_class
* @param string $sensor_descr
2019-08-08 03:01:58 +02:00
* @return bool
*/
2020-05-13 16:02:30 +02:00
function can_skip_sensor ( $device , $sensor_class = '' , $sensor_descr = '' )
2019-08-08 03:01:58 +02:00
{
2022-04-21 21:49:26 -05:00
if ( ! empty ( $sensor_class ) && ( Config :: getOsSetting ( $device [ 'os' ], "disabled_sensors. $sensor_class " ) || Config :: get ( "disabled_sensors. $sensor_class " ))) {
2019-08-08 03:01:58 +02:00
return true ;
}
2022-04-21 21:49:26 -05:00
foreach ( Config :: getCombined ( $device [ 'os' ], 'disabled_sensors_regex' ) as $skipRegex ) {
2019-08-08 03:01:58 +02:00
if ( ! empty ( $sensor_descr ) && preg_match ( $skipRegex , $sensor_descr )) {
return true ;
}
}
2022-04-21 21:49:26 -05:00
foreach ( Config :: getCombined ( $device [ 'os' ], "disabled_sensors_regex. $sensor_class " ) as $skipRegex ) {
2021-07-23 23:46:12 +02:00
if ( ! empty ( $sensor_descr ) && preg_match ( $skipRegex , $sensor_descr )) {
return true ;
}
}
2020-09-21 15:40:17 +02:00
2019-08-08 03:01:58 +02:00
return false ;
}
2017-10-04 02:16:23 -05:00
/**
* check if we should skip this device from discovery
2021-09-10 20:09:53 +02:00
*
2021-09-08 23:35:56 +02:00
* @param string $sysName
* @param string $sysDescr
* @param string $platform
2017-10-04 02:16:23 -05:00
* @return bool
*/
function can_skip_discovery ( $sysName , $sysDescr = '' , $platform = '' )
{
if ( $sysName ) {
foreach (( array ) Config :: get ( 'autodiscovery.xdp_exclude.sysname_regexp' ) as $needle ) {
if ( preg_match ( $needle . 'i' , $sysName )) {
d_echo ( " $sysName - regexp ' $needle ' matches ' $sysName ' - skipping device discovery \n " );
2020-09-21 15:40:17 +02:00
2017-10-04 02:16:23 -05:00
return true ;
}
}
}
if ( $sysDescr ) {
foreach (( array ) Config :: get ( 'autodiscovery.xdp_exclude.sysdesc_regexp' ) as $needle ) {
if ( preg_match ( $needle . 'i' , $sysDescr )) {
d_echo ( " $sysName - regexp ' $needle ' matches ' $sysDescr ' - skipping device discovery \n " );
2020-09-21 15:40:17 +02:00
2017-10-04 02:16:23 -05:00
return true ;
}
}
}
if ( $platform ) {
foreach (( array ) Config :: get ( 'autodiscovery.cdp_exclude.platform_regexp' ) as $needle ) {
if ( preg_match ( $needle . 'i' , $platform )) {
d_echo ( " $sysName - regexp ' $needle ' matches ' $platform ' - skipping device discovery \n " );
2020-09-21 15:40:17 +02:00
2017-10-04 02:16:23 -05:00
return true ;
}
}
}
return false ;
}
/**
* Try to find a device by sysName, hostname, ip, or mac_address
* If a device cannot be found, returns 0
*
2021-09-08 23:35:56 +02:00
* @param string $name sysName or hostname
* @param string $ip May be an IP or hex string
* @param string $mac_address
2017-10-04 02:16:23 -05:00
* @return int the device_id or 0
*/
function find_device_id ( $name = '' , $ip = '' , $mac_address = '' )
{
$where = [];
$params = [];
2021-03-28 17:25:30 -05:00
if ( $name && \LibreNMS\Util\Validate :: hostname ( $name )) {
2017-10-04 02:16:23 -05:00
$where [] = '`hostname`=?' ;
$params [] = $name ;
if ( $mydomain = Config :: get ( 'mydomain' )) {
$where [] = '`hostname`=?' ;
$params [] = " $name . $mydomain " ;
2020-05-15 05:25:41 +02:00
$where [] = 'concat(`hostname`, \'.\', ?) =?' ;
$params [] = " $mydomain " ;
$params [] = " $name " ;
2017-10-04 02:16:23 -05:00
}
}
if ( $ip ) {
$where [] = '`hostname`=?' ;
$params [] = $ip ;
try {
$params [] = IP :: fromHexString ( $ip ) -> packed ();
$where [] = '`ip`=?' ;
} catch ( InvalidIpException $e ) {
//
}
}
if ( ! empty ( $where )) {
$sql = 'SELECT `device_id` FROM `devices` WHERE ' . implode ( ' OR ' , $where );
if ( $device_id = dbFetchCell ( $sql , $params )) {
return ( int ) $device_id ;
}
}
if ( $mac_address && $mac_address != '000000000000' ) {
if ( $device_id = dbFetchCell ( 'SELECT `device_id` FROM `ports` WHERE `ifPhysAddress`=?' , [ $mac_address ])) {
return ( int ) $device_id ;
}
}
2020-07-05 10:23:11 +07:00
if ( $name ) {
$where = [];
$params = [];
$where [] = '`sysName`=?' ;
$params [] = $name ;
if ( $mydomain = Config :: get ( 'mydomain' )) {
$where [] = '`sysName`=?' ;
$params [] = " $name . $mydomain " ;
$where [] = 'concat(`sysName`, \'.\', ?) =?' ;
$params [] = " $mydomain " ;
$params [] = " $name " ;
}
$sql = 'SELECT `device_id` FROM `devices` WHERE ' . implode ( ' OR ' , $where ) . ' LIMIT 2' ;
$ids = dbFetchColumn ( $sql , $params );
if ( count ( $ids ) == 1 ) {
return ( int ) $ids [ 0 ];
} elseif ( count ( $ids ) > 1 ) {
d_echo ( "find_device_id: more than one device found with sysName ' $name '. \n " );
// don't do anything, try other methods, if any
}
}
2017-10-04 02:16:23 -05:00
return 0 ;
}
/**
2018-05-07 15:17:45 -05:00
* Try to find a port by ifDescr, ifName, ifAlias, or MAC
2017-10-04 02:16:23 -05:00
*
2021-09-08 23:35:56 +02:00
* @param string $description matched against ifDescr, ifName, and ifAlias
* @param string $identifier matched against ifDescr, ifName, and ifAlias
* @param int $device_id restrict search to ports on a specific device
* @param string $mac_address check against ifPhysAddress (should be in lowercase hexadecimal)
2017-10-04 02:16:23 -05:00
* @return int
*/
function find_port_id ( $description , $identifier = '' , $device_id = 0 , $mac_address = null )
{
2017-10-15 13:49:28 -05:00
if ( ! ( $device_id || $mac_address )) {
return 0 ;
}
2017-10-29 13:37:39 -05:00
$statements = [];
2017-10-06 08:53:16 -05:00
$params = [];
2017-10-04 02:16:23 -05:00
2017-10-29 13:37:39 -05:00
if ( $device_id ) {
if ( $description ) {
2018-05-07 15:17:45 -05:00
// order is important here, the standard says this is ifDescr, which some mfg confuse with ifName
2017-10-29 13:37:39 -05:00
$statements [] = 'SELECT `port_id` FROM `ports` WHERE `device_id`=? AND (`ifDescr`=? OR `ifName`=?)' ;
$params [] = $device_id ;
$params [] = $description ;
$params [] = $description ;
}
if ( $identifier ) {
if ( is_numeric ( $identifier )) {
$statements [] = 'SELECT `port_id` FROM `ports` WHERE `device_id`=? AND (`ifIndex`=? OR `ifAlias`=?)' ;
} else {
$statements [] = 'SELECT `port_id` FROM `ports` WHERE `device_id`=? AND (`ifDescr`=? OR `ifName`=?)' ;
}
$params [] = $device_id ;
$params [] = $identifier ;
$params [] = $identifier ;
2017-10-06 08:53:16 -05:00
}
2021-05-26 00:17:48 +02:00
if ( $description ) {
// we check ifAlias last because this is a user editable field, but some bad LLDP implementations use it
$statements [] = 'SELECT `port_id` FROM `ports` WHERE `device_id`=? AND `ifAlias`=?' ;
$params [] = $device_id ;
$params [] = $description ;
}
2017-10-04 02:16:23 -05:00
}
if ( $mac_address ) {
2017-10-29 13:37:39 -05:00
$mac_statement = 'SELECT `port_id` FROM `ports` WHERE ' ;
if ( $device_id ) {
$mac_statement .= '`device_id`=? AND ' ;
$params [] = $device_id ;
}
$mac_statement .= '`ifPhysAddress`=?' ;
$statements [] = $mac_statement ;
2017-10-04 02:16:23 -05:00
$params [] = $mac_address ;
}
2017-10-29 13:37:39 -05:00
if ( empty ( $statements )) {
return 0 ;
2017-10-04 02:16:23 -05:00
}
2017-10-29 13:37:39 -05:00
$queries = implode ( ' UNION ' , $statements );
$sql = "SELECT * FROM ( $queries LIMIT 1) p" ;
2017-10-04 02:16:23 -05:00
return ( int ) dbFetchCell ( $sql , $params );
}