Pandora bandwidth server plugin

This commit is contained in:
fbsanchez 2021-02-12 15:25:41 +01:00
parent b026f5c16c
commit 24ed77b5a1
3 changed files with 656 additions and 42 deletions

View File

@ -937,8 +937,8 @@ class AgentWizard extends HTML
$ipsResult = [];
// In this case we need the full information provided by snmpwalk.
$ipsResult = $this->snmpwalkValues($snmpIpDiscover, false, true);
$indexes = $this->snmpwalkValues($snmpIpIndexes, false, true);
$ipsResult = $this->snmpWalkValues($snmpIpDiscover, false, true);
$indexes = $this->snmpWalkValues($snmpIpIndexes, false, true);
$unicastIpReferences = [];
foreach ($indexes as $k => $v) {
@ -960,11 +960,11 @@ class AgentWizard extends HTML
// Set the name of interface.
$interfaces[$indexKey]['name'] = $name;
// Get the description.
$interfaces[$indexKey]['descr'] = $this->snmpgetValue(
$interfaces[$indexKey]['descr'] = $this->snmpGetValue(
'.1.3.6.1.2.1.2.2.1.2.'.$indexKey
);
// Get the MAC address.
$interfaces[$indexKey]['mac'] = $this->snmpgetValue(
$interfaces[$indexKey]['mac'] = $this->snmpGetValue(
'.1.3.6.1.2.1.2.2.1.6.'.$indexKey
);
// Get unicast IP address.
@ -974,12 +974,12 @@ class AgentWizard extends HTML
}
// Get interface alias.
$interfaces[$indexKey]['alias'] = $this->snmpgetValue(
$interfaces[$indexKey]['alias'] = $this->snmpGetValue(
'.1.3.6.1.2.1.31.1.1.1.18.'.$indexKey
);
// Get interface speed.
$interfaces[$indexKey]['speed'] = $this->snmpgetValue(
$interfaces[$indexKey]['speed'] = $this->snmpGetValue(
'.1.3.6.1.2.1.2.2.1.5.'.$indexKey
);
}
@ -1045,7 +1045,7 @@ class AgentWizard extends HTML
if ($this->wizardSection === 'snmp_interfaces_explorer') {
// Check if thereis x64 counters.
$snmp_tmp = '.1.3.6.1.2.1.31.1.1.1.6';
$check_x64 = $this->snmpwalkValues(
$check_x64 = $this->snmpWalkValues(
$snmp_tmp,
false,
true
@ -1061,7 +1061,7 @@ class AgentWizard extends HTML
// Explore interface names.
$oidExplore = '.1.3.6.1.2.1.31.1.1.1.1';
$receivedOid = $this->snmpwalkValues(
$receivedOid = $this->snmpWalkValues(
$oidExplore,
false,
true
@ -1072,7 +1072,7 @@ class AgentWizard extends HTML
}
// Doc Interfaces de red.
$receivedOid = $this->snmpwalkValues(
$receivedOid = $this->snmpWalkValues(
$oidExplore,
false,
false
@ -1083,7 +1083,7 @@ class AgentWizard extends HTML
$oidExplore = '1.3.6.1.2.1.2.2.1.2';
// Doc Interfaces de red.
$receivedOid = $this->snmpwalkValues(
$receivedOid = $this->snmpWalkValues(
$oidExplore,
false,
true
@ -2403,7 +2403,7 @@ class AgentWizard extends HTML
}
// Get current value.
$currentValue = $this->snmpgetValue($moduleData['value']);
$currentValue = $this->snmpGetValue($moduleData['value']);
// It unit of measure have data, attach to current value.
if (empty($moduleData['module_unit']) === false) {
@ -2556,7 +2556,7 @@ class AgentWizard extends HTML
}
// Get current value.
$currentValue = $this->snmpgetValue($moduleData['value']);
$currentValue = $this->snmpGetValue($moduleData['value']);
// Format current value with thousands and decimals.
if (is_numeric($currentValue) === true) {
@ -2927,7 +2927,7 @@ class AgentWizard extends HTML
// Common for FIXED Scan types.
// If _nameOID_ macro exists, stablish the name getted.
if (empty($module['name_oid']) === false) {
$nameValue = $this->snmpgetValue($module['name_oid']);
$nameValue = $this->snmpGetValue($module['name_oid']);
$moduleBlocks[$k]['name'] = str_replace(
'_nameOID_',
$nameValue,
@ -2941,7 +2941,7 @@ class AgentWizard extends HTML
$module['value'] = 0;
}
$value = $this->snmpgetValue($module['value']);
$value = $this->snmpGetValue($module['value']);
// If the value is missing, we must not show this module.
if (empty($value) === true) {
unset($moduleBlocks[$k]);
@ -2963,7 +2963,7 @@ class AgentWizard extends HTML
// OIDs and get his values.
foreach ($macros as $key => $oid) {
if (preg_match('/extra_field_/', $key) !== 0) {
$value = (float) $this->snmpgetValue($oid);
$value = (float) $this->snmpGetValue($oid);
// If the value not exists,
// we must not create a module.
@ -2999,20 +2999,20 @@ class AgentWizard extends HTML
} else {
if ($module['execution_type'] == EXECUTION_TYPE_NETWORK) {
// Get the values of snmpwalk.
$snmpwalkNames = $this->snmpwalkValues($module['name_oid']);
$snmpwalkValues = $this->snmpwalkValues($module['value']);
$snmpwalkNames = $this->snmpWalkValues($module['name_oid']);
$snmpWalkValues = $this->snmpWalkValues($module['value']);
$snmpwalkCombined = [];
foreach ($snmpwalkNames as $index => $name) {
if (isset($name) !== true
|| isset($snmpwalkValues[$index]) !== true
|| isset($snmpWalkValues[$index]) !== true
) {
continue;
}
$snmpwalkCombined[$index] = [
'name' => $name,
'value' => $snmpwalkValues[$index],
'value' => $snmpWalkValues[$index],
];
}
@ -3062,7 +3062,7 @@ class AgentWizard extends HTML
$snmpwalkNamesTmp = [];
// Is needed the index and the values of snmpwalk.
$snmpwalkNamesTmp = $this->snmpwalkValues(
$snmpwalkNamesTmp = $this->snmpWalkValues(
$module['name_oid'],
true
);
@ -3082,7 +3082,7 @@ class AgentWizard extends HTML
foreach ($oids as $oidName => $oid) {
$currentOid = $oid.'.'.$tmpSecond[0];
$macros['macros'][$oidName] = $currentOid;
$currentOidValue = $this->snmpgetValue($currentOid);
$currentOidValue = $this->snmpGetValue($currentOid);
// If for any reason the value comes empty, add 1.
if ($currentOidValue == '') {
$currentOidValue = 1;
@ -3240,6 +3240,58 @@ class AgentWizard extends HTML
}
/**
* Returns associated PEN code of this device.
*
* @return integer|null PEN oid or null if not found.
*/
private function getPEN()
{
$oid = '.1.3.6.1.2.1.1.2.0';
$output = $this->snmpWalkValues($oid, false, true, true);
static $pen;
if (isset($pen) === true) {
return $pen;
}
if (is_array($output) === true
&& isset($output[$oid]) === true
) {
// Output should be an array with only 1 element.
$pen = (int) explode('.', $output[$oid])[7];
}
if ($pen === 0) {
return null;
}
return $pen;
}
/**
* Returns the index oid matching selected expected value.
*
* @param string $oidTree Tree to search in.
* @param string $expectedValue Expected value.
*
* @return string|false Index where expected value is stored or false if not
* found.
*/
private function snmpGetValueInverse($oidTree, $expectedValue)
{
$oidTree = $this->snmpWalkValues($oidTree);
if (is_array($oidTree) === false) {
return false;
}
return array_search($expectedValue, $oidTree);
}
/**
* Perform a snmpget for get a value from provided oid.
*
@ -3248,13 +3300,13 @@ class AgentWizard extends HTML
*
* @return mixed String when response, null if error.
*/
private function snmpgetValue(string $oid, ?bool $full_output=false)
private function snmpGetValue(string $oid, ?bool $full_output=false)
{
if ($oid[0] !== '.') {
$oid = '.'.$oid;
}
$output = $this->snmpwalkValues($oid, false, true, true);
$output = $this->snmpWalkValues($oid, false, true, true);
if (is_array($output) === true) {
foreach ($output as $k => $v) {
@ -3287,7 +3339,7 @@ class AgentWizard extends HTML
*
* @return array
*/
private function snmpwalkValues(
private function snmpWalkValues(
string $oid,
bool $full_output=false,
bool $pure=false,
@ -4286,7 +4338,7 @@ class AgentWizard extends HTML
{
$moduleDescription = '';
$name = '';
$value = '1';
$value = '_generic_';
// Unpack the array with data.
if (empty($data) === false) {
if (empty($data['mac']) === false) {
@ -4320,7 +4372,7 @@ class AgentWizard extends HTML
// IfOperStatus.
$adminStatusValue = 1;
if (empty($data) === false) {
$adminStatusValue = $this->snmpgetValue(
$adminStatusValue = $this->snmpGetValue(
'1.3.6.1.2.1.2.2.1.7.'.$value
);
@ -4331,7 +4383,7 @@ class AgentWizard extends HTML
// IfOperStatus.
$operStatusValue = 1;
if (empty($data) === false) {
$operStatusValue = $this->snmpgetValue(
$operStatusValue = $this->snmpGetValue(
'1.3.6.1.2.1.2.2.1.8.'.$value
);
@ -4408,9 +4460,11 @@ class AgentWizard extends HTML
'ifOutNUcastPkts / ifHCOutNUcastPkts',
];
if ($name == '') {
if ($name === '') {
foreach ($definition_temp as $module => $module_def) {
$definition_temp[$module]['module_name'] = array_shift($general_module_names);
$definition_temp[$module]['module_name'] = array_shift(
$general_module_names
);
}
}
@ -4444,6 +4498,59 @@ class AgentWizard extends HTML
],
];
// Manufacturer specific modules.
$pen = $this->getPEN();
switch ($pen) {
case 9:
// CISCO.
$valueTranslated = $this->snmpGetValueInverse(
'.1.3.6.1.4.1.9.5.1.4.1.1.11.1',
$value
);
if ($valueTranslated === false && $value !== '_generic_') {
$duplexMismatchOID = null;
} else {
$duplexMismatchOID = '.1.3.6.1.4.1.9.5.1.4.1.1.10.1';
$duplexMismatchOID .= $valueTranslated;
$minc = 2.5;
$maxc = 3.5;
}
break;
// TODO: Add here extra manufacturers.
default:
// Unknown.
$duplexMismatchOID = null;
break;
}
if (isset($duplexMismatchOID) === true) {
// Duplex mismatch.
$moduleName = $name.'DuplexMismatch';
$definition['DuplexMismatch'] = [
'module_name' => $moduleName,
'module_type' => MODULE_TYPE_REMOTE_SNMP,
'module_description' => sprintf(
'(%s%s)',
$moduleDescription,
$moduleName
),
'module_info' => 'Indicates whether the port is operating in half-duplex, full-duplex, disagree or auto negotiation mode. If the port could not agree with the far end on port duplex, the port will be in disagree(3) mode.',
'execution_type' => 'network',
'value' => $duplexMismatchOID,
'default_enabled' => true,
'module_enabled' => false,
'module_thresholds' => [
'min_warning' => '0',
'max_warning' => '0',
'inv_warning' => false,
'min_critical' => $minc,
'max_critical' => $maxc,
'inv_critical' => false,
],
];
}
// Continue with common x86 and x84 modules.
// IfAdminStatus.
$moduleName = $name.'ifAdminStatus';

View File

@ -2042,19 +2042,18 @@ sub api_create_group {
# -> means $context (v3)
#
# Configuration hash
#
# $snmp{version}
# $snmp{community}
# $snmp{host}
# $snmp{oid}
# $snmp{port}
# $snmp{securityName}
# $snmp{context
# $snmp{securityLevel}
# $snmp{authProtocol}
# $snmp{authKey}
# $snmp{privProtocol}
# $snmp{privKey}
# $snmp{version}
# $snmp{community}
# $snmp{host}
# $snmp{oid}
# $snmp{port}
# $snmp{securityName}
# $snmp{context
# $snmp{securityLevel}
# $snmp{authProtocol}
# $snmp{authKey}
# $snmp{privProtocol}
# $snmp{privKey}
################################################################################
sub snmp_walk {
my $snmp = shift;

View File

@ -0,0 +1,508 @@
#!/usr/bin/perl
#
################################################################################
#
# Bandwith plugin
#
# Requirements:
# snmpget
# snmpwalk
#
# (c) Fco de Borja Sanchez <fborja.sanchez@artica.es>
#
# 2018/06/27
# Changes:
# First version
#
################################################################################
use strict;
use warnings;
use POSIX qw(strftime);
use lib '/usr/lib/perl5';
use PandoraFMS::PluginTools;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
# version: Defines actual version of Pandora FMS
my $pandora_version = "7.0NG.752";
my $pandora_build = "210212";
our $VERSION = $pandora_version." ".$pandora_build;
my $HELP=<<EO_HELP;
Pandora FMS Server plugin for bandwidth monitoring $VERSION
Where OPTIONS could be:
[OIDS]
-use_x64 Use x64 counters (1) or not (0).
[SNMP]
-community community
-version SNMP version (1,2c,3)
-host target host
-port target port (161)
[SNMPv3]
-securityName
-context
-securityLevel
-authProtocol
-authKey
-privProtocol
-privKey
[EXTRA]
-ifIndex Target interface to retrieve, if not specified, total
bandwith will be reported.
Note: You can also use snmpget/snmpwalk argument notation,
e.g. -v is equal to -version, -c to -community, etc.
EO_HELP
use constant {
UNKNOWN_DUPLEX => 0,
HALF_DUPLEX => 2,
FULL_DUPLEX => 3,
};
################################################################################
# Translate argument to config hash key
################################################################################
sub update_config_key ($) {
my $arg = shift;
if ($arg eq "c"){
return "community";
}
if ($arg eq "v"){
return "version";
}
if ($arg eq "h"){
return "host";
}
if ($arg eq "p"){
return "port";
}
if ($arg eq "o"){
return "oid_base";
}
if ($arg eq "d"){
return "datatype";
}
if ($arg eq "u"){
return "securityName";
}
if ($arg eq "n"){
return "context";
}
if ($arg eq "l"){
return "securityLevel";
}
if ($arg eq "a"){
return "authProtocol";
}
if ($arg eq "A"){
return "authKey";
}
if ($arg eq "x"){
return "privProtocol";
}
if ($arg eq "X"){
return "privKey";
}
if ($arg eq "agent") {
return "agent_name";
}
if ($arg eq "names") {
return "names";
}
if ($arg eq "branches") {
return "branches";
}
if ($arg eq 'ifIndex') {
return "ifIndex";
}
}
################################################################################
# Prepare analysis tree
################################################################################
sub prepare_tree {
my ($config) = @_;
my $tree;
my %snmp_call = %{$config};
my $ifIndex = $config->{'ifIndex'};
$ifIndex = '' if empty($ifIndex);
if (!empty($ifIndex) && $ifIndex !~ /^\./) {
$ifIndex = '.'.$ifIndex;
}
if (is_enabled($config->{'use_x64'})) {
$snmp_call{'oid'} = $config->{'oid_base'} . $config->{'x64_indexes'}{'__idx__'}.$ifIndex;
} else {
$snmp_call{'oid'} = $config->{'oid_base'} . $config->{'x86_indexes'}{'__idx__'}.$ifIndex;
}
my $raw = snmp_walk(\%snmp_call);
return $raw if (ref($raw) eq "HASH");
my @data = split /\n/, $raw;
foreach my $it (@data) {
my ($key, $value) = split /=/, $it;
$value = trim($value);
$key = trim($key);
$value =~ s/^.*:\ {0,1}//;
if ($value =~ /No such instance/i) {
return {};
}
$ifIndex = $value;
if ($ifIndex !~ /^\./) {
$ifIndex = '.'.$ifIndex;
}
my %inOctets_call = %{$config};
if (is_enabled($config->{'use_x64'})) {
$inOctets_call{'oid'} = $config->{'oid_base'};
$inOctets_call{'oid'} .= $config->{'x64_indexes'}{'inOctets'}.$ifIndex;
} else {
$inOctets_call{'oid'} = $config->{'oid_base'};
$inOctets_call{'oid'} .= $config->{'x86_indexes'}{'inOctets'}.$ifIndex;
}
my $inOctets = snmp_get(\%inOctets_call);
if (ref($inOctets) eq "HASH") {
$inOctets = $inOctets->{'data'};
} else {
# Ignore, cannot retrieve inOctets.
next;
}
my %outOctets_call = %{$config};
if (is_enabled($config->{'use_x64'})) {
$outOctets_call{'oid'} = $config->{'oid_base'};
$outOctets_call{'oid'} .= $config->{'x64_indexes'}{'outOctets'}.$ifIndex;
} else {
$outOctets_call{'oid'} = $config->{'oid_base'};
$outOctets_call{'oid'} .= $config->{'x86_indexes'}{'outOctets'}.$ifIndex;
}
my $outOctets = snmp_get(\%outOctets_call);
if (ref($outOctets) eq "HASH") {
$outOctets = $outOctets->{'data'};
} else {
# Ignore, cannot retrieve inOctets.
next;
}
my %duplex_call = %{$config};
if (is_enabled($config->{'use_x64'})) {
$duplex_call{'oid'} = $config->{'oid_base'};
$duplex_call{'oid'} .= $config->{'x64_indexes'}{'duplex'}.$ifIndex;
} else {
$duplex_call{'oid'} = $config->{'oid_base'};
$duplex_call{'oid'} .= $config->{'x86_indexes'}{'duplex'}.$ifIndex;
}
my $duplex = snmp_get(\%duplex_call);
if (ref($duplex) eq "HASH") {
$duplex = $duplex->{'data'};
} else {
# Ignore, cannot retrieve inOctets.
next;
}
my %speed = %{$config};
if (is_enabled($config->{'use_x64'})) {
$speed{'oid'} = $config->{'oid_base'};
$speed{'oid'} .= $config->{'x64_indexes'}{'ifSpeed'}.$ifIndex;
} else {
$speed{'oid'} = $config->{'oid_base'};
$speed{'oid'} .= $config->{'x86_indexes'}{'ifSpeed'}.$ifIndex;
}
my $speed = snmp_get(\%speed);
if (ref($speed) eq "HASH") {
$speed = $speed->{'data'};
} else {
# Ignore, cannot retrieve inOctets.
next;
}
$tree->{$value} = {
'duplex' => int $duplex,
'speed' => int $speed,
'now' => {
'timestamp' => time(),
'inOctets' => int $inOctets,
'outOctets' => int $outOctets,
},
}
}
load_data($config, $tree);
save_data($config, $tree);
return $tree;
}
################################################################################
# Load previous metrics from temporal file.
################################################################################
sub load_data {
my ($config, $tree) = @_;
my $_f;
eval {
open($_f, "<$config->{'tmp_file'}") or die('Cannot open ' . $config->{'tmp_file'});
};
if( $@ ) {
foreach my $iface (keys %{$tree}) {
$tree->{$iface}{'old'} = {
'timestamp' => int $tree->{$iface}{'now'}{'timestamp'},
'inOctets' => int $tree->{$iface}{'now'}{'inOctets'},
'outOctets' => int $tree->{$iface}{'now'}{'outOctets'},
};
}
return;
}
# File opened, load previous values.
while (my $line =<$_f>) {
$line = trim($line);
my ($timestamp, $iface, $inOctets, $outOctets) = split /$config->{'tmp_separator'}/, $line;
next if (!defined($tree->{trim($iface)}));
$tree->{trim($iface)}{'old'} = {
'timestamp' => int trim($timestamp),
'inOctets' => int trim($inOctets),
'outOctets' => int trim($outOctets),
};
}
close($_f);
foreach my $iface (keys %{$tree}) {
if (empty($tree->{trim($iface)}{'old'}{'timestamp'})) {
$tree->{$iface}{'old'} = {
'timestamp' => int $tree->{$iface}{'now'}{'timestamp'},
'inOctets' => int $tree->{$iface}{'now'}{'inOctets'},
'outOctets' => int $tree->{$iface}{'now'}{'outOctets'},
};
}
}
}
################################################################################
# Save metrics to temporal file.
################################################################################
sub save_data {
my ($config, $tree) = @_;
my $_f;
eval {
open($_f, ">$config->{'tmp_file'}") or die('Cannot open ' . $config->{'tmp_file'});
};
if( $@ ) {
logger($config, 'info', "Cannot save stats, please check writting permissions on [" . $config->{'tmp_file'} . "]");
return;
}
# File not available, reset old data.
my $target_oids = 'x86_indexes';
$target_oids = 'x64_indexes' if is_enabled($config->{'use_x64'});
foreach my $iface (keys %{$tree}) {
# Timestamp.
print $_f $tree->{$iface}{'now'}{'timestamp'} . $config->{'tmp_separator'};
# Iface.
print $_f $iface . $config->{'tmp_separator'};
# InOctets.
print $_f $tree->{$iface}{'now'}{'inOctets'} . $config->{'tmp_separator'};
# OutOctets.
print $_f $tree->{$iface}{'now'}{'outOctets'} . $config->{'tmp_separator'};
# End.
print $_f "\n";
}
close($_f);
}
################################################################################
# Calculate bandwidth
################################################################################
sub get_bandwidth {
my ($config, $tree) = @_;
foreach my $iface (keys %{$tree}) {
my $ifIndex = $iface;
if ($ifIndex !~ /^\./) {
$ifIndex = '.'.$ifIndex;
}
my $speed = $tree->{$iface}{'speed'};
my $input = $tree->{$iface}{'now'}{'inOctets'} - $tree->{$iface}{'old'}{'inOctets'};
my $output = $tree->{$iface}{'now'}{'outOctets'} - $tree->{$iface}{'old'}{'outOctets'};
my $delta = $tree->{$iface}{'now'}{'timestamp'} - $tree->{$iface}{'old'}{'timestamp'};
my $bandwidth = 0;
$tree->{$iface}->{'delta'} = {
'inOctets' => $input,
'outOctets' => $output,
'seconds' => $delta,
};
$tree->{$iface}->{'speed'} = $speed;
if (($speed > 0) && ($delta > 0)) {
# Information about bandwidth calculation: https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/8141-calculate-bandwidth-snmp.html
if ($tree->{$iface}{'duplex'} == HALF_DUPLEX
|| $tree->{$iface}{'duplex'} == UNKNOWN_DUPLEX
) {
$bandwidth = (($input + $output) * 8) / ($delta * $speed);
}
elsif ($tree->{$iface}{'duplex'} == FULL_DUPLEX) {
my $input_bandwidth = ($input * 8) / ($delta * $speed);
my $output_bandwidth = ($output * 8) / ($delta * $speed);
$bandwidth = ($input_bandwidth + $output_bandwidth) / 2;
}
else {
logger($config, 'info', "Failed to calculate bandwidth, unknown duplex mode: [" . $tree->{$iface}{'duplex_mode'} . "]");
}
}
else {
logger($config, 'info', "Failed to calculate bandwidth, interface [" . $iface . "] speed is 0");
}
$tree->{$iface}->{'bandwidth'} = 100 * $bandwidth;
}
}
################################################################################
#
# MAIN
#
################################################################################
if ($#ARGV < 0) {
print $HELP;
exit 0;
}
# Base config definition
my $_config = {
'oid_base' => ".1.3.6.1.2.1",
'as_agent_plugin' => 1,
'use_x64' => 0,
'x86_indexes' => {
'__idx__' => ".2.2.1.1",
'duplex' => ".10.7.2.1.19",
'inOctets' => ".2.2.1.16",
'outOctets' => ".2.2.1.10",
'ifSpeed' => ".2.2.1.5",
},
'x64_indexes' => {
# In x64 there is no 'index' branch. Uses latest 'id' in OID as ID.
'__idx__' => ".2.2.1.1",
'duplex' => ".10.7.2.1.19",
'inOctets' => ".31.1.1.1.6",
'outOctets' => ".31.1.1.1.10",
'ifSpeed' => ".2.2.1.5",
},
};
$_config = read_configuration($_config);
if (check_lib_version($pandora_version) == 0){
print_stderror($_config, "Incorrect PluginTools library version " . get_lib_version() . " != " . $VERSION . " functionality could be affected.");
}
my $config;
foreach my $pk (keys %{$_config}) {
my $k = update_config_key($pk);
if (!empty($k)) {
$config->{$k} = $_config->{$pk};
}
else {
$config->{$pk} = $_config->{$pk};
}
}
$config->{'host'} = '127.0.0.1' if empty($config->{'host'});
$config->{'port'} = '161' if empty($config->{'port'});
$config->{'tmp_separator'} = ';' if empty($config->{'tmp_separator'});
$config->{'tmp'} = (($^O =~ /win/)?$ENV{'TMP'}:'/tmp') if empty($config->{'tmp'});
# Create unique name for tmp and log file for host
my $filename = $config->{'tmp'}.'/pandora_bandwith_'.$config->{'host'};
# Replace every dot for underscore
$filename =~ tr/./_/;
$config->{'tmp_file'} = $filename.'.idx' if empty($config->{'tmp_file'});
$config->{'log'} = $filename.'.log' if empty($config->{'log'});
my @int_exc = split /,/, trim($config->{'interface_exceptions'}) if (!empty($config->{'interface_exceptions'}));
if ($#int_exc >= 0) {
$config->{'interface_exceptions'} = \@int_exc;
}
my @only_int = split /,/, trim($config->{'only_interfaces'}) if (!empty($config->{'only_interfaces'}));
if ($#only_int >= 0) {
$config->{'only_interfaces'} = \@only_int;
}
logger($config, 'info', "Plugin starts");
if (is_enabled($config->{'debug'})) {
eval {
eval "use Data::Dumper;1;";if($@) {}
logger($config, Dumper($config));
};
if($@) {}
}
my $analysis_tree = prepare_tree($config);
if (!empty($analysis_tree->{'error'})) {
logger($config, 'info', "Failed: " . $analysis_tree->{'error'});
exit 0;
}
else {
get_bandwidth($config, $analysis_tree);
}
# Report data
my @modules;
my $bandwidth = 0;
my $i = 0;
foreach my $iface (keys %{$analysis_tree}) {
# Calculate summary;
if (is_enabled($analysis_tree->{$iface}{'bandwidth'})) {
$bandwidth = $analysis_tree->{$iface}{'bandwidth'};
$i++;
}
}
if ($i > 0) {
$bandwidth /= $i;
print sprintf("%.9f\n", $bandwidth);
}
logger($config, 'info', "Plugin ends");