Pandora bandwidth server plugin
This commit is contained in:
parent
b026f5c16c
commit
24ed77b5a1
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
Loading…
Reference in New Issue