PageRenderTime 55ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 2ms

/check_nwc_health

https://github.com/bigbrozer/netplugins
Perl | 8210 lines | 7207 code | 735 blank | 268 comment | 541 complexity | c44bbd95e4109065b20a9f1f133f9323 MD5 | raw file
Possible License(s): GPL-3.0
  1. #! /usr/bin/perl -w
  2. package Nagios::MiniPlugin;
  3. use strict;
  4. use Getopt::Long qw(:config no_ignore_case bundling);
  5. our @STATUS_CODES = qw(OK WARNING CRITICAL UNKNOWN DEPENDENT);
  6. require Exporter;
  7. our @ISA = qw(Exporter);
  8. our @EXPORT = (@STATUS_CODES, qw(nagios_exit nagios_die check_messages));
  9. our @EXPORT_OK = qw(%ERRORS);
  10. use constant OK => 0;
  11. use constant WARNING => 1;
  12. use constant CRITICAL => 2;
  13. use constant UNKNOWN => 3;
  14. use constant DEPENDENT => 4;
  15. our %ERRORS = (
  16. 'OK' => OK,
  17. 'WARNING' => WARNING,
  18. 'CRITICAL' => CRITICAL,
  19. 'UNKNOWN' => UNKNOWN,
  20. 'DEPENDENT' => DEPENDENT,
  21. );
  22. our %STATUS_TEXT = reverse %ERRORS;
  23. sub new {
  24. my $class = shift;
  25. my %params = @_;
  26. my $self = {
  27. perfdata => [],
  28. messages => {
  29. ok => [],
  30. warning => [],
  31. critical => [],
  32. unknown => [],
  33. },
  34. args => [],
  35. opts => Nagios::MiniPlugin::Getopt->new(%params),
  36. };
  37. foreach (qw(shortname usage version url plugin blurb extra
  38. license timeout)) {
  39. $self->{$_} = $params{$_};
  40. }
  41. bless $self, $class;
  42. }
  43. sub add_arg {
  44. my $self = shift;
  45. $self->{opts}->add_arg(@_);
  46. }
  47. sub getopts {
  48. my $self = shift;
  49. $self->{opts}->getopts();
  50. }
  51. sub override_opt {
  52. my $self = shift;
  53. $self->{opts}->override_opt(@_);
  54. }
  55. sub opts {
  56. my $self = shift;
  57. return $self->{opts};
  58. }
  59. sub add_message {
  60. my $self = shift;
  61. my ($code, @messages) = @_;
  62. $code = (qw(ok warning critical unknown))[$code] if $code =~ /^\d+$/;
  63. $code = lc $code;
  64. push @{$self->{messages}->{$code}}, @messages;
  65. }
  66. sub add_perfdata {
  67. my ($self, %args) = @_;
  68. #if ($args{label} =~ /\s/) {
  69. $args{label} = '\''.$args{label}.'\'';
  70. #}
  71. if (! exists $args{places}) {
  72. $args{places} = 2;
  73. }
  74. my $format = '%d';
  75. if ($args{value} =~ /\./) {
  76. $format = '%.'.$args{places}.'f';
  77. }
  78. my $str = $args{label}.'='.sprintf $format, $args{value};
  79. if ($args{uom}) {
  80. $str .= $args{uom};
  81. }
  82. if ($args{warning}) {
  83. $str .= ';'.$args{warning};
  84. }
  85. if ($args{critical}) {
  86. $str .= ';'.$args{critical};
  87. }
  88. push @{$self->{perfdata}}, $str;
  89. }
  90. sub clear_messages {
  91. my $self = shift;
  92. my $code = shift;
  93. $code = (qw(ok warning critical unknown))[$code] if $code =~ /^\d+$/;
  94. $code = lc $code;
  95. $self->{messages}->{$code} = [];
  96. }
  97. sub check_messages {
  98. my $self = shift;
  99. my %args = @_;
  100. # Add object messages to any passed in as args
  101. for my $code (qw(critical warning unknown ok)) {
  102. my $messages = $self->{messages}->{$code} || [];
  103. if ($args{$code}) {
  104. unless (ref $args{$code} eq 'ARRAY') {
  105. if ($code eq 'ok') {
  106. $args{$code} = [ $args{$code} ];
  107. }
  108. }
  109. push @{$args{$code}}, @$messages;
  110. } else {
  111. $args{$code} = $messages;
  112. }
  113. }
  114. my %arg = %args;
  115. $arg{join} = ' ' unless defined $arg{join};
  116. # Decide $code
  117. my $code = OK;
  118. $code ||= CRITICAL if @{$arg{critical}};
  119. $code ||= WARNING if @{$arg{warning}};
  120. $code ||= UNKNOWN if @{$arg{unknown}};
  121. return $code unless wantarray;
  122. # Compose message
  123. my $message = '';
  124. if ($arg{join_all}) {
  125. $message = join( $arg{join_all},
  126. map { @$_ ? join( $arg{'join'}, @$_) : () }
  127. $arg{critical},
  128. $arg{warning},
  129. $arg{unknown},
  130. $arg{ok} ? (ref $arg{ok} ? $arg{ok} : [ $arg{ok} ]) : []
  131. );
  132. }
  133. else {
  134. $message ||= join( $arg{'join'}, @{$arg{critical}} )
  135. if $code == CRITICAL;
  136. $message ||= join( $arg{'join'}, @{$arg{warning}} )
  137. if $code == WARNING;
  138. $message ||= join( $arg{'join'}, @{$arg{unknown}} )
  139. if $code == UNKNOWN;
  140. $message ||= ref $arg{ok} ? join( $arg{'join'}, @{$arg{ok}} ) : $arg{ok}
  141. if $arg{ok};
  142. }
  143. return ($code, $message);
  144. }
  145. sub nagios_exit {
  146. my $self = shift;
  147. my ($code, $message, $arg) = @_;
  148. $code = $ERRORS{$code} if defined $code && exists $ERRORS{$code};
  149. $code = UNKNOWN unless defined $code && exists $STATUS_TEXT{$code};
  150. $message = '' unless defined $message;
  151. if (ref $message && ref $message eq 'ARRAY') {
  152. $message = join(' ', map { chomp; $_ } @$message);
  153. } else {
  154. chomp $message;
  155. }
  156. my $output = "$STATUS_TEXT{$code}";
  157. $output .= " - $message" if defined $message && $message ne '';
  158. if (scalar (@{$self->{perfdata}})) {
  159. $output .= " | ".join(" ", @{$self->{perfdata}});
  160. }
  161. $output .= "\n";
  162. print $output;
  163. exit $code;
  164. }
  165. sub set_thresholds {
  166. my $self = shift;
  167. my %params = @_;
  168. $self->{mywarning} = $self->opts->warning || $params{warning} || 0;
  169. $self->{mycritical} = $self->opts->critical || $params{critical} || 0;
  170. }
  171. sub get_thresholds {
  172. my $self = shift;
  173. return ($self->{mywarning}, $self->{mycritical});
  174. }
  175. sub check_thresholds {
  176. my $self = shift;
  177. my @params = @_;
  178. my $level = $ERRORS{OK};
  179. my $warningrange;
  180. my $criticalrange;
  181. my $value;
  182. if (scalar(@params) > 1) {
  183. my %params = @params;
  184. $value = $params{check};
  185. $warningrange = (defined $params{warning}) ?
  186. $params{warning} : $self->{mywarning};
  187. $criticalrange = (defined $params{critical}) ?
  188. $params{critical} : $self->{mycritical};
  189. } else {
  190. $value = $params[0];
  191. $warningrange = $self->{mywarning};
  192. $criticalrange = $self->{mycritical};
  193. }
  194. if ($warningrange !~ /:/ && $criticalrange !~ /:/) {
  195. # warning = 10, critical = 20, warn if > 10, crit if > 20
  196. $level = $ERRORS{WARNING} if $value > $warningrange;
  197. $level = $ERRORS{CRITICAL} if $value > $criticalrange;
  198. } elsif ($warningrange =~ /(\d+):/ &&
  199. $criticalrange =~ /(\d+):/) {
  200. # warning = 98:, critical = 95:, warn if < 98, crit if < 95
  201. $warningrange =~ /(\d+):/;
  202. $level = $ERRORS{WARNING} if $value < $1;
  203. $criticalrange =~ /(\d+):/;
  204. $level = $ERRORS{CRITICAL} if $value < $1;
  205. }
  206. return $level;
  207. #
  208. # syntax error must be reported with returncode -1
  209. #
  210. }
  211. package Nagios::MiniPlugin::Getopt;
  212. use strict;
  213. use File::Basename;
  214. use Data::Dumper;
  215. use Getopt::Long qw(:config no_ignore_case bundling);
  216. # Standard defaults
  217. my %DEFAULT = (
  218. timeout => 15,
  219. verbose => 0,
  220. license =>
  221. "This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY.
  222. It may be used, redistributed and/or modified under the terms of the GNU
  223. General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).",
  224. );
  225. # Standard arguments
  226. my @ARGS = ({
  227. spec => 'usage|?',
  228. help => "-?, --usage\n Print usage information",
  229. }, {
  230. spec => 'help|h',
  231. help => "-h, --help\n Print detailed help screen",
  232. }, {
  233. spec => 'version|V',
  234. help => "-V, --version\n Print version information",
  235. }, {
  236. #spec => 'extra-opts:s@',
  237. #help => "--extra-opts=[<section>[@<config_file>]]\n Section and/or config_file from which to load extra options (may repeat)",
  238. }, {
  239. spec => 'timeout|t=i',
  240. help => sprintf("-t, --timeout=INTEGER\n Seconds before plugin times out (default: %s)", $DEFAULT{timeout}),
  241. default => $DEFAULT{timeout},
  242. }, {
  243. spec => 'verbose|v+',
  244. help => "-v, --verbose\n Show details for command-line debugging (can repeat up to 3 times)",
  245. default => $DEFAULT{verbose},
  246. },
  247. );
  248. # Standard arguments we traditionally display last in the help output
  249. my %DEFER_ARGS = map { $_ => 1 } qw(timeout verbose);
  250. sub _init
  251. {
  252. my $self = shift;
  253. my %params = @_;
  254. # Check params
  255. my $plugin = basename($ENV{NAGIOS_PLUGIN} || $0);
  256. #my %attr = validate( @_, {
  257. my %attr = (
  258. usage => 1,
  259. version => 0,
  260. url => 0,
  261. plugin => { default => $plugin },
  262. blurb => 0,
  263. extra => 0,
  264. 'extra-opts' => 0,
  265. license => { default => $DEFAULT{license} },
  266. timeout => { default => $DEFAULT{timeout} },
  267. );
  268. # Add attr to private _attr hash (except timeout)
  269. $self->{timeout} = delete $attr{timeout};
  270. $self->{_attr} = { %attr };
  271. foreach (keys %{$self->{_attr}}) {
  272. if (exists $params{$_}) {
  273. $self->{_attr}->{$_} = $params{$_};
  274. } else {
  275. $self->{_attr}->{$_} = $self->{_attr}->{$_}->{default}
  276. if ref ($self->{_attr}->{$_}) eq 'HASH' &&
  277. exists $self->{_attr}->{$_}->{default};
  278. }
  279. }
  280. # Chomp _attr values
  281. chomp foreach values %{$self->{_attr}};
  282. # Setup initial args list
  283. $self->{_args} = [ grep { exists $_->{spec} } @ARGS ];
  284. $self
  285. }
  286. sub new
  287. {
  288. my $class = shift;
  289. my $self = bless {}, $class;
  290. $self->_init(@_);
  291. }
  292. sub add_arg {
  293. my $self = shift;
  294. my %arg = @_;
  295. push (@{$self->{_args}}, \%arg);
  296. }
  297. sub getopts {
  298. my $self = shift;
  299. my %commandline = ();
  300. my @params = map { $_->{spec} } @{$self->{_args}};
  301. if (! GetOptions(\%commandline, @params)) {
  302. $self->print_help();
  303. exit 0;
  304. } else {
  305. no strict 'refs';
  306. do { $self->print_help(); exit 0; } if $commandline{help};
  307. do { $self->print_version(); exit 0 } if $commandline{version};
  308. do { $self->print_usage(); exit 0 } if $commandline{usage};
  309. foreach (map { $_->{spec} =~ /^([\w\-]+)/; $1; } @{$self->{_args}}) {
  310. my $field = $_;
  311. *{"$field"} = sub {
  312. return $self->{opts}->{$field};
  313. };
  314. }
  315. foreach (grep { exists $_->{default} } @{$self->{_args}}) {
  316. $_->{spec} =~ /^([\w\-]+)/;
  317. my $spec = $1;
  318. $self->{opts}->{$spec} = $_->{default};
  319. }
  320. foreach (keys %commandline) {
  321. $self->{opts}->{$_} = $commandline{$_};
  322. }
  323. }
  324. }
  325. sub override_opt {
  326. my $self = shift;
  327. my $key = shift;
  328. my $value = shift;
  329. $self->{opts}->{$key} = $value;
  330. }
  331. sub get {
  332. my $self = shift;
  333. my $opt = shift;
  334. return $self->{opts}->{$opt};
  335. }
  336. sub print_help {
  337. my $self = shift;
  338. $self->print_version();
  339. printf "\n%s\n", $self->{_attr}->{license};
  340. printf "\n%s\n\n", $self->{_attr}->{blurb};
  341. $self->print_usage();
  342. foreach (@{$self->{_args}}) {
  343. printf " %s\n", $_->{help};
  344. }
  345. exit 0;
  346. }
  347. sub print_usage {
  348. my $self = shift;
  349. printf $self->{_attr}->{usage}, $self->{_attr}->{plugin};
  350. print "\n";
  351. }
  352. sub print_version {
  353. my $self = shift;
  354. printf "%s %s", $self->{_attr}->{plugin}, $self->{_attr}->{version};
  355. printf " [%s]", $self->{_attr}->{url} if $self->{_attr}->{url};
  356. print "\n";
  357. }
  358. sub print_license {
  359. my $self = shift;
  360. printf "%s\n", $self->{_attr}->{license};
  361. print "\n";
  362. }
  363. package Server::Linux;
  364. use strict;
  365. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  366. our @ISA = qw(NWC::Device);
  367. sub init {
  368. my $self = shift;
  369. $self->{components} = {
  370. interface_subsystem => undef,
  371. };
  372. $self->{serial} = 'unknown';
  373. $self->{product} = 'unknown';
  374. $self->{romversion} = 'unknown';
  375. if (! $self->check_messages()) {
  376. if ($self->mode =~ /device::interfaces/) {
  377. $self->analyze_interface_subsystem();
  378. $self->check_interface_subsystem();
  379. }
  380. }
  381. }
  382. sub analyze_interface_subsystem {
  383. my $self = shift;
  384. $self->{components}->{interface_subsystem} =
  385. Server::Linux::Component::InterfaceSubsystem->new();
  386. }
  387. sub check_interface_subsystem {
  388. my $self = shift;
  389. $self->{components}->{interface_subsystem}->check();
  390. $self->{components}->{interface_subsystem}->dump()
  391. if $self->opts->verbose >= 2;
  392. }
  393. package Server::Linux::Component::InterfaceSubsystem;
  394. our @ISA = qw(Server::Linux);
  395. use strict;
  396. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  397. sub new {
  398. my $class = shift;
  399. my %params = @_;
  400. my $self = {
  401. interfaces => [],
  402. blacklisted => 0,
  403. info => undef,
  404. extendedinfo => undef,
  405. };
  406. bless $self, $class;
  407. $self->init(%params);
  408. return $self;
  409. }
  410. sub init {
  411. my $self = shift;
  412. my %params = @_;
  413. if ($self->mode =~ /device::interfaces::list/) {
  414. foreach (glob "/sys/class/net/*") {
  415. my $name = $_;
  416. $name =~ s/.*\///g;
  417. my $tmpif = {
  418. ifDescr => $name,
  419. };
  420. push(@{$self->{interfaces}},
  421. Server::Linux::Component::InterfaceSubsystem::Interface->new(%{$tmpif}));
  422. }
  423. } else {
  424. foreach (glob "/sys/class/net/*") {
  425. my $name = $_;
  426. $name =~ s/.*\///g;
  427. if ($self->opts->name) {
  428. if ($self->opts->regexp) {
  429. my $pattern = $self->opts->name;
  430. if ($name !~ /$pattern/i) {
  431. next;
  432. }
  433. } elsif (lc $name ne lc $self->opts->name) {
  434. next;
  435. }
  436. }
  437. my $tmpif = {
  438. ifDescr => $name,
  439. ifSpeed => (-f "/sys/class/net/$name/speed" ? do { local (@ARGV, $/) = "/sys/class/net/$name/speed"; my $x = <>; close ARGV; $x} * 1024*1024 : 1024*1024*1024),
  440. ifInOctets => do { local (@ARGV, $/) = "/sys/class/net/$name/statistics/rx_bytes"; my $x = <>; close ARGV; $x},
  441. ifInDiscards => do { local (@ARGV, $/) = "/sys/class/net/$name/statistics/rx_dropped"; my $x = <>; close ARGV; $x},
  442. ifInErrors => do { local (@ARGV, $/) = "/sys/class/net/$name/statistics/rx_errors"; my $x = <>; close ARGV; $x},
  443. ifOutOctets => do { local (@ARGV, $/) = "/sys/class/net/$name/statistics/tx_bytes"; my $x = <>; close ARGV; $x},
  444. ifOutDiscards => do { local (@ARGV, $/) = "/sys/class/net/$name/statistics/tx_dropped"; my $x = <>; close ARGV; $x},
  445. ifOutErrors => do { local (@ARGV, $/) = "/sys/class/net/$name/statistics/tx_errors"; my $x = <>; close ARGV; $x},
  446. };
  447. foreach (keys %{$tmpif}) {
  448. chomp($tmpif->{$_});
  449. }
  450. push(@{$self->{interfaces}},
  451. Server::Linux::Component::InterfaceSubsystem::Interface->new(%{$tmpif}));
  452. }
  453. }
  454. }
  455. sub check {
  456. my $self = shift;
  457. my $errorfound = 0;
  458. $self->add_info('checking interfaces');
  459. $self->blacklist('ff', '');
  460. if (scalar(@{$self->{interfaces}}) == 0) {
  461. $self->add_message(UNKNOWN, 'no interfaces');
  462. return;
  463. }
  464. if ($self->mode =~ /device::interfaces::list/) {
  465. foreach (sort {$a->{ifDescr} cmp $b->{ifDescr}} @{$self->{interfaces}}) {
  466. $_->list();
  467. }
  468. } else {
  469. if (scalar (@{$self->{interfaces}}) == 0) {
  470. } else {
  471. foreach (@{$self->{interfaces}}) {
  472. $_->check();
  473. }
  474. }
  475. }
  476. }
  477. sub dump {
  478. my $self = shift;
  479. foreach (@{$self->{interfaces}}) {
  480. $_->dump();
  481. }
  482. }
  483. package Server::Linux::Component::InterfaceSubsystem::Interface;
  484. our @ISA = qw(Server::Linux::Component::InterfaceSubsystem);
  485. use strict;
  486. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  487. sub new {
  488. my $class = shift;
  489. my %params = @_;
  490. my $self = {
  491. ifDescr => $params{ifDescr},
  492. ifSpeed => $params{ifSpeed},
  493. ifInOctets => $params{ifInOctets},
  494. ifInDiscards => $params{ifInDiscards},
  495. ifInErrors => $params{ifInErrors},
  496. ifOutOctets => $params{ifOutOctets},
  497. ifOutDiscards => $params{ifOutDiscards},
  498. ifOutErrors => $params{ifOutErrors},
  499. blacklisted => 0,
  500. info => undef,
  501. extendedinfo => undef,
  502. };
  503. foreach my $key (keys %params) {
  504. $self->{$key} = 0 if ! defined $params{$key};
  505. }
  506. bless $self, $class;
  507. $self->init();
  508. return $self;
  509. }
  510. sub init {
  511. my $self = shift;
  512. if ($self->mode =~ /device::interfaces::traffic/) {
  513. $self->valdiff({name => $self->{ifDescr}}, qw(ifInOctets ifInDiscards ifInErrors ifOutOctets ifOutDiscards ifOutErrors));
  514. } elsif ($self->mode =~ /device::interfaces::usage/) {
  515. $self->valdiff({name => $self->{ifDescr}}, qw(ifInOctets ifOutOctets));
  516. if ($self->{ifSpeed} == 0) {
  517. # vlan graffl
  518. $self->{inputUtilization} = 0;
  519. $self->{outputUtilization} = 0;
  520. } else {
  521. $self->{inputUtilization} = $self->{delta_ifInOctets} * 8 * 100 /
  522. ($self->{delta_timestamp} * $self->{ifSpeed});
  523. $self->{outputUtilization} = $self->{delta_ifOutOctets} * 8 * 100 /
  524. ($self->{delta_timestamp} * $self->{ifSpeed});
  525. }
  526. $self->{inputRate} = $self->{delta_ifInOctets} / $self->{delta_timestamp};
  527. $self->{outputRate} = $self->{delta_ifOutOctets} / $self->{delta_timestamp};
  528. my $factor = 1/8; # default Bits
  529. if ($self->opts->units) {
  530. if ($self->opts->units eq "GB") {
  531. $factor = 1024 * 1024 * 1024;
  532. } elsif ($self->opts->units eq "MB") {
  533. $factor = 1024 * 1024;
  534. } elsif ($self->opts->units eq "KB") {
  535. $factor = 1024;
  536. } elsif ($self->opts->units eq "GBi") {
  537. $factor = 1024 * 1024 * 1024 / 8;
  538. } elsif ($self->opts->units eq "MBi") {
  539. $factor = 1024 * 1024 / 8;
  540. } elsif ($self->opts->units eq "KBi") {
  541. $factor = 1024 / 8;
  542. } elsif ($self->opts->units eq "B") {
  543. $factor = 1;
  544. } elsif ($self->opts->units eq "Bit") {
  545. $factor = 1/8;
  546. }
  547. }
  548. $self->{inputRate} /= $factor;
  549. $self->{outputRate} /= $factor;
  550. } elsif ($self->mode =~ /device::interfaces::errors/) {
  551. $self->valdiff({name => $self->{ifDescr}}, qw(ifInErrors ifOutErrors ifInDiscards ifOutDiscards));
  552. $self->{inputErrorRate} = $self->{delta_ifInErrors}
  553. / $self->{delta_timestamp};
  554. $self->{outputErrorRate} = $self->{delta_ifOutErrors}
  555. / $self->{delta_timestamp};
  556. $self->{inputDiscardRate} = $self->{delta_ifInDiscards}
  557. / $self->{delta_timestamp};
  558. $self->{outputDiscardRate} = $self->{delta_ifOutDiscards}
  559. / $self->{delta_timestamp};
  560. $self->{inputRate} = ($self->{delta_ifInErrors} + $self->{delta_ifInDiscards})
  561. / $self->{delta_timestamp};
  562. $self->{outputRate} = ($self->{delta_ifOutErrors} + $self->{delta_ifOutDiscards})
  563. / $self->{delta_timestamp};
  564. } elsif ($self->mode =~ /device::interfaces::operstatus/) {
  565. }
  566. return $self;
  567. }
  568. sub check {
  569. my $self = shift;
  570. $self->blacklist('if', $self->{ifDescr});
  571. if ($self->mode =~ /device::interfaces::traffic/) {
  572. } elsif ($self->mode =~ /device::interfaces::usage/) {
  573. my $info = sprintf 'interface %s usage is in:%.2f%% (%s) out:%.2f%% (%s)',
  574. $self->{ifDescr},
  575. $self->{inputUtilization},
  576. sprintf("%.2f%s/s", $self->{inputRate},
  577. ($self->opts->units ? $self->opts->units : 'Bits')),
  578. $self->{outputUtilization},
  579. sprintf("%.2f%s/s", $self->{outputRate},
  580. ($self->opts->units ? $self->opts->units : 'Bits'));
  581. $self->add_info($info);
  582. $self->set_thresholds(warning => 80, critical => 90);
  583. my $in = $self->check_thresholds($self->{inputUtilization});
  584. my $out = $self->check_thresholds($self->{outputUtilization});
  585. my $level = ($in > $out) ? $in : ($out > $in) ? $out : $in;
  586. $self->add_message($level, $info);
  587. $self->add_perfdata(
  588. label => $self->{ifDescr}.'_usage_in',
  589. value => $self->{inputUtilization},
  590. uom => '%',
  591. warning => $self->{warning},
  592. critical => $self->{critical},
  593. );
  594. $self->add_perfdata(
  595. label => $self->{ifDescr}.'_usage_out',
  596. value => $self->{outputUtilization},
  597. uom => '%',
  598. warning => $self->{warning},
  599. critical => $self->{critical},
  600. );
  601. $self->add_perfdata(
  602. label => $self->{ifDescr}.'_traffic_in',
  603. value => $self->{inputRate},
  604. uom => $self->opts->units,
  605. );
  606. $self->add_perfdata(
  607. label => $self->{ifDescr}.'_traffic_out',
  608. value => $self->{outputRate},
  609. uom => $self->opts->units,
  610. );
  611. } elsif ($self->mode =~ /device::interfaces::errors/) {
  612. my $info = sprintf 'interface %s errors in:%.2f/s out:%.2f/s '.
  613. 'discards in:%.2f/s out:%.2f/s',
  614. $self->{ifDescr},
  615. $self->{inputErrorRate} , $self->{outputErrorRate},
  616. $self->{inputDiscardRate} , $self->{outputDiscardRate};
  617. $self->add_info($info);
  618. $self->set_thresholds(warning => 1, critical => 10);
  619. my $in = $self->check_thresholds($self->{inputRate});
  620. my $out = $self->check_thresholds($self->{outputRate});
  621. my $level = ($in > $out) ? $in : ($out > $in) ? $out : $in;
  622. $self->add_message($level, $info);
  623. $self->add_perfdata(
  624. label => $self->{ifDescr}.'_errors_in',
  625. value => $self->{inputErrorRate},
  626. warning => $self->{warning},
  627. critical => $self->{critical},
  628. );
  629. $self->add_perfdata(
  630. label => $self->{ifDescr}.'_errors_out',
  631. value => $self->{outputErrorRate},
  632. warning => $self->{warning},
  633. critical => $self->{critical},
  634. );
  635. $self->add_perfdata(
  636. label => $self->{ifDescr}.'_discards_in',
  637. value => $self->{inputDiscardRate},
  638. warning => $self->{warning},
  639. critical => $self->{critical},
  640. );
  641. $self->add_perfdata(
  642. label => $self->{ifDescr}.'_discards_out',
  643. value => $self->{outputDiscardRate},
  644. warning => $self->{warning},
  645. critical => $self->{critical},
  646. );
  647. }
  648. }
  649. sub list {
  650. my $self = shift;
  651. printf "%s\n", $self->{ifDescr};
  652. }
  653. sub dump {
  654. my $self = shift;
  655. printf "[IF_%s]\n", $self->{ifDescr};
  656. foreach (qw(ifDescr ifSpeed ifInOctets ifInDiscards ifInErrors ifOutOctets ifOutDiscards ifOutErrors)) {
  657. printf "%s: %s\n", $_, defined $self->{$_} ? $self->{$_} : 'undefined';
  658. }
  659. # printf "info: %s\n", $self->{info};
  660. printf "\n";
  661. }
  662. package NWC::CiscoIOS::Component::CpuSubsystem;
  663. our @ISA = qw(NWC::CiscoIOS);
  664. use strict;
  665. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  666. sub new {
  667. my $class = shift;
  668. my %params = @_;
  669. my $self = {
  670. cpus => [],
  671. blacklisted => 0,
  672. info => undef,
  673. extendedinfo => undef,
  674. };
  675. bless $self, $class;
  676. $self->init(%params);
  677. return $self;
  678. }
  679. sub init {
  680. my $self = shift;
  681. my %params = @_;
  682. my $type = 0;
  683. foreach ($self->get_snmp_table_objects(
  684. 'CISCO-PROCESS-MIB', 'cpmCPUTotalTable')) {
  685. $_->{cpmCPUTotalIndex} ||= $type++;
  686. push(@{$self->{cpus}},
  687. NWC::CiscoIOS::Component::CpuSubsystem::Cpu->new(%{$_}));
  688. }
  689. if (scalar(@{$self->{cpus}}) == 0) {
  690. # maybe too old. i fake a cpu. be careful. this is a really bad hack
  691. my $response = $self->get_request(
  692. -varbindlist => [
  693. $NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1},
  694. $NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy5},
  695. $NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{busyPer},
  696. ]
  697. );
  698. if (exists $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1}}) {
  699. push(@{$self->{cpus}},
  700. NWC::CiscoIOS::Component::CpuSubsystem::Cpu->new(
  701. cpmCPUTotalPhysicalIndex => 0, #fake
  702. cpmCPUTotalIndex => 0, #fake
  703. cpmCPUTotal5sec => 0, #fake
  704. cpmCPUTotal5secRev => 0, #fake
  705. cpmCPUTotal1min => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1}},
  706. cpmCPUTotal1minRev => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1}},
  707. cpmCPUTotal5min => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy5}},
  708. cpmCPUTotal5minRev => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy5}},
  709. cpmCPUMonInterval => 0, #fake
  710. cpmCPUTotalMonIntervalValue => 0, #fake
  711. cpmCPUInterruptMonIntervalValue => 0, #fake
  712. ));
  713. }
  714. }
  715. }
  716. sub check {
  717. my $self = shift;
  718. my $errorfound = 0;
  719. $self->add_info('checking cpus');
  720. $self->blacklist('ff', '');
  721. if (scalar (@{$self->{cpus}}) == 0) {
  722. } else {
  723. foreach (@{$self->{cpus}}) {
  724. $_->check();
  725. }
  726. }
  727. }
  728. sub dump {
  729. my $self = shift;
  730. foreach (@{$self->{cpus}}) {
  731. $_->dump();
  732. }
  733. }
  734. package NWC::CiscoIOS::Component::CpuSubsystem::Cpu;
  735. our @ISA = qw(NWC::CiscoIOS::Component::CpuSubsystem);
  736. use strict;
  737. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  738. sub new {
  739. my $class = shift;
  740. my %params = @_;
  741. my $self = {
  742. blacklisted => 0,
  743. info => undef,
  744. extendedinfo => undef,
  745. };
  746. foreach my $param (qw(cpmCPUTotalIndex cpmCPUTotalPhysicalIndex
  747. cpmCPUTotal5sec cpmCPUTotal1min cpmCPUTotal5min
  748. cpmCPUTotal5secRev cpmCPUTotal1minRev cpmCPUTotal5minRev
  749. cpmCPUMonInterval cpmCPUTotalMonIntervalValue
  750. cpmCPUInterruptMonIntervalValue)) {
  751. if (exists $params{$param}) {
  752. $self->{$param} = $params{$param};
  753. }
  754. }
  755. bless $self, $class;
  756. if (exists $params{cpmCPUTotal5minRev}) {
  757. $self->{usage} = $params{cpmCPUTotal5minRev};
  758. } else {
  759. $self->{usage} = $params{cpmCPUTotal5min};
  760. }
  761. if ($self->{cpmCPUTotalPhysicalIndex}) {
  762. my $entPhysicalName = '1.3.6.1.2.1.47.1.1.1.1.7';
  763. $self->{entPhysicalName} = $self->get_request(
  764. -varbindlist => [$entPhysicalName.'.'.$self->{cpmCPUTotalPhysicalIndex}]
  765. );
  766. $self->{entPhysicalName} = $self->{entPhysicalName}->{$entPhysicalName.'.'.$self->{cpmCPUTotalPhysicalIndex}};
  767. } else {
  768. $self->{entPhysicalName} = $self->{cpmCPUTotalIndex};
  769. }
  770. return $self;
  771. }
  772. sub check {
  773. my $self = shift;
  774. $self->blacklist('c', $self->{cpmCPUTotalPhysicalIndex});
  775. my $info = sprintf 'cpu %s usage (5 min avg.) is %.2f%%',
  776. $self->{entPhysicalName}, $self->{usage};
  777. $self->add_info($info);
  778. $self->set_thresholds(warning => 80, critical => 90);
  779. $self->add_message($self->check_thresholds($self->{usage}), $info);
  780. $self->add_perfdata(
  781. label => 'cpu_'.$self->{entPhysicalName}.'_usage',
  782. value => $self->{usage},
  783. uom => '%',
  784. warning => $self->{warning},
  785. critical => $self->{critical},
  786. );
  787. }
  788. sub dump {
  789. my $self = shift;
  790. printf "[CPU_%s]\n", $self->{cpmCPUTotalPhysicalIndex};
  791. foreach (qw(cpmCPUTotalIndex cpmCPUTotalPhysicalIndex cpmCPUTotal5sec cpmCPUTotal1min cpmCPUTotal5min cpmCPUTotal5secRev cpmCPUTotal1minRev cpmCPUTotal5minRev cpmCPUMonInterval cpmCPUTotalMonIntervalValue cpmCPUInterruptMonIntervalValue)) {
  792. if (exists $self->{$_}) {
  793. printf "%s: %s\n", $_, $self->{$_};
  794. }
  795. }
  796. printf "info: %s\n", $self->{info};
  797. printf "\n";
  798. }
  799. package NWC::CiscoIOS::Component::MemSubsystem;
  800. our @ISA = qw(NWC::CiscoIOS);
  801. use strict;
  802. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  803. sub new {
  804. my $class = shift;
  805. my %params = @_;
  806. my $self = {
  807. runtime => $params{runtime},
  808. rawdata => $params{rawdata},
  809. mems => [],
  810. blacklisted => 0,
  811. info => undef,
  812. extendedinfo => undef,
  813. };
  814. bless $self, $class;
  815. $self->init(%params);
  816. return $self;
  817. }
  818. sub init {
  819. my $self = shift;
  820. my %params = @_;
  821. my $snmpwalk = $params{rawdata};
  822. my $ignore_redundancy = $params{ignore_redundancy};
  823. my $type = 0;
  824. foreach ($self->get_snmp_table_objects(
  825. 'CISCO-MEMORY-POOL-MIB', 'ciscoMemoryPoolTable')) {
  826. $_->{ciscoMemoryPoolType} ||= $type++;
  827. push(@{$self->{mems}},
  828. NWC::CiscoIOS::Component::MemSubsystem::Mem->new(%{$_}));
  829. }
  830. }
  831. sub check {
  832. my $self = shift;
  833. my $errorfound = 0;
  834. $self->add_info('checking mems');
  835. $self->blacklist('ff', '');
  836. if (scalar (@{$self->{mems}}) == 0) {
  837. } else {
  838. foreach (@{$self->{mems}}) {
  839. $_->check();
  840. }
  841. }
  842. }
  843. sub dump {
  844. my $self = shift;
  845. foreach (@{$self->{mems}}) {
  846. $_->dump();
  847. }
  848. }
  849. package NWC::CiscoIOS::Component::MemSubsystem::Mem;
  850. our @ISA = qw(NWC::CiscoIOS::Component::MemSubsystem);
  851. use strict;
  852. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  853. sub new {
  854. my $class = shift;
  855. my %params = @_;
  856. my $self = {
  857. blacklisted => 0,
  858. info => undef,
  859. extendedinfo => undef,
  860. };
  861. foreach my $param (qw(ciscoMemoryPoolTable ciscoMemoryPoolEntry
  862. ciscoMemoryPoolType ciscoMemoryPoolName ciscoMemoryPoolAlternate
  863. ciscoMemoryPoolValid ciscoMemoryPoolUsed ciscoMemoryPoolFree
  864. ciscoMemoryPoolLargestFree)) {
  865. $self->{$param} = $params{$param};
  866. }
  867. bless $self, $class;
  868. $self->{usage} = 100 * $params{ciscoMemoryPoolUsed} /
  869. ($params{ciscoMemoryPoolFree} + $params{ciscoMemoryPoolUsed});
  870. return $self;
  871. }
  872. sub check {
  873. my $self = shift;
  874. $self->blacklist('m', $self->{ciscoMemoryPoolType});
  875. my $info = sprintf 'mempool %s usage is %.2f%%',
  876. $self->{ciscoMemoryPoolName}, $self->{usage};
  877. $self->add_info($info);
  878. $self->set_thresholds(warning => 80, critical => 90);
  879. $self->add_message($self->check_thresholds($self->{usage}), $info);
  880. $self->add_perfdata(
  881. label => $self->{ciscoMemoryPoolName}.'_usage',
  882. value => $self->{usage},
  883. uom => '%',
  884. warning => $self->{warning},
  885. critical => $self->{critical}
  886. );
  887. }
  888. sub dump {
  889. my $self = shift;
  890. printf "[MEMPOOL_%s]\n", $self->{ciscoMemoryPoolType};
  891. foreach (qw(ciscoMemoryPoolType ciscoMemoryPoolName ciscoMemoryPoolAlternate ciscoMemoryPoolValid ciscoMemoryPoolUsed ciscoMemoryPoolFree ciscoMemoryPoolLargestFree)) {
  892. printf "%s: %s\n", $_, $self->{$_};
  893. }
  894. printf "info: %s\n", $self->{info};
  895. printf "\n";
  896. }
  897. package NWC::CiscoIOS::Component::EnvironmentalSubsystem;
  898. our @ISA = qw(NWC::CiscoIOS);
  899. use strict;
  900. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  901. sub new {
  902. my $class = shift;
  903. my %params = @_;
  904. my $self = {
  905. runtime => $params{runtime},
  906. rawdata => $params{rawdata},
  907. method => $params{method},
  908. condition => $params{condition},
  909. status => $params{status},
  910. fan_subsystem => undef,
  911. temperature_subsystem => undef,
  912. powersupply_subsystem => undef,
  913. voltage_subsystem => undef,
  914. blacklisted => 0,
  915. info => undef,
  916. extendedinfo => undef,
  917. };
  918. bless $self, $class;
  919. $self->init(%params);
  920. return $self;
  921. }
  922. sub init {
  923. my $self = shift;
  924. my %params = @_;
  925. #
  926. # 1.3.6.1.4.1.9.9.13.1.1.0 ciscoEnvMonPresent (irgendein typ of envmon)
  927. #
  928. $self->{fan_subsystem} =
  929. NWC::CiscoIOS::Component::FanSubsystem->new(%params);
  930. $self->{temperature_subsystem} =
  931. NWC::CiscoIOS::Component::TemperatureSubsystem->new(%params);
  932. $self->{powersupply_subsystem} =
  933. NWC::CiscoIOS::Component::SupplySubsystem->new(%params);
  934. $self->{voltage_subsystem} =
  935. NWC::CiscoIOS::Component::VoltageSubsystem->new(%params);
  936. }
  937. sub check {
  938. my $self = shift;
  939. my $errorfound = 0;
  940. $self->{fan_subsystem}->check();
  941. $self->{temperature_subsystem}->check();
  942. $self->{voltage_subsystem}->check();
  943. $self->{powersupply_subsystem}->check();
  944. if (! $self->check_messages()) {
  945. $self->add_message(OK, "environmental hardware working fine");
  946. }
  947. }
  948. sub dump {
  949. my $self = shift;
  950. $self->{fan_subsystem}->dump();
  951. $self->{temperature_subsystem}->dump();
  952. $self->{voltage_subsystem}->dump();
  953. $self->{powersupply_subsystem}->dump();
  954. }
  955. package NWC::CiscoIOS::Component::TemperatureSubsystem;
  956. our @ISA = qw(NWC::CiscoIOS::Component::EnvironmentalSubsystem);
  957. use strict;
  958. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  959. sub new {
  960. my $class = shift;
  961. my %params = @_;
  962. my $self = {
  963. temperatures => [],
  964. blacklisted => 0,
  965. info => undef,
  966. extendedinfo => undef,
  967. };
  968. bless $self, $class;
  969. $self->init(%params);
  970. return $self;
  971. }
  972. sub init {
  973. my $self = shift;
  974. my $tempcnt = 0;
  975. foreach ($self->get_snmp_table_objects(
  976. 'CISCO-ENVMON-MIB', 'ciscoEnvMonTemperatureStatusTable')) {
  977. $_->{ciscoEnvMonTemperatureStatusIndex} = $tempcnt++ if (! exists $_->{ciscoEnvMonTemperatureStatusIndex});
  978. push(@{$self->{temperatures}},
  979. NWC::CiscoIOS::Component::TemperatureSubsystem::Temperature->new(%{$_}));
  980. }
  981. }
  982. sub check {
  983. my $self = shift;
  984. my $errorfound = 0;
  985. $self->add_info('checking temperatures');
  986. $self->blacklist('t', '');
  987. if (scalar (@{$self->{temperatures}}) == 0) {
  988. } else {
  989. foreach (@{$self->{temperatures}}) {
  990. $_->check();
  991. }
  992. }
  993. }
  994. sub dump {
  995. my $self = shift;
  996. foreach (@{$self->{temperatures}}) {
  997. $_->dump();
  998. }
  999. }
  1000. package NWC::CiscoIOS::Component::TemperatureSubsystem::Temperature;
  1001. our @ISA = qw(NWC::CiscoIOS::Component::TemperatureSubsystem);
  1002. use strict;
  1003. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1004. sub new {
  1005. my $class = shift;
  1006. my %params = @_;
  1007. my $self = {
  1008. blacklisted => 0,
  1009. info => undef,
  1010. extendedinfo => undef,
  1011. };
  1012. foreach my $param (qw(ciscoEnvMonTemperatureStatusIndex
  1013. ciscoEnvMonTemperatureStatusDescr ciscoEnvMonTemperatureStatusValue
  1014. ciscoEnvMonTemperatureThreshold ciscoEnvMonTemperatureLastShutdown
  1015. ciscoEnvMonTemperatureState)) {
  1016. $self->{$param} = $params{$param};
  1017. }
  1018. $self->{ciscoEnvMonTemperatureStatusIndex} ||= 0;
  1019. $self->{ciscoEnvMonTemperatureLastShutdown} ||= 0;
  1020. if ($self->{ciscoEnvMonTemperatureStatusValue}) {
  1021. bless $self, $class;
  1022. } else {
  1023. bless $self, $class.'::Simple';
  1024. }
  1025. return $self;
  1026. }
  1027. sub check {
  1028. my $self = shift;
  1029. $self->blacklist('t', $self->{ciscoEnvMonTemperatureStatusIndex});
  1030. if ($self->{ciscoEnvMonTemperatureStatusValue} >
  1031. $self->{ciscoEnvMonTemperatureThreshold}) {
  1032. $self->add_info(sprintf 'temperature %d %s is too high (%d of %d max = %s)',
  1033. $self->{ciscoEnvMonTemperatureStatusIndex},
  1034. $self->{ciscoEnvMonTemperatureStatusDescr},
  1035. $self->{ciscoEnvMonTemperatureStatusValue},
  1036. $self->{ciscoEnvMonTemperatureThreshold},
  1037. $self->{ciscoEnvMonTemperatureState});
  1038. if ($self->{ciscoEnvMonTemperatureState} eq 'warning') {
  1039. $self->add_message(WARNING, $self->{info});
  1040. } elsif ($self->{ciscoEnvMonTemperatureState} eq 'critical') {
  1041. $self->add_message(CRITICAL, $self->{info});
  1042. }
  1043. } else {
  1044. $self->add_info(sprintf 'temperature %d %s is %d (of %d max = normal)',
  1045. $self->{ciscoEnvMonTemperatureStatusIndex},
  1046. $self->{ciscoEnvMonTemperatureStatusDescr},
  1047. $self->{ciscoEnvMonTemperatureStatusValue},
  1048. $self->{ciscoEnvMonTemperatureThreshold},
  1049. $self->{ciscoEnvMonTemperatureState});
  1050. }
  1051. $self->add_perfdata(
  1052. label => sprintf('temp_%s', $self->{ciscoEnvMonTemperatureStatusIndex}),
  1053. value => $self->{ciscoEnvMonTemperatureStatusValue},
  1054. warning => $self->{ciscoEnvMonTemperatureThreshold},
  1055. critical => undef,
  1056. );
  1057. }
  1058. sub dump {
  1059. my $self = shift;
  1060. printf "[TEMP_%s]\n", $self->{ciscoEnvMonTemperatureStatusIndex};
  1061. foreach (qw(ciscoEnvMonTemperatureStatusIndex ciscoEnvMonTemperatureStatusDescr ciscoEnvMonTemperatureStatusValue ciscoEnvMonTemperatureThreshold ciscoEnvMonTemperatureLastShutdown ciscoEnvMonTemperatureState)) {
  1062. printf "%s: %s\n", $_, $self->{$_};
  1063. }
  1064. printf "info: %s\n", $self->{info};
  1065. printf "\n";
  1066. }
  1067. package NWC::CiscoIOS::Component::TemperatureSubsystem::Temperature::Simple;
  1068. our @ISA = qw(NWC::CiscoIOS::Component::TemperatureSubsystem::Temperature);
  1069. use strict;
  1070. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1071. sub new {
  1072. my $class = shift;
  1073. my %params = @_;
  1074. my $self = {
  1075. runtime => $params{runtime},
  1076. ciscoEnvMonTemperatureStatusIndex => $params{ciscoEnvMonTemperatureStatusIndex} || 0,
  1077. ciscoEnvMonTemperatureStatusDescr => $params{ciscoEnvMonTemperatureStatusDescr},
  1078. ciscoEnvMonTemperatureState => $params{ciscoEnvMonTemperatureState},
  1079. blacklisted => 0,
  1080. info => undef,
  1081. extendedinfo => undef,
  1082. };
  1083. bless $self, $class;
  1084. return $self;
  1085. }
  1086. sub check {
  1087. my $self = shift;
  1088. $self->blacklist('t', $self->{ciscoEnvMonTemperatureStatusIndex});
  1089. $self->add_info(sprintf 'temperature %d %s is %s',
  1090. $self->{ciscoEnvMonTemperatureStatusIndex},
  1091. $self->{ciscoEnvMonTemperatureStatusDescr},
  1092. $self->{ciscoEnvMonTemperatureState});
  1093. if ($self->{ciscoEnvMonTemperatureState} ne 'normal') {
  1094. if ($self->{ciscoEnvMonTemperatureState} eq 'warning') {
  1095. $self->add_message(WARNING, $self->{info});
  1096. } elsif ($self->{ciscoEnvMonTemperatureState} eq 'critical') {
  1097. $self->add_message(CRITICAL, $self->{info});
  1098. }
  1099. } else {
  1100. }
  1101. }
  1102. sub dump {
  1103. my $self = shift;
  1104. printf "[TEMP_%s]\n", $self->{ciscoEnvMonTemperatureStatusIndex};
  1105. foreach (qw(ciscoEnvMonTemperatureStatusIndex ciscoEnvMonTemperatureStatusDescr ciscoEnvMonTemperatureState)) {
  1106. printf "%s: %s\n", $_, $self->{$_};
  1107. }
  1108. printf "info: %s\n", $self->{info};
  1109. printf "\n";
  1110. }
  1111. package NWC::CiscoIOS::Component::SupplySubsystem;
  1112. our @ISA = qw(NWC::CiscoIOS::Component::EnvironmentalSubsystem);
  1113. use strict;
  1114. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1115. sub new {
  1116. my $class = shift;
  1117. my %params = @_;
  1118. my $self = {
  1119. supplies => [],
  1120. blacklisted => 0,
  1121. info => undef,
  1122. extendedinfo => undef,
  1123. };
  1124. bless $self, $class;
  1125. $self->init(%params);
  1126. return $self;
  1127. }
  1128. sub init {
  1129. my $self = shift;
  1130. foreach ($self->get_snmp_table_objects(
  1131. 'CISCO-ENVMON-MIB', 'ciscoEnvMonSupplyStatusTable')) {
  1132. push(@{$self->{supplies}},
  1133. NWC::CiscoIOS::Component::SupplySubsystem::Supply->new(%{$_}));
  1134. }
  1135. }
  1136. sub check {
  1137. my $self = shift;
  1138. my $errorfound = 0;
  1139. $self->add_info('checking supplies');
  1140. $self->blacklist('ps', '');
  1141. if (scalar (@{$self->{supplies}}) == 0) {
  1142. } else {
  1143. foreach (@{$self->{supplies}}) {
  1144. $_->check();
  1145. }
  1146. }
  1147. }
  1148. sub dump {
  1149. my $self = shift;
  1150. foreach (@{$self->{supplies}}) {
  1151. $_->dump();
  1152. }
  1153. }
  1154. package NWC::CiscoIOS::Component::SupplySubsystem::Supply;
  1155. our @ISA = qw(NWC::CiscoIOS::Component::SupplySubsystem);
  1156. use strict;
  1157. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1158. sub new {
  1159. my $class = shift;
  1160. my %params = @_;
  1161. my $self = {
  1162. blacklisted => 0,
  1163. info => undef,
  1164. extendedinfo => undef,
  1165. };
  1166. foreach my $param (qw(ciscoEnvMonSupplyStatusIndex
  1167. ciscoEnvMonSupplyStatusDescr ciscoEnvMonSupplyState
  1168. ciscoEnvMonSupplySource)) {
  1169. $self->{$param} = $params{$param};
  1170. }
  1171. $self->{ciscoEnvMonSupplyStatusIndex} ||= 0;
  1172. bless $self, $class;
  1173. return $self;
  1174. }
  1175. sub check {
  1176. my $self = shift;
  1177. $self->blacklist('f', $self->{ciscoEnvMonSupplyStatusIndex});
  1178. $self->add_info(sprintf 'powersupply %d (%s) is %s',
  1179. $self->{ciscoEnvMonSupplyStatusIndex},
  1180. $self->{ciscoEnvMonSupplyStatusDescr},
  1181. $self->{ciscoEnvMonSupplyState});
  1182. if ($self->{ciscoEnvMonSupplyState} eq 'notPresent') {
  1183. } elsif ($self->{ciscoEnvMonSupplyState} ne 'normal') {
  1184. $self->add_message(CRITICAL, $self->{info});
  1185. }
  1186. }
  1187. sub dump {
  1188. my $self = shift;
  1189. printf "[PS_%s]\n", $self->{ciscoEnvMonSupplyStatusIndex};
  1190. foreach (qw(ciscoEnvMonSupplyStatusIndex ciscoEnvMonSupplyStatusDescr ciscoEnvMonSupplyState ciscoEnvMonSupplySource)) {
  1191. printf "%s: %s\n", $_, $self->{$_};
  1192. }
  1193. printf "info: %s\n", $self->{info};
  1194. printf "\n";
  1195. }
  1196. package NWC::CiscoIOS::Component::VoltageSubsystem;
  1197. our @ISA = qw(NWC::CiscoIOS::Component::EnvironmentalSubsystem);
  1198. use strict;
  1199. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1200. sub new {
  1201. my $class = shift;
  1202. my %params = @_;
  1203. my $self = {
  1204. voltages => [],
  1205. blacklisted => 0,
  1206. info => undef,
  1207. extendedinfo => undef,
  1208. };
  1209. bless $self, $class;
  1210. $self->init(%params);
  1211. return $self;
  1212. }
  1213. sub init {
  1214. my $self = shift;
  1215. my $index = 0;
  1216. foreach ($self->get_snmp_table_objects(
  1217. 'CISCO-ENVMON-MIB', 'ciscoEnvMonVoltageStatusTable')) {
  1218. $_->{ciscoEnvMonVoltageStatusIndex} ||= $index++;
  1219. push(@{$self->{voltages}},
  1220. NWC::CiscoIOS::Component::VoltageSubsystem::Voltage->new(%{$_}));
  1221. }
  1222. }
  1223. sub check {
  1224. my $self = shift;
  1225. my $errorfound = 0;
  1226. $self->add_info('checking voltages');
  1227. $self->blacklist('ff', '');
  1228. if (scalar (@{$self->{voltages}}) == 0) {
  1229. } else {
  1230. foreach (@{$self->{voltages}}) {
  1231. $_->check();
  1232. }
  1233. }
  1234. }
  1235. sub dump {
  1236. my $self = shift;
  1237. foreach (@{$self->{voltages}}) {
  1238. $_->dump();
  1239. }
  1240. }
  1241. package NWC::CiscoIOS::Component::VoltageSubsystem::Voltage;
  1242. our @ISA = qw(NWC::CiscoIOS::Component::VoltageSubsystem);
  1243. use strict;
  1244. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1245. sub new {
  1246. my $class = shift;
  1247. my %params = @_;
  1248. my $self = {
  1249. blacklisted => 0,
  1250. info => undef,
  1251. extendedinfo => undef,
  1252. };
  1253. foreach my $param (qw(ciscoEnvMonVoltageStatusTable
  1254. ciscoEnvMonVoltageStatusEntry ciscoEnvMonVoltageStatusIndex
  1255. ciscoEnvMonVoltageStatusDescr ciscoEnvMonVoltageStatusValue
  1256. ciscoEnvMonVoltageThresholdLow ciscoEnvMonVoltageThresholdHigh
  1257. ciscoEnvMonVoltageLastShutdown ciscoEnvMonVoltageState)) {
  1258. $self->{$param} = $params{$param};
  1259. }
  1260. bless $self, $class;
  1261. return $self;
  1262. }
  1263. sub check {
  1264. my $self = shift;
  1265. $self->blacklist('v', $self->{ciscoEnvMonVoltageStatusIndex});
  1266. $self->add_info(sprintf 'voltage %d (%s) is %s',
  1267. $self->{ciscoEnvMonVoltageStatusIndex},
  1268. $self->{ciscoEnvMonVoltageStatusDescr},
  1269. $self->{ciscoEnvMonVoltageState});
  1270. if ($self->{ciscoEnvMonVoltageState} eq 'notPresent') {
  1271. } elsif ($self->{ciscoEnvMonVoltageState} ne 'normal') {
  1272. $self->add_message(CRITICAL, $self->{info});
  1273. }
  1274. $self->add_perfdata(
  1275. label => sprintf('mvolt_%s', $self->{ciscoEnvMonVoltageStatusIndex}),
  1276. value => $self->{ciscoEnvMonVoltageStatusValue},
  1277. warning => $self->{ciscoEnvMonVoltageThresholdLow},
  1278. critical => $self->{ciscoEnvMonVoltageThresholdHigh},
  1279. );
  1280. }
  1281. sub dump {
  1282. my $self = shift;
  1283. printf "[VOLTAGE_%s]\n", $self->{ciscoEnvMonVoltageStatusIndex};
  1284. foreach (qw(ciscoEnvMonVoltageStatusTable ciscoEnvMonVoltageStatusEntry ciscoEnvMonVoltageStatusIndex ciscoEnvMonVoltageStatusDescr ciscoEnvMonVoltageStatusValue ciscoEnvMonVoltageThresholdLow ciscoEnvMonVoltageThresholdHigh ciscoEnvMonVoltageLastShutdown ciscoEnvMonVoltageState)) {
  1285. printf "%s: %s\n", $_, $self->{$_};
  1286. }
  1287. printf "info: %s\n", $self->{info};
  1288. printf "\n";
  1289. }
  1290. package NWC::CiscoIOS::Component::FanSubsystem;
  1291. our @ISA = qw(NWC::CiscoIOS::Component::EnvironmentalSubsystem);
  1292. use strict;
  1293. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1294. sub new {
  1295. my $class = shift;
  1296. my %params = @_;
  1297. my $self = {
  1298. fans => [],
  1299. blacklisted => 0,
  1300. info => undef,
  1301. extendedinfo => undef,
  1302. };
  1303. bless $self, $class;
  1304. $self->init(%params);
  1305. return $self;
  1306. }
  1307. sub init {
  1308. my $self = shift;
  1309. foreach ($self->get_snmp_table_objects(
  1310. 'CISCO-ENVMON-MIB', 'ciscoEnvMonFanStatusTable')) {
  1311. push(@{$self->{fans}},
  1312. NWC::CiscoIOS::Component::FanSubsystem::Fan->new(%{$_}));
  1313. }
  1314. }
  1315. sub check {
  1316. my $self = shift;
  1317. my $errorfound = 0;
  1318. $self->add_info('checking fans');
  1319. $self->blacklist('ff', '');
  1320. if (scalar (@{$self->{fans}}) == 0) {
  1321. } else {
  1322. foreach (@{$self->{fans}}) {
  1323. $_->check();
  1324. }
  1325. }
  1326. }
  1327. sub dump {
  1328. my $self = shift;
  1329. foreach (@{$self->{fans}}) {
  1330. $_->dump();
  1331. }
  1332. }
  1333. package NWC::CiscoIOS::Component::FanSubsystem::Fan;
  1334. our @ISA = qw(NWC::CiscoIOS::Component::FanSubsystem);
  1335. use strict;
  1336. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1337. sub new {
  1338. my $class = shift;
  1339. my %params = @_;
  1340. my $self = {
  1341. blacklisted => 0,
  1342. info => undef,
  1343. extendedinfo => undef,
  1344. };
  1345. foreach my $param (qw(ciscoEnvMonFanStatusIndex
  1346. ciscoEnvMonFanStatusDescr ciscoEnvMonFanState)) {
  1347. $self->{$param} = $params{$param};
  1348. }
  1349. $self->{ciscoEnvMonFanStatusIndex} ||= 0;
  1350. bless $self, $class;
  1351. return $self;
  1352. }
  1353. sub check {
  1354. my $self = shift;
  1355. $self->blacklist('f', $self->{ciscoEnvMonFanStatusIndex});
  1356. $self->add_info(sprintf 'fan %d (%s) is %s',
  1357. $self->{ciscoEnvMonFanStatusIndex},
  1358. $self->{ciscoEnvMonFanStatusDescr},
  1359. $self->{ciscoEnvMonFanState});
  1360. if ($self->{ciscoEnvMonFanState} eq 'notPresent') {
  1361. } elsif ($self->{ciscoEnvMonFanState} ne 'normal') {
  1362. $self->add_message(CRITICAL, $self->{info});
  1363. }
  1364. }
  1365. sub dump {
  1366. my $self = shift;
  1367. printf "[FAN_%s]\n", $self->{ciscoEnvMonFanStatusIndex};
  1368. foreach (qw(ciscoEnvMonFanStatusIndex ciscoEnvMonFanStatusDescr
  1369. ciscoEnvMonFanState)) {
  1370. printf "%s: %s\n", $_, $self->{$_};
  1371. }
  1372. printf "info: %s\n", $self->{info};
  1373. printf "\n";
  1374. }
  1375. package NWC::CiscoIOS;
  1376. use strict;
  1377. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1378. our @ISA = qw(NWC::Cisco);
  1379. sub init {
  1380. my $self = shift;
  1381. $self->{components} = {
  1382. powersupply_subsystem => undef,
  1383. fan_subsystem => undef,
  1384. temperature_subsystem => undef,
  1385. cpu_subsystem => undef,
  1386. memory_subsystem => undef,
  1387. disk_subsystem => undef,
  1388. environmental_subsystem => undef,
  1389. };
  1390. $self->{serial} = 'unknown';
  1391. $self->{product} = 'unknown';
  1392. $self->{romversion} = 'unknown';
  1393. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  1394. #$self->collect();
  1395. if (! $self->check_messages()) {
  1396. ##$self->set_serial();
  1397. if ($self->mode =~ /device::hardware::health/) {
  1398. $self->analyze_environmental_subsystem();
  1399. #$self->auto_blacklist();
  1400. $self->check_environmental_subsystem();
  1401. } elsif ($self->mode =~ /device::hardware::load/) {
  1402. $self->analyze_cpu_subsystem();
  1403. #$self->auto_blacklist();
  1404. $self->check_cpu_subsystem();
  1405. } elsif ($self->mode =~ /device::hardware::memory/) {
  1406. $self->analyze_mem_subsystem();
  1407. #$self->auto_blacklist();
  1408. $self->check_mem_subsystem();
  1409. } elsif ($self->mode =~ /device::interfaces/) {
  1410. $self->analyze_interface_subsystem();
  1411. $self->check_interface_subsystem();
  1412. } elsif ($self->mode =~ /device::shinken::interface/) {
  1413. $self->analyze_interface_subsystem();
  1414. $self->shinken_interface_subsystem();
  1415. } elsif ($self->mode =~ /device::hsrp/) {
  1416. $self->analyze_hsrp_subsystem();
  1417. $self->check_hsrp_subsystem();
  1418. }
  1419. }
  1420. }
  1421. sub analyze_hsrp_subsystem {
  1422. my $self = shift;
  1423. $self->{components}->{hsrp} =
  1424. NWC::HSRP::Component::HSRPSubsystem->new();
  1425. }
  1426. sub analyze_environmental_subsystem {
  1427. my $self = shift;
  1428. $self->{components}->{environmental_subsystem} =
  1429. NWC::CiscoIOS::Component::EnvironmentalSubsystem->new();
  1430. }
  1431. sub analyze_interface_subsystem {
  1432. my $self = shift;
  1433. $self->{components}->{interface_subsystem} =
  1434. NWC::IFMIB::Component::InterfaceSubsystem->new();
  1435. }
  1436. sub analyze_cpu_subsystem {
  1437. my $self = shift;
  1438. $self->{components}->{cpu_subsystem} =
  1439. NWC::CiscoIOS::Component::CpuSubsystem->new();
  1440. }
  1441. sub analyze_mem_subsystem {
  1442. my $self = shift;
  1443. $self->{components}->{mem_subsystem} =
  1444. NWC::CiscoIOS::Component::MemSubsystem->new();
  1445. }
  1446. sub check_hsrp_subsystem {
  1447. my $self = shift;
  1448. $self->{components}->{hsrp}->check();
  1449. $self->{components}->{hsrp}->dump()
  1450. if $self->opts->verbose >= 2;
  1451. }
  1452. sub check_environmental_subsystem {
  1453. my $self = shift;
  1454. $self->{components}->{environmental_subsystem}->check();
  1455. $self->{components}->{environmental_subsystem}->dump()
  1456. if $self->opts->verbose >= 2;
  1457. }
  1458. sub check_interface_subsystem {
  1459. my $self = shift;
  1460. $self->{components}->{interface_subsystem}->check();
  1461. $self->{components}->{interface_subsystem}->dump()
  1462. if $self->opts->verbose >= 2;
  1463. }
  1464. sub check_cpu_subsystem {
  1465. my $self = shift;
  1466. $self->{components}->{cpu_subsystem}->check();
  1467. $self->{components}->{cpu_subsystem}->dump()
  1468. if $self->opts->verbose >= 2;
  1469. }
  1470. sub check_mem_subsystem {
  1471. my $self = shift;
  1472. $self->{components}->{mem_subsystem}->check();
  1473. $self->{components}->{mem_subsystem}->dump()
  1474. if $self->opts->verbose >= 2;
  1475. }
  1476. sub shinken_interface_subsystem {
  1477. my $self = shift;
  1478. my $attr = sprintf "%s", join(',', map {
  1479. sprintf '%s$(%s)$$()$', $_->{ifDescr}, $_->{ifIndex}
  1480. } @{$self->{components}->{interface_subsystem}->{interfaces}});
  1481. printf <<'EOEO', $self->opts->hostname(), $self->opts->hostname(), $attr;
  1482. define host {
  1483. host_name %s
  1484. address %s
  1485. use default-host
  1486. _interfaces %s
  1487. }
  1488. EOEO
  1489. printf <<'EOEO', $self->opts->hostname();
  1490. define service {
  1491. host_name %s
  1492. service_description net_cpu
  1493. check_command check_nwc_health!cpu-load!80%%!90%%
  1494. }
  1495. EOEO
  1496. printf <<'EOEO', $self->opts->hostname();
  1497. define service {
  1498. host_name %s
  1499. service_description net_mem
  1500. check_command check_nwc_health!memory-usage!80%%!90%%
  1501. }
  1502. EOEO
  1503. printf <<'EOEO', $self->opts->hostname();
  1504. define service {
  1505. host_name %s
  1506. service_description net_ifusage_$KEY$
  1507. check_command check_nwc_health!interface-usage!$VALUE1$!$VALUE2$
  1508. duplicate_foreach _interfaces
  1509. default_value 80%%|90%%
  1510. }
  1511. EOEO
  1512. }
  1513. package NWC::CiscoNXOS::Component::CpuSubsystem;
  1514. our @ISA = qw(NWC::CiscoNXOS);
  1515. use strict;
  1516. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1517. sub new {
  1518. my $class = shift;
  1519. my %params = @_;
  1520. my $self = {
  1521. cpus => [],
  1522. blacklisted => 0,
  1523. info => undef,
  1524. extendedinfo => undef,
  1525. };
  1526. bless $self, $class;
  1527. $self->init(%params);
  1528. return $self;
  1529. }
  1530. sub init {
  1531. my $self = shift;
  1532. my %params = @_;
  1533. my $type = 0;
  1534. foreach ($self->get_snmp_table_objects(
  1535. 'CISCO-PROCESS-MIB', 'cpmCPUTotalTable')) {
  1536. $_->{cpmCPUTotalIndex} ||= $type++;
  1537. push(@{$self->{cpus}},
  1538. NWC::CiscoNXOS::Component::CpuSubsystem::Cpu->new(%{$_}));
  1539. }
  1540. if (scalar(@{$self->{cpus}}) == 0) {
  1541. # maybe too old. i fake a cpu. be careful. this is a really bad hack
  1542. my $response = $self->get_request(
  1543. -varbindlist => [
  1544. $NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1},
  1545. $NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy5},
  1546. $NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{busyPer},
  1547. ]
  1548. );
  1549. if (exists $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1}}) {
  1550. push(@{$self->{cpus}},
  1551. NWC::CiscoNXOS::Component::CpuSubsystem::Cpu->new(
  1552. cpmCPUTotalPhysicalIndex => 0, #fake
  1553. cpmCPUTotalIndex => 0, #fake
  1554. cpmCPUTotal5sec => 0, #fake
  1555. cpmCPUTotal5secRev => 0, #fake
  1556. cpmCPUTotal1min => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1}},
  1557. cpmCPUTotal1minRev => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy1}},
  1558. cpmCPUTotal5min => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy5}},
  1559. cpmCPUTotal5minRev => $response->{$NWC::Device::mibs_and_oids->{'OLD-CISCO-CPU-MIB'}->{avgBusy5}},
  1560. cpmCPUMonInterval => 0, #fake
  1561. cpmCPUTotalMonIntervalValue => 0, #fake
  1562. cpmCPUInterruptMonIntervalValue => 0, #fake
  1563. ));
  1564. }
  1565. }
  1566. }
  1567. sub check {
  1568. my $self = shift;
  1569. my $errorfound = 0;
  1570. $self->add_info('checking cpus');
  1571. $self->blacklist('ff', '');
  1572. if (scalar (@{$self->{cpus}}) == 0) {
  1573. } else {
  1574. foreach (@{$self->{cpus}}) {
  1575. $_->check();
  1576. }
  1577. }
  1578. }
  1579. sub dump {
  1580. my $self = shift;
  1581. foreach (@{$self->{cpus}}) {
  1582. $_->dump();
  1583. }
  1584. }
  1585. package NWC::CiscoNXOS::Component::CpuSubsystem::Cpu;
  1586. our @ISA = qw(NWC::CiscoNXOS::Component::CpuSubsystem);
  1587. use strict;
  1588. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1589. sub new {
  1590. my $class = shift;
  1591. my %params = @_;
  1592. my $self = {
  1593. blacklisted => 0,
  1594. info => undef,
  1595. extendedinfo => undef,
  1596. };
  1597. foreach my $param (qw(cpmCPUTotalIndex cpmCPUTotalPhysicalIndex
  1598. cpmCPUTotal5sec cpmCPUTotal1min cpmCPUTotal5min
  1599. cpmCPUTotal5secRev cpmCPUTotal1minRev cpmCPUTotal5minRev
  1600. cpmCPUMonInterval cpmCPUTotalMonIntervalValue
  1601. cpmCPUInterruptMonIntervalValue)) {
  1602. $self->{$param} = $params{$param};
  1603. }
  1604. bless $self, $class;
  1605. $self->{usage} = $params{cpmCPUTotal5minRev};
  1606. if ($self->{cpmCPUTotalPhysicalIndex}) {
  1607. my $entPhysicalName = '1.3.6.1.2.1.47.1.1.1.1.7';
  1608. $self->{entPhysicalName} = $self->get_request(
  1609. -varbindlist => [$entPhysicalName.'.'.$self->{cpmCPUTotalPhysicalIndex}]
  1610. );
  1611. $self->{entPhysicalName} = $self->{entPhysicalName}->{$entPhysicalName.'.'.$self->{cpmCPUTotalPhysicalIndex}};
  1612. } else {
  1613. $self->{entPhysicalName} = $self->{cpmCPUTotalIndex};
  1614. }
  1615. return $self;
  1616. }
  1617. sub check {
  1618. my $self = shift;
  1619. $self->blacklist('c', $self->{cpmCPUTotalPhysicalIndex});
  1620. my $info = sprintf 'cpu %s usage (5 min avg.) is %.2f%%',
  1621. $self->{entPhysicalName}, $self->{usage};
  1622. $self->add_info($info);
  1623. $self->set_thresholds(warning => 80, critical => 90);
  1624. $self->add_message($self->check_thresholds($self->{usage}), $info);
  1625. $self->add_perfdata(
  1626. label => 'cpu_'.$self->{entPhysicalName}.'_usage',
  1627. value => $self->{usage},
  1628. uom => '%',
  1629. warning => $self->{warning},
  1630. critical => $self->{critical},
  1631. );
  1632. }
  1633. sub dump {
  1634. my $self = shift;
  1635. printf "[CPU_%s]\n", $self->{cpmCPUTotalPhysicalIndex};
  1636. foreach (qw(cpmCPUTotalIndex cpmCPUTotalPhysicalIndex cpmCPUTotal5sec cpmCPUTotal1min cpmCPUTotal5min cpmCPUTotal5secRev cpmCPUTotal1minRev cpmCPUTotal5minRev cpmCPUMonInterval cpmCPUTotalMonIntervalValue cpmCPUInterruptMonIntervalValue)) {
  1637. printf "%s: %s\n", $_, $self->{$_};
  1638. }
  1639. printf "info: %s\n", $self->{info};
  1640. printf "\n";
  1641. }
  1642. package NWC::CiscoNXOS::Component::MemSubsystem;
  1643. our @ISA = qw(NWC::CiscoNXOS);
  1644. use strict;
  1645. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1646. sub new {
  1647. my $class = shift;
  1648. my %params = @_;
  1649. my $self = {
  1650. runtime => $params{runtime},
  1651. rawdata => $params{rawdata},
  1652. mems => [],
  1653. blacklisted => 0,
  1654. info => undef,
  1655. extendedinfo => undef,
  1656. };
  1657. bless $self, $class;
  1658. $self->init(%params);
  1659. return $self;
  1660. }
  1661. sub init {
  1662. my $self = shift;
  1663. my %params = @_;
  1664. my $snmpwalk = $params{rawdata};
  1665. my $ignore_redundancy = $params{ignore_redundancy};
  1666. my $type = 0;
  1667. $self->{cseSysMemoryUtilization} = $self->get_snmp_object('CISCO-SYSTEM-EXT-MIB', 'cseSysMemoryUtilization');
  1668. }
  1669. sub check {
  1670. my $self = shift;
  1671. my $errorfound = 0;
  1672. $self->add_info('checking memory');
  1673. $self->blacklist('m', '');
  1674. if (defined $self->{cseSysMemoryUtilization}) {
  1675. my $info = sprintf 'memory usage is %.2f%%',
  1676. $self->{cseSysMemoryUtilization};
  1677. $self->add_info($info);
  1678. $self->set_thresholds(warning => 80, critical => 90);
  1679. $self->add_message($self->check_thresholds($self->{cseSysMemoryUtilization}), $info);
  1680. $self->add_perfdata(
  1681. label => 'memory_usage',
  1682. value => $self->{cseSysMemoryUtilization},
  1683. uom => '%',
  1684. warning => $self->{warning},
  1685. critical => $self->{critical}
  1686. );
  1687. } else {
  1688. $self->add_message(UNKNOWN, 'cannot aquire momory usage');
  1689. }
  1690. }
  1691. sub dump {
  1692. my $self = shift;
  1693. printf "[MEMORY]\n";
  1694. foreach (qw(cseSysMemoryUtilization)) {
  1695. printf "%s: %s\n", $_, $self->{$_};
  1696. }
  1697. printf "info: %s\n", $self->{info};
  1698. printf "\n";
  1699. }
  1700. package NWC::CiscoNXOS::Component::EnvironmentalSubsystem;
  1701. our @ISA = qw(NWC::CiscoNXOS);
  1702. use strict;
  1703. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1704. sub new {
  1705. my $class = shift;
  1706. my %params = @_;
  1707. my $self = {
  1708. runtime => $params{runtime},
  1709. rawdata => $params{rawdata},
  1710. method => $params{method},
  1711. condition => $params{condition},
  1712. status => $params{status},
  1713. sensor_subsystem => undef,
  1714. blacklisted => 0,
  1715. info => undef,
  1716. extendedinfo => undef,
  1717. };
  1718. bless $self, $class;
  1719. $self->init(%params);
  1720. return $self;
  1721. }
  1722. sub init {
  1723. my $self = shift;
  1724. my %params = @_;
  1725. $self->{sensor_subsystem} =
  1726. NWC::CiscoNXOS::Component::SensorSubsystem->new(%params);
  1727. }
  1728. sub check {
  1729. my $self = shift;
  1730. my $errorfound = 0;
  1731. $self->{sensor_subsystem}->check();
  1732. if (! $self->check_messages()) {
  1733. $self->add_message(OK, "environmental hardware working fine");
  1734. }
  1735. }
  1736. sub dump {
  1737. my $self = shift;
  1738. $self->{sensor_subsystem}->dump();
  1739. }
  1740. package NWC::CiscoNXOS::Component::SensorSubsystem;
  1741. our @ISA = qw(NWC::CiscoNXOS::Component::EnvironmentalSubsystem);
  1742. use strict;
  1743. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1744. sub new {
  1745. my $class = shift;
  1746. my %params = @_;
  1747. my $self = {
  1748. sensors => [],
  1749. sensorthresholds => [],
  1750. blacklisted => 0,
  1751. info => undef,
  1752. extendedinfo => undef,
  1753. };
  1754. bless $self, $class;
  1755. $self->init(%params);
  1756. return $self;
  1757. }
  1758. sub init {
  1759. my $self = shift;
  1760. my $sensors = {};
  1761. foreach ($self->get_snmp_table_objects(
  1762. 'CISCO-ENTITY-SENSOR-MIB', 'entSensorValueTable')) {
  1763. my $sensor = NWC::CiscoNXOS::Component::SensorSubsystem::Sensor->new(%{$_});
  1764. $sensors->{$sensor->{entPhysicalIndex}} = $sensor;
  1765. }
  1766. foreach ($self->get_snmp_table_objects(
  1767. 'CISCO-ENTITY-SENSOR-MIB', 'entSensorThresholdTable')) {
  1768. my $threshold = NWC::CiscoNXOS::Component::SensorSubsystem::SensorThreshold->new(%{$_});
  1769. if (exists $sensors->{$threshold->{entPhysicalIndex}}) {
  1770. push(@{$sensors->{$threshold->{entPhysicalIndex}}->{thresholds}},
  1771. $threshold);
  1772. } else {
  1773. printf STDERR "sensorthreshold without sensor\n";
  1774. }
  1775. }
  1776. #printf "%s\n", Data::Dumper::Dumper($sensors);
  1777. foreach my $sensorid (sort {$a <=> $b} keys %{$sensors}) {
  1778. push(@{$self->{sensors}}, $sensors->{$sensorid});
  1779. }
  1780. }
  1781. sub check {
  1782. my $self = shift;
  1783. my $errorfound = 0;
  1784. $self->add_info('checking sensors');
  1785. $self->blacklist('t', '');
  1786. if (scalar (@{$self->{sensors}}) == 0) {
  1787. } else {
  1788. foreach (@{$self->{sensors}}) {
  1789. $_->check();
  1790. }
  1791. }
  1792. }
  1793. sub dump {
  1794. my $self = shift;
  1795. foreach (@{$self->{sensors}}) {
  1796. $_->dump();
  1797. }
  1798. }
  1799. package NWC::CiscoNXOS::Component::SensorSubsystem::Sensor;
  1800. our @ISA = qw(NWC::CiscoNXOS::Component::SensorSubsystem);
  1801. use strict;
  1802. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1803. sub new {
  1804. my $class = shift;
  1805. my %params = @_;
  1806. my $self = {
  1807. blacklisted => 0,
  1808. info => undef,
  1809. extendedinfo => undef,
  1810. };
  1811. foreach my $param (qw(entSensorType entSensorScale entSensorPrecision
  1812. entSensorValue entSensorStatus entSensorMeasuredEntity indices)) {
  1813. $self->{$param} = $params{$param};
  1814. }
  1815. $self->{entPhysicalIndex} = $params{indices}[0];
  1816. # www.thaiadmin.org%2Fboard%2Findex.php%3Faction%3Ddlattach%3Btopic%3D45832.0%3Battach%3D23494&ei=kV9zT7GHJ87EsgbEvpX6DQ&usg=AFQjCNHuHiS2MR9TIpYtu7C8bvgzuqxgMQ&cad=rja
  1817. # zu klaeren. entPhysicalIndex entspricht dem entPhysicalindex der ENTITY-MIB.
  1818. # In der stehen alle moeglichen Powersupplies etc.
  1819. # Was bedeutet aber dann entSensorMeasuredEntity? gibt's eh nicht in meinen
  1820. # Beispiel-walks
  1821. $self->{thresholds} = [];
  1822. $self->{entSensorMeasuredEntity} ||= 'undef';
  1823. bless $self, $class;
  1824. return $self;
  1825. }
  1826. sub check {
  1827. my $self = shift;
  1828. $self->blacklist('se', $self->{entPhysicalIndex});
  1829. $self->add_info(sprintf '%s sensor %s is %s',
  1830. $self->{entSensorType},
  1831. $self->{entPhysicalIndex},
  1832. $self->{entSensorStatus});
  1833. if ($self->{entSensorStatus} eq "nonoperational") {
  1834. $self->add_message(CRITICAL, $self->{info});
  1835. } elsif ($self->{entSensorStatus} eq "unavailable") {
  1836. } elsif (scalar(grep { $_->{entSensorThresholdEvaluation} eq "true" }
  1837. @{$self->{thresholds}})) {
  1838. $self->add_message(CRITICAL,
  1839. sprintf "%s sensor %s threshold evaluation is true",
  1840. $self->{entSensorType},
  1841. $self->{entPhysicalIndex});
  1842. } else {
  1843. }
  1844. if (scalar(@{$self->{thresholds}} == 2)) {
  1845. my $warning = (map { $_->{entSensorThresholdValue} }
  1846. grep { $_->{entSensorThresholdSeverity} eq "minor" }
  1847. @{$self->{thresholds}})[0];
  1848. my $critical = (map { $_->{entSensorThresholdValue} }
  1849. grep { $_->{entSensorThresholdSeverity} eq "major" }
  1850. @{$self->{thresholds}})[0];
  1851. $self->add_perfdata(
  1852. label => sprintf('sens_%s_%s', $self->{entSensorType}, $self->{entPhysicalIndex}),
  1853. value => $self->{entSensorValue},
  1854. warning => $warning,
  1855. critical => $critical,
  1856. );
  1857. } else {
  1858. $self->add_perfdata(
  1859. label => sprintf('sens_%s_%s', $self->{entSensorType}, $self->{entPhysicalIndex}),
  1860. value => $self->{entSensorValue},
  1861. warning => $self->{ciscoEnvMonSensorThreshold},
  1862. critical => undef,
  1863. );
  1864. }
  1865. }
  1866. sub dump {
  1867. my $self = shift;
  1868. printf "[SENSOR_%s]\n", $self->{entPhysicalIndex};
  1869. foreach (qw(entSensorType entSensorScale entSensorPrecision
  1870. entSensorValue entSensorStatus entSensorMeasuredEntity)) {
  1871. printf "%s: %s\n", $_, $self->{$_};
  1872. }
  1873. printf "info: %s\n", $self->{info};
  1874. foreach my $threshold (@{$self->{thresholds}}) {
  1875. $threshold->dump();
  1876. }
  1877. printf "\n";
  1878. }
  1879. package NWC::CiscoNXOS::Component::SensorSubsystem::SensorThreshold;
  1880. our @ISA = qw(NWC::CiscoNXOS::Component::SensorSubsystem);
  1881. use strict;
  1882. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1883. sub new {
  1884. my $class = shift;
  1885. my %params = @_;
  1886. my $self = {
  1887. blacklisted => 0,
  1888. info => undef,
  1889. extendedinfo => undef,
  1890. };
  1891. foreach my $param (qw(entSensorThresholdRelation entSensorThresholdValue
  1892. entSensorThresholdSeverity entSensorThresholdNotificationEnable
  1893. entSensorThresholdEvaluation indices)) {
  1894. $self->{$param} = $params{$param};
  1895. }
  1896. $self->{entPhysicalIndex} = $params{indices}[0];
  1897. $self->{entSensorThresholdIndex} = $params{indices}[1];
  1898. bless $self, $class;
  1899. return $self;
  1900. }
  1901. sub dump {
  1902. my $self = shift;
  1903. printf "[SENSOR_THRESHOLD_%s_%s]\n",
  1904. $self->{entPhysicalIndex}, $self->{entSensorThresholdIndex};
  1905. foreach (qw(entSensorThresholdRelation entSensorThresholdValue
  1906. entSensorThresholdSeverity entSensorThresholdNotificationEnable
  1907. entSensorThresholdEvaluation)) {
  1908. printf "%s: %s\n", $_, $self->{$_};
  1909. }
  1910. }
  1911. package NWC::CiscoNXOS;
  1912. use strict;
  1913. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  1914. our @ISA = qw(NWC::Cisco);
  1915. sub init {
  1916. my $self = shift;
  1917. $self->{components} = {
  1918. powersupply_subsystem => undef,
  1919. fan_subsystem => undef,
  1920. temperature_subsystem => undef,
  1921. cpu_subsystem => undef,
  1922. memory_subsystem => undef,
  1923. disk_subsystem => undef,
  1924. environmental_subsystem => undef,
  1925. };
  1926. $self->{serial} = 'unknown';
  1927. $self->{product} = 'unknown';
  1928. $self->{romversion} = 'unknown';
  1929. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  1930. #$self->collect();
  1931. if (! $self->check_messages()) {
  1932. ##$self->set_serial();
  1933. if ($self->mode =~ /device::hardware::health/) {
  1934. $self->analyze_environmental_subsystem();
  1935. #$self->auto_blacklist();
  1936. $self->check_environmental_subsystem();
  1937. } elsif ($self->mode =~ /device::hardware::load/) {
  1938. $self->analyze_cpu_subsystem();
  1939. #$self->auto_blacklist();
  1940. $self->check_cpu_subsystem();
  1941. } elsif ($self->mode =~ /device::hardware::memory/) {
  1942. $self->analyze_mem_subsystem();
  1943. #$self->auto_blacklist();
  1944. $self->check_mem_subsystem();
  1945. } elsif ($self->mode =~ /device::interfaces/) {
  1946. $self->analyze_interface_subsystem();
  1947. $self->check_interface_subsystem();
  1948. } elsif ($self->mode =~ /device::shinken::interface/) {
  1949. $self->analyze_interface_subsystem();
  1950. $self->shinken_interface_subsystem();
  1951. }
  1952. }
  1953. }
  1954. sub analyze_environmental_subsystem {
  1955. my $self = shift;
  1956. $self->{components}->{environmental_subsystem} =
  1957. NWC::CiscoNXOS::Component::EnvironmentalSubsystem->new();
  1958. }
  1959. sub analyze_interface_subsystem {
  1960. my $self = shift;
  1961. $self->{components}->{interface_subsystem} =
  1962. NWC::IFMIB::Component::InterfaceSubsystem->new();
  1963. }
  1964. sub analyze_cpu_subsystem {
  1965. my $self = shift;
  1966. $self->{components}->{cpu_subsystem} =
  1967. NWC::CiscoNXOS::Component::CpuSubsystem->new();
  1968. }
  1969. sub analyze_mem_subsystem {
  1970. my $self = shift;
  1971. $self->{components}->{mem_subsystem} =
  1972. NWC::CiscoNXOS::Component::MemSubsystem->new();
  1973. }
  1974. sub check_environmental_subsystem {
  1975. my $self = shift;
  1976. $self->{components}->{environmental_subsystem}->check();
  1977. $self->{components}->{environmental_subsystem}->dump()
  1978. if $self->opts->verbose >= 2;
  1979. }
  1980. sub check_interface_subsystem {
  1981. my $self = shift;
  1982. $self->{components}->{interface_subsystem}->check();
  1983. $self->{components}->{interface_subsystem}->dump()
  1984. if $self->opts->verbose >= 2;
  1985. }
  1986. sub check_cpu_subsystem {
  1987. my $self = shift;
  1988. $self->{components}->{cpu_subsystem}->check();
  1989. $self->{components}->{cpu_subsystem}->dump()
  1990. if $self->opts->verbose >= 2;
  1991. }
  1992. sub check_mem_subsystem {
  1993. my $self = shift;
  1994. $self->{components}->{mem_subsystem}->check();
  1995. $self->{components}->{mem_subsystem}->dump()
  1996. if $self->opts->verbose >= 2;
  1997. }
  1998. sub shinken_interface_subsystem {
  1999. my $self = shift;
  2000. my $attr = sprintf "%s", join(',', map {
  2001. sprintf '%s$(%s)$$()$', $_->{ifDescr}, $_->{ifIndex}
  2002. } @{$self->{components}->{interface_subsystem}->{interfaces}});
  2003. printf <<'EOEO', $self->opts->hostname(), $self->opts->hostname(), $attr;
  2004. define host {
  2005. host_name %s
  2006. address %s
  2007. use default-host
  2008. _interfaces %s
  2009. }
  2010. EOEO
  2011. printf <<'EOEO', $self->opts->hostname();
  2012. define service {
  2013. host_name %s
  2014. service_description net_cpu
  2015. check_command check_nwc_health!cpu-load!80%%!90%%
  2016. }
  2017. EOEO
  2018. printf <<'EOEO', $self->opts->hostname();
  2019. define service {
  2020. host_name %s
  2021. service_description net_mem
  2022. check_command check_nwc_health!memory-usage!80%%!90%%
  2023. }
  2024. EOEO
  2025. printf <<'EOEO', $self->opts->hostname();
  2026. define service {
  2027. host_name %s
  2028. service_description net_ifusage_$KEY$
  2029. check_command check_nwc_health!interface-usage!$VALUE1$!$VALUE2$
  2030. duplicate_foreach _interfaces
  2031. default_value 80%%|90%%
  2032. }
  2033. EOEO
  2034. }
  2035. package NWC::Cisco;
  2036. use strict;
  2037. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2038. our @ISA = qw(NWC::Device);
  2039. use constant trees => (
  2040. '1.3.6.1.2.1', # mib-2
  2041. '1.3.6.1.4.1.9', # cisco
  2042. '1.3.6.1.4.1.9.1', # ciscoProducts
  2043. '1.3.6.1.4.1.9.2', # local
  2044. '1.3.6.1.4.1.9.3', # temporary
  2045. '1.3.6.1.4.1.9.4', # pakmon
  2046. '1.3.6.1.4.1.9.5', # workgroup
  2047. '1.3.6.1.4.1.9.6', # otherEnterprises
  2048. '1.3.6.1.4.1.9.7', # ciscoAgentCapability
  2049. '1.3.6.1.4.1.9.8', # ciscoConfig
  2050. '1.3.6.1.4.1.9.9', # ciscoMgmt
  2051. '1.3.6.1.4.1.9.10', # ciscoExperiment
  2052. '1.3.6.1.4.1.9.11', # ciscoAdmin
  2053. '1.3.6.1.4.1.9.12', # ciscoModules
  2054. '1.3.6.1.4.1.9.13', # lightstream
  2055. '1.3.6.1.4.1.9.14', # ciscoworks
  2056. '1.3.6.1.4.1.9.15', # newport
  2057. '1.3.6.1.4.1.9.16', # ciscoPartnerProducts
  2058. '1.3.6.1.4.1.9.17', # ciscoPolicy
  2059. '1.3.6.1.4.1.9.18', # ciscoPolicyAuto
  2060. '1.3.6.1.4.1.9.19', # ciscoDomains
  2061. );
  2062. sub init {
  2063. my $self = shift;
  2064. if ($self->{productname} =~ /Cisco NX-OS/i) {
  2065. bless $self, 'NWC::CiscoNXOS';
  2066. $self->debug('using NWC::CiscoNXOS');
  2067. } elsif ($self->{productname} =~ /Cisco/i) {
  2068. bless $self, 'NWC::CiscoIOS';
  2069. $self->debug('using NWC::CiscoIOS');
  2070. }
  2071. $self->init();
  2072. }
  2073. package NWC::Nortel;
  2074. use strict;
  2075. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2076. our @ISA = qw(NWC::Device);
  2077. sub init {
  2078. my $self = shift;
  2079. $self->{components} = {
  2080. powersupply_subsystem => undef,
  2081. fan_subsystem => undef,
  2082. temperature_subsystem => undef,
  2083. cpu_subsystem => undef,
  2084. memory_subsystem => undef,
  2085. disk_subsystem => undef,
  2086. environmental_subsystem => undef,
  2087. };
  2088. $self->{serial} = 'unknown';
  2089. $self->{product} = 'unknown';
  2090. $self->{romversion} = 'unknown';
  2091. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  2092. #$self->collect();
  2093. if (! $self->check_messages()) {
  2094. ##$self->set_serial();
  2095. if ($self->mode =~ /device::hardware::health/) {
  2096. $self->analyze_environmental_subsystem();
  2097. #$self->auto_blacklist();
  2098. $self->check_environmental_subsystem();
  2099. } elsif ($self->mode =~ /device::hardware::load/) {
  2100. $self->analyze_cpu_subsystem();
  2101. #$self->auto_blacklist();
  2102. $self->check_cpu_subsystem();
  2103. } elsif ($self->mode =~ /device::hardware::memory/) {
  2104. $self->analyze_mem_subsystem();
  2105. #$self->auto_blacklist();
  2106. $self->check_mem_subsystem();
  2107. } elsif ($self->mode =~ /device::interfaces/) {
  2108. $self->analyze_interface_subsystem();
  2109. $self->check_interface_subsystem();
  2110. } elsif ($self->mode =~ /device::shinken::interface/) {
  2111. $self->analyze_interface_subsystem();
  2112. $self->shinken_interface_subsystem();
  2113. } elsif ($self->mode =~ /device::hsrp/) {
  2114. $self->analyze_hsrp_subsystem();
  2115. $self->check_interface_subsystem();
  2116. }
  2117. }
  2118. }
  2119. sub analyze_hsrp_subsystem {
  2120. my $self = shift;
  2121. $self->{components}->{hsrp} =
  2122. NWC::HSRP::Component::HSRPSubsystem->new();
  2123. }
  2124. sub analyze_environmental_subsystem {
  2125. my $self = shift;
  2126. $self->{components}->{environmental_subsystem} =
  2127. NWC::Nortel::Component::EnvironmentalSubsystem->new();
  2128. }
  2129. sub analyze_interface_subsystem {
  2130. my $self = shift;
  2131. $self->{components}->{interface_subsystem} =
  2132. NWC::IFMIB::Component::InterfaceSubsystem->new();
  2133. }
  2134. sub analyze_cpu_subsystem {
  2135. my $self = shift;
  2136. $self->{components}->{cpu_subsystem} =
  2137. NWC::Nortel::Component::CpuSubsystem->new();
  2138. }
  2139. sub analyze_mem_subsystem {
  2140. my $self = shift;
  2141. $self->{components}->{mem_subsystem} =
  2142. NWC::Nortel::Component::MemSubsystem->new();
  2143. }
  2144. sub check_environmental_subsystem {
  2145. my $self = shift;
  2146. $self->{components}->{environmental_subsystem}->check();
  2147. $self->{components}->{environmental_subsystem}->dump()
  2148. if $self->opts->verbose >= 2;
  2149. }
  2150. sub check_interface_subsystem {
  2151. my $self = shift;
  2152. $self->{components}->{interface_subsystem}->check();
  2153. $self->{components}->{interface_subsystem}->dump()
  2154. if $self->opts->verbose >= 2;
  2155. }
  2156. sub check_cpu_subsystem {
  2157. my $self = shift;
  2158. $self->{components}->{cpu_subsystem}->check();
  2159. $self->{components}->{cpu_subsystem}->dump()
  2160. if $self->opts->verbose >= 2;
  2161. }
  2162. sub check_mem_subsystem {
  2163. my $self = shift;
  2164. $self->{components}->{mem_subsystem}->check();
  2165. $self->{components}->{mem_subsystem}->dump()
  2166. if $self->opts->verbose >= 2;
  2167. }
  2168. sub shinken_interface_subsystem {
  2169. my $self = shift;
  2170. my $attr = sprintf "%s", join(',', map {
  2171. sprintf '%s$(%s)$$()$', $_->{ifDescr}, $_->{ifIndex}
  2172. } @{$self->{components}->{interface_subsystem}->{interfaces}});
  2173. printf <<'EOEO', $self->opts->hostname(), $self->opts->hostname(), $attr;
  2174. define host {
  2175. host_name %s
  2176. address %s
  2177. use default-host
  2178. _interfaces %s
  2179. }
  2180. EOEO
  2181. printf <<'EOEO', $self->opts->hostname();
  2182. define service {
  2183. host_name %s
  2184. service_description net_cpu
  2185. check_command check_nwc_health!cpu-load!80%%!90%%
  2186. }
  2187. EOEO
  2188. printf <<'EOEO', $self->opts->hostname();
  2189. define service {
  2190. host_name %s
  2191. service_description net_mem
  2192. check_command check_nwc_health!memory-usage!80%%!90%%
  2193. }
  2194. EOEO
  2195. printf <<'EOEO', $self->opts->hostname();
  2196. define service {
  2197. host_name %s
  2198. service_description net_ifusage_$KEY$
  2199. check_command check_nwc_health!interface-usage!$VALUE1$!$VALUE2$
  2200. duplicate_foreach _interfaces
  2201. default_value 80%%|90%%
  2202. }
  2203. EOEO
  2204. }
  2205. package NWC::Netscreen;
  2206. use strict;
  2207. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2208. our @ISA = qw(NWC::Device);
  2209. use constant trees => (
  2210. '1.3.6.1.2.1', # mib-2
  2211. '1.3.6.1.2.1.105',
  2212. );
  2213. sub init {
  2214. my $self = shift;
  2215. $self->{components} = {
  2216. powersupply_subsystem => undef,
  2217. fan_subsystem => undef,
  2218. temperature_subsystem => undef,
  2219. cpu_subsystem => undef,
  2220. memory_subsystem => undef,
  2221. disk_subsystem => undef,
  2222. environmental_subsystem => undef,
  2223. };
  2224. $self->{serial} = 'unknown';
  2225. $self->{product} = 'unknown';
  2226. $self->{romversion} = 'unknown';
  2227. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  2228. #$self->collect();
  2229. if (! $self->check_messages()) {
  2230. ##$self->set_serial();
  2231. if ($self->mode =~ /device::hardware::health/) {
  2232. $self->no_such_mode();
  2233. } elsif ($self->mode =~ /device::hardware::load/) {
  2234. $self->no_such_mode();
  2235. } elsif ($self->mode =~ /device::hardware::memory/) {
  2236. $self->no_such_mode();
  2237. } elsif ($self->mode =~ /device::interfaces/) {
  2238. $self->analyze_interface_subsystem();
  2239. $self->check_interface_subsystem();
  2240. }
  2241. }
  2242. }
  2243. sub analyze_interface_subsystem {
  2244. my $self = shift;
  2245. $self->{components}->{interface_subsystem} =
  2246. NWC::IFMIB::Component::InterfaceSubsystem->new();
  2247. }
  2248. sub check_interface_subsystem {
  2249. my $self = shift;
  2250. $self->{components}->{interface_subsystem}->check();
  2251. $self->{components}->{interface_subsystem}->dump()
  2252. if $self->opts->verbose >= 2;
  2253. }
  2254. package NWC::AlliedTelesyn;
  2255. use strict;
  2256. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2257. our @ISA = qw(NWC::Device);
  2258. sub init {
  2259. my $self = shift;
  2260. $self->{components} = {
  2261. powersupply_subsystem => undef,
  2262. fan_subsystem => undef,
  2263. temperature_subsystem => undef,
  2264. cpu_subsystem => undef,
  2265. memory_subsystem => undef,
  2266. disk_subsystem => undef,
  2267. environmental_subsystem => undef,
  2268. };
  2269. $self->{serial} = 'unknown';
  2270. $self->{product} = 'unknown';
  2271. $self->{romversion} = 'unknown';
  2272. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  2273. #$self->collect();
  2274. if (! $self->check_messages()) {
  2275. ##$self->set_serial();
  2276. if ($self->mode =~ /device::hardware::health/) {
  2277. $self->analyze_environmental_subsystem();
  2278. #$self->auto_blacklist();
  2279. $self->check_environmental_subsystem();
  2280. } elsif ($self->mode =~ /device::hardware::load/) {
  2281. $self->analyze_cpu_subsystem();
  2282. #$self->auto_blacklist();
  2283. $self->check_cpu_subsystem();
  2284. } elsif ($self->mode =~ /device::hardware::memory/) {
  2285. $self->analyze_mem_subsystem();
  2286. #$self->auto_blacklist();
  2287. $self->check_mem_subsystem();
  2288. } elsif ($self->mode =~ /device::interfaces/) {
  2289. $self->analyze_interface_subsystem();
  2290. $self->check_interface_subsystem();
  2291. } elsif ($self->mode =~ /device::shinken::interface/) {
  2292. $self->analyze_interface_subsystem();
  2293. $self->shinken_interface_subsystem();
  2294. } elsif ($self->mode =~ /device::hsrp/) {
  2295. $self->analyze_hsrp_subsystem();
  2296. $self->check_interface_subsystem();
  2297. }
  2298. }
  2299. }
  2300. sub analyze_hsrp_subsystem {
  2301. my $self = shift;
  2302. $self->{components}->{hsrp} =
  2303. NWC::HSRP::Component::HSRPSubsystem->new();
  2304. }
  2305. sub analyze_environmental_subsystem {
  2306. my $self = shift;
  2307. $self->{components}->{environmental_subsystem} =
  2308. NWC::AlliedTelesyn::Component::EnvironmentalSubsystem->new();
  2309. }
  2310. sub analyze_interface_subsystem {
  2311. my $self = shift;
  2312. $self->{components}->{interface_subsystem} =
  2313. NWC::IFMIB::Component::InterfaceSubsystem->new();
  2314. }
  2315. sub analyze_cpu_subsystem {
  2316. my $self = shift;
  2317. $self->{components}->{cpu_subsystem} =
  2318. NWC::AlliedTelesyn::Component::CpuSubsystem->new();
  2319. }
  2320. sub analyze_mem_subsystem {
  2321. my $self = shift;
  2322. $self->{components}->{mem_subsystem} =
  2323. NWC::AlliedTelesyn::Component::MemSubsystem->new();
  2324. }
  2325. sub check_environmental_subsystem {
  2326. my $self = shift;
  2327. $self->{components}->{environmental_subsystem}->check();
  2328. $self->{components}->{environmental_subsystem}->dump()
  2329. if $self->opts->verbose >= 2;
  2330. }
  2331. sub check_interface_subsystem {
  2332. my $self = shift;
  2333. $self->{components}->{interface_subsystem}->check();
  2334. $self->{components}->{interface_subsystem}->dump()
  2335. if $self->opts->verbose >= 2;
  2336. }
  2337. sub check_cpu_subsystem {
  2338. my $self = shift;
  2339. $self->{components}->{cpu_subsystem}->check();
  2340. $self->{components}->{cpu_subsystem}->dump()
  2341. if $self->opts->verbose >= 2;
  2342. }
  2343. sub check_mem_subsystem {
  2344. my $self = shift;
  2345. $self->{components}->{mem_subsystem}->check();
  2346. $self->{components}->{mem_subsystem}->dump()
  2347. if $self->opts->verbose >= 2;
  2348. }
  2349. sub shinken_interface_subsystem {
  2350. my $self = shift;
  2351. my $attr = sprintf "%s", join(',', map {
  2352. sprintf '%s$(%s)$$()$', $_->{ifDescr}, $_->{ifIndex}
  2353. } @{$self->{components}->{interface_subsystem}->{interfaces}});
  2354. printf <<'EOEO', $self->opts->hostname(), $self->opts->hostname(), $attr;
  2355. define host {
  2356. host_name %s
  2357. address %s
  2358. use default-host
  2359. _interfaces %s
  2360. }
  2361. EOEO
  2362. printf <<'EOEO', $self->opts->hostname();
  2363. define service {
  2364. host_name %s
  2365. service_description net_cpu
  2366. check_command check_nwc_health!cpu-load!80%%!90%%
  2367. }
  2368. EOEO
  2369. printf <<'EOEO', $self->opts->hostname();
  2370. define service {
  2371. host_name %s
  2372. service_description net_mem
  2373. check_command check_nwc_health!memory-usage!80%%!90%%
  2374. }
  2375. EOEO
  2376. printf <<'EOEO', $self->opts->hostname();
  2377. define service {
  2378. host_name %s
  2379. service_description net_ifusage_$KEY$
  2380. check_command check_nwc_health!interface-usage!$VALUE1$!$VALUE2$
  2381. duplicate_foreach _interfaces
  2382. default_value 80%%|90%%
  2383. }
  2384. EOEO
  2385. }
  2386. package NWC::FabOS::Component::MemSubsystem;
  2387. our @ISA = qw(NWC::FabOS);
  2388. use strict;
  2389. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2390. sub new {
  2391. my $class = shift;
  2392. my %params = @_;
  2393. my $self = {
  2394. runtime => $params{runtime},
  2395. rawdata => $params{rawdata},
  2396. mems => [],
  2397. blacklisted => 0,
  2398. info => undef,
  2399. extendedinfo => undef,
  2400. };
  2401. bless $self, $class;
  2402. $self->init(%params);
  2403. return $self;
  2404. }
  2405. sub init {
  2406. my $self = shift;
  2407. my %params = @_;
  2408. my $snmpwalk = $params{rawdata};
  2409. my $ignore_redundancy = $params{ignore_redundancy};
  2410. my $type = 0;
  2411. foreach (qw(swMemUsage swMemUsageLimit1 swMemUsageLimit3 swMemPollingInterval
  2412. swMemNoOfRetries swMemAction)) {
  2413. $self->{$_} = $self->get_snmp_object('SW-MIB', $_, 0);
  2414. }
  2415. }
  2416. sub check {
  2417. my $self = shift;
  2418. my $errorfound = 0;
  2419. $self->add_info('checking memory');
  2420. $self->blacklist('m', '');
  2421. if (defined $self->{swMemUsage}) {
  2422. my $info = sprintf 'memory usage is %.2f%%',
  2423. $self->{swMemUsage};
  2424. $self->add_info($info);
  2425. $self->set_thresholds(warning => $self->{swMemUsageLimit1},
  2426. critical => $self->{swMemUsageLimit3});
  2427. $self->add_message($self->check_thresholds($self->{swMemUsage}), $info);
  2428. $self->add_perfdata(
  2429. label => 'memory_usage',
  2430. value => $self->{swMemUsage},
  2431. uom => '%',
  2432. warning => $self->{warning},
  2433. critical => $self->{critical}
  2434. );
  2435. } else {
  2436. $self->add_message(UNKNOWN, 'cannot aquire momory usage');
  2437. }
  2438. }
  2439. sub dump {
  2440. my $self = shift;
  2441. printf "[MEMORY]\n";
  2442. foreach (qw(swMemUsage swMemUsageLimit1 swMemUsageLimit3 swMemPollingInterval
  2443. swMemNoOfRetries swMemAction)) {
  2444. printf "%s: %s\n", $_, $self->{$_};
  2445. }
  2446. printf "info: %s\n", $self->{info};
  2447. printf "\n";
  2448. }
  2449. package NWC::FabOS::Component::CpuSubsystem;
  2450. our @ISA = qw(NWC::FabOS);
  2451. use strict;
  2452. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2453. sub new {
  2454. my $class = shift;
  2455. my %params = @_;
  2456. my $self = {
  2457. cpus => [],
  2458. blacklisted => 0,
  2459. info => undef,
  2460. extendedinfo => undef,
  2461. };
  2462. bless $self, $class;
  2463. $self->init(%params);
  2464. return $self;
  2465. }
  2466. sub init {
  2467. my $self = shift;
  2468. my %params = @_;
  2469. my $type = 0;
  2470. foreach (qw(swCpuUsage swCpuNoOfRetries swCpuUsageLimit swCpuPollingInterval
  2471. swCpuAction)) {
  2472. $self->{$_} = $self->get_snmp_object('SW-MIB', $_, 0);
  2473. }
  2474. }
  2475. sub check {
  2476. my $self = shift;
  2477. my $errorfound = 0;
  2478. $self->add_info('checking cpus');
  2479. $self->blacklist('c', undef);
  2480. my $info = sprintf 'cpu usage is %.2f%%', $self->{swCpuUsage};
  2481. $self->add_info($info);
  2482. $self->set_thresholds(warning => $self->{swCpuUsageLimit},
  2483. critical => $self->{swCpuUsageLimit});
  2484. $self->add_message($self->check_thresholds($self->{swCpuUsage}), $info);
  2485. $self->add_perfdata(
  2486. label => 'cpu_usage',
  2487. value => $self->{swCpuUsage},
  2488. uom => '%',
  2489. warning => $self->{warning},
  2490. critical => $self->{critical},
  2491. );
  2492. }
  2493. sub dump {
  2494. my $self = shift;
  2495. printf "[CPU]\n";
  2496. foreach (qw(swCpuUsage swCpuNoOfRetries swCpuUsageLimit swCpuPollingInterval
  2497. swCpuAction)) {
  2498. printf "%s: %s\n", $_, $self->{$_};
  2499. }
  2500. printf "info: %s\n", $self->{info};
  2501. printf "\n";
  2502. }
  2503. package NWC::FabOS::Component::EnvironmentalSubsystem;
  2504. our @ISA = qw(NWC::FabOS);
  2505. use strict;
  2506. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2507. sub new {
  2508. my $class = shift;
  2509. my %params = @_;
  2510. my $self = {
  2511. runtime => $params{runtime},
  2512. rawdata => $params{rawdata},
  2513. method => $params{method},
  2514. condition => $params{condition},
  2515. status => $params{status},
  2516. sensor_subsystem => undef,
  2517. blacklisted => 0,
  2518. info => undef,
  2519. extendedinfo => undef,
  2520. };
  2521. bless $self, $class;
  2522. $self->init(%params);
  2523. return $self;
  2524. }
  2525. sub init {
  2526. my $self = shift;
  2527. my %params = @_;
  2528. $self->{sensor_subsystem} =
  2529. NWC::FabOS::Component::SensorSubsystem->new(%params);
  2530. }
  2531. sub check {
  2532. my $self = shift;
  2533. my $errorfound = 0;
  2534. $self->{sensor_subsystem}->check();
  2535. if (! $self->check_messages()) {
  2536. $self->add_message(OK, "environmental hardware working fine");
  2537. }
  2538. }
  2539. sub dump {
  2540. my $self = shift;
  2541. $self->{sensor_subsystem}->dump();
  2542. }
  2543. package NWC::FabOS::Component::SensorSubsystem;
  2544. our @ISA = qw(NWC::FabOS::Component::EnvironmentalSubsystem);
  2545. use strict;
  2546. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2547. sub new {
  2548. my $class = shift;
  2549. my %params = @_;
  2550. my $self = {
  2551. sensors => [],
  2552. sensorthresholds => [],
  2553. blacklisted => 0,
  2554. info => undef,
  2555. extendedinfo => undef,
  2556. };
  2557. bless $self, $class;
  2558. $self->init(%params);
  2559. return $self;
  2560. }
  2561. sub init {
  2562. my $self = shift;
  2563. my $sensors = {};
  2564. foreach ($self->get_snmp_table_objects(
  2565. 'SW-MIB', 'swSensorTable')) {
  2566. push(@{$self->{sensors}},
  2567. NWC::FabOS::Component::SensorSubsystem::Sensor->new(%{$_}));
  2568. }
  2569. #foreach ($self->get_snmp_table_objects(
  2570. # 'SW-MIB', 'swFwThresholdTable')) {
  2571. # printf "%s\n", Data::Dumper::Dumper($_);
  2572. #}
  2573. }
  2574. sub check {
  2575. my $self = shift;
  2576. my $errorfound = 0;
  2577. $self->add_info('checking sensors');
  2578. $self->blacklist('ses', '');
  2579. if (scalar (@{$self->{sensors}}) == 0) {
  2580. } else {
  2581. foreach (@{$self->{sensors}}) {
  2582. $_->check();
  2583. }
  2584. }
  2585. }
  2586. sub dump {
  2587. my $self = shift;
  2588. foreach (@{$self->{sensors}}) {
  2589. $_->dump();
  2590. }
  2591. }
  2592. package NWC::FabOS::Component::SensorSubsystem::Sensor;
  2593. our @ISA = qw(NWC::FabOS::Component::SensorSubsystem);
  2594. use strict;
  2595. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2596. sub new {
  2597. my $class = shift;
  2598. my %params = @_;
  2599. my $self = {
  2600. blacklisted => 0,
  2601. info => undef,
  2602. extendedinfo => undef,
  2603. };
  2604. foreach my $param (qw(swSensorIndex swSensorType swSensorStatus
  2605. swSensorValue swSensorInfo)) {
  2606. $self->{$param} = $params{$param};
  2607. }
  2608. bless $self, $class;
  2609. return $self;
  2610. }
  2611. sub check {
  2612. my $self = shift;
  2613. $self->blacklist('se', $self->{swSensorIndex});
  2614. $self->add_info(sprintf '%s sensor %s (%s) is %s',
  2615. $self->{swSensorType},
  2616. $self->{swSensorIndex},
  2617. $self->{swSensorInfo},
  2618. $self->{swSensorStatus});
  2619. if ($self->{swSensorStatus} eq "faulty") {
  2620. $self->add_message(CRITICAL, $self->{info});
  2621. } elsif ($self->{swSensorStatus} eq "absent") {
  2622. } elsif ($self->{swSensorStatus} eq "unknown") {
  2623. $self->add_message(CRITICAL, $self->{info});
  2624. } else {
  2625. if ($self->{swSensorStatus} eq "nominal") {
  2626. #$self->add_message(OK, $self->{info});
  2627. } else {
  2628. $self->add_message(CRITICAL, $self->{info});
  2629. }
  2630. $self->add_perfdata(
  2631. label => sprintf('sensor_%s_%s',
  2632. $self->{swSensorType}, $self->{swSensorIndex}),
  2633. value => $self->{swSensorValue},
  2634. ) if $self->{swSensorType} ne "power-supply";
  2635. }
  2636. }
  2637. sub dump {
  2638. my $self = shift;
  2639. printf "[SENSOR_%s_%s]\n", $self->{swSensorType}, $self->{swSensorIndex};
  2640. foreach (qw(swSensorIndex swSensorType swSensorStatus
  2641. swSensorValue swSensorInfo)) {
  2642. printf "%s: %s\n", $_, $self->{$_};
  2643. }
  2644. printf "info: %s\n", $self->{info};
  2645. printf "\n";
  2646. }
  2647. package NWC::FabOS::Component::SensorSubsystem::SensorThreshold;
  2648. our @ISA = qw(NWC::FabOS::Component::SensorSubsystem);
  2649. use strict;
  2650. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2651. sub new {
  2652. my $class = shift;
  2653. my %params = @_;
  2654. my $self = {
  2655. blacklisted => 0,
  2656. info => undef,
  2657. extendedinfo => undef,
  2658. };
  2659. foreach my $param (qw(entSensorThresholdRelation entSensorThresholdValue
  2660. entSensorThresholdSeverity entSensorThresholdNotificationEnable
  2661. entSensorThresholdEvaluation indices)) {
  2662. $self->{$param} = $params{$param};
  2663. }
  2664. $self->{entPhysicalIndex} = $params{indices}[0];
  2665. $self->{entSensorThresholdIndex} = $params{indices}[1];
  2666. bless $self, $class;
  2667. return $self;
  2668. }
  2669. sub dump {
  2670. my $self = shift;
  2671. printf "[SENSOR_THRESHOLD_%s_%s]\n",
  2672. $self->{entPhysicalIndex}, $self->{entSensorThresholdIndex};
  2673. foreach (qw(entSensorThresholdRelation entSensorThresholdValue
  2674. entSensorThresholdSeverity entSensorThresholdNotificationEnable
  2675. entSensorThresholdEvaluation)) {
  2676. printf "%s: %s\n", $_, $self->{$_};
  2677. }
  2678. }
  2679. package NWC::FabOS;
  2680. use strict;
  2681. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2682. our @ISA = qw(NWC::Brocade);
  2683. sub init {
  2684. my $self = shift;
  2685. $self->{components} = {
  2686. powersupply_subsystem => undef,
  2687. fan_subsystem => undef,
  2688. temperature_subsystem => undef,
  2689. cpu_subsystem => undef,
  2690. };
  2691. $self->{serial} = 'unknown';
  2692. $self->{product} = 'unknown';
  2693. $self->{romversion} = 'unknown';
  2694. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  2695. #$self->collect();
  2696. if (! $self->check_messages()) {
  2697. ##$self->set_serial();
  2698. if ($self->mode =~ /device::hardware::health/) {
  2699. $self->analyze_environmental_subsystem();
  2700. $self->check_environmental_subsystem();
  2701. } elsif ($self->mode =~ /device::hardware::load/) {
  2702. $self->analyze_cpu_subsystem();
  2703. $self->check_cpu_subsystem();
  2704. } elsif ($self->mode =~ /device::hardware::memory/) {
  2705. $self->analyze_mem_subsystem();
  2706. $self->check_mem_subsystem();
  2707. } elsif ($self->mode =~ /device::interfaces/) {
  2708. $self->analyze_interface_subsystem();
  2709. $self->check_interface_subsystem();
  2710. }
  2711. }
  2712. }
  2713. sub analyze_environmental_subsystem {
  2714. my $self = shift;
  2715. $self->{components}->{environmental_subsystem} =
  2716. NWC::FabOS::Component::EnvironmentalSubsystem->new();
  2717. }
  2718. sub analyze_cpu_subsystem {
  2719. my $self = shift;
  2720. $self->{components}->{cpu_subsystem} =
  2721. NWC::FabOS::Component::CpuSubsystem->new();
  2722. #printf "%s\n", Data::Dumper::Dumper($self->{components});
  2723. }
  2724. sub analyze_mem_subsystem {
  2725. my $self = shift;
  2726. $self->{components}->{mem_subsystem} =
  2727. NWC::FabOS::Component::MemSubsystem->new();
  2728. }
  2729. sub analyze_interface_subsystem {
  2730. my $self = shift;
  2731. $self->{components}->{interface_subsystem} =
  2732. NWC::IFMIB::Component::InterfaceSubsystem->new();
  2733. }
  2734. sub check_environmental_subsystem {
  2735. my $self = shift;
  2736. $self->{components}->{environmental_subsystem}->check();
  2737. $self->{components}->{environmental_subsystem}->dump()
  2738. if $self->opts->verbose >= 2;
  2739. }
  2740. sub check_cpu_subsystem {
  2741. my $self = shift;
  2742. $self->{components}->{cpu_subsystem}->check();
  2743. $self->{components}->{cpu_subsystem}->dump()
  2744. if $self->opts->verbose >= 2;
  2745. }
  2746. sub check_mem_subsystem {
  2747. my $self = shift;
  2748. $self->{components}->{mem_subsystem}->check();
  2749. $self->{components}->{mem_subsystem}->dump()
  2750. if $self->opts->verbose >= 2;
  2751. }
  2752. sub check_interface_subsystem {
  2753. my $self = shift;
  2754. $self->{components}->{interface_subsystem}->check();
  2755. $self->{components}->{interface_subsystem}->dump()
  2756. if $self->opts->verbose >= 2;
  2757. }
  2758. package NWC::HP::Procurve::Component::MemSubsystem;
  2759. our @ISA = qw(NWC::HP::Procurve::Component::EnvironmentalSubsystem);
  2760. use strict;
  2761. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2762. sub new {
  2763. my $class = shift;
  2764. my %params = @_;
  2765. my $self = {
  2766. sensors => [],
  2767. sensorthresholds => [],
  2768. blacklisted => 0,
  2769. info => undef,
  2770. extendedinfo => undef,
  2771. };
  2772. bless $self, $class;
  2773. $self->init(%params);
  2774. return $self;
  2775. }
  2776. sub init {
  2777. my $self = shift;
  2778. my $sensors = {};
  2779. foreach ($self->get_snmp_table_objects(
  2780. 'NETSWITCH-MIB', 'hpLocalMemTable')) {
  2781. push(@{$self->{mem}},
  2782. NWC::HP::Procurve::Component::MemSubsystem::Memory->new(%{$_}));
  2783. }
  2784. }
  2785. sub check {
  2786. my $self = shift;
  2787. my $errorfound = 0;
  2788. $self->add_info('checking memory');
  2789. $self->blacklist('m', '');
  2790. if (scalar (@{$self->{mem}}) == 0) {
  2791. } else {
  2792. foreach (@{$self->{mem}}) {
  2793. $_->check();
  2794. }
  2795. }
  2796. }
  2797. sub dump {
  2798. my $self = shift;
  2799. foreach (@{$self->{mem}}) {
  2800. $_->dump();
  2801. }
  2802. }
  2803. package NWC::HP::Procurve::Component::MemSubsystem::Memory;
  2804. our @ISA = qw(NWC::HP::Procurve::Component::MemSubsystem);
  2805. use strict;
  2806. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2807. sub new {
  2808. my $class = shift;
  2809. my %params = @_;
  2810. my $self = {
  2811. blacklisted => 0,
  2812. info => undef,
  2813. extendedinfo => undef,
  2814. };
  2815. foreach (qw(hpLocalMemSlotIndex hpLocalMemSlabCnt
  2816. hpLocalMemFreeSegCnt hpLocalMemAllocSegCnt hpLocalMemTotalBytes
  2817. hpLocalMemFreeBytes hpLocalMemAllocBytes)) {
  2818. $self->{$_} = $params{$_};
  2819. }
  2820. bless $self, $class;
  2821. return $self;
  2822. }
  2823. sub check {
  2824. my $self = shift;
  2825. $self->blacklist('m', $self->{hpicfMemIndex});
  2826. $self->{usage} = $self->{hpLocalMemAllocBytes} /
  2827. $self->{hpLocalMemTotalBytes} * 100;
  2828. my $info = sprintf 'memory %s usage is %.2f',
  2829. $self->{hpLocalMemSlotIndex},
  2830. $self->{usage};
  2831. $self->add_info($info);
  2832. $self->set_thresholds(warning => 80, critical => 90);
  2833. $self->add_message($self->check_thresholds($self->{usage}), $info);
  2834. $self->add_perfdata(
  2835. label => 'memory_'.$self->{hpLocalMemSlotIndex}.'_usage',
  2836. value => $self->{usage},
  2837. uom => '%',
  2838. warning => $self->{warning},
  2839. critical => $self->{critical}
  2840. );
  2841. }
  2842. sub dump {
  2843. my $self = shift;
  2844. printf "[MEM%s]\n", $self->{hpLocalMemSlotIndex};
  2845. foreach (qw(hpLocalMemSlotIndex hpLocalMemSlabCnt
  2846. hpLocalMemFreeSegCnt hpLocalMemAllocSegCnt hpLocalMemTotalBytes
  2847. hpLocalMemFreeBytes hpLocalMemAllocBytes)) {
  2848. printf "%s: %s\n", $_, $self->{$_};
  2849. }
  2850. printf "info: %s\n", $self->{info};
  2851. printf "\n";
  2852. }
  2853. package NWC::HP::Procurve::Component::CpuSubsystem;
  2854. our @ISA = qw(NWC::HP::Procurve);
  2855. use strict;
  2856. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2857. sub new {
  2858. my $class = shift;
  2859. my %params = @_;
  2860. my $self = {
  2861. cpus => [],
  2862. blacklisted => 0,
  2863. info => undef,
  2864. extendedinfo => undef,
  2865. };
  2866. bless $self, $class;
  2867. $self->init(%params);
  2868. return $self;
  2869. }
  2870. sub init {
  2871. my $self = shift;
  2872. my %params = @_;
  2873. $self->{hpSwitchCpuStat} = $self->get_snmp_object('STATISTICS-MIB', 'hpSwitchCpuStat');
  2874. }
  2875. sub check {
  2876. my $self = shift;
  2877. my $errorfound = 0;
  2878. $self->add_info('checking cpus');
  2879. my $info = sprintf 'cpu usage is %.2f%%', $self->{hpSwitchCpuStat};
  2880. $self->add_info($info);
  2881. $self->set_thresholds(warning => 80, critical => 90); # maybe lower, because the switching is done in hardware
  2882. $self->add_message($self->check_thresholds($self->{hpSwitchCpuStat}), $info);
  2883. $self->add_perfdata(
  2884. label => 'cpu_usage',
  2885. value => $self->{hpSwitchCpuStat},
  2886. uom => '%',
  2887. warning => $self->{warning},
  2888. critical => $self->{critical},
  2889. );
  2890. }
  2891. sub dump {
  2892. my $self = shift;
  2893. printf "[CPU]\n";
  2894. foreach (qw(hpSwitchCpuStat)) {
  2895. printf "%s: %s\n", $_, $self->{$_};
  2896. }
  2897. printf "info: %s\n", $self->{info};
  2898. printf "\n";
  2899. }
  2900. package NWC::HP::Procurve::Component::EnvironmentalSubsystem;
  2901. our @ISA = qw(NWC::HP::Procurve);
  2902. use strict;
  2903. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2904. sub new {
  2905. my $class = shift;
  2906. my %params = @_;
  2907. my $self = {
  2908. runtime => $params{runtime},
  2909. rawdata => $params{rawdata},
  2910. method => $params{method},
  2911. condition => $params{condition},
  2912. status => $params{status},
  2913. sensor_subsystem => undef,
  2914. blacklisted => 0,
  2915. info => undef,
  2916. extendedinfo => undef,
  2917. };
  2918. bless $self, $class;
  2919. $self->init(%params);
  2920. return $self;
  2921. }
  2922. sub init {
  2923. my $self = shift;
  2924. my %params = @_;
  2925. $self->{sensor_subsystem} =
  2926. NWC::HP::Procurve::Component::SensorSubsystem->new(%params);
  2927. }
  2928. sub check {
  2929. my $self = shift;
  2930. my $errorfound = 0;
  2931. $self->{sensor_subsystem}->check();
  2932. if (! $self->check_messages()) {
  2933. $self->add_message(OK, "environmental hardware working fine");
  2934. }
  2935. }
  2936. sub dump {
  2937. my $self = shift;
  2938. $self->{sensor_subsystem}->dump();
  2939. }
  2940. package NWC::HP::Procurve::Component::SensorSubsystem;
  2941. our @ISA = qw(NWC::HP::Procurve::Component::EnvironmentalSubsystem);
  2942. use strict;
  2943. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2944. sub new {
  2945. my $class = shift;
  2946. my %params = @_;
  2947. my $self = {
  2948. sensors => [],
  2949. sensorthresholds => [],
  2950. blacklisted => 0,
  2951. info => undef,
  2952. extendedinfo => undef,
  2953. };
  2954. bless $self, $class;
  2955. $self->init(%params);
  2956. return $self;
  2957. }
  2958. sub init {
  2959. my $self = shift;
  2960. my $sensors = {};
  2961. foreach ($self->get_snmp_table_objects(
  2962. 'HP-ICF-CHASSIS-MIB', 'hpicfSensorTable')) {
  2963. push(@{$self->{sensors}},
  2964. NWC::HP::Procurve::Component::SensorSubsystem::Sensor->new(%{$_}));
  2965. }
  2966. }
  2967. sub check {
  2968. my $self = shift;
  2969. my $errorfound = 0;
  2970. $self->add_info('checking sensors');
  2971. $self->blacklist('ses', '');
  2972. if (scalar (@{$self->{sensors}}) == 0) {
  2973. } else {
  2974. foreach (@{$self->{sensors}}) {
  2975. $_->check();
  2976. }
  2977. }
  2978. }
  2979. sub dump {
  2980. my $self = shift;
  2981. foreach (@{$self->{sensors}}) {
  2982. $_->dump();
  2983. }
  2984. }
  2985. package NWC::HP::Procurve::Component::SensorSubsystem::Sensor;
  2986. our @ISA = qw(NWC::HP::Procurve::Component::SensorSubsystem);
  2987. use strict;
  2988. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  2989. sub new {
  2990. my $class = shift;
  2991. my %params = @_;
  2992. my $self = {
  2993. blacklisted => 0,
  2994. info => undef,
  2995. extendedinfo => undef,
  2996. };
  2997. foreach my $param (qw(hpicfSensorIndex hpicfSensorObjectId
  2998. hpicfSensorNumber hpicfSensorStatus hpicfSensorWarnings
  2999. hpicfSensorFailures hpicfSensorDescr)) {
  3000. $self->{$param} = $params{$param};
  3001. }
  3002. bless $self, $class;
  3003. return $self;
  3004. }
  3005. sub check {
  3006. my $self = shift;
  3007. $self->blacklist('se', $self->{hpicfSensorIndex});
  3008. $self->add_info(sprintf 'sensor %s (%s) is %s',
  3009. $self->{hpicfSensorIndex},
  3010. $self->{hpicfSensorDescr},
  3011. $self->{hpicfSensorStatus});
  3012. if ($self->{hpicfSensorStatus} eq "notPresent") {
  3013. } elsif ($self->{hpicfSensorStatus} eq "bad") {
  3014. $self->add_message(CRITICAL, $self->{info});
  3015. } elsif ($self->{hpicfSensorStatus} eq "warning") {
  3016. $self->add_message(WARNING, $self->{info});
  3017. } elsif ($self->{hpicfSensorStatus} eq "good") {
  3018. #$self->add_message(OK, $self->{info});
  3019. } else {
  3020. $self->add_message(UNKNOWN, $self->{info});
  3021. }
  3022. }
  3023. sub dump {
  3024. my $self = shift;
  3025. printf "[SENSOR_%s]\n", $self->{hpicfSensorIndex};
  3026. foreach (qw(hpicfSensorIndex hpicfSensorObjectId
  3027. hpicfSensorNumber hpicfSensorStatus hpicfSensorWarnings
  3028. hpicfSensorFailures hpicfSensorDescr)) {
  3029. printf "%s: %s\n", $_, $self->{$_};
  3030. }
  3031. printf "info: %s\n", $self->{info};
  3032. printf "\n";
  3033. }
  3034. package NWC::HP::Procurve;
  3035. use strict;
  3036. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3037. our @ISA = qw(NWC::F5);
  3038. sub init {
  3039. my $self = shift;
  3040. $self->{components} = {
  3041. cpu_subsystem => undef,
  3042. memory_subsystem => undef,
  3043. environmental_subsystem => undef,
  3044. };
  3045. $self->{serial} = 'unknown';
  3046. $self->{product} = 'unknown';
  3047. $self->{romversion} = 'unknown';
  3048. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  3049. #$self->collect();
  3050. if (! $self->check_messages()) {
  3051. ##$self->set_serial();
  3052. if ($self->mode =~ /device::hardware::health/) {
  3053. $self->analyze_environmental_subsystem();
  3054. #$self->auto_blacklist();
  3055. $self->check_environmental_subsystem();
  3056. } elsif ($self->mode =~ /device::hardware::load/) {
  3057. $self->analyze_cpu_subsystem();
  3058. #$self->auto_blacklist();
  3059. $self->check_cpu_subsystem();
  3060. } elsif ($self->mode =~ /device::hardware::memory/) {
  3061. $self->analyze_mem_subsystem();
  3062. #$self->auto_blacklist();
  3063. $self->check_mem_subsystem();
  3064. } elsif ($self->mode =~ /device::interfaces/) {
  3065. $self->analyze_interface_subsystem();
  3066. $self->check_interface_subsystem();
  3067. } elsif ($self->mode =~ /device::shinken::interface/) {
  3068. $self->analyze_interface_subsystem();
  3069. $self->shinken_interface_subsystem();
  3070. }
  3071. }
  3072. }
  3073. sub analyze_environmental_subsystem {
  3074. my $self = shift;
  3075. $self->{components}->{environmental_subsystem} =
  3076. NWC::HP::Procurve::Component::EnvironmentalSubsystem->new();
  3077. }
  3078. sub analyze_interface_subsystem {
  3079. my $self = shift;
  3080. $self->{components}->{interface_subsystem} =
  3081. NWC::IFMIB::Component::InterfaceSubsystem->new();
  3082. }
  3083. sub analyze_cpu_subsystem {
  3084. my $self = shift;
  3085. $self->{components}->{cpu_subsystem} =
  3086. NWC::HP::Procurve::Component::CpuSubsystem->new();
  3087. }
  3088. sub analyze_mem_subsystem {
  3089. my $self = shift;
  3090. $self->{components}->{mem_subsystem} =
  3091. NWC::HP::Procurve::Component::MemSubsystem->new();
  3092. }
  3093. sub check_environmental_subsystem {
  3094. my $self = shift;
  3095. $self->{components}->{environmental_subsystem}->check();
  3096. $self->{components}->{environmental_subsystem}->dump()
  3097. if $self->opts->verbose >= 2;
  3098. }
  3099. sub check_interface_subsystem {
  3100. my $self = shift;
  3101. $self->{components}->{interface_subsystem}->check();
  3102. $self->{components}->{interface_subsystem}->dump()
  3103. if $self->opts->verbose >= 2;
  3104. }
  3105. sub check_cpu_subsystem {
  3106. my $self = shift;
  3107. $self->{components}->{cpu_subsystem}->check();
  3108. $self->{components}->{cpu_subsystem}->dump()
  3109. if $self->opts->verbose >= 2;
  3110. }
  3111. sub check_mem_subsystem {
  3112. my $self = shift;
  3113. $self->{components}->{mem_subsystem}->check();
  3114. $self->{components}->{mem_subsystem}->dump()
  3115. if $self->opts->verbose >= 2;
  3116. }
  3117. package NWC::HP;
  3118. use strict;
  3119. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3120. our @ISA = qw(NWC::Device);
  3121. use constant trees => (
  3122. '1.3.6.1.4.1.11.2.14.11.1.2', # HP-ICF-CHASSIS
  3123. '1.3.6.1.2.1.1.7.11.12.9', # STATISTICS-MIB (old?)
  3124. '1.3.6.1.2.1.1.7.11.12.1', # NETSWITCH-MIB (old?)
  3125. '1.3.6.1.4.1.11.2.14.11.5.1.9', # STATISTICS-MIB
  3126. '1.3.6.1.4.1.11.2.14.11.5.1.1', # NETSWITCH-MIB
  3127. );
  3128. sub init {
  3129. my $self = shift;
  3130. if ($self->{productname} =~ /Procurve/i) {
  3131. bless $self, 'NWC::HP::Procurve';
  3132. $self->debug('using NWC::HP::Procurve');
  3133. }
  3134. $self->init();
  3135. }
  3136. package NWC::MEOS;
  3137. use strict;
  3138. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3139. our @ISA = qw(NWC::Brocade);
  3140. sub init {
  3141. my $self = shift;
  3142. $self->{components} = {
  3143. powersupply_subsystem => undef,
  3144. fan_subsystem => undef,
  3145. temperature_subsystem => undef,
  3146. cpu_subsystem => undef,
  3147. };
  3148. $self->{serial} = 'unknown';
  3149. $self->{product} = 'unknown';
  3150. $self->{romversion} = 'unknown';
  3151. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  3152. #$self->collect();
  3153. if (! $self->check_messages()) {
  3154. if ($self->mode =~ /device::hardware::health/) {
  3155. $self->analyze_environmental_subsystem();
  3156. $self->check_environmental_subsystem();
  3157. } elsif ($self->mode =~ /device::hardware::load/) {
  3158. $self->analyze_cpu_subsystem();
  3159. $self->check_cpu_subsystem();
  3160. } elsif ($self->mode =~ /device::hardware::memory/) {
  3161. $self->analyze_mem_subsystem();
  3162. $self->check_mem_subsystem();
  3163. } elsif ($self->mode =~ /device::interfaces/) {
  3164. $self->analyze_interface_subsystem();
  3165. $self->check_interface_subsystem();
  3166. }
  3167. }
  3168. }
  3169. sub analyze_environmental_subsystem {
  3170. my $self = shift;
  3171. $self->{components}->{environmental_subsystem1} =
  3172. NWC::FCMGMT::Component::EnvironmentalSubsystem->new();
  3173. $self->{components}->{environmental_subsystem2} =
  3174. NWC::FCEOS::Component::EnvironmentalSubsystem->new();
  3175. }
  3176. sub analyze_cpu_subsystem {
  3177. my $self = shift;
  3178. $self->no_such_mode();
  3179. $self->{components}->{cpu_subsystem} =
  3180. NWC::UCDMIB::Component::CpuSubsystem->new();
  3181. }
  3182. sub analyze_mem_subsystem {
  3183. my $self = shift;
  3184. $self->no_such_mode();
  3185. $self->{components}->{mem_subsystem} =
  3186. NWC::UCDMIB::Component::MemSubsystem->new();
  3187. }
  3188. sub analyze_interface_subsystem {
  3189. my $self = shift;
  3190. $self->{components}->{interface_subsystem} =
  3191. NWC::IFMIB::Component::InterfaceSubsystem->new();
  3192. }
  3193. sub check_environmental_subsystem {
  3194. my $self = shift;
  3195. $self->{components}->{environmental_subsystem1}->check();
  3196. $self->{components}->{environmental_subsystem2}->check();
  3197. if ($self->check_messages()) {
  3198. $self->clear_messages(OK);
  3199. }
  3200. $self->{components}->{environmental_subsystem1}->dump()
  3201. if $self->opts->verbose >= 2;
  3202. $self->{components}->{environmental_subsystem2}->dump()
  3203. if $self->opts->verbose >= 2;
  3204. }
  3205. sub check_cpu_subsystem {
  3206. my $self = shift;
  3207. $self->{components}->{cpu_subsystem}->check();
  3208. $self->{components}->{cpu_subsystem}->dump()
  3209. if $self->opts->verbose >= 2;
  3210. }
  3211. sub check_mem_subsystem {
  3212. my $self = shift;
  3213. $self->{components}->{mem_subsystem}->check();
  3214. $self->{components}->{mem_subsystem}->dump()
  3215. if $self->opts->verbose >= 2;
  3216. }
  3217. sub check_interface_subsystem {
  3218. my $self = shift;
  3219. $self->{components}->{interface_subsystem}->check();
  3220. $self->{components}->{interface_subsystem}->dump()
  3221. if $self->opts->verbose >= 2;
  3222. }
  3223. package NWC::Brocade;
  3224. use strict;
  3225. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3226. our @ISA = qw(NWC::Device);
  3227. use constant trees => (
  3228. '1.3.6.1.2.1', # mib-2
  3229. '1.3.6.1.4.1.289', # mcData
  3230. '1.3.6.1.4.1.333', # cnt
  3231. '1.3.6.1.4.1.1588', # bcsi
  3232. '1.3.6.1.4.1.1991', # foundry
  3233. '1.3.6.1.4.1.4369', # nishan
  3234. );
  3235. sub init {
  3236. my $self = shift;
  3237. foreach ($self->get_snmp_table_objects(
  3238. 'ENTITY-MIB', 'entPhysicalTable')) {
  3239. if ($_->{entPhysicalDescr} =~ /Brocade/) {
  3240. $self->{productname} = "FabOS";
  3241. }
  3242. }
  3243. my $swFirmwareVersion = $self->get_snmp_object('SW-MIB', 'swFirmwareVersion');
  3244. if ($swFirmwareVersion && $swFirmwareVersion =~ /^v6/) {
  3245. $self->{productname} = "FabOS"
  3246. }
  3247. if ($self->{productname} =~ /EMC\s*DS.*4700M/i) {
  3248. bless $self, 'NWC::MEOS';
  3249. $self->debug('using NWC::MEOS');
  3250. $self->init();
  3251. } elsif ($self->{productname} =~ /EMC\s*DS-24M2/i) {
  3252. bless $self, 'NWC::MEOS';
  3253. $self->debug('using NWC::MEOS');
  3254. $self->init();
  3255. } elsif ($self->{productname} =~ /FabOS/i) {
  3256. bless $self, 'NWC::FabOS';
  3257. $self->debug('using NWC::FabOS');
  3258. $self->init();
  3259. }
  3260. }
  3261. package NWC::SecureOS;
  3262. use strict;
  3263. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3264. our @ISA = qw(NWC::Device);
  3265. sub init {
  3266. my $self = shift;
  3267. $self->{components} = {
  3268. mem_subsystem => undef,
  3269. cpu_subsystem => undef,
  3270. };
  3271. $self->{serial} = 'unknown';
  3272. $self->{product} = 'unknown';
  3273. $self->{romversion} = 'unknown';
  3274. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  3275. #$self->collect();
  3276. if (! $self->check_messages()) {
  3277. if ($self->mode =~ /device::hardware::health/) {
  3278. $self->analyze_environmental_subsystem();
  3279. $self->check_environmental_subsystem();
  3280. } elsif ($self->mode =~ /device::hardware::load/) {
  3281. $self->analyze_cpu_subsystem();
  3282. $self->check_cpu_subsystem();
  3283. } elsif ($self->mode =~ /device::hardware::memory/) {
  3284. $self->analyze_mem_subsystem();
  3285. $self->check_mem_subsystem();
  3286. } elsif ($self->mode =~ /device::interfaces/) {
  3287. $self->analyze_interface_subsystem();
  3288. $self->check_interface_subsystem();
  3289. }
  3290. }
  3291. }
  3292. sub analyze_environmental_subsystem {
  3293. my $self = shift;
  3294. $self->no_such_mode();
  3295. $self->{components}->{environmental_subsystem} =
  3296. #NWC::SecureOS::Component::EnvironmentalSubsystem->new();
  3297. NWC::FCMGMT::Component::EnvironmentalSubsystem->new();
  3298. }
  3299. sub analyze_cpu_subsystem {
  3300. my $self = shift;
  3301. $self->{components}->{cpu_subsystem} =
  3302. NWC::UCDMIB::Component::CpuSubsystem->new();
  3303. }
  3304. sub analyze_mem_subsystem {
  3305. my $self = shift;
  3306. $self->{components}->{mem_subsystem} =
  3307. NWC::UCDMIB::Component::MemSubsystem->new();
  3308. }
  3309. sub analyze_interface_subsystem {
  3310. my $self = shift;
  3311. $self->{components}->{interface_subsystem} =
  3312. NWC::IFMIB::Component::InterfaceSubsystem->new();
  3313. }
  3314. sub check_environmental_subsystem {
  3315. my $self = shift;
  3316. $self->{components}->{environmental_subsystem}->check();
  3317. $self->{components}->{environmental_subsystem}->dump()
  3318. if $self->opts->verbose >= 2;
  3319. }
  3320. sub check_cpu_subsystem {
  3321. my $self = shift;
  3322. $self->{components}->{cpu_subsystem}->check();
  3323. $self->{components}->{cpu_subsystem}->dump()
  3324. if $self->opts->verbose >= 2;
  3325. }
  3326. sub check_mem_subsystem {
  3327. my $self = shift;
  3328. $self->{components}->{mem_subsystem}->check();
  3329. $self->{components}->{mem_subsystem}->dump()
  3330. if $self->opts->verbose >= 2;
  3331. }
  3332. sub check_interface_subsystem {
  3333. my $self = shift;
  3334. $self->{components}->{interface_subsystem}->check();
  3335. $self->{components}->{interface_subsystem}->dump()
  3336. if $self->opts->verbose >= 2;
  3337. }
  3338. package NWC::HSRP::Component::HSRPSubsystem;
  3339. our @ISA = qw(NWC::HSRP);
  3340. use strict;
  3341. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3342. sub new {
  3343. my $class = shift;
  3344. my %params = @_;
  3345. my $self = {
  3346. groups => [],
  3347. blacklisted => 0,
  3348. info => undef,
  3349. extendedinfo => undef,
  3350. };
  3351. bless $self, $class;
  3352. $self->init(%params);
  3353. return $self;
  3354. }
  3355. sub init {
  3356. my $self = shift;
  3357. my %params = @_;
  3358. if ($self->mode =~ /device::hsrp/) {
  3359. foreach ($self->get_snmp_table_objects(
  3360. 'CISCO-HSRP-MIB', 'cHsrpGrpTable')) {
  3361. push(@{$self->{groups}},
  3362. NWC::HSRP::Component::HSRPSubsystem::Group->new(%{$_}));
  3363. }
  3364. }
  3365. }
  3366. sub check {
  3367. my $self = shift;
  3368. my $errorfound = 0;
  3369. $self->add_info('checking hsrp groups');
  3370. $self->blacklist('hhsrp', '');
  3371. if ($self->mode =~ /device::hsrp::list/) {
  3372. foreach (@{$self->{groups}}) {
  3373. $_->list();
  3374. }
  3375. } elsif ($self->mode =~ /device::hsrp/) {
  3376. if (scalar (@{$self->{groups}}) == 0) {
  3377. $self->add_message(UNKNOWN, 'no hsrp groups');
  3378. } else {
  3379. foreach (@{$self->{groups}}) {
  3380. $_->check();
  3381. }
  3382. }
  3383. }
  3384. }
  3385. sub dump {
  3386. my $self = shift;
  3387. foreach (@{$self->{groups}}) {
  3388. $_->dump();
  3389. }
  3390. }
  3391. package NWC::HSRP::Component::HSRPSubsystem::Group;
  3392. our @ISA = qw(NWC::HSRP::Component::HSRPSubsystem);
  3393. use strict;
  3394. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3395. sub new {
  3396. my $class = shift;
  3397. my %params = @_;
  3398. my $self = {
  3399. blacklisted => 0,
  3400. info => undef,
  3401. extendedinfo => undef,
  3402. };
  3403. bless $self, $class;
  3404. foreach ($self->get_snmp_table_attributes(
  3405. 'CISCO-HSRP-MIB', 'cHsrpGrpTable')) {
  3406. $self->{$_} = $params{$_};
  3407. }
  3408. $self->{ifIndex} = $params{indices}->[0];
  3409. $self->{cHsrpGrpNumber} = $params{indices}->[1];
  3410. $self->{name} = $self->{cHsrpGrpNumber}.':'.$self->{ifIndex};
  3411. foreach my $key (keys %params) {
  3412. $self->{$key} = 0 if ! defined $params{$key};
  3413. }
  3414. $self->init();
  3415. return $self;
  3416. }
  3417. sub init {
  3418. my $self = shift;
  3419. if ($self->mode =~ /device::hsrp::state/) {
  3420. if (! $self->opts->role()) {
  3421. $self->opts->override_opt('role', 'active');
  3422. }
  3423. }
  3424. return $self;
  3425. }
  3426. sub check {
  3427. my $self = shift;
  3428. $self->blacklist('hsrp', $self->{name});
  3429. if ($self->mode =~ /device::hsrp::state/) {
  3430. my $info = sprintf 'hsrp group %s (interface %s) state is %s (active router is %s, standby router is %s',
  3431. $self->{cHsrpGrpNumber}, $self->{ifIndex},
  3432. $self->{cHsrpGrpStandbyState},
  3433. $self->{cHsrpGrpActiveRouter}, $self->{cHsrpGrpStandbyRouter};
  3434. $self->add_info($info);
  3435. if ($self->opts->role() eq $self->{cHsrpGrpStandbyState}) {
  3436. $self->add_message(OK, $info);
  3437. } else {
  3438. $self->add_message(CRITICAL,
  3439. sprintf 'state in group %s (interface %s) is %s instead of %s',
  3440. $self->{cHsrpGrpNumber}, $self->{ifIndex},
  3441. $self->{cHsrpGrpStandbyState},
  3442. $self->opts->role());
  3443. }
  3444. } elsif ($self->mode =~ /device::hsrp::failover/) {
  3445. my $info = sprintf "Vlan %s: active node is %s, standby node is %s \n",
  3446. $self->{cHsrpGrpNumber}, $self->{cHsrpGrpActiveRouter}, $self->{cHsrpGrpStandbyRouter};
  3447. if (my $laststate = $self->load_state( name => $self->{name} )) {
  3448. if ($laststate->{active} ne $self->{cHsrpGrpActiveRouter}) {
  3449. $self->add_message(WARNING, sprintf "Vlan %s: active node %s --> %s \n",
  3450. $self->{cHsrpGrpNumber}, $laststate->{active}, $self->{cHsrpGrpActiveRouter});
  3451. }
  3452. if ($laststate->{standby} ne $self->{cHsrpGrpStandbyRouter}) {
  3453. $self->add_message(WARNING, sprintf "Vlan %s: standby node %s --> %s \n",
  3454. $self->{cHsrpGrpNumber}, $laststate->{standby}, $self->{cHsrpGrpStandbyRouter});
  3455. }
  3456. if (($laststate->{active} eq $self->{cHsrpGrpActiveRouter}) &&
  3457. ($laststate->{standby} eq $self->{cHsrpGrpStandbyRouter})) {
  3458. $self->add_message(OK, $info);
  3459. }
  3460. } else {
  3461. $self->add_message(OK, 'initializing....');
  3462. }
  3463. $self->save_state( name => $self->{name}, save => {
  3464. active => $self->{cHsrpGrpActiveRouter},
  3465. standby => $self->{cHsrpGrpStandbyRouter},
  3466. });
  3467. }
  3468. }
  3469. sub list {
  3470. my $self = shift;
  3471. printf "%s %s %s %s\n", $self->{name}, $self->{cHsrpGrpVirtualIpAddr},
  3472. $self->{cHsrpGrpActiveRouter}, $self->{cHsrpGrpStandbyRouter};
  3473. }
  3474. sub dump {
  3475. my $self = shift;
  3476. printf "[HSRPGRP_%s]\n", $self->{name};
  3477. foreach (qw(cHsrpGrpNumber cHsrpGrpVirtualIpAddr cHsrpGrpStandbyState cHsrpGrpActiveRouter cHsrpGrpStandbyRouter cHsrpGrpEntryRowStatus)) {
  3478. printf "%s: %s\n", $_, defined $self->{$_} ? $self->{$_} : 'undefined';
  3479. }
  3480. # printf "info: %s\n", $self->{info};
  3481. printf "\n";
  3482. }
  3483. package NWC::HSRP;
  3484. use strict;
  3485. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3486. our @ISA = qw(NWC::Device);
  3487. package NWC::IFMIB::Component::InterfaceSubsystem;
  3488. our @ISA = qw(NWC::IFMIB);
  3489. use strict;
  3490. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3491. sub new {
  3492. my $class = shift;
  3493. my %params = @_;
  3494. my $self = {
  3495. interface_cache => {},
  3496. interfaces => [],
  3497. blacklisted => 0,
  3498. info => undef,
  3499. extendedinfo => undef,
  3500. };
  3501. bless $self, $class;
  3502. $self->init(%params);
  3503. return $self;
  3504. }
  3505. sub init {
  3506. my $self = shift;
  3507. my %params = @_;
  3508. if ($self->mode =~ /device::interfaces::list/) {
  3509. $self->update_interface_cache(1);
  3510. foreach my $ifidxdescr (keys %{$self->{interface_cache}}) {
  3511. my ($ifIndex, $ifDescr) = split('#', $ifidxdescr, 2);
  3512. push(@{$self->{interfaces}},
  3513. NWC::IFMIB::Component::InterfaceSubsystem::Interface->new(
  3514. #ifIndex => $self->{interface_cache}->{$ifDescr},
  3515. #ifDescr => $ifDescr,
  3516. ifIndex => $ifIndex,
  3517. ifDescr => $ifDescr,
  3518. ));
  3519. }
  3520. } else {
  3521. $self->update_interface_cache(0);
  3522. #next if $self->opts->can('name') && $self->opts->name &&
  3523. # $self->opts->name ne $_->{ifDescr};
  3524. # if limited search
  3525. # name is a number -> get_table with extra param
  3526. # name is a regexp -> list of names -> list of numbers
  3527. my @indices = $self->get_interface_indices();
  3528. if (scalar(@indices) > 0) {
  3529. foreach ($self->get_snmp_table_objects(
  3530. 'IFMIB', 'ifTable+ifXTable', \@indices)) {
  3531. push(@{$self->{interfaces}},
  3532. NWC::IFMIB::Component::InterfaceSubsystem::Interface->new(%{$_}));
  3533. }
  3534. }
  3535. }
  3536. }
  3537. sub check {
  3538. my $self = shift;
  3539. my $errorfound = 0;
  3540. $self->add_info('checking interfaces');
  3541. $self->blacklist('ff', '');
  3542. if (scalar(@{$self->{interfaces}}) == 0) {
  3543. $self->add_message(UNKNOWN, 'no interfaces');
  3544. return;
  3545. }
  3546. if ($self->mode =~ /device::interfaces::list/) {
  3547. foreach (sort {$a->{ifIndex} <=> $b->{ifIndex}} @{$self->{interfaces}}) {
  3548. #foreach (sort @{$self->{interfaces}}) {
  3549. $_->list();
  3550. }
  3551. } else {
  3552. if (scalar (@{$self->{interfaces}}) == 0) {
  3553. } else {
  3554. my $unique = {};
  3555. foreach (@{$self->{interfaces}}) {
  3556. if (exists $unique->{$_->{ifDescr}}) {
  3557. $unique->{$_->{ifDescr}}++;
  3558. } else {
  3559. $unique->{$_->{ifDescr}} = 0;
  3560. }
  3561. }
  3562. foreach (sort {$a->{ifIndex} <=> $b->{ifIndex}} @{$self->{interfaces}}) {
  3563. if ($unique->{$_->{ifDescr}}) {
  3564. $_->{ifDescr} .= ' '.$_->{ifIndex};
  3565. }
  3566. $_->check();
  3567. }
  3568. }
  3569. }
  3570. }
  3571. sub update_interface_cache {
  3572. my $self = shift;
  3573. my $force = shift;
  3574. my $statefile = lc sprintf "%s/%s_interface_cache",
  3575. $NWC::Device::statefilesdir, $self->opts->hostname;
  3576. my $update = time - 3600;
  3577. if ($force || ! -f $statefile || ((stat $statefile)[9]) < ($update)) {
  3578. $self->debug('force update of interface cache');
  3579. $self->{interface_cache} = {};
  3580. foreach ($self->get_snmp_table_objects( 'IFMIB', 'ifTable')) {
  3581. # neuerdings index+descr, weil die drecksscheiss allied telesyn ports
  3582. # alle gleich heissen
  3583. $self->{interface_cache}->{$_->{ifIndex}.'#'.$_->{ifDescr}} =
  3584. $_->{ifIndex};
  3585. }
  3586. $self->save_interface_cache();
  3587. }
  3588. $self->load_interface_cache();
  3589. }
  3590. sub save_interface_cache {
  3591. my $self = shift;
  3592. $self->create_statefilesdir();
  3593. my $statefile = lc sprintf "%s/%s_interface_cache",
  3594. $NWC::Device::statefilesdir, $self->opts->hostname;
  3595. open(STATE, ">$statefile");
  3596. ############################
  3597. # printf ohne %s ????
  3598. ############################
  3599. printf STATE Data::Dumper::Dumper($self->{interface_cache});
  3600. close STATE;
  3601. $self->debug(sprintf "saved %s to %s",
  3602. Data::Dumper::Dumper($self->{interface_cache}), $statefile);
  3603. }
  3604. sub load_interface_cache {
  3605. my $self = shift;
  3606. my $statefile = lc sprintf "%s/%s_interface_cache",
  3607. $NWC::Device::statefilesdir, $self->opts->hostname;
  3608. if ( -f $statefile) {
  3609. our $VAR1;
  3610. eval {
  3611. require $statefile;
  3612. };
  3613. if($@) {
  3614. printf "rumms\n";
  3615. }
  3616. $self->debug(sprintf "load %s", Data::Dumper::Dumper($VAR1));
  3617. $self->{interface_cache} = $VAR1;
  3618. }
  3619. }
  3620. sub get_interface_indices {
  3621. my $self = shift;
  3622. my @indices = ();
  3623. foreach my $ifidxdescr (keys %{$self->{interface_cache}}) {
  3624. my ($ifindex, $ifdescr) = split('#', $ifidxdescr, 2);
  3625. if ($self->opts->name) {
  3626. if ($self->opts->regexp) {
  3627. my $pattern = $self->opts->name;
  3628. if ($ifdescr =~ /$pattern/i) {
  3629. push(@indices, [$ifindex]);
  3630. }
  3631. } else {
  3632. if ($self->opts->name =~ /^\d+$/) {
  3633. if ($ifindex == 1 * $self->opts->name) {
  3634. push(@indices, [1 * $self->opts->name]);
  3635. }
  3636. } else {
  3637. if (lc $ifdescr eq lc $self->opts->name) {
  3638. push(@indices, [$ifindex]);
  3639. }
  3640. }
  3641. }
  3642. } else {
  3643. push(@indices, [$ifindex]);
  3644. }
  3645. }
  3646. return @indices;
  3647. }
  3648. sub dump {
  3649. my $self = shift;
  3650. foreach (@{$self->{interfaces}}) {
  3651. $_->dump();
  3652. }
  3653. }
  3654. package NWC::IFMIB::Component::InterfaceSubsystem::Interface;
  3655. our @ISA = qw(NWC::IFMIB::Component::InterfaceSubsystem);
  3656. use strict;
  3657. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3658. sub new {
  3659. my $class = shift;
  3660. my %params = @_;
  3661. my $self = {
  3662. ifTable => $params{ifTable},
  3663. ifEntry => $params{ifEntry},
  3664. ifIndex => $params{ifIndex},
  3665. ifDescr => $params{ifDescr},
  3666. ifType => $params{ifType},
  3667. ifMtu => $params{ifMtu},
  3668. ifSpeed => $params{ifSpeed},
  3669. ifPhysAddress => $params{ifPhysAddress},
  3670. ifAdminStatus => $params{ifAdminStatus},
  3671. ifOperStatus => $params{ifOperStatus},
  3672. ifLastChange => $params{ifLastChange},
  3673. ifInOctets => $params{ifInOctets},
  3674. ifInUcastPkts => $params{ifInUcastPkts},
  3675. ifInNUcastPkts => $params{ifInNUcastPkts},
  3676. ifInDiscards => $params{ifInDiscards},
  3677. ifInErrors => $params{ifInErrors},
  3678. ifInUnknownProtos => $params{ifInUnknownProtos},
  3679. ifOutOctets => $params{ifOutOctets},
  3680. ifOutUcastPkts => $params{ifOutUcastPkts},
  3681. ifOutNUcastPkts => $params{ifOutNUcastPkts},
  3682. ifOutDiscards => $params{ifOutDiscards},
  3683. ifOutErrors => $params{ifOutErrors},
  3684. ifOutQLen => $params{ifOutQLen},
  3685. ifSpecific => $params{ifSpecific},
  3686. blacklisted => 0,
  3687. info => undef,
  3688. extendedinfo => undef,
  3689. };
  3690. foreach my $key (keys %{$self}) {
  3691. next if $key !~ /^if/;
  3692. $self->{$key} = 0 if ! defined $params{$key};
  3693. }
  3694. bless $self, $class;
  3695. if (0) {
  3696. #if ($params{ifName}) {
  3697. my $self64 = {
  3698. ifName => $params{ifName},
  3699. ifInMulticastPkts => $params{ifInMulticastPkts},
  3700. ifInBroadcastPkts => $params{ifInBroadcastPkts},
  3701. ifOutMulticastPkts => $params{ifOutMulticastPkts},
  3702. ifOutBroadcastPkts => $params{ifOutBroadcastPkts},
  3703. ifHCInOctets => $params{ifHCInOctets},
  3704. ifHCInUcastPkts => $params{ifHCInUcastPkts},
  3705. ifHCInMulticastPkts => $params{ifHCInMulticastPkts},
  3706. ifHCInBroadcastPkts => $params{ifHCInBroadcastPkts},
  3707. ifHCOutOctets => $params{ifHCOutOctets},
  3708. ifHCOutUcastPkts => $params{ifHCOutUcastPkts},
  3709. ifHCOutMulticastPkts => $params{ifHCOutMulticastPkts},
  3710. ifHCOutBroadcastPkts => $params{ifHCOutBroadcastPkts},
  3711. ifLinkUpDownTrapEnable => $params{ifLinkUpDownTrapEnable},
  3712. ifHighSpeed => $params{ifHighSpeed},
  3713. ifPromiscuousMode => $params{ifPromiscuousMode},
  3714. ifConnectorPresent => $params{ifConnectorPresent},
  3715. ifAlias => $params{ifAlias},
  3716. ifCounterDiscontinuityTime => $params{ifCounterDiscontinuityTime},
  3717. };
  3718. map { $self->{$_} = $self64->{$_} } keys %{$self64};
  3719. bless $self, 'NWC::IFMIB::Component::InterfaceSubsystem::Interface::64bit';
  3720. }
  3721. $self->init();
  3722. return $self;
  3723. }
  3724. sub init {
  3725. my $self = shift;
  3726. if ($self->mode =~ /device::interfaces::traffic/) {
  3727. $self->valdiff({name => $self->{ifDescr}}, qw(ifInOctets ifInUcastPkts ifInNUcastPkts ifInDiscards ifInErrors ifInUnknownProtos ifOutOctets ifOutUcastPkts ifOutNUcastPkts ifOutDiscards ifOutErrors));
  3728. } elsif ($self->mode =~ /device::interfaces::usage/) {
  3729. $self->valdiff({name => $self->{ifIndex}.'#'.$self->{ifDescr}}, qw(ifInOctets ifOutOctets));
  3730. if ($self->{ifSpeed} == 0) {
  3731. # vlan graffl
  3732. $self->{inputUtilization} = 0;
  3733. $self->{outputUtilization} = 0;
  3734. } else {
  3735. $self->{inputUtilization} = $self->{delta_ifInOctets} * 8 * 100 /
  3736. ($self->{delta_timestamp} * $self->{ifSpeed});
  3737. $self->{outputUtilization} = $self->{delta_ifOutOctets} * 8 * 100 /
  3738. ($self->{delta_timestamp} * $self->{ifSpeed});
  3739. }
  3740. if (defined $self->opts->ifspeedin) {
  3741. $self->{inputUtilization} = $self->{delta_ifInOctets} * 8 * 100 /
  3742. ($self->{delta_timestamp} * $self->opts->ifspeedin);
  3743. }
  3744. if (defined $self->opts->ifspeedout) {
  3745. $self->{outputUtilization} = $self->{delta_ifOutOctets} * 8 * 100 /
  3746. ($self->{delta_timestamp} * $self->opts->ifspeedout);
  3747. }
  3748. if (defined $self->opts->ifspeed) {
  3749. $self->{inputUtilization} = $self->{delta_ifInOctets} * 8 * 100 /
  3750. ($self->{delta_timestamp} * $self->opts->ifspeed);
  3751. $self->{outputUtilization} = $self->{delta_ifOutOctets} * 8 * 100 /
  3752. ($self->{delta_timestamp} * $self->opts->ifspeed);
  3753. }
  3754. $self->{inputRate} = $self->{delta_ifInOctets} / $self->{delta_timestamp};
  3755. $self->{outputRate} = $self->{delta_ifOutOctets} / $self->{delta_timestamp};
  3756. my $factor = 1/8; # default Bits
  3757. if ($self->opts->units) {
  3758. if ($self->opts->units eq "GB") {
  3759. $factor = 1024 * 1024 * 1024;
  3760. } elsif ($self->opts->units eq "MB") {
  3761. $factor = 1024 * 1024;
  3762. } elsif ($self->opts->units eq "KB") {
  3763. $factor = 1024;
  3764. } elsif ($self->opts->units eq "GBi") {
  3765. $factor = 1024 * 1024 * 1024 / 8;
  3766. } elsif ($self->opts->units eq "MBi") {
  3767. $factor = 1024 * 1024 / 8;
  3768. } elsif ($self->opts->units eq "KBi") {
  3769. $factor = 1024 / 8;
  3770. } elsif ($self->opts->units eq "B") {
  3771. $factor = 1;
  3772. } elsif ($self->opts->units eq "Bit") {
  3773. $factor = 1/8;
  3774. }
  3775. }
  3776. $self->{inputRate} /= $factor;
  3777. $self->{outputRate} /= $factor;
  3778. } elsif ($self->mode =~ /device::interfaces::errors/) {
  3779. $self->valdiff({name => $self->{ifDescr}}, qw(ifInErrors ifOutErrors ifInDiscards ifOutDiscards));
  3780. $self->{inputErrorRate} = $self->{delta_ifInErrors}
  3781. / $self->{delta_timestamp};
  3782. $self->{outputErrorRate} = $self->{delta_ifOutErrors}
  3783. / $self->{delta_timestamp};
  3784. $self->{inputDiscardRate} = $self->{delta_ifInDiscards}
  3785. / $self->{delta_timestamp};
  3786. $self->{outputDiscardRate} = $self->{delta_ifOutDiscards}
  3787. / $self->{delta_timestamp};
  3788. $self->{inputRate} = ($self->{delta_ifInErrors} + $self->{delta_ifInDiscards})
  3789. / $self->{delta_timestamp};
  3790. $self->{outputRate} = ($self->{delta_ifOutErrors} + $self->{delta_ifOutDiscards})
  3791. / $self->{delta_timestamp};
  3792. } elsif ($self->mode =~ /device::interfaces::operstatus/) {
  3793. }
  3794. return $self;
  3795. }
  3796. sub check {
  3797. my $self = shift;
  3798. $self->blacklist('if', $self->{ifIndex});
  3799. if ($self->mode =~ /device::interfaces::traffic/) {
  3800. } elsif ($self->mode =~ /device::interfaces::usage/) {
  3801. my $info = sprintf 'interface %s usage is in:%.2f%% (%s) out:%.2f%% (%s)',
  3802. $self->{ifDescr},
  3803. $self->{inputUtilization},
  3804. sprintf("%.2f%s/s", $self->{inputRate},
  3805. ($self->opts->units ? $self->opts->units : 'Bits')),
  3806. $self->{outputUtilization},
  3807. sprintf("%.2f%s/s", $self->{outputRate},
  3808. ($self->opts->units ? $self->opts->units : 'Bits'));
  3809. $self->add_info($info);
  3810. $self->set_thresholds(warning => 80, critical => 90);
  3811. my $in = $self->check_thresholds($self->{inputUtilization});
  3812. my $out = $self->check_thresholds($self->{outputUtilization});
  3813. my $level = ($in > $out) ? $in : ($out > $in) ? $out : $in;
  3814. $self->add_message($level, $info);
  3815. $self->add_perfdata(
  3816. label => $self->{ifDescr}.'_usage_in',
  3817. value => $self->{inputUtilization},
  3818. uom => '%',
  3819. warning => $self->{warning},
  3820. critical => $self->{critical},
  3821. );
  3822. $self->add_perfdata(
  3823. label => $self->{ifDescr}.'_usage_out',
  3824. value => $self->{outputUtilization},
  3825. uom => '%',
  3826. warning => $self->{warning},
  3827. critical => $self->{critical},
  3828. );
  3829. $self->add_perfdata(
  3830. label => $self->{ifDescr}.'_traffic_in',
  3831. value => $self->{inputRate},
  3832. uom => $self->opts->units,
  3833. );
  3834. $self->add_perfdata(
  3835. label => $self->{ifDescr}.'_traffic_out',
  3836. value => $self->{outputRate},
  3837. uom => $self->opts->units,
  3838. );
  3839. } elsif ($self->mode =~ /device::interfaces::errors/) {
  3840. my $info = sprintf 'interface %s errors in:%.2f/s out:%.2f/s '.
  3841. 'discards in:%.2f/s out:%.2f/s',
  3842. $self->{ifDescr},
  3843. $self->{inputErrorRate} , $self->{outputErrorRate},
  3844. $self->{inputDiscardRate} , $self->{outputDiscardRate};
  3845. $self->add_info($info);
  3846. $self->set_thresholds(warning => 1, critical => 10);
  3847. my $in = $self->check_thresholds($self->{inputRate});
  3848. my $out = $self->check_thresholds($self->{outputRate});
  3849. my $level = ($in > $out) ? $in : ($out > $in) ? $out : $in;
  3850. $self->add_message($level, $info);
  3851. $self->add_perfdata(
  3852. label => $self->{ifDescr}.'_errors_in',
  3853. value => $self->{inputErrorRate},
  3854. warning => $self->{warning},
  3855. critical => $self->{critical},
  3856. );
  3857. $self->add_perfdata(
  3858. label => $self->{ifDescr}.'_errors_out',
  3859. value => $self->{outputErrorRate},
  3860. warning => $self->{warning},
  3861. critical => $self->{critical},
  3862. );
  3863. $self->add_perfdata(
  3864. label => $self->{ifDescr}.'_discards_in',
  3865. value => $self->{inputDiscardRate},
  3866. warning => $self->{warning},
  3867. critical => $self->{critical},
  3868. );
  3869. $self->add_perfdata(
  3870. label => $self->{ifDescr}.'_discards_out',
  3871. value => $self->{outputDiscardRate},
  3872. warning => $self->{warning},
  3873. critical => $self->{critical},
  3874. );
  3875. } elsif ($self->mode =~ /device::interfaces::operstatus/) {
  3876. #rfc2863
  3877. #(1) if ifAdminStatus is not down and ifOperStatus is down then a
  3878. # fault condition is presumed to exist on the interface.
  3879. #(2) if ifAdminStatus is down, then ifOperStatus will normally also
  3880. # be down (or notPresent) i.e., there is not (necessarily) a
  3881. # fault condition on the interface.
  3882. # --warning onu,anu
  3883. # Admin: admindown,admin
  3884. # Admin: --warning
  3885. # --critical admindown
  3886. # !ad+od ad+!(od*on)
  3887. # warn & warnbitfield
  3888. # if ($self->opts->critical) {
  3889. # if ($self->opts->critical =~ /^u/) {
  3890. # } elsif ($self->opts->critical =~ /^u/) {
  3891. # }
  3892. # }
  3893. # if ($self->{ifOperStatus} ne 'up') {
  3894. # }
  3895. # }
  3896. my $info = sprintf '%s is %s/%s',
  3897. $self->{ifDescr}, $self->{ifOperStatus}, $self->{ifAdminStatus};
  3898. $self->add_info($info);
  3899. $self->add_message(OK, $info);
  3900. if ($self->{ifOperStatus} eq 'down' && $self->{ifAdminStatus} ne 'down') {
  3901. $self->add_message(CRITICAL,
  3902. sprintf 'fault condition is presumed to exist on %s',
  3903. $self->{ifDescr});
  3904. }
  3905. }
  3906. }
  3907. sub list {
  3908. my $self = shift;
  3909. if ($self->mode =~ /device::interfaces::listdetail/) {
  3910. my $cL2L3IfModeOper = $self->get_snmp_object('CISCO-L2L3-INTERFACE-CONFIG-MIB', 'cL2L3IfModeOper', $self->{ifIndex}) || "unknown";
  3911. my $vlanTrunkPortDynamicStatus = $self->get_snmp_object('CISCO-VTP-MIB', 'vlanTrunkPortDynamicStatus', $self->{ifIndex}) || "unknown";
  3912. printf "%06d %s %s %s\n", $self->{ifIndex}, $self->{ifDescr},
  3913. $cL2L3IfModeOper, $vlanTrunkPortDynamicStatus;
  3914. } else {
  3915. printf "%06d %s\n", $self->{ifIndex}, $self->{ifDescr};
  3916. }
  3917. }
  3918. sub dump {
  3919. my $self = shift;
  3920. printf "[IF32_%s]\n", $self->{ifIndex};
  3921. foreach (qw(ifIndex ifDescr ifType ifMtu ifSpeed ifPhysAddress ifAdminStatus ifOperStatus ifLastChange ifInOctets ifInUcastPkts ifInNUcastPkts ifInDiscards ifInErrors ifInUnknownProtos ifOutOctets ifOutUcastPkts ifOutNUcastPkts ifOutDiscards ifOutErrors ifOutQLen ifSpecific)) {
  3922. printf "%s: %s\n", $_, defined $self->{$_} ? $self->{$_} : 'undefined';
  3923. }
  3924. # printf "info: %s\n", $self->{info};
  3925. printf "\n";
  3926. }
  3927. package NWC::IFMIB::Component::InterfaceSubsystem::Interface::64bit;
  3928. our @ISA = qw(NWC::IFMIB::Component::InterfaceSubsystem::Interface);
  3929. use strict;
  3930. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3931. sub dump {
  3932. my $self = shift;
  3933. printf "[IF64_%s]\n", $self->{ifIndex};
  3934. foreach (qw(ifIndex ifDescr ifType ifMtu ifSpeed ifPhysAddress ifAdminStatus ifOperStatus ifLastChange ifInOctets ifInUcastPkts ifInNUcastPkts ifInDiscards ifInErrors ifInUnknownProtos ifOutOctets ifOutUcastPkts ifOutNUcastPkts ifOutDiscards ifOutErrors ifOutQLen ifSpecific ifName ifInMulticastPkts ifInBroadcastPkts ifOutMulticastPkts ifOutBroadcastPkts ifHCInOctets ifHCInUcastPkts ifHCInMulticastPkts ifHCInBroadcastPkts ifHCOutOctets ifHCOutUcastPkts ifHCOutMulticastPkts ifHCOutBroadcastPkts ifLinkUpDownTrapEnable ifHighSpeed ifPromiscuousMode ifConnectorPresent ifAlias ifCounterDiscontinuityTime)) {
  3935. printf "%s: %s\n", $_, defined $self->{$_} ? $self->{$_} : 'undefined';
  3936. }
  3937. # printf "info: %s\n", $self->{info};
  3938. printf "\n";
  3939. }
  3940. package NWC::IFMIB;
  3941. use strict;
  3942. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3943. our @ISA = qw(NWC::Device);
  3944. package NWC::FCMGMT::Component::EnvironmentalSubsystem;
  3945. our @ISA = qw(NWC::FCMGMT);
  3946. use strict;
  3947. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3948. sub new {
  3949. my $class = shift;
  3950. my %params = @_;
  3951. my $self = {
  3952. runtime => $params{runtime},
  3953. rawdata => $params{rawdata},
  3954. method => $params{method},
  3955. condition => $params{condition},
  3956. status => $params{status},
  3957. sensor_subsystem => undef,
  3958. blacklisted => 0,
  3959. info => undef,
  3960. extendedinfo => undef,
  3961. };
  3962. bless $self, $class;
  3963. $self->init(%params);
  3964. return $self;
  3965. }
  3966. sub init {
  3967. my $self = shift;
  3968. my %params = @_;
  3969. $self->{sensor_subsystem} =
  3970. NWC::FCMGMT::Component::SensorSubsystem->new(%params);
  3971. }
  3972. sub check {
  3973. my $self = shift;
  3974. my $errorfound = 0;
  3975. $self->{sensor_subsystem}->check();
  3976. if (! $self->check_messages()) {
  3977. $self->add_message(OK, "environmental hardware working fine");
  3978. }
  3979. }
  3980. sub dump {
  3981. my $self = shift;
  3982. $self->{sensor_subsystem}->dump();
  3983. }
  3984. package NWC::FCMGMT::Component::SensorSubsystem;
  3985. our @ISA = qw(NWC::FCMGMT::Component::EnvironmentalSubsystem);
  3986. use strict;
  3987. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  3988. sub new {
  3989. my $class = shift;
  3990. my %params = @_;
  3991. my $self = {
  3992. sensors => [],
  3993. sensorthresholds => [],
  3994. blacklisted => 0,
  3995. info => undef,
  3996. extendedinfo => undef,
  3997. };
  3998. bless $self, $class;
  3999. $self->init(%params);
  4000. return $self;
  4001. }
  4002. sub init {
  4003. my $self = shift;
  4004. my $sensors = {};
  4005. foreach ($self->get_snmp_table_objects(
  4006. 'FCMGMT-MIB', 'fcConnUnitSensorTable')) {
  4007. $_->{fcConnUnitSensorIndex} ||= $_->{indices}->[-1];
  4008. push(@{$self->{sensors}},
  4009. NWC::FCMGMT::Component::SensorSubsystem::Sensor->new(%{$_}));
  4010. }
  4011. }
  4012. sub check {
  4013. my $self = shift;
  4014. my $errorfound = 0;
  4015. $self->add_info('checking sensors');
  4016. $self->blacklist('ses', '');
  4017. if (scalar (@{$self->{sensors}}) == 0) {
  4018. } else {
  4019. foreach (@{$self->{sensors}}) {
  4020. $_->check();
  4021. }
  4022. }
  4023. }
  4024. sub dump {
  4025. my $self = shift;
  4026. foreach (@{$self->{sensors}}) {
  4027. $_->dump();
  4028. }
  4029. }
  4030. package NWC::FCMGMT::Component::SensorSubsystem::Sensor;
  4031. our @ISA = qw(NWC::FCMGMT::Component::SensorSubsystem);
  4032. use strict;
  4033. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4034. sub new {
  4035. my $class = shift;
  4036. my %params = @_;
  4037. my $self = {
  4038. blacklisted => 0,
  4039. info => undef,
  4040. extendedinfo => undef,
  4041. };
  4042. foreach my $param (qw(fcConnUnitSensorIndex fcConnUnitSensorName
  4043. fcConnUnitSensorStatus fcConnUnitSensorStatus
  4044. fcConnUnitSensorType fcConnUnitSensorCharacteristic
  4045. fcConnUnitSensorInfo fcConnUnitSensorMessage)) {
  4046. $self->{$param} = $params{$param};
  4047. }
  4048. bless $self, $class;
  4049. return $self;
  4050. }
  4051. sub check {
  4052. my $self = shift;
  4053. $self->blacklist('se', $self->{swSensorIndex});
  4054. $self->add_info(sprintf '%s sensor %s (%s) is %s (%s)',
  4055. $self->{fcConnUnitSensorType},
  4056. $self->{fcConnUnitSensorIndex},
  4057. $self->{fcConnUnitSensorInfo},
  4058. $self->{fcConnUnitSensorStatus},
  4059. $self->{fcConnUnitSensorMessage});
  4060. if ($self->{fcConnUnitSensorStatus} ne "ok") {
  4061. $self->add_message(CRITICAL, $self->{info});
  4062. } else {
  4063. #$self->add_message(OK, $self->{info});
  4064. }
  4065. }
  4066. sub dump {
  4067. my $self = shift;
  4068. printf "[SENSOR_%s_%s]\n", $self->{fcConnUnitSensorType}, $self->{fcConnUnitSensorIndex};
  4069. foreach (qw(fcConnUnitSensorIndex fcConnUnitSensorName
  4070. fcConnUnitSensorType fcConnUnitSensorCharacteristic
  4071. fcConnUnitSensorStatus
  4072. fcConnUnitSensorInfo fcConnUnitSensorMessage)) {
  4073. printf "%s: %s\n", $_, $self->{$_};
  4074. }
  4075. printf "info: %s\n", $self->{info};
  4076. printf "\n";
  4077. }
  4078. package NWC::FCMGMT;
  4079. use strict;
  4080. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4081. our @ISA = qw(NWC::Device);
  4082. package NWC::FCEOS::Component::EnvironmentalSubsystem;
  4083. our @ISA = qw(NWC::FCEOS);
  4084. use strict;
  4085. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4086. sub new {
  4087. my $class = shift;
  4088. my %params = @_;
  4089. my $self = {
  4090. runtime => $params{runtime},
  4091. rawdata => $params{rawdata},
  4092. method => $params{method},
  4093. condition => $params{condition},
  4094. status => $params{status},
  4095. fru_subsystem => undef,
  4096. blacklisted => 0,
  4097. info => undef,
  4098. extendedinfo => undef,
  4099. };
  4100. bless $self, $class;
  4101. $self->overall_init(%params);
  4102. $self->init(%params);
  4103. return $self;
  4104. }
  4105. sub overall_init {
  4106. my $self = shift;
  4107. my %params = @_;
  4108. $self->{oper_status} = $self->get_snmp_object('FCEOS-MIB', 'fcEosSysOperStatus');
  4109. }
  4110. sub init {
  4111. my $self = shift;
  4112. my %params = @_;
  4113. $self->{fru_subsystem} =
  4114. NWC::FCEOS::Component::FruSubsystem->new(%params);
  4115. }
  4116. sub check {
  4117. my $self = shift;
  4118. my $errorfound = 0;
  4119. $self->{fru_subsystem}->check();
  4120. if (! $self->check_messages()) {
  4121. $self->add_message(OK, "environmental hardware working fine");
  4122. } else {
  4123. if ($self->{oper_status} eq "operational") {
  4124. $self->clear_messages(CRITICAL);
  4125. $self->clear_messages(WARNING);
  4126. } elsif ($self->{oper_status} eq "major-failure") {
  4127. $self->add_message(CRITICAL, "major device failure");
  4128. } else {
  4129. $self->add_message(WARNING, $self->{oper_status});
  4130. }
  4131. }
  4132. }
  4133. sub dump {
  4134. my $self = shift;
  4135. $self->{fru_subsystem}->dump();
  4136. }
  4137. package NWC::FCEOS::Component::FruSubsystem;
  4138. our @ISA = qw(NWC::FCEOS::Component::EnvironmentalSubsystem);
  4139. use strict;
  4140. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4141. sub new {
  4142. my $class = shift;
  4143. my %params = @_;
  4144. my $self = {
  4145. frus => [],
  4146. thresholds => [],
  4147. blacklisted => 0,
  4148. info => undef,
  4149. extendedinfo => undef,
  4150. };
  4151. bless $self, $class;
  4152. $self->init(%params);
  4153. return $self;
  4154. }
  4155. sub init {
  4156. my $self = shift;
  4157. my $sensors = {};
  4158. foreach ($self->get_snmp_table_objects(
  4159. 'FCEOS-MIB', 'fcEosFruTable')) {
  4160. push(@{$self->{frus}},
  4161. NWC::FCEOS::Component::FruSubsystem::Fcu->new(%{$_}));
  4162. }
  4163. }
  4164. sub check {
  4165. my $self = shift;
  4166. my $errorfound = 0;
  4167. $self->add_info('checking frus');
  4168. $self->blacklist('frus', '');
  4169. if (scalar (@{$self->{frus}}) == 0) {
  4170. } else {
  4171. foreach (@{$self->{frus}}) {
  4172. $_->check();
  4173. }
  4174. }
  4175. }
  4176. sub dump {
  4177. my $self = shift;
  4178. foreach (@{$self->{frus}}) {
  4179. $_->dump();
  4180. }
  4181. }
  4182. package NWC::FCEOS::Component::FruSubsystem::Fcu;
  4183. our @ISA = qw(NWC::FCEOS::Component::FruSubsystem);
  4184. use strict;
  4185. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4186. sub new {
  4187. my $class = shift;
  4188. my %params = @_;
  4189. my $self = {
  4190. blacklisted => 0,
  4191. info => undef,
  4192. extendedinfo => undef,
  4193. };
  4194. foreach my $param (qw(fcEosFruCode fcEosFruPosition fcEosFruStatus
  4195. fcEosFruPartNumber fcEosFruPowerOnHours)) {
  4196. $self->{$param} = $params{$param};
  4197. }
  4198. bless $self, $class;
  4199. return $self;
  4200. }
  4201. sub check {
  4202. my $self = shift;
  4203. $self->blacklist('fru', $self->{swSensorIndex});
  4204. $self->add_info(sprintf '%s fru (pos %s) is %s',
  4205. $self->{fcEosFruCode},
  4206. $self->{fcEosFruPosition},
  4207. $self->{fcEosFruStatus});
  4208. if ($self->{fcEosFruStatus} eq "failed") {
  4209. $self->add_message(CRITICAL, $self->{info});
  4210. } else {
  4211. #$self->add_message(OK, $self->{info});
  4212. }
  4213. }
  4214. sub dump {
  4215. my $self = shift;
  4216. printf "[FRU_%s]\n", $self->{fcEosFruPosition};
  4217. foreach (qw(fcEosFruCode fcEosFruPosition fcEosFruStatus
  4218. fcEosFruPartNumber fcEosFruPowerOnHours)) {
  4219. printf "%s: %s\n", $_, $self->{$_};
  4220. }
  4221. printf "info: %s\n", $self->{info};
  4222. printf "\n";
  4223. }
  4224. package NWC::FCEOS;
  4225. use strict;
  4226. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4227. our @ISA = qw(NWC::Device);
  4228. package NWC::UCDMIB::Component::MemSubsystem;
  4229. our @ISA = qw(NWC::UCDMIB);
  4230. use strict;
  4231. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4232. sub new {
  4233. my $class = shift;
  4234. my %params = @_;
  4235. my $self = {
  4236. runtime => $params{runtime},
  4237. rawdata => $params{rawdata},
  4238. mems => [],
  4239. blacklisted => 0,
  4240. info => undef,
  4241. extendedinfo => undef,
  4242. };
  4243. bless $self, $class;
  4244. $self->init(%params);
  4245. return $self;
  4246. }
  4247. sub init {
  4248. my $self = shift;
  4249. my %params = @_;
  4250. my $snmpwalk = $params{rawdata};
  4251. my $ignore_redundancy = $params{ignore_redundancy};
  4252. my $type = 0;
  4253. foreach (qw(memTotalSwap memAvailSwap memTotalReal memAvailReal memTotalFree)) {
  4254. $self->{$_} = $self->get_snmp_object('UCD-SNMP-MIB', $_, 0);
  4255. }
  4256. # https://kc.mcafee.com/corporate/index?page=content&id=KB73175
  4257. $self->{mem_usage} = ($self->{memTotalReal} - $self->{memTotalFree}) /
  4258. $self->{memTotalReal} * 100;
  4259. $self->{mem_usage} = $self->{memAvailReal} * 100 / $self->{memTotalReal};
  4260. }
  4261. sub check {
  4262. my $self = shift;
  4263. my $errorfound = 0;
  4264. $self->add_info('checking memory');
  4265. $self->blacklist('m', '');
  4266. if (defined $self->{mem_usage}) {
  4267. my $info = sprintf 'memory usage is %.2f%%',
  4268. $self->{mem_usage};
  4269. $self->add_info($info);
  4270. $self->set_thresholds(warning => 80,
  4271. critical => 90);
  4272. $self->add_message($self->check_thresholds($self->{mem_usage}), $info);
  4273. $self->add_perfdata(
  4274. label => 'memory_usage',
  4275. value => $self->{mem_usage},
  4276. uom => '%',
  4277. warning => $self->{warning},
  4278. critical => $self->{critical}
  4279. );
  4280. } else {
  4281. $self->add_message(UNKNOWN, 'cannot aquire momory usage');
  4282. }
  4283. }
  4284. sub dump {
  4285. my $self = shift;
  4286. printf "[MEMORY]\n";
  4287. foreach (qw(memTotalSwap memAvailSwap memTotalReal memAvailReal memTotalFree)) {
  4288. printf "%s: %s\n", $_, $self->{$_};
  4289. }
  4290. printf "info: %s\n", $self->{info};
  4291. printf "\n";
  4292. }
  4293. package NWC::UCDMIB::Component::CpuSubsystem;
  4294. our @ISA = qw(NWC::UCDMIB);
  4295. use strict;
  4296. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4297. sub new {
  4298. my $class = shift;
  4299. my %params = @_;
  4300. my $self = {
  4301. loads => [],
  4302. blacklisted => 0,
  4303. info => undef,
  4304. extendedinfo => undef,
  4305. };
  4306. bless $self, $class;
  4307. $self->init(%params);
  4308. return $self;
  4309. }
  4310. sub init {
  4311. my $self = shift;
  4312. my %params = @_;
  4313. my $type = 0;
  4314. foreach (qw(ssCpuUser ssCpuSystem ssCpuIdle
  4315. ssCpuRawUser ssCpuRawSystem ssCpuRawIdle ssCpuRawNice)) {
  4316. $self->{$_} = $self->get_snmp_object('UCD-SNMP-MIB', $_, 0);
  4317. }
  4318. $self->valdiff(\%params, qw(ssCpuRawUser ssCpuRawSystem ssCpuRawIdle ssCpuRawNice));
  4319. my $cpu_total = $self->{delta_ssCpuRawUser} + $self->{delta_ssCpuRawSystem} +
  4320. $self->{delta_ssCpuRawIdle} + $self->{delta_ssCpuRawNice};
  4321. if ($cpu_total == 0) {
  4322. $self->{cpu_usage} = 0;
  4323. } else {
  4324. $self->{cpu_usage} = (100 - ($self->{delta_ssCpuRawIdle} / $cpu_total) * 100);
  4325. }
  4326. }
  4327. sub check {
  4328. my $self = shift;
  4329. my $errorfound = 0;
  4330. $self->add_info('checking cpus');
  4331. $self->blacklist('c', undef);
  4332. my $info = sprintf 'cpu usage is %.2f%%', $self->{cpu_usage};
  4333. $self->add_info($info);
  4334. $self->set_thresholds(warning => 50, critical => 90);
  4335. $self->add_message($self->check_thresholds($self->{cpu_usage}), $info);
  4336. $self->add_perfdata(
  4337. label => 'cpu_usage',
  4338. value => $self->{cpu_usage},
  4339. uom => '%',
  4340. warning => $self->{warning},
  4341. critical => $self->{critical},
  4342. );
  4343. }
  4344. sub dump {
  4345. my $self = shift;
  4346. printf "[CPU]\n";
  4347. foreach (qw(ssCpuUser ssCpuSystem ssCpuIdle
  4348. ssCpuRawUser ssCpuRawSystem ssCpuRawIdle ssCpuRawNice)) {
  4349. printf "%s: %s\n", $_, $self->{$_};
  4350. }
  4351. printf "info: %s\n", $self->{info};
  4352. printf "\n";
  4353. }
  4354. sub unix_init {
  4355. my $self = shift;
  4356. my %params = @_;
  4357. my $type = 0;
  4358. foreach ($self->get_snmp_table_objects(
  4359. 'UCD-SNMP-MIB', 'laTable')) {
  4360. push(@{$self->{loads}},
  4361. NWC::UCDMIB::Component::CpuSubsystem::Load->new(%{$_}));
  4362. }
  4363. }
  4364. sub unix_check {
  4365. my $self = shift;
  4366. my $errorfound = 0;
  4367. $self->add_info('checking loads');
  4368. $self->blacklist('c', '');
  4369. foreach (@{$self->{loads}}) {
  4370. $_->check();
  4371. }
  4372. }
  4373. sub unix_dump {
  4374. my $self = shift;
  4375. foreach (@{$self->{loads}}) {
  4376. $_->dump();
  4377. }
  4378. }
  4379. package NWC::UCDMIB::Component::CpuSubsystem::Load;
  4380. our @ISA = qw(NWC::UCDMIB::Component::CpuSubsystem);
  4381. use strict;
  4382. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4383. sub new {
  4384. my $class = shift;
  4385. my %params = @_;
  4386. my $self = {
  4387. blacklisted => 0,
  4388. info => undef,
  4389. extendedinfo => undef,
  4390. };
  4391. foreach my $param (qw(laIndex laNames laLoad laConfig laLoadFloat
  4392. laErrorFlag laErrMessage)) {
  4393. $self->{$param} = $params{$param};
  4394. }
  4395. bless $self, $class;
  4396. return $self;
  4397. }
  4398. sub check {
  4399. my $self = shift;
  4400. my $errorfound = 0;
  4401. $self->blacklist('c', undef);
  4402. my $info = sprintf '%s is %.2f', lc $self->{laNames}, $self->{laLoadFloat};
  4403. $self->add_info($info);
  4404. $self->set_thresholds(warning => $self->{laConfig},
  4405. critical => $self->{laConfig});
  4406. $self->add_message($self->check_thresholds($self->{laLoadFloat}), $info);
  4407. $self->add_perfdata(
  4408. label => lc $self->{laNames},
  4409. value => $self->{laLoadFloat},
  4410. warning => $self->{warning},
  4411. critical => $self->{critical},
  4412. );
  4413. }
  4414. sub dump {
  4415. my $self = shift;
  4416. printf "[LOAD_%s]\n", lc $self->{laNames};
  4417. foreach (qw(laIndex laNames laLoad laConfig laLoadFloat
  4418. laErrorFlag laErrMessage)) {
  4419. printf "%s: %s\n", $_, $self->{$_};
  4420. }
  4421. printf "info: %s\n", $self->{info};
  4422. printf "\n";
  4423. }
  4424. package NWC::UCDMIB;
  4425. use strict;
  4426. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4427. our @ISA = qw(NWC::Device);
  4428. package NWC::F5::F5BIGIP::Component::MemSubsystem;
  4429. our @ISA = qw(NWC::F5::F5BIGIP::Component::EnvironmentalSubsystem);
  4430. use strict;
  4431. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4432. sub new {
  4433. my $class = shift;
  4434. my %params = @_;
  4435. my $self = {
  4436. mems => [],
  4437. blacklisted => 0,
  4438. info => undef,
  4439. extendedinfo => undef,
  4440. };
  4441. bless $self, $class;
  4442. $self->overall_init(%params);
  4443. return $self;
  4444. }
  4445. sub overall_init {
  4446. my $self = shift;
  4447. $self->{sysStatMemoryTotal} = $self->get_snmp_object(
  4448. 'F5-BIGIP-SYSTEM-MIB', 'sysStatMemoryTotal');
  4449. $self->{sysStatMemoryUsed} = $self->get_snmp_object(
  4450. 'F5-BIGIP-SYSTEM-MIB', 'sysStatMemoryUsed');
  4451. $self->{sysHostMemoryTotal} = $self->get_snmp_object(
  4452. 'F5-BIGIP-SYSTEM-MIB', 'sysHostMemoryTotal');
  4453. $self->{sysHostMemoryUsed} = $self->get_snmp_object(
  4454. 'F5-BIGIP-SYSTEM-MIB', 'sysHostMemoryUsed');
  4455. $self->{stat_mem_usage} = ($self->{sysStatMemoryUsed} / $self->{sysStatMemoryTotal}) * 100;
  4456. $self->{host_mem_usage} = ($self->{sysHostMemoryUsed} / $self->{sysHostMemoryTotal}) * 100;
  4457. }
  4458. sub check {
  4459. my $self = shift;
  4460. my %params = @_;
  4461. my $errorfound = 0;
  4462. $self->add_info('checking memory');
  4463. $self->blacklist('mm', '');
  4464. my $info = sprintf 'tmm memory usage is %.2f%%',
  4465. $self->{stat_mem_usage};
  4466. $self->add_info($info);
  4467. $self->set_thresholds(warning => 80, critical => 90);
  4468. $self->add_message($self->check_thresholds($self->{stat_mem_usage}), $info);
  4469. $self->add_perfdata(
  4470. label => 'tmm_usage',
  4471. value => $self->{stat_mem_usage},
  4472. uom => '%',
  4473. warning => $self->{warning},
  4474. critical => $self->{critical},
  4475. );
  4476. $info = sprintf 'host memory usage is %.2f%%',
  4477. $self->{host_mem_usage};
  4478. $self->add_info($info);
  4479. $self->set_thresholds(warning => 80, critical => 90);
  4480. $self->add_message(OK, $info);
  4481. $self->add_perfdata(
  4482. label => 'host_usage',
  4483. value => $self->{host_mem_usage},
  4484. uom => '%',
  4485. warning => $self->{warning},
  4486. critical => $self->{critical},
  4487. );
  4488. return;
  4489. }
  4490. sub dump {
  4491. my $self = shift;
  4492. foreach (@{$self->{mems}}) {
  4493. $_->dump();
  4494. }
  4495. }
  4496. package NWC::F5::F5BIGIP::Component::PowersupplySubsystem;
  4497. our @ISA = qw(NWC::F5::F5BIGIP::Component::EnvironmentalSubsystem);
  4498. use strict;
  4499. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4500. sub new {
  4501. my $class = shift;
  4502. my %params = @_;
  4503. my $self = {
  4504. powersupplies => [],
  4505. blacklisted => 0,
  4506. info => undef,
  4507. extendedinfo => undef,
  4508. };
  4509. bless $self, $class;
  4510. $self->init(%params);
  4511. return $self;
  4512. }
  4513. sub init {
  4514. my $self = shift;
  4515. foreach ($self->get_snmp_table_objects(
  4516. 'F5-BIGIP-SYSTEM-MIB', 'sysChassisPowerSupplyTable')) {
  4517. push(@{$self->{powersupplies}},
  4518. NWC::F5::F5BIGIP::Component::PowersupplySubsystem::Powersupply->new(%{$_}));
  4519. }
  4520. }
  4521. sub check {
  4522. my $self = shift;
  4523. my $errorfound = 0;
  4524. $self->add_info('checking powersupplies');
  4525. $self->blacklist('pp', '');
  4526. if (scalar (@{$self->{powersupplies}}) == 0) {
  4527. } else {
  4528. foreach (@{$self->{powersupplies}}) {
  4529. $_->check();
  4530. }
  4531. }
  4532. }
  4533. sub dump {
  4534. my $self = shift;
  4535. foreach (@{$self->{powersupplies}}) {
  4536. $_->dump();
  4537. }
  4538. }
  4539. package NWC::F5::F5BIGIP::Component::PowersupplySubsystem::Powersupply;
  4540. our @ISA = qw(NWC::F5::F5BIGIP::Component::PowersupplySubsystem);
  4541. use strict;
  4542. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4543. sub new {
  4544. my $class = shift;
  4545. my %params = @_;
  4546. my $self = {
  4547. blacklisted => 0,
  4548. info => undef,
  4549. extendedinfo => undef,
  4550. };
  4551. foreach(qw(sysChassisPowerSupplyIndex sysChassisPowerSupplyStatus)) {
  4552. $self->{$_} = $params{$_};
  4553. }
  4554. bless $self, $class;
  4555. return $self;
  4556. }
  4557. sub check {
  4558. my $self = shift;
  4559. $self->blacklist('p', $self->{sysChassisPowerSupplyIndex});
  4560. $self->add_info(sprintf 'chassis powersupply %d is %s',
  4561. $self->{sysChassisPowerSupplyIndex},
  4562. $self->{sysChassisPowerSupplyStatus});
  4563. if ($self->{sysChassisPowerSupplyStatus} eq 'notpresent') {
  4564. } else {
  4565. if ($self->{sysChassisPowerSupplyStatus} ne 'good') {
  4566. $self->add_message(CRITICAL, $self->{info});
  4567. }
  4568. }
  4569. }
  4570. sub dump {
  4571. my $self = shift;
  4572. printf "[PS_%s]\n", $self->{sysChassisPowerSupplyIndex};
  4573. foreach(qw(sysChassisPowerSupplyIndex sysChassisPowerSupplyStatus)) {
  4574. printf "%s: %s\n", $_, $self->{$_};
  4575. }
  4576. printf "info: %s\n", $self->{info};
  4577. printf "\n";
  4578. }
  4579. package NWC::F5::F5BIGIP::Component::TemperatureSubsystem;
  4580. our @ISA = qw(NWC::F5::F5BIGIP::Component::EnvironmentalSubsystem);
  4581. use strict;
  4582. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4583. sub new {
  4584. my $class = shift;
  4585. my %params = @_;
  4586. my $self = {
  4587. temperatures => [],
  4588. blacklisted => 0,
  4589. info => undef,
  4590. extendedinfo => undef,
  4591. };
  4592. bless $self, $class;
  4593. $self->init(%params);
  4594. return $self;
  4595. }
  4596. sub init {
  4597. my $self = shift;
  4598. foreach ($self->get_snmp_table_objects(
  4599. 'F5-BIGIP-SYSTEM-MIB', 'sysChassisTempTable')) {
  4600. push(@{$self->{temperatures}},
  4601. NWC::F5::F5BIGIP::Component::TemperatureSubsystem::Temperature->new(%{$_}));
  4602. }
  4603. }
  4604. sub check {
  4605. my $self = shift;
  4606. my $errorfound = 0;
  4607. $self->add_info('checking temperatures');
  4608. $self->blacklist('tt', '');
  4609. if (scalar (@{$self->{temperatures}}) == 0) {
  4610. } else {
  4611. foreach (@{$self->{temperatures}}) {
  4612. $_->check();
  4613. }
  4614. }
  4615. }
  4616. sub dump {
  4617. my $self = shift;
  4618. foreach (@{$self->{temperatures}}) {
  4619. $_->dump();
  4620. }
  4621. }
  4622. package NWC::F5::F5BIGIP::Component::TemperatureSubsystem::Temperature;
  4623. our @ISA = qw(NWC::F5::F5BIGIP::Component::TemperatureSubsystem);
  4624. use strict;
  4625. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4626. sub new {
  4627. my $class = shift;
  4628. my %params = @_;
  4629. my $self = {
  4630. blacklisted => 0,
  4631. info => undef,
  4632. extendedinfo => undef,
  4633. };
  4634. foreach(qw(sysChassisTempIndex sysChassisTempTemperature)) {
  4635. $self->{$_} = $params{$_};
  4636. }
  4637. bless $self, $class;
  4638. return $self;
  4639. }
  4640. sub check {
  4641. my $self = shift;
  4642. $self->blacklist('t', $self->{sysChassisTempIndex});
  4643. $self->add_info(sprintf 'chassis temperature %d is %sC',
  4644. $self->{sysChassisTempIndex},
  4645. $self->{sysChassisTempTemperature});
  4646. $self->add_perfdata(
  4647. label => sprintf('temp_%s', $self->{sysChassisTempIndex}),
  4648. value => $self->{sysChassisTempTemperature},
  4649. warning => undef,
  4650. critical => undef,
  4651. );
  4652. }
  4653. sub dump {
  4654. my $self = shift;
  4655. printf "[TEMP_%s]\n", $self->{sysChassisTempIndex};
  4656. foreach(qw(sysChassisTempIndex sysChassisTempTemperature)) {
  4657. printf "%s: %s\n", $_, $self->{$_};
  4658. }
  4659. printf "info: %s\n", $self->{info};
  4660. printf "\n";
  4661. }
  4662. package NWC::F5::F5BIGIP::Component::CpuSubsystem;
  4663. our @ISA = qw(NWC::F5::F5BIGIP::Component::EnvironmentalSubsystem);
  4664. use strict;
  4665. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4666. sub new {
  4667. my $class = shift;
  4668. my %params = @_;
  4669. my $self = {
  4670. cpus => [],
  4671. blacklisted => 0,
  4672. info => undef,
  4673. extendedinfo => undef,
  4674. };
  4675. bless $self, $class;
  4676. if ($self->mode =~ /load/) {
  4677. $self->overall_init(%params);
  4678. } else {
  4679. $self->init(%params);
  4680. }
  4681. return $self;
  4682. }
  4683. sub overall_init {
  4684. my $self = shift;
  4685. $self->{sysStatTmTotalCycles} = $self->get_snmp_object(
  4686. 'F5-BIGIP-SYSTEM-MIB', 'sysStatTmTotalCycles');
  4687. $self->{sysStatTmIdleCycles} = $self->get_snmp_object(
  4688. 'F5-BIGIP-SYSTEM-MIB', 'sysStatTmIdleCycles');
  4689. $self->{sysStatTmSleepCycles} = $self->get_snmp_object(
  4690. 'F5-BIGIP-SYSTEM-MIB', 'sysStatTmSleepCycles');
  4691. $self->valdiff({name => 'cpu'}, qw(sysStatTmTotalCycles sysStatTmIdleCycles sysStatTmSleepCycles ));
  4692. my $delta_used_cycles = $self->{delta_sysStatTmTotalCycles} -
  4693. ($self->{delta_sysStatTmIdleCycles} + $self->{delta_sysStatTmSleepCycles});
  4694. $self->{cpu_usage} = $self->{delta_sysStatTmTotalCycles} ?
  4695. (($delta_used_cycles / $self->{delta_sysStatTmTotalCycles}) * 100) : 0;
  4696. }
  4697. sub init {
  4698. my $self = shift;
  4699. foreach ($self->get_snmp_table_objects(
  4700. 'F5-BIGIP-SYSTEM-MIB', 'sysCpuTable')) {
  4701. push(@{$self->{cpus}},
  4702. NWC::F5::F5BIGIP::Component::CpuSubsystem::Cpu->new(%{$_}));
  4703. }
  4704. }
  4705. sub check {
  4706. my $self = shift;
  4707. my %params = @_;
  4708. my $errorfound = 0;
  4709. $self->add_info('checking cpus');
  4710. $self->blacklist('cc', '');
  4711. if ($self->mode =~ /load/) {
  4712. my $info = sprintf 'tmm cpu usage is %.2f%%',
  4713. $self->{cpu_usage};
  4714. $self->add_info($info);
  4715. $self->set_thresholds(warning => 80, critical => 90);
  4716. $self->add_message($self->check_thresholds($self->{cpu_usage}), $info);
  4717. $self->add_perfdata(
  4718. label => 'cpu_tmm_usage',
  4719. value => $self->{cpu_usage},
  4720. uom => '%',
  4721. warning => $self->{warning},
  4722. critical => $self->{critical},
  4723. );
  4724. return;
  4725. }
  4726. if (scalar (@{$self->{cpus}}) == 0) {
  4727. } else {
  4728. foreach (@{$self->{cpus}}) {
  4729. $_->check();
  4730. }
  4731. }
  4732. }
  4733. sub dump {
  4734. my $self = shift;
  4735. foreach (@{$self->{cpus}}) {
  4736. $_->dump();
  4737. }
  4738. }
  4739. package NWC::F5::F5BIGIP::Component::CpuSubsystem::Cpu;
  4740. our @ISA = qw(NWC::F5::F5BIGIP::Component::CpuSubsystem);
  4741. use strict;
  4742. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4743. sub new {
  4744. my $class = shift;
  4745. my %params = @_;
  4746. my $self = {
  4747. blacklisted => 0,
  4748. info => undef,
  4749. extendedinfo => undef,
  4750. };
  4751. foreach(qw(sysCpuIndex sysCpuTemperature sysCpuFanSpeed
  4752. sysCpuName sysCpuSlot)) {
  4753. $self->{$_} = $params{$_};
  4754. }
  4755. bless $self, $class;
  4756. return $self;
  4757. }
  4758. sub check {
  4759. my $self = shift;
  4760. $self->blacklist('c', $self->{sysCpuIndex});
  4761. $self->add_info(sprintf 'cpu %d has %dC (%drpm)',
  4762. $self->{sysCpuIndex},
  4763. $self->{sysCpuTemperature},
  4764. $self->{sysCpuFanSpeed});
  4765. $self->add_perfdata(
  4766. label => sprintf('temp_c%s', $self->{sysCpuIndex}),
  4767. value => $self->{sysCpuTemperature},
  4768. warning => undef,
  4769. critical => undef,
  4770. );
  4771. $self->add_perfdata(
  4772. label => sprintf('fan_c%s', $self->{sysCpuIndex}),
  4773. value => $self->{sysCpuFanSpeed},
  4774. warning => undef,
  4775. critical => undef,
  4776. );
  4777. }
  4778. sub dump {
  4779. my $self = shift;
  4780. printf "[CPU_%s]\n", $self->{sysCpuIndex};
  4781. foreach(qw(sysCpuIndex sysCpuTemperature sysCpuFanSpeed
  4782. sysCpuName sysCpuSlot)) {
  4783. printf "%s: %s\n", $_, $self->{$_};
  4784. }
  4785. printf "info: %s\n", $self->{info};
  4786. printf "\n";
  4787. }
  4788. package NWC::F5::F5BIGIP::Component::FanSubsystem;
  4789. our @ISA = qw(NWC::F5::F5BIGIP::Component::EnvironmentalSubsystem);
  4790. use strict;
  4791. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4792. sub new {
  4793. my $class = shift;
  4794. my %params = @_;
  4795. my $self = {
  4796. fans => [],
  4797. blacklisted => 0,
  4798. info => undef,
  4799. extendedinfo => undef,
  4800. };
  4801. bless $self, $class;
  4802. $self->init(%params);
  4803. return $self;
  4804. }
  4805. sub init {
  4806. my $self = shift;
  4807. foreach ($self->get_snmp_table_objects(
  4808. 'F5-BIGIP-SYSTEM-MIB', 'sysChassisFanTable')) {
  4809. push(@{$self->{fans}},
  4810. NWC::F5::F5BIGIP::Component::FanSubsystem::Fan->new(%{$_}));
  4811. }
  4812. }
  4813. sub check {
  4814. my $self = shift;
  4815. my $errorfound = 0;
  4816. $self->add_info('checking fans');
  4817. $self->blacklist('ff', '');
  4818. if (scalar (@{$self->{fans}}) == 0) {
  4819. } else {
  4820. foreach (@{$self->{fans}}) {
  4821. $_->check();
  4822. }
  4823. }
  4824. }
  4825. sub dump {
  4826. my $self = shift;
  4827. foreach (@{$self->{fans}}) {
  4828. $_->dump();
  4829. }
  4830. }
  4831. package NWC::F5::F5BIGIP::Component::FanSubsystem::Fan;
  4832. our @ISA = qw(NWC::F5::F5BIGIP::Component::FanSubsystem);
  4833. use strict;
  4834. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4835. sub new {
  4836. my $class = shift;
  4837. my %params = @_;
  4838. my $self = {
  4839. blacklisted => 0,
  4840. info => undef,
  4841. extendedinfo => undef,
  4842. };
  4843. foreach(qw(sysChassisFanIndex sysChassisFanStatus
  4844. sysChassisFanSpeed)) {
  4845. $self->{$_} = $params{$_};
  4846. }
  4847. bless $self, $class;
  4848. return $self;
  4849. }
  4850. sub check {
  4851. my $self = shift;
  4852. $self->blacklist('f', $self->{sysChassisFanIndex});
  4853. $self->add_info(sprintf 'chassis fan %d is %s (%drpm)',
  4854. $self->{sysChassisFanIndex},
  4855. $self->{sysChassisFanStatus},
  4856. $self->{sysChassisFanSpeed});
  4857. if ($self->{sysChassisFanStatus} eq 'notpresent') {
  4858. } else {
  4859. if ($self->{sysChassisFanStatus} ne 'good') {
  4860. $self->add_message(CRITICAL, $self->{info});
  4861. }
  4862. $self->add_perfdata(
  4863. label => sprintf('fan_%s', $self->{sysChassisFanIndex}),
  4864. value => $self->{sysChassisFanSpeed},
  4865. warning => undef,
  4866. critical => undef,
  4867. );
  4868. }
  4869. }
  4870. sub dump {
  4871. my $self = shift;
  4872. printf "[FAN_%s]\n", $self->{sysChassisFanIndex};
  4873. foreach(qw(sysChassisFanIndex sysChassisFanStatus
  4874. sysChassisFanSpeed)) {
  4875. printf "%s: %s\n", $_, $self->{$_};
  4876. }
  4877. printf "info: %s\n", $self->{info};
  4878. printf "\n";
  4879. }
  4880. package NWC::F5::F5BIGIP::Component::EnvironmentalSubsystem;
  4881. our @ISA = qw(NWC::F5::F5BIGIP);
  4882. use strict;
  4883. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4884. sub new {
  4885. my $class = shift;
  4886. my %params = @_;
  4887. my $self = {
  4888. runtime => $params{runtime},
  4889. rawdata => $params{rawdata},
  4890. method => $params{method},
  4891. condition => $params{condition},
  4892. status => $params{status},
  4893. cpu_subsystem => undef,
  4894. fan_subsystem => undef,
  4895. temperature_subsystem => undef,
  4896. powersupply_subsystem => undef,
  4897. blacklisted => 0,
  4898. info => undef,
  4899. extendedinfo => undef,
  4900. };
  4901. bless $self, $class;
  4902. $self->init(%params);
  4903. return $self;
  4904. }
  4905. sub init {
  4906. my $self = shift;
  4907. my %params = @_;
  4908. $self->{cpu_subsystem} =
  4909. NWC::F5::F5BIGIP::Component::CpuSubsystem->new(%params);
  4910. $self->{fan_subsystem} =
  4911. NWC::F5::F5BIGIP::Component::FanSubsystem->new(%params);
  4912. $self->{temperature_subsystem} =
  4913. NWC::F5::F5BIGIP::Component::TemperatureSubsystem->new(%params);
  4914. $self->{powersupply_subsystem} =
  4915. NWC::F5::F5BIGIP::Component::PowersupplySubsystem->new(%params);
  4916. }
  4917. sub check {
  4918. my $self = shift;
  4919. my $errorfound = 0;
  4920. $self->{cpu_subsystem}->check();
  4921. $self->{fan_subsystem}->check();
  4922. $self->{temperature_subsystem}->check();
  4923. $self->{powersupply_subsystem}->check();
  4924. if (! $self->check_messages()) {
  4925. $self->add_message(OK, "environmental hardware working fine");
  4926. }
  4927. }
  4928. sub dump {
  4929. my $self = shift;
  4930. $self->{cpu_subsystem}->dump();
  4931. $self->{fan_subsystem}->dump();
  4932. $self->{temperature_subsystem}->dump();
  4933. $self->{powersupply_subsystem}->dump();
  4934. }
  4935. package NWC::F5::F5BIGIP;
  4936. use strict;
  4937. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  4938. our @ISA = qw(NWC::F5);
  4939. sub init {
  4940. my $self = shift;
  4941. $self->{components} = {
  4942. powersupply_subsystem => undef,
  4943. fan_subsystem => undef,
  4944. temperature_subsystem => undef,
  4945. cpu_subsystem => undef,
  4946. memory_subsystem => undef,
  4947. disk_subsystem => undef,
  4948. environmental_subsystem => undef,
  4949. };
  4950. $self->{serial} = 'unknown';
  4951. $self->{product} = 'unknown';
  4952. $self->{romversion} = 'unknown';
  4953. # serial is 1.3.6.1.2.1.47.1.1.1.1.11.1
  4954. #$self->collect();
  4955. if (! $self->check_messages()) {
  4956. ##$self->set_serial();
  4957. if ($self->mode =~ /device::hardware::health/) {
  4958. $self->analyze_environmental_subsystem();
  4959. #$self->auto_blacklist();
  4960. $self->check_environmental_subsystem();
  4961. } elsif ($self->mode =~ /device::hardware::load/) {
  4962. $self->analyze_cpu_subsystem();
  4963. #$self->auto_blacklist();
  4964. $self->check_cpu_subsystem();
  4965. } elsif ($self->mode =~ /device::hardware::memory/) {
  4966. $self->analyze_mem_subsystem();
  4967. #$self->auto_blacklist();
  4968. $self->check_mem_subsystem();
  4969. } elsif ($self->mode =~ /device::interfaces/) {
  4970. $self->analyze_interface_subsystem();
  4971. $self->check_interface_subsystem();
  4972. } elsif ($self->mode =~ /device::shinken::interface/) {
  4973. $self->analyze_interface_subsystem();
  4974. $self->shinken_interface_subsystem();
  4975. }
  4976. }
  4977. }
  4978. sub analyze_environmental_subsystem {
  4979. my $self = shift;
  4980. $self->{components}->{environmental_subsystem} =
  4981. NWC::F5::F5BIGIP::Component::EnvironmentalSubsystem->new();
  4982. }
  4983. sub analyze_interface_subsystem {
  4984. my $self = shift;
  4985. $self->{components}->{interface_subsystem} =
  4986. NWC::IFMIB::Component::InterfaceSubsystem->new();
  4987. }
  4988. sub analyze_cpu_subsystem {
  4989. my $self = shift;
  4990. $self->{components}->{cpu_subsystem} =
  4991. NWC::F5::F5BIGIP::Component::CpuSubsystem->new();
  4992. }
  4993. sub analyze_mem_subsystem {
  4994. my $self = shift;
  4995. $self->{components}->{mem_subsystem} =
  4996. NWC::F5::F5BIGIP::Component::MemSubsystem->new();
  4997. }
  4998. sub check_environmental_subsystem {
  4999. my $self = shift;
  5000. $self->{components}->{environmental_subsystem}->check();
  5001. $self->{components}->{environmental_subsystem}->dump()
  5002. if $self->opts->verbose >= 2;
  5003. }
  5004. sub check_interface_subsystem {
  5005. my $self = shift;
  5006. $self->{components}->{interface_subsystem}->check();
  5007. $self->{components}->{interface_subsystem}->dump()
  5008. if $self->opts->verbose >= 2;
  5009. }
  5010. sub check_cpu_subsystem {
  5011. my $self = shift;
  5012. $self->{components}->{cpu_subsystem}->check();
  5013. $self->{components}->{cpu_subsystem}->dump()
  5014. if $self->opts->verbose >= 2;
  5015. }
  5016. sub check_mem_subsystem {
  5017. my $self = shift;
  5018. $self->{components}->{mem_subsystem}->check();
  5019. $self->{components}->{mem_subsystem}->dump()
  5020. if $self->opts->verbose >= 2;
  5021. }
  5022. package NWC::F5;
  5023. use strict;
  5024. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  5025. our @ISA = qw(NWC::Device);
  5026. use constant trees => (
  5027. '1.3.6.1.4.1.3375.1.2.1.1.1', # F5-3DNS-MIB
  5028. '1.3.6.1.4.1.3375', # F5-BIGIP-COMMON-MIB
  5029. '1.3.6.1.4.1.3375.2.2', # F5-BIGIP-LOCAL-MIB
  5030. '1.3.6.1.4.1.3375.2.1', # F5-BIGIP-SYSTEM-MIB
  5031. '1.3.6.1.4.1.3375.1.1.1.1', # LOAD-BAL-SYSTEM-MIB
  5032. '1.3.6.1.4.1.2021', # UCD-SNMP-MIB
  5033. );
  5034. sub init {
  5035. my $self = shift;
  5036. if ($self->{productname} =~ /Linux.*((el6.f5.x86_64)|(el5.1.0.f5app)) .*/i) {
  5037. bless $self, 'NWC::F5::F5BIGIP';
  5038. $self->debug('using NWC::F5::F5BIGIP');
  5039. }
  5040. $self->init();
  5041. }
  5042. $NWC::Device::mibs_and_oids = {
  5043. 'MIB-II' => {
  5044. sysDescr => '1.3.6.1.2.1.1.1',
  5045. sysUpTime => '1.3.6.1.2.1.1.3',
  5046. },
  5047. 'IFMIB' => {
  5048. ifTable => '1.3.6.1.2.1.2.2',
  5049. ifEntry => '1.3.6.1.2.1.2.2.1',
  5050. ifIndex => '1.3.6.1.2.1.2.2.1.1',
  5051. ifDescr => '1.3.6.1.2.1.2.2.1.2',
  5052. ifType => '1.3.6.1.2.1.2.2.1.3',
  5053. ifMtu => '1.3.6.1.2.1.2.2.1.4',
  5054. ifSpeed => '1.3.6.1.2.1.2.2.1.5',
  5055. ifPhysAddress => '1.3.6.1.2.1.2.2.1.6',
  5056. ifAdminStatus => '1.3.6.1.2.1.2.2.1.7',
  5057. ifOperStatus => '1.3.6.1.2.1.2.2.1.8',
  5058. ifLastChange => '1.3.6.1.2.1.2.2.1.9',
  5059. ifInOctets => '1.3.6.1.2.1.2.2.1.10',
  5060. ifInUcastPkts => '1.3.6.1.2.1.2.2.1.11',
  5061. ifInNUcastPkts => '1.3.6.1.2.1.2.2.1.12',
  5062. ifInDiscards => '1.3.6.1.2.1.2.2.1.13',
  5063. ifInErrors => '1.3.6.1.2.1.2.2.1.14',
  5064. ifInUnknownProtos => '1.3.6.1.2.1.2.2.1.15',
  5065. ifOutOctets => '1.3.6.1.2.1.2.2.1.16',
  5066. ifOutUcastPkts => '1.3.6.1.2.1.2.2.1.17',
  5067. ifOutNUcastPkts => '1.3.6.1.2.1.2.2.1.18',
  5068. ifOutDiscards => '1.3.6.1.2.1.2.2.1.19',
  5069. ifOutErrors => '1.3.6.1.2.1.2.2.1.20',
  5070. ifOutQLen => '1.3.6.1.2.1.2.2.1.21',
  5071. ifSpecific => '1.3.6.1.2.1.2.2.1.22',
  5072. ifAdminStatusDefinition => {
  5073. 1 => 'up',
  5074. 2 => 'down',
  5075. 3 => 'testing',
  5076. },
  5077. ifOperStatusDefinition => {
  5078. 1 => 'up',
  5079. 2 => 'down',
  5080. 3 => 'testing',
  5081. 4 => 'unknown',
  5082. 5 => 'dormant',
  5083. 6 => 'notPresent',
  5084. 7 => 'lowerLayerDown',
  5085. },
  5086. # INDEX { ifIndex }
  5087. #
  5088. ifXTable => '1.3.6.1.2.1.31.1.1',
  5089. ifXEntry => '1.3.6.1.2.1.31.1.1.1',
  5090. ifName => '1.3.6.1.2.1.31.1.1.1.1',
  5091. ifInMulticastPkts => '1.3.6.1.2.1.31.1.1.1.2',
  5092. ifInBroadcastPkts => '1.3.6.1.2.1.31.1.1.1.3',
  5093. ifOutMulticastPkts => '1.3.6.1.2.1.31.1.1.1.4',
  5094. ifOutBroadcastPkts => '1.3.6.1.2.1.31.1.1.1.5',
  5095. ifHCInOctets => '1.3.6.1.2.1.31.1.1.1.6',
  5096. ifHCInUcastPkts => '1.3.6.1.2.1.31.1.1.1.7',
  5097. ifHCInMulticastPkts => '1.3.6.1.2.1.31.1.1.1.8',
  5098. ifHCInBroadcastPkts => '1.3.6.1.2.1.31.1.1.1.9',
  5099. ifHCOutOctets => '1.3.6.1.2.1.31.1.1.1.10',
  5100. ifHCOutUcastPkts => '1.3.6.1.2.1.31.1.1.1.11',
  5101. ifHCOutMulticastPkts => '1.3.6.1.2.1.31.1.1.1.12',
  5102. ifHCOutBroadcastPkts => '1.3.6.1.2.1.31.1.1.1.13',
  5103. ifLinkUpDownTrapEnable => '1.3.6.1.2.1.31.1.1.1.14',
  5104. ifHighSpeed => '1.3.6.1.2.1.31.1.1.1.15',
  5105. ifPromiscuousMode => '1.3.6.1.2.1.31.1.1.1.16',
  5106. ifConnectorPresent => '1.3.6.1.2.1.31.1.1.1.17',
  5107. ifAlias => '1.3.6.1.2.1.31.1.1.1.18',
  5108. ifCounterDiscontinuityTime => '1.3.6.1.2.1.31.1.1.1.19',
  5109. ifLinkUpDownTrapEnableDefinition => {
  5110. 1 => 'enabled',
  5111. 2 => 'disabled',
  5112. },
  5113. # ifXEntry AUGMENTS ifEntry
  5114. #
  5115. },
  5116. 'CISCO-PROCESS-MIB' => {
  5117. cpmCPUTotalTable => '1.3.6.1.4.1.9.9.109.1.1.1',
  5118. cpmCPUTotalEntry => '1.3.6.1.4.1.9.9.109.1.1.1.1',
  5119. cpmCPUTotalIndex => '1.3.6.1.4.1.9.9.109.1.1.1.1.1',
  5120. cpmCPUTotalPhysicalIndex => '1.3.6.1.4.1.9.9.109.1.1.1.1.2',
  5121. cpmCPUTotal5sec => '1.3.6.1.4.1.9.9.109.1.1.1.1.3',
  5122. cpmCPUTotal1min => '1.3.6.1.4.1.9.9.109.1.1.1.1.4',
  5123. cpmCPUTotal5min => '1.3.6.1.4.1.9.9.109.1.1.1.1.5',
  5124. cpmCPUTotal5secRev => '1.3.6.1.4.1.9.9.109.1.1.1.1.6',
  5125. cpmCPUTotal1minRev => '1.3.6.1.4.1.9.9.109.1.1.1.1.7',
  5126. cpmCPUTotal5minRev => '1.3.6.1.4.1.9.9.109.1.1.1.1.8',
  5127. cpmCPUMonInterval => '1.3.6.1.4.1.9.9.109.1.1.1.1.9',
  5128. cpmCPUTotalMonIntervalDefinition => '1.3.6.1.4.1.9.9.109.1.1.1.1.10',
  5129. cpmCPUInterruptMonIntervalDefinition => '1.3.6.1.4.1.9.9.109.1.1.1.1.11',
  5130. # INDEX { cpmCPUTotalIndex }
  5131. },
  5132. 'CISCO-MEMORY-POOL-MIB' => {
  5133. ciscoMemoryPoolTable => '1.3.6.1.4.1.9.9.48.1.1',
  5134. ciscoMemoryPoolEntry => '1.3.6.1.4.1.9.9.48.1.1.1',
  5135. ciscoMemoryPoolType => '1.3.6.1.4.1.9.9.48.1.1.1.1',
  5136. ciscoMemoryPoolName => '1.3.6.1.4.1.9.9.48.1.1.1.2',
  5137. ciscoMemoryPoolAlternate => '1.3.6.1.4.1.9.9.48.1.1.1.3',
  5138. ciscoMemoryPoolValid => '1.3.6.1.4.1.9.9.48.1.1.1.4',
  5139. ciscoMemoryPoolUsed => '1.3.6.1.4.1.9.9.48.1.1.1.5',
  5140. ciscoMemoryPoolFree => '1.3.6.1.4.1.9.9.48.1.1.1.6',
  5141. ciscoMemoryPoolLargestFree => '1.3.6.1.4.1.9.9.48.1.1.1.7',
  5142. # INDEX { ciscoMemoryPoolType }
  5143. },
  5144. 'CISCO-ENVMON-MIB' => {
  5145. ciscoEnvMonFanStatusTable => '1.3.6.1.4.1.9.9.13.1.4',
  5146. ciscoEnvMonFanStatusEntry => '1.3.6.1.4.1.9.9.13.1.4.1',
  5147. ciscoEnvMonFanStatusIndex => '1.3.6.1.4.1.9.9.13.1.4.1.1',
  5148. ciscoEnvMonFanStatusDescr => '1.3.6.1.4.1.9.9.13.1.4.1.2',
  5149. ciscoEnvMonFanState => '1.3.6.1.4.1.9.9.13.1.4.1.3',
  5150. ciscoEnvMonFanStateDefinition => 'CISCO-ENVMON-MIB::ciscoEnvMonState',
  5151. # INDEX { ciscoEnvMonFanStatusIndex }
  5152. ciscoEnvMonSupplyStatusTable => '1.3.6.1.4.1.9.9.13.1.5',
  5153. ciscoEnvMonSupplyStatusEntry => '1.3.6.1.4.1.9.9.13.1.5.1',
  5154. ciscoEnvMonSupplyStatusIndex => '1.3.6.1.4.1.9.9.13.1.5.1.1',
  5155. ciscoEnvMonSupplyStatusDescr => '1.3.6.1.4.1.9.9.13.1.5.1.2',
  5156. ciscoEnvMonSupplyState => '1.3.6.1.4.1.9.9.13.1.5.1.3',
  5157. ciscoEnvMonSupplySource => '1.3.6.1.4.1.9.9.13.1.5.1.4',
  5158. ciscoEnvMonSupplyStateDefinition => 'CISCO-ENVMON-MIB::ciscoEnvMonState',
  5159. # INDEX { ciscoEnvMonSupplyStatusIndex }
  5160. ciscoEnvMonTemperatureStatusTable => '1.3.6.1.4.1.9.9.13.1.3',
  5161. ciscoEnvMonTemperatureStatusEntry => '1.3.6.1.4.1.9.9.13.1.3.1',
  5162. ciscoEnvMonTemperatureStatusIndex => '1.3.6.1.4.1.9.9.13.1.3.1.1',
  5163. ciscoEnvMonTemperatureStatusDescr => '1.3.6.1.4.1.9.9.13.1.3.1.2',
  5164. ciscoEnvMonTemperatureStatusValue => '1.3.6.1.4.1.9.9.13.1.3.1.3',
  5165. ciscoEnvMonTemperatureThreshold => '1.3.6.1.4.1.9.9.13.1.3.1.4',
  5166. ciscoEnvMonTemperatureLastShutdown => '1.3.6.1.4.1.9.9.13.1.3.1.5',
  5167. ciscoEnvMonTemperatureState => '1.3.6.1.4.1.9.9.13.1.3.1.6',
  5168. ciscoEnvMonTemperatureStateDefinition => 'CISCO-ENVMON-MIB::ciscoEnvMonState',
  5169. # INDEX { ciscoEnvMonTemperatureStatusIndex }
  5170. ciscoEnvMonVoltageStatusTable => '1.3.6.1.4.1.9.9.13.1.2',
  5171. ciscoEnvMonVoltageStatusEntry => '1.3.6.1.4.1.9.9.13.1.2.1',
  5172. ciscoEnvMonVoltageStatusIndex => '1.3.6.1.4.1.9.9.13.1.2.1.1',
  5173. ciscoEnvMonVoltageStatusDescr => '1.3.6.1.4.1.9.9.13.1.2.1.2',
  5174. ciscoEnvMonVoltageStatusValue => '1.3.6.1.4.1.9.9.13.1.2.1.3',
  5175. ciscoEnvMonVoltageThresholdLow => '1.3.6.1.4.1.9.9.13.1.2.1.4',
  5176. ciscoEnvMonVoltageThresholdHigh => '1.3.6.1.4.1.9.9.13.1.2.1.5',
  5177. ciscoEnvMonVoltageLastShutdown => '1.3.6.1.4.1.9.9.13.1.2.1.6',
  5178. ciscoEnvMonVoltageState => '1.3.6.1.4.1.9.9.13.1.2.1.7',
  5179. ciscoEnvMonVoltageStateDefinition => 'CISCO-ENVMON-MIB::ciscoEnvMonState',
  5180. # INDEX { ciscoEnvMonVoltageStatusIndex }
  5181. },
  5182. 'CISCO-HSRP-MIB' => {
  5183. cHsrpGrpTable => '1.3.6.1.4.1.9.9.106.1.2.1',
  5184. cHsrpGrpEntry => '1.3.6.1.4.1.9.9.106.1.2.1.1',
  5185. cHsrpGrpNumber => '1.3.6.1.4.1.9.9.106.1.2.1.1.1',
  5186. cHsrpGrpAuth => '1.3.6.1.4.1.9.9.106.1.2.1.1.2',
  5187. cHsrpGrpPriority => '1.3.6.1.4.1.9.9.106.1.2.1.1.3',
  5188. cHsrpGrpPreempt => '1.3.6.1.4.1.9.9.106.1.2.1.1.4',
  5189. cHsrpGrpPreemptDelay => '1.3.6.1.4.1.9.9.106.1.2.1.1.5',
  5190. cHsrpGrpUseConfiguredTimers => '1.3.6.1.4.1.9.9.106.1.2.1.1.6',
  5191. cHsrpGrpConfiguredHelloTime => '1.3.6.1.4.1.9.9.106.1.2.1.1.7',
  5192. cHsrpGrpConfiguredHoldTime => '1.3.6.1.4.1.9.9.106.1.2.1.1.8',
  5193. cHsrpGrpLearnedHelloTime => '1.3.6.1.4.1.9.9.106.1.2.1.1.9',
  5194. cHsrpGrpLearnedHoldTime => '1.3.6.1.4.1.9.9.106.1.2.1.1.10',
  5195. cHsrpGrpVirtualIpAddr => '1.3.6.1.4.1.9.9.106.1.2.1.1.11',
  5196. cHsrpGrpUseConfigVirtualIpAddr => '1.3.6.1.4.1.9.9.106.1.2.1.1.12',
  5197. cHsrpGrpActiveRouter => '1.3.6.1.4.1.9.9.106.1.2.1.1.13',
  5198. cHsrpGrpStandbyRouter => '1.3.6.1.4.1.9.9.106.1.2.1.1.14',
  5199. cHsrpGrpStandbyState => '1.3.6.1.4.1.9.9.106.1.2.1.1.15',
  5200. cHsrpGrpStandbyStateDefinition => 'CISCO-HSRP-MIB::HsrpState',
  5201. cHsrpGrpVirtualMacAddr => '1.3.6.1.4.1.9.9.106.1.2.1.1.16',
  5202. cHsrpGrpEntryRowStatus => '1.3.6.1.4.1.9.9.106.1.2.1.1.17',
  5203. cHsrpGrpEntryRowStatusDefinition => 'SNMPv2-TC-v1::RowStatus',
  5204. # INDEX { ifIndex, cHsrpGrpNumber }
  5205. },
  5206. 'OLD-CISCO-CPU-MIB' => {
  5207. 'avgBusy1' => '1.3.6.1.4.1.9.2.1.57.0',
  5208. 'avgBusy5' => '1.3.6.1.4.1.9.2.1.58.0',
  5209. 'busyPer' => '1.3.6.1.4.1.9.2.1.56.0',
  5210. 'idleCount' => '1.3.6.1.4.1.9.2.1.59.0',
  5211. 'idleWired' => '1.3.6.1.4.1.9.2.1.60.0',
  5212. },
  5213. 'CISCO-SYSTEM-EXT-MIB' => {
  5214. cseSysCPUUtilization => '1.3.6.1.4.1.9.9.305.1.1.1.0',
  5215. cseSysMemoryUtilization => '1.3.6.1.4.1.9.9.305.1.1.2.0',
  5216. cseSysConfLastChange => '1.3.6.1.4.1.9.9.305.1.1.3.0',
  5217. cseSysAutoSync => '1.3.6.1.4.1.9.9.305.1.1.4.0',
  5218. cseSysAutoSyncState => '1.3.6.1.4.1.9.9.305.1.1.5.0',
  5219. cseWriteErase => '1.3.6.1.4.1.9.9.305.1.1.6.0',
  5220. cseSysConsolePortStatus => '1.3.6.1.4.1.9.9.305.1.1.7.0',
  5221. cseSysTelnetServiceActivation => '1.3.6.1.4.1.9.9.305.1.1.8.0',
  5222. cseSysFIPSModeActivation => '1.3.6.1.4.1.9.9.305.1.1.9.0',
  5223. cseSysUpTime => '1.3.6.1.4.1.9.9.305.1.1.10.0',
  5224. },
  5225. 'CISCO-ENTITY-SENSOR-MIB' => {
  5226. entSensorValueTable => '1.3.6.1.4.1.9.9.91.1.1.1',
  5227. entSensorValueEntry => '1.3.6.1.4.1.9.9.91.1.1.1.1',
  5228. entSensorType => '1.3.6.1.4.1.9.9.91.1.1.1.1.1',
  5229. entSensorTypeDefinition => 'CISCO-ENTITY-SENSOR-MIB::SensorDataType',
  5230. entSensorScale => '1.3.6.1.4.1.9.9.91.1.1.1.1.2',
  5231. entSensorScaleDefinition => 'CISCO-ENTITY-SENSOR-MIB::SensorDataScale',
  5232. entSensorPrecision => '1.3.6.1.4.1.9.9.91.1.1.1.1.3',
  5233. entSensorValue => '1.3.6.1.4.1.9.9.91.1.1.1.1.4',
  5234. entSensorStatus => '1.3.6.1.4.1.9.9.91.1.1.1.1.5',
  5235. entSensorStatusDefinition => 'CISCO-ENTITY-SENSOR-MIB::SensorStatus',
  5236. entSensorValueTimeStamp => '1.3.6.1.4.1.9.9.91.1.1.1.1.6',
  5237. entSensorValueUpdateRate => '1.3.6.1.4.1.9.9.91.1.1.1.1.7',
  5238. entSensorMeasuredEntity => '1.3.6.1.4.1.9.9.91.1.1.1.1.8',
  5239. entSensorThresholdTable => '1.3.6.1.4.1.9.9.91.1.2.1',
  5240. entSensorThresholdEntry => '1.3.6.1.4.1.9.9.91.1.2.1.1',
  5241. entSensorThresholdIndex => '1.3.6.1.4.1.9.9.91.1.2.1.1.1',
  5242. entSensorThresholdSeverity => '1.3.6.1.4.1.9.9.91.1.2.1.1.2',
  5243. entSensorThresholdSeverityDefinition => 'CISCO-ENTITY-SENSOR-MIB::SensorThresholdSeverity',
  5244. entSensorThresholdRelation => '1.3.6.1.4.1.9.9.91.1.2.1.1.3',
  5245. entSensorThresholdRelationDefinition => 'CISCO-ENTITY-SENSOR-MIB::SensorThresholdRelation',
  5246. entSensorThresholdValue => '1.3.6.1.4.1.9.9.91.1.2.1.1.4',
  5247. entSensorThresholdEvaluation => '1.3.6.1.4.1.9.9.91.1.2.1.1.5',
  5248. entSensorThresholdEvaluationDefinition => 'SNMPv2-TC-v1::TruthValue',
  5249. entSensorThresholdNotificationEnable => '1.3.6.1.4.1.9.9.91.1.2.1.1.6',
  5250. entSensorThresholdNotificationEnableDefinition => 'SNMPv2-TC-v1::TruthValue',
  5251. },
  5252. 'CISCO-L2L3-INTERFACE-CONFIG-MIB' => {
  5253. cL2L3IfTable => '1.3.6.1.4.1.9.9.151.1.1.1',
  5254. cL2L3IfEntry => '1.3.6.1.4.1.9.9.151.1.1.1.1',
  5255. cL2L3IfModeAdmin => '1.3.6.1.4.1.9.9.151.1.1.1.1.1',
  5256. cL2L3IfModeAdminDefinition => 'CISCO-L2L3-INTERFACE-CONFIG-MIB::CL2L3InterfaceMode',
  5257. cL2L3IfModeOper => '1.3.6.1.4.1.9.9.151.1.1.1.1.2',
  5258. cL2L3IfModeOperDefinition => 'CISCO-L2L3-INTERFACE-CONFIG-MIB::CL2L3InterfaceMode',
  5259. },
  5260. 'CISCO-VTP-MIB' => {
  5261. vlanTrunkPortTable => '1.3.6.1.4.1.9.9.46.1.6.1',
  5262. vlanTrunkPortEntry => '1.3.6.1.4.1.9.9.46.1.6.1.1',
  5263. vlanTrunkPortIfIndex => '1.3.6.1.4.1.9.9.46.1.6.1.1.1',
  5264. vlanTrunkPortVlansPruningEligible => '1.3.6.1.4.1.9.9.46.1.6.1.1.10',
  5265. vlanTrunkPortVlansXmitJoined => '1.3.6.1.4.1.9.9.46.1.6.1.1.11',
  5266. vlanTrunkPortVlansRcvJoined => '1.3.6.1.4.1.9.9.46.1.6.1.1.12',
  5267. vlanTrunkPortDynamicState => '1.3.6.1.4.1.9.9.46.1.6.1.1.13',
  5268. vlanTrunkPortDynamicStatus => '1.3.6.1.4.1.9.9.46.1.6.1.1.14',
  5269. vlanTrunkPortDynamicStatusDefinition => {
  5270. 1 => 'trunking',
  5271. 2 => 'notTrunking',
  5272. },
  5273. vlanTrunkPortVtpEnabled => '1.3.6.1.4.1.9.9.46.1.6.1.1.15',
  5274. vlanTrunkPortEncapsulationOperType => '1.3.6.1.4.1.9.9.46.1.6.1.1.16',
  5275. vlanTrunkPortVlansEnabled2k => '1.3.6.1.4.1.9.9.46.1.6.1.1.17',
  5276. vlanTrunkPortVlansEnabled3k => '1.3.6.1.4.1.9.9.46.1.6.1.1.18',
  5277. vlanTrunkPortVlansEnabled4k => '1.3.6.1.4.1.9.9.46.1.6.1.1.19',
  5278. vlanTrunkPortManagementDomain => '1.3.6.1.4.1.9.9.46.1.6.1.1.2',
  5279. vtpVlansPruningEligible2k => '1.3.6.1.4.1.9.9.46.1.6.1.1.20',
  5280. vtpVlansPruningEligible3k => '1.3.6.1.4.1.9.9.46.1.6.1.1.21',
  5281. vtpVlansPruningEligible4k => '1.3.6.1.4.1.9.9.46.1.6.1.1.22',
  5282. vlanTrunkPortVlansXmitJoined2k => '1.3.6.1.4.1.9.9.46.1.6.1.1.23',
  5283. vlanTrunkPortVlansXmitJoined3k => '1.3.6.1.4.1.9.9.46.1.6.1.1.24',
  5284. vlanTrunkPortVlansXmitJoined4k => '1.3.6.1.4.1.9.9.46.1.6.1.1.25',
  5285. vlanTrunkPortVlansRcvJoined2k => '1.3.6.1.4.1.9.9.46.1.6.1.1.26',
  5286. vlanTrunkPortVlansRcvJoined3k => '1.3.6.1.4.1.9.9.46.1.6.1.1.27',
  5287. vlanTrunkPortVlansRcvJoined4k => '1.3.6.1.4.1.9.9.46.1.6.1.1.28',
  5288. vlanTrunkPortDot1qTunnel => '1.3.6.1.4.1.9.9.46.1.6.1.1.29',
  5289. vlanTrunkPortEncapsulationType => '1.3.6.1.4.1.9.9.46.1.6.1.1.3',
  5290. vlanTrunkPortVlansActiveFirst2k => '1.3.6.1.4.1.9.9.46.1.6.1.1.30',
  5291. vlanTrunkPortVlansActiveSecond2k => '1.3.6.1.4.1.9.9.46.1.6.1.1.31',
  5292. vlanTrunkPortVlansEnabled => '1.3.6.1.4.1.9.9.46.1.6.1.1.4',
  5293. vlanTrunkPortNativeVlan => '1.3.6.1.4.1.9.9.46.1.6.1.1.5',
  5294. vlanTrunkPortRowStatus => '1.3.6.1.4.1.9.9.46.1.6.1.1.6',
  5295. vlanTrunkPortInJoins => '1.3.6.1.4.1.9.9.46.1.6.1.1.7',
  5296. vlanTrunkPortOutJoins => '1.3.6.1.4.1.9.9.46.1.6.1.1.8',
  5297. vlanTrunkPortOldAdverts => '1.3.6.1.4.1.9.9.46.1.6.1.1.9',
  5298. },
  5299. 'SW-MIB' => {
  5300. swFirmwareVersion => '1.3.6.1.4.1.1588.2.1.1.1.1.6.0',
  5301. swSensorTable => '1.3.6.1.4.1.1588.2.1.1.1.1.22',
  5302. swSensorEntry => '1.3.6.1.4.1.1588.2.1.1.1.1.22.1',
  5303. swSensorIndex => '1.3.6.1.4.1.1588.2.1.1.1.1.22.1.1',
  5304. swSensorType => '1.3.6.1.4.1.1588.2.1.1.1.1.22.1.2',
  5305. swSensorTypeDefinition => {
  5306. 1 => 'temperature',
  5307. 2 => 'fan',
  5308. 3 => 'power-supply',
  5309. },
  5310. swSensorStatus => '1.3.6.1.4.1.1588.2.1.1.1.1.22.1.3',
  5311. swSensorStatusDefinition => {
  5312. 1 => 'unknown',
  5313. 2 => 'faulty',
  5314. 3 => 'below-min',
  5315. 4 => 'nominal',
  5316. 5 => 'above-max',
  5317. 6 => 'absent',
  5318. },
  5319. # The value, -2147483648, represents an unknown quantity
  5320. # In V2.0, the temperature sensor
  5321. # value will be in Celsius; the fan value will be in RPM
  5322. # (revoluation per minute); and the power supply sensor reading
  5323. # will be unknown.
  5324. swSensorValue => '1.3.6.1.4.1.1588.2.1.1.1.1.22.1.4',
  5325. swSensorInfo => '1.3.6.1.4.1.1588.2.1.1.1.1.22.1.5',
  5326. swFwThresholdTable => '1.3.6.1.4.1.1588.2.1.1.1.10.3',
  5327. swFwThresholdEntry => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1',
  5328. swFwThresholdIndex => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.1',
  5329. swFwStatus => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.2',
  5330. swFwName => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.3',
  5331. swFwLabel => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.4',
  5332. swFwCurVal => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.5',
  5333. swFwLastEvent => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.6',
  5334. swFwLastEventVal => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.7',
  5335. swFwLastEventTime => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.8',
  5336. swFwLastState => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.9',
  5337. swFwBehaviorType => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.10',
  5338. swFwBehaviorInt => '1.3.6.1.4.1.1588.2.1.1.1.10.3.1.11',
  5339. swCpuOrMemoryUsage => '1.3.6.1.4.1.1588.2.1.1.1.26',
  5340. swCpuUsage => '1.3.6.1.4.1.1588.2.1.1.1.26.1',
  5341. # The system's CPU usage.
  5342. swCpuNoOfRetries => '1.3.6.1.4.1.1588.2.1.1.1.26.2',
  5343. # The number of times the system should take a CPU utilization sample before sending the CPU utilization trap.
  5344. swCpuUsageLimit => '1.3.6.1.4.1.1588.2.1.1.1.26.3',
  5345. # The CPU usage limit.
  5346. swCpuPollingInterval => '1.3.6.1.4.1.1588.2.1.1.1.26.4',
  5347. # The time after which the next CPU usage value will be recorded.
  5348. swCpuAction => '1.3.6.1.4.1.1588.2.1.1.1.26.5',
  5349. # The action to be taken if the CPU usage exceeds the specified threshold limit.
  5350. swMemUsage => '1.3.6.1.4.1.1588.2.1.1.1.26.6',
  5351. # The system's memory usage.
  5352. swMemNoOfRetries => '1.3.6.1.4.1.1588.2.1.1.1.26.7',
  5353. # The number of times the system should take a memory usage sample before sending the Fabric Watch trap that indicates the current memory usage.
  5354. swMemUsageLimit => '1.3.6.1.4.1.1588.2.1.1.1.26.8',
  5355. # The memory usage limit. This OID specifies the in-between threshold value.
  5356. swMemPollingInterval => '1.3.6.1.4.1.1588.2.1.1.1.26.9',
  5357. # The time after which the next memory usage sample will be taken
  5358. swMemAction => '1.3.6.1.4.1.1588.2.1.1.1.26.10',
  5359. # The action to be taken if the memory usage exceed the specified threshold limit.
  5360. swMemUsageLimit1 => '1.3.6.1.4.1.1588.2.1.1.1.26.11',
  5361. # This OID specifies the low threshold value.
  5362. swMemUsageLimit3 => '1.3.6.1.4.1.1588.2.1.1.1.26.12',
  5363. # This OID specifies the high threshold value.
  5364. },
  5365. 'ENTITY-MIB' => {
  5366. entPhysicalTable => '1.3.6.1.2.1.47.1.1.1',
  5367. entPhysicalEntry => '1.3.6.1.2.1.47.1.1.1.1',
  5368. entPhysicalDescr => '1.3.6.1.2.1.47.1.1.1.1.2',
  5369. },
  5370. 'UCD-SNMP-MIB' => {
  5371. laTable => '1.3.6.1.4.1.2021.10',
  5372. laEntry => '1.3.6.1.4.1.2021.10.1',
  5373. laIndex => '1.3.6.1.4.1.2021.10.1.1',
  5374. laNames => '1.3.6.1.4.1.2021.10.1.2',
  5375. laLoad => '1.3.6.1.4.1.2021.10.1.3',
  5376. laConfig => '1.3.6.1.4.1.2021.10.1.4',
  5377. laLoadInt => '1.3.6.1.4.1.2021.10.1.5',
  5378. laLoadFloat => '1.3.6.1.4.1.2021.10.1.6',
  5379. laErrorFlag => '1.3.6.1.4.1.2021.10.1.100',
  5380. laErrMessage => '1.3.6.1.4.1.2021.10.1.101',
  5381. memoryGroup => '1.3.6.1.4.1.2021.4',
  5382. memIndex => '1.3.6.1.4.1.2021.4.1',
  5383. memErrorName => '1.3.6.1.4.1.2021.4.2',
  5384. memTotalSwap => '1.3.6.1.4.1.2021.4.3',
  5385. memAvailSwap => '1.3.6.1.4.1.2021.4.4',
  5386. memTotalReal => '1.3.6.1.4.1.2021.4.5',
  5387. memAvailReal => '1.3.6.1.4.1.2021.4.6',
  5388. memTotalSwapTXT => '1.3.6.1.4.1.2021.4.7',
  5389. memAvailSwapTXT => '1.3.6.1.4.1.2021.4.8',
  5390. memTotalRealTXT => '1.3.6.1.4.1.2021.4.9',
  5391. memAvailRealTXT => '1.3.6.1.4.1.2021.4.10',
  5392. memTotalFree => '1.3.6.1.4.1.2021.4.11',
  5393. memMinimumSwap => '1.3.6.1.4.1.2021.4.12',
  5394. memShared => '1.3.6.1.4.1.2021.4.13',
  5395. memBuffer => '1.3.6.1.4.1.2021.4.14',
  5396. memCached => '1.3.6.1.4.1.2021.4.15',
  5397. memSwapError => '1.3.6.1.4.1.2021.4.100',
  5398. memSwapErrorMsg => '1.3.6.1.4.1.2021.4.101',
  5399. systemStatsGroup => '1.3.6.1.4.1.2021.11',
  5400. ssIndex => '1.3.6.1.4.1.2021.11.1',
  5401. ssErrorName => '1.3.6.1.4.1.2021.11.2',
  5402. ssSwapIn => '1.3',
  5403. ssSwapOut => '1.3.6.1.4.1.2021.11.4',
  5404. ssIOSent => '1.3.6.1.4.1.2021.11.5',
  5405. ssIOReceive => '1.3.6.1.4.1.2021.11.6',
  5406. ssSysInterrupts => '1.3.6.1.4.1.2021.11.7',
  5407. ssSysContext => '1.3.6.1.4.1.2021.11.8',
  5408. ssCpuUser => '1.3.6.1.4.1.2021.11.9',
  5409. ssCpuSystem => '1.3.6.1.4.1.2021.11.10',
  5410. ssCpuIdle => '1.3.6.1.4.1.2021.11.11',
  5411. ssCpuRawUser => '1.3.6.1.4.1.2021.11.50',
  5412. ssCpuRawNice => '1.3.6.1.4.1.2021.11.51',
  5413. ssCpuRawSystem => '1.3.6.1.4.1.2021.11.52',
  5414. ssCpuRawIdle => '1.3.6.1.4.1.2021.11.53',
  5415. },
  5416. 'FCMGMT-MIB' => {
  5417. fcConnUnitTable => '1.3',
  5418. fcConnUnitEntry => '1.3.1',
  5419. fcConnUnitId => '1.3.1.1',
  5420. fcConnUnitGlobalId => '1.3.1.2',
  5421. fcConnUnitType => '1.3',
  5422. fcConnUnitNumPorts => '1.3.1.4',
  5423. fcConnUnitState => '1.3.1.5',
  5424. fcConnUnitStatus => '1.3.1.6',
  5425. fcConnUnitProduct => '1.3.1.7',
  5426. fcConnUnitSerialNo => '1.3.1.8',
  5427. fcConnUnitUpTime => '1.3.1.9',
  5428. fcConnUnitUrl => '1.3.1.10',
  5429. fcConnUnitDomainId => '1.3.1.11',
  5430. fcConnUnitProxyMaster => '1.3.1.12',
  5431. fcConnUnitPrincipal => '1.3.1.13',
  5432. fcConnUnitNumSensors => '1.3.1.14',
  5433. fcConnUnitNumRevs => '1.3.1.15',
  5434. fcConnUnitModuleId => '1.3.1.16',
  5435. fcConnUnitName => '1.3.1.17',
  5436. fcConnUnitInfo => '1.3.1.18',
  5437. fcConnUnitControl => '1.3.1.19',
  5438. fcConnUnitContact => '1.3.1.20',
  5439. fcConnUnitLocation => '1.3.1.21',
  5440. fcConnUnitEventFilter => '1.3.1.22',
  5441. fcConnUnitNumEvents => '1.3.1.23',
  5442. fcConnUnitMaxEvents => '1.3.1.24',
  5443. fcConnUnitEventCurrID => '1.3.1.25',
  5444. fcConnUnitRevsTable => '1.3.6.1.2.1.8888.1.1.4',
  5445. fcConnUnitRevsEntry => '1.3.6.1.2.1.8888.1.1.4.1',
  5446. fcConnUnitRevsIndex => '1.3.6.1.2.1.8888.1.1.4.1.1',
  5447. fcConnUnitRevsRevision => '1.3.6.1.2.1.8888.1.1.4.1.2',
  5448. fcConnUnitRevsDescription => '1.3',
  5449. fcConnUnitSensorTable => '1.3.6.1.2.1.8888.1.1.5',
  5450. fcConnUnitSensorEntry => '1.3.6.1.2.1.8888.1.1.5.1',
  5451. fcConnUnitSensorIndex => '1.3.6.1.2.1.8888.1.1.5.1.1',
  5452. fcConnUnitSensorName => '1.3.6.1.2.1.8888.1.1.5.1.2',
  5453. fcConnUnitSensorStatus => '1.3.6.1.2.1.8888.1.1.5.1.3',
  5454. fcConnUnitSensorStatusDefinition => {
  5455. 1 => 'unknown',
  5456. 2 => 'other',
  5457. 3 => 'ok',
  5458. 4 => 'warning',
  5459. 5 => 'failed',
  5460. },
  5461. fcConnUnitSensorInfo => '1.3.6.1.2.1.8888.1.1.5.1.4',
  5462. fcConnUnitSensorMessage => '1.3.6.1.2.1.8888.1.1.5.1.5',
  5463. fcConnUnitSensorType => '1.3.6.1.2.1.8888.1.1.5.1.6',
  5464. fcConnUnitSensorTypeDefinition => {
  5465. 1 => 'unknown',
  5466. 2 => 'other',
  5467. 3 => 'battery',
  5468. 4 => 'fan',
  5469. 5 => 'powerSupply',
  5470. 6 => 'transmitter',
  5471. 7 => 'enclosure',
  5472. 8 => 'board',
  5473. 9 => 'receiver',
  5474. },
  5475. fcConnUnitSensorCharacteristic => '1.3.6.1.2.1.8888.1.1.5.1.7',
  5476. fcConnUnitSensorCharacteristicDefinition => {
  5477. 1 => 'unknown',
  5478. 2 => 'other',
  5479. 3 => 'temperature',
  5480. 4 => 'pressure',
  5481. 5 => 'emf',
  5482. 6 => 'currentValue',
  5483. 7 => 'airflow',
  5484. 8 => 'frequency',
  5485. 9 => 'power',
  5486. },
  5487. fcConnUnitPortTable => '1.3.6.1.2.1.8888.1.1.6',
  5488. fcConnUnitPortEntry => '1.3.6.1.2.1.8888.1.1.6.1',
  5489. fcConnUnitPortIndex => '1.3.6.1.2.1.8888.1.1.6.1.1',
  5490. fcConnUnitPortType => '1.3.6.1.2.1.8888.1.1.6.1.2',
  5491. fcConnUnitPortFCClassCap => '1.3',
  5492. fcConnUnitPortFCClassOp => '1.3.6.1.2.1.8888.1.1.6.1.4',
  5493. fcConnUnitPortState => '1.3.6.1.2.1.8888.1.1.6.1.5',
  5494. fcConnUnitPortStatus => '1.3.6.1.2.1.8888.1.1.6.1.6',
  5495. fcConnUnitPortTransmitterType => '1.3.6.1.2.1.8888.1.1.6.1.7',
  5496. fcConnUnitPortModuleType => '1.3.6.1.2.1.8888.1.1.6.1.8',
  5497. fcConnUnitPortWwn => '1.3.6.1.2.1.8888.1.1.6.1.9',
  5498. fcConnUnitPortFCId => '1.3.6.1.2.1.8888.1.1.6.1.10',
  5499. fcConnUnitPortSerialNo => '1.3.6.1.2.1.8888.1.1.6.1.11',
  5500. fcConnUnitPortRevision => '1.3.6.1.2.1.8888.1.1.6.1.12',
  5501. fcConnUnitPortVendor => '1.3.6.1.2.1.8888.1.1.6.1.13',
  5502. fcConnUnitPortSpeed => '1.3.6.1.2.1.8888.1.1.6.1.14',
  5503. fcConnUnitPortControl => '1.3.6.1.2.1.8888.1.1.6.1.15',
  5504. fcConnUnitPortName => '1.3.6.1.2.1.8888.1.1.6.1.16',
  5505. fcConnUnitPortPhysicalNumber => '1.3.6.1.2.1.8888.1.1.6.1.17',
  5506. fcConnUnitPortProtocolCap => '1.3.6.1.2.1.8888.1.1.6.1.18',
  5507. fcConnUnitPortProtocolOp => '1.3.6.1.2.1.8888.1.1.6.1.19',
  5508. fcConnUnitPortNodeWwn => '1.3.6.1.2.1.8888.1.1.6.1.20',
  5509. fcConnUnitPortHWState => '1.3.6.1.2.1.8888.1.1.6.1.21',
  5510. fcConnUnitEventTable => '1.3.6.1.2.1.8888.1.1.7',
  5511. fcConnUnitEventEntry => '1.3.6.1.2.1.8888.1.1.7.1',
  5512. fcConnUnitEventIndex => '1.3.6.1.2.1.8888.1.1.7.1.1',
  5513. fcConnUnitREventTime => '1.3.6.1.2.1.8888.1.1.7.1.2',
  5514. fcConnUnitSEventTime => '1.3',
  5515. fcConnUnitEventSeverity => '1.3.6.1.2.1.8888.1.1.7.1.4',
  5516. fcConnUnitEventType => '1.3.6.1.2.1.8888.1.1.7.1.5',
  5517. fcConnUnitEventObject => '1.3.6.1.2.1.8888.1.1.7.1.6',
  5518. fcConnUnitEventDescr => '1.3.6.1.2.1.8888.1.1.7.1.7',
  5519. fcConnUnitLinkTable => '1.3.6.1.2.1.8888.1.1.8',
  5520. fcConnUnitLinkEntry => '1.3.6.1.2.1.8888.1.1.8.1',
  5521. fcConnUnitLinkIndex => '1.3.6.1.2.1.8888.1.1.8.1.1',
  5522. fcConnUnitLinkNodeIdX => '1.3.6.1.2.1.8888.1.1.8.1.2',
  5523. fcConnUnitLinkPortNumberX => '1.3',
  5524. fcConnUnitLinkPortWwnX => '1.3.6.1.2.1.8888.1.1.8.1.4',
  5525. fcConnUnitLinkNodeIdY => '1.3.6.1.2.1.8888.1.1.8.1.5',
  5526. fcConnUnitLinkPortNumberY => '1.3.6.1.2.1.8888.1.1.8.1.6',
  5527. fcConnUnitLinkPortWwnY => '1.3.6.1.2.1.8888.1.1.8.1.7',
  5528. fcConnUnitLinkAgentAddressY => '1.3.6.1.2.1.8888.1.1.8.1.8',
  5529. fcConnUnitLinkAgentAddressTypeY => '1.3.6.1.2.1.8888.1.1.8.1.9',
  5530. fcConnUnitLinkAgentPortY => '1.3.6.1.2.1.8888.1.1.8.1.10',
  5531. fcConnUnitLinkUnitTypeY => '1.3.6.1.2.1.8888.1.1.8.1.11',
  5532. fcConnUnitLinkConnIdY => '1.3.6.1.2.1.8888.1.1.8.1.12',
  5533. fcConnUnitPortStatTable => '1.3.1',
  5534. fcConnUnitPortStatEntry => '1.3.1.1',
  5535. fcConnUnitPortStatIndex => '1.3.1.1.1',
  5536. fcConnUnitPortStatErrs => '1.3.1.1.2',
  5537. fcConnUnitPortStatTxObjects => '1.3',
  5538. fcConnUnitPortStatRxObjects => '1.3.1.1.4',
  5539. fcConnUnitPortStatTxElements => '1.3.1.1.5',
  5540. fcConnUnitPortStatRxElements => '1.3.1.1.6',
  5541. fcConnUnitPortStatBBCreditZero => '1.3.1.1.7',
  5542. fcConnUnitPortStatInputBuffsFull => '1.3.1.1.8',
  5543. fcConnUnitPortStatFBSYFrames => '1.3.1.1.9',
  5544. fcConnUnitPortStatPBSYFrames => '1.3.1.1.10',
  5545. fcConnUnitPortStatFRJTFrames => '1.3.1.1.11',
  5546. fcConnUnitPortStatPRJTFrames => '1.3.1.1.12',
  5547. fcConnUnitPortStatC1RxFrames => '1.3.1.1.13',
  5548. fcConnUnitPortStatC1TxFrames => '1.3.1.1.14',
  5549. fcConnUnitPortStatC1FBSYFrames => '1.3.1.1.15',
  5550. fcConnUnitPortStatC1PBSYFrames => '1.3.1.1.16',
  5551. fcConnUnitPortStatC1FRJTFrames => '1.3.1.1.17',
  5552. fcConnUnitPortStatC1PRJTFrames => '1.3.1.1.18',
  5553. fcConnUnitPortStatC2RxFrames => '1.3.1.1.19',
  5554. fcConnUnitPortStatC2TxFrames => '1.3.1.1.20',
  5555. fcConnUnitPortStatC2FBSYFrames => '1.3.1.1.21',
  5556. fcConnUnitPortStatC2PBSYFrames => '1.3.1.1.22',
  5557. fcConnUnitPortStatC2FRJTFrames => '1.3.1.1.23',
  5558. fcConnUnitPortStatC2PRJTFrames => '1.3.1.1.24',
  5559. fcConnUnitPortStatC3RxFrames => '1.3.1.1.25',
  5560. fcConnUnitPortStatC3TxFrames => '1.3.1.1.26',
  5561. fcConnUnitPortStatC3Discards => '1.3.1.1.27',
  5562. fcConnUnitPortStatRxMcastObjects => '1.3.1.1.28',
  5563. fcConnUnitPortStatTxMcastObjects => '1.3.1.1.29',
  5564. fcConnUnitPortStatRxBcastObjects => '1.30',
  5565. fcConnUnitPortStatTxBcastObjects => '1.31',
  5566. fcConnUnitPortStatRxLinkResets => '1.32',
  5567. fcConnUnitPortStatTxLinkResets => '1.33',
  5568. fcConnUnitPortStatLinkResets => '1.34',
  5569. fcConnUnitPortStatRxOfflineSeqs => '1.35',
  5570. fcConnUnitPortStatTxOfflineSeqs => '1.36',
  5571. fcConnUnitPortStatOfflineSeqs => '1.37',
  5572. fcConnUnitPortStatLinkFailures => '1.38',
  5573. fcConnUnitPortStatInvalidCRC => '1.39',
  5574. fcConnUnitPortStatInvalidTxWords => '1.3.1.1.40',
  5575. fcConnUnitPortStatPSPErrs => '1.3.1.1.41',
  5576. fcConnUnitPortStatLossOfSignal => '1.3.1.1.42',
  5577. fcConnUnitPortStatLossOfSync => '1.3.1.1.43',
  5578. fcConnUnitPortStatInvOrderedSets => '1.3.1.1.44',
  5579. fcConnUnitPortStatFramesTooLong => '1.3.1.1.45',
  5580. fcConnUnitPortStatFramesTooShort => '1.3.1.1.46',
  5581. fcConnUnitPortStatAddressErrs => '1.3.1.1.47',
  5582. fcConnUnitPortStatDelimiterErrs => '1.3.1.1.48',
  5583. fcConnUnitPortStatEncodingErrs => '1.3.1.1.49',
  5584. fcConnUnitSnsMaxRows => '1.3.6.1.2.1.8888.1.1.9.0',
  5585. fcConnUnitSnsTable => '1.3.6.1.2.1.8888.1.4.1',
  5586. fcConnUnitSnsEntry => '1.3.6.1.2.1.8888.1.4.1.1',
  5587. fcConnUnitSnsPortIndex => '1.3.6.1.2.1.8888.1.4.1.1.1',
  5588. fcConnUnitSnsPortIdentifier => '1.3.6.1.2.1.8888.1.4.1.1.2',
  5589. fcConnUnitSnsPortName => '1.3',
  5590. fcConnUnitSnsNodeName => '1.3.6.1.2.1.8888.1.4.1.1.4',
  5591. fcConnUnitSnsClassOfSvc => '1.3.6.1.2.1.8888.1.4.1.1.5',
  5592. fcConnUnitSnsNodeIPAddress => '1.3.6.1.2.1.8888.1.4.1.1.6',
  5593. fcConnUnitSnsProcAssoc => '1.3.6.1.2.1.8888.1.4.1.1.7',
  5594. fcConnUnitSnsFC4Type => '1.3.6.1.2.1.8888.1.4.1.1.8',
  5595. fcConnUnitSnsPortType => '1.3.6.1.2.1.8888.1.4.1.1.9',
  5596. fcConnUnitSnsPortIPAddress => '1.3.6.1.2.1.8888.1.4.1.1.10',
  5597. fcConnUnitSnsFabricPortName => '1.3.6.1.2.1.8888.1.4.1.1.11',
  5598. fcConnUnitSnsHardAddress => '1.3.6.1.2.1.8888.1.4.1.1.12',
  5599. fcConnUnitSnsSymbolicPortName => '1.3.6.1.2.1.8888.1.4.1.1.13',
  5600. fcConnUnitSnsSymbolicNodeName => '1.3.6.1.2.1.8888.1.4.1.1.14',
  5601. },
  5602. 'FCEOS-MIB' => {
  5603. fcEosSysCurrentDate => '1.3.6.1.4.1.289.2.1.1.2.1.1.0',
  5604. fcEosSysBootDate => '1.3.6.1.4.1.289.2.1.1.2.1.2.0',
  5605. fcEosSysFirmwareVersion => '1.3.6.1.4.1.289.2.1.1.2.1.3.0',
  5606. fcEosSysTypeNum => '1.3.6.1.4.1.289.2.1.1.2.1.4.0',
  5607. fcEosSysModelNum => '1.3.6.1.4.1.289.2.1.1.2.1.5.0',
  5608. fcEosSysMfg => '1.3.6.1.4.1.289.2.1.1.2.1.6.0',
  5609. fcEosSysPlantOfMfg => '1.3.6.1.4.1.289.2.1.1.2.1.7.0',
  5610. fcEosSysEcLevel => '1.3.6.1.4.1.289.2.1.1.2.1.8.0',
  5611. fcEosSysSerialNum => '1.3.6.1.4.1.289.2.1.1.2.1.9.0',
  5612. fcEosSysOperStatus => '1.3.6.1.4.1.289.2.1.1.2.1.10.0',
  5613. fcEosSysOperStatusDefinition => {
  5614. 1 => 'operational',
  5615. 2 => 'redundant-failure',
  5616. 3 => 'minor-failure',
  5617. 4 => 'major-failure',
  5618. 5 => 'not-operational',
  5619. },
  5620. fcEosSysState => '1.3.6.1.4.1.289.2.1.1.2.1.11.0',
  5621. fcEosSysAdmStatus => '1.3.6.1.4.1.289.2.1.1.2.1.12.0',
  5622. fcEosSysConfigSpeed => '1.3.6.1.4.1.289.2.1.1.2.1.13.0',
  5623. fcEosSysOpenTrunking => '1.3.6.1.4.1.289.2.1.1.2.1.14.0',
  5624. fcEosFruTable => '1.3.6.1.4.1.289.2.1.1.2.2.1',
  5625. fcEosFruEntry => '1.3.6.1.4.1.289.2.1.1.2.2.1.1',
  5626. fcEosFruCode => '1.3.6.1.4.1.289.2.1.1.2.2.1.1.1',
  5627. fcEosFruCodeDefinition => {
  5628. 1 => 'fru-bkplane', # Backplane
  5629. 2 => 'fru-ctp', # Control Processor card
  5630. 3 => 'fru-sbar', # Serial Crossbar
  5631. 4 => 'fru-fan2', # Center fan module
  5632. 5 => 'fru-fan', # Fan module
  5633. 6 => 'fru-power', # Power supply module
  5634. 7 => 'fru-reserved', # Reserved, not used
  5635. 8 => 'fru-glsl', # Longwave, Single-Mode, LC connector, 1 Gig
  5636. 9 => 'fru-gsml', # Shortwave, Multi-Mode, LC connector, 1 Gig
  5637. 10 => 'fru-gxxl', # Mixed, LC connector, 1 Gig
  5638. 11 => 'fru-gsf1', # SFO pluggable, 1 Gig
  5639. 12 => 'fru-gsf2', # SFO pluggable, 2 Gig
  5640. 13 => 'fru-glsr', # Longwave, Single-Mode, MT-RJ connector, 1 Gig
  5641. 14 => 'fru-gsmr', # Shortwave, Multi-Mode, MT-RJ connector, 1 Gig
  5642. 15 => 'fru-gxxr', # Mixed, MT-RJ connector, 1 Gig
  5643. 16 => 'fru-fint1', # F-Port, internal, 1 Gig
  5644. },
  5645. fcEosFruPosition => '1.3.6.1.4.1.289.2.1.1.2.2.1.1.2',
  5646. fcEosFruStatus => '1.3.6.1.4.1.289.2.1.1.2.2.1.1.3',
  5647. fcEosFruStatusDefinition => {
  5648. 0 => 'unknown',
  5649. 1 => 'active',
  5650. 2 => 'backup',
  5651. 3 => 'update-busy',
  5652. 4 => 'failed',
  5653. },
  5654. fcEosFruPartNumber => '1.3.6.1.4.1.289.2.1.1.2.2.1.1.4',
  5655. fcEosFruSerialNumber => '1.3.6.1.4.1.289.2.1.1.2.2.1.1.5',
  5656. fcEosFruPowerOnHours => '1.3.6.1.4.1.289.2.1.1.2.2.1.1.6',
  5657. fcEosFruTestDate => '1.3.6.1.4.1.289.2.1.1.2.2.1.1.7',
  5658. fcEosTATable => '1.3.6.1.4.1.289.2.1.1.2.6.1',
  5659. fcEosTAEntry => '1.3.6.1.4.1.289.2.1.1.2.6.1.1',
  5660. fcEosTAIndex => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.1',
  5661. fcEosTAName => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.2',
  5662. fcEosTAState => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.3',
  5663. fcEosTAType => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.4',
  5664. fcEosTAPortType => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.5',
  5665. fcEosTAPortList => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.6',
  5666. fcEosTAInterval => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.7',
  5667. fcEosTATriggerValue => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.8',
  5668. fcEosTTADirection => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.9',
  5669. fcEosTTATriggerDuration => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.10',
  5670. fcEosCTACounter => '1.3.6.1.4.1.289.2.1.1.2.6.1.1.11',
  5671. },
  5672. 'F5-BIGIP-SYSTEM-MIB' => {
  5673. # http://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip9_2_2mgmt/BIG-IP_9_2_2nsm_guide-16-1.html
  5674. # http://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/tmos_management_guide_10_0_0/tmos_appendix_a_traps.html
  5675. # http://support.f5.com/kb/en-us/solutions/public/9000/400/sol9476.html
  5676. sysStatMemoryTotal => '1.3.6.1.4.1.3375.2.1.1.2.1.44.0',
  5677. sysStatMemoryUsed => '1.3.6.1.4.1.3375.2.1.1.2.1.45.0',
  5678. sysHostMemoryTotal => '1.3.6.1.4.1.3375.2.1.7.1.1.0',
  5679. sysHostMemoryUsed => '1.3.6.1.4.1.3375.2.1.7.1.2.0',
  5680. # http://www.midnight-visions.de/f5-bigip-und-snmp/
  5681. sysStatTmTotalCycles => '1.3.6.1.4.1.3375.2.1.1.2.1.41.0',
  5682. sysStatTmIdleCycles => '1.3.6.1.4.1.3375.2.1.1.2.1.42.0',
  5683. sysStatTmSleepCycles => '1.3.6.1.4.1.3375.2.1.1.2.1.43.0',
  5684. sysCpuNumber => '1.3.6.1.4.1.3375.2.1.3.1.1.0',
  5685. sysCpuTable => '1.3.6.1.4.1.3375.2.1.3.1.2',
  5686. sysCpuEntry => '1.3.6.1.4.1.3375.2.1.3.1.2.1',
  5687. sysCpuIndex => '1.3.6.1.4.1.3375.2.1.3.1.2.1.1',
  5688. sysCpuTemperature => '1.3.6.1.4.1.3375.2.1.3.1.2.1.2',
  5689. sysCpuFanSpeed => '1.3.6.1.4.1.3375.2.1.3.1.2.1.3',
  5690. sysCpuName => '1.3.6.1.4.1.3375.2.1.3.1.2.1.4',
  5691. sysCpuSlot => '1.3.6.1.4.1.3375.2.1.3.1.2.1.5',
  5692. sysChassisFan => '1.3.6.1.4.1.3375.2.1.3.2.1',
  5693. sysChassisFanNumber => '1.3.6.1.4.1.3375.2.1.3.2.1.1.0',
  5694. sysChassisFanTable => '1.3.6.1.4.1.3375.2.1.3.2.1.2',
  5695. sysChassisFanEntry => '1.3.6.1.4.1.3375.2.1.3.2.1.2.1',
  5696. sysChassisFanIndex => '1.3.6.1.4.1.3375.2.1.3.2.1.2.1.1',
  5697. sysChassisFanStatus => '1.3.6.1.4.1.3375.2.1.3.2.1.2.1.2',
  5698. sysChassisFanStatusDefinition => {
  5699. 0 => 'bad',
  5700. 1 => 'good',
  5701. 2 => 'notpresent',
  5702. },
  5703. sysChassisFanSpeed => '1.3.6.1.4.1.3375.2.1.3.2.1.2.1.3',
  5704. sysChassisPowerSupply => '1.3.6.1.4.1.3375.2.1.3.2.2',
  5705. sysChassisPowerSupplyNumber => '1.3.6.1.4.1.3375.2.1.3.2.2.1.0',
  5706. sysChassisPowerSupplyTable => '1.3.6.1.4.1.3375.2.1.3.2.2.2',
  5707. sysChassisPowerSupplyEntry => '1.3.6.1.4.1.3375.2.1.3.2.2.2.1',
  5708. sysChassisPowerSupplyIndex => '1.3.6.1.4.1.3375.2.1.3.2.2.2.1.1',
  5709. sysChassisPowerSupplyStatus => '1.3.6.1.4.1.3375.2.1.3.2.2.2.1.2',
  5710. sysChassisPowerSupplyStatusDefinition => {
  5711. 0 => 'bad',
  5712. 1 => 'good',
  5713. 2 => 'notpresent',
  5714. },
  5715. sysChassisTemp => '1.3.6.1.4.1.3375.2.1.3.2.3',
  5716. sysChassisTempNumber => '1.3.6.1.4.1.3375.2.1.3.2.3.1.0',
  5717. sysChassisTempTable => '1.3.6.1.4.1.3375.2.1.3.2.3.2',
  5718. sysChassisTempEntry => '1.3.6.1.4.1.3375.2.1.3.2.3.2.1',
  5719. sysChassisTempIndex => '1.3.6.1.4.1.3375.2.1.3.2.3.2.1.1',
  5720. sysChassisTempTemperature => '1.3.6.1.4.1.3375.2.1.3.2.3.2.1.2',
  5721. sysProduct => '1.3.6.1.4.1.3375.2.1.4',
  5722. sysProductName => '1.3.6.1.4.1.3375.2.1.4.1.0',
  5723. sysProductVersion => '1.3.6.1.4.1.3375.2.1.4.2.0',
  5724. sysProductBuild => '1.3.6.1.4.1.3375.2.1.4.3.0',
  5725. sysProductEdition => '1.3.6.1.4.1.3375.2.1.4.4.0',
  5726. sysProductDate => '1.3.6.1.4.1.3375.2.1.4.5.0',
  5727. sysSubMemory => '1.3.6.1.4.1.3375.2.1.5',
  5728. sysSubMemoryResetStats => '1.3.6.1.4.1.3375.2.1.5.1.0',
  5729. sysSubMemoryNumber => '1.3.6.1.4.1.3375.2.1.5.2.0',
  5730. sysSubMemoryTable => '1.3.6.1.4.1.3375.2.1.5.3',
  5731. sysSubMemoryEntry => '1.3.6.1.4.1.3375.2.1.5.3.1',
  5732. sysSubMemoryName => '1.3.6.1.4.1.3375.2.1.5.3.1.1',
  5733. sysSubMemoryAllocated => '1.3.6.1.4.1.3375.2.1.5.3.1.2',
  5734. sysSubMemoryMaxAllocated => '1.3.6.1.4.1.3375.2.1.5.3.1.3',
  5735. sysSubMemorySize => '1.3.6.1.4.1.3375.2.1.5.3.1.4',
  5736. sysSystem => '1.3.6.1.4.1.3375.2.1.6',
  5737. sysSystemName => '1.3.6.1.4.1.3375.2.1.6.1.0',
  5738. sysSystemNodeName => '1.3.6.1.4.1.3375.2.1.6.2.0',
  5739. sysSystemRelease => '1.3.6.1.4.1.3375.2.1.6.3.0',
  5740. sysSystemVersion => '1.3.6.1.4.1.3375.2.1.6.4.0',
  5741. sysSystemMachine => '1.3.6.1.4.1.3375.2.1.6.5.0',
  5742. sysSystemUptime => '1.3.6.1.4.1.3375.2.1.6.6.0',
  5743. bigipSystemGroups => '1.3.6.1.4.1.3375.2.5.2.1',
  5744. },
  5745. 'HP-ICF-CHASSIS-MIB' => {
  5746. hpicfSensorTable => '1.3.6.1.4.1.11.2.14.11.1.2.6',
  5747. hpicfSensorEntry => '1.3.6.1.4.1.11.2.14.11.1.2.6.1',
  5748. hpicfSensorIndex => '1.3.6.1.4.1.11.2.14.11.1.2.6.1.1',
  5749. hpicfSensorObjectId => '1.3.6.1.4.1.11.2.14.11.1.2.6.1.2',
  5750. hpicfSensorObjectIdDefinition => {
  5751. 1 => 'fan sensor',
  5752. 2 => 'power supply',
  5753. 3 => 'redundant power supply',
  5754. 4 => 'over-temperature sensor',
  5755. },
  5756. hpicfSensorNumber => '1.3.6.1.4.1.11.2.14.11.1.2.6.1.3',
  5757. hpicfSensorStatus => '1.3.6.1.4.1.11.2.14.11.1.2.6.1.4',
  5758. hpicfSensorStatusDefinition => {
  5759. 1 => 'unknown',
  5760. 2 => 'bad',
  5761. 3 => 'warning',
  5762. 4 => 'good',
  5763. 5 => 'notPresent',
  5764. },
  5765. hpicfSensorWarnings => '1.3.6.1.4.1.11.2.14.11.1.2.6.1.5',
  5766. hpicfSensorFailures => '1.3.6.1.4.1.11.2.14.11.1.2.6.1.6',
  5767. hpicfSensorDescr => '1.3.6.1.4.1.11.2.14.11.1.2.6.1.7',
  5768. #hpicfSensorObjectId.1 = icfFanSensor
  5769. #hpicfSensorObjectId.2 = icfPowerSupplySensor
  5770. #hpicfSensorObjectId.3 = icfPowerSupplySensor
  5771. #hpicfSensorObjectId.4 = icfTemperatureSensor
  5772. #hpicfSensorDescr.1 = Fan Sensor
  5773. #hpicfSensorDescr.2 = Power Supply Sensor
  5774. #hpicfSensorDescr.3 = Redundant Power Supply Sensor
  5775. #hpicfSensorDescr.4 = Over-temperature Sensor
  5776. },
  5777. 'OLD-STATISTICS-MIB' => {
  5778. hpSwitchCpuStat => '1.3.6.1.2.1.1.7.11.12.9.6.1.0', # "The CPU utilization in percent(%)."
  5779. },
  5780. 'STATISTICS-MIB' => {
  5781. hpSwitchCpuStat => '1.3.6.1.4.1.11.2.14.11.5.1.9.6.1.0', # "The CPU utilization in percent(%)."
  5782. },
  5783. 'OLD-NETSWITCH-MIB' => {
  5784. # hpLocalMemTotalBytes 1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.5
  5785. # hpLocalMemFreeBytes 1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.6
  5786. # hpLocalMemAllocBytes 1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.7
  5787. hpLocalMemTable => '1.3.6.1.2.1.1.7.11.12.1.2.1.1',
  5788. hpLocalMemEntry => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1',
  5789. hpLocalMemSlotIndex => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1.1',
  5790. hpLocalMemSlabCnt => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1.2',
  5791. hpLocalMemFreeSegCnt => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1.3',
  5792. hpLocalMemAllocSegCnt => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1.4',
  5793. hpLocalMemTotalBytes => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1.5',
  5794. hpLocalMemFreeBytes => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1.6',
  5795. hpLocalMemAllocBytes => '1.3.6.1.2.1.1.7.11.12.1.2.1.1.1.7',
  5796. hpGlobalMemTable => '1.3.6.1.2.1.1.7.11.12.1.2.2.1',
  5797. hpGlobalMemEntry => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1',
  5798. hpGlobalMemSlotIndex => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1.1',
  5799. hpGlobalMemSlabCnt => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1.2',
  5800. hpGlobalMemFreeSegCnt => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1.3',
  5801. hpGlobalMemAllocSegCnt => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1.4',
  5802. hpGlobalMemTotalBytes => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1.5',
  5803. hpGlobalMemFreeBytes => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1.6',
  5804. hpGlobalMemAllocBytes => '1.3.6.1.2.1.1.7.11.12.1.2.2.1.1.7',
  5805. },
  5806. 'NETSWITCH-MIB' => { #evt moderner
  5807. hpLocalMemTable => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1',
  5808. hpLocalMemEntry => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1',
  5809. hpLocalMemSlotIndex => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.1',
  5810. hpLocalMemSlabCnt => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.2',
  5811. hpLocalMemFreeSegCnt => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.3',
  5812. hpLocalMemAllocSegCnt => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.4',
  5813. hpLocalMemTotalBytes => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.5',
  5814. hpLocalMemFreeBytes => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.6',
  5815. hpLocalMemAllocBytes => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.1.1.1.7',
  5816. hpGlobalMemTable => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1',
  5817. hpGlobalMemEntry => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1',
  5818. hpGlobalMemSlotIndex => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.1',
  5819. hpGlobalMemSlabCnt => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.2',
  5820. hpGlobalMemFreeSegCnt => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.3',
  5821. hpGlobalMemAllocSegCnt => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.4',
  5822. hpGlobalMemTotalBytes => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.5',
  5823. hpGlobalMemFreeBytes => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.6',
  5824. hpGlobalMemAllocBytes => '1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.7',
  5825. },
  5826. };
  5827. $NWC::Device::definitions = {
  5828. 'CISCO-ENVMON-MIB' => {
  5829. ciscoEnvMonState => {
  5830. 1 => 'normal',
  5831. 2 => 'warning',
  5832. 3 => 'critical',
  5833. 4 => 'shutdown',
  5834. 5 => 'notPresent',
  5835. 6 => 'notFunctioning',
  5836. },
  5837. },
  5838. 'CISCO-HSRP-MIB' => {
  5839. HsrpState => {
  5840. 1 => 'initial',
  5841. 2 => 'learn',
  5842. 3 => 'listen',
  5843. 4 => 'speak',
  5844. 5 => 'standby',
  5845. 6 => 'active',
  5846. },
  5847. },
  5848. 'SNMPv2-TC-v1' => {
  5849. 'TruthValue' => {
  5850. 1 => 'true',
  5851. 2 => 'false',
  5852. },
  5853. 'RowStatus' => {
  5854. 1 => 'active',
  5855. 2 => 'notInService',
  5856. 3 => 'notReady',
  5857. 4 => 'createAndGo',
  5858. 5 => 'createAndWait',
  5859. 6 => 'destroy',
  5860. },
  5861. },
  5862. 'CISCO-ENTITY-SENSOR-MIB' => {
  5863. 'SensorDataType' => {
  5864. 1 => 'other',
  5865. 2 => 'unknown',
  5866. 3 => 'voltsAC',
  5867. 4 => 'voltsDC',
  5868. 5 => 'amperes',
  5869. 6 => 'watts',
  5870. 7 => 'hertz',
  5871. 8 => 'celsius',
  5872. 9 => 'percentRH',
  5873. 10 => 'rpm',
  5874. 11 => 'cmm',
  5875. 12 => 'truthvalue',
  5876. 13 => 'specialEnum',
  5877. 14 => 'dBm',
  5878. },
  5879. 'SensorStatus' => {
  5880. 1 => 'ok',
  5881. 2 => 'unavailable',
  5882. 3 => 'nonoperational',
  5883. },
  5884. 'SensorDataScale' => {
  5885. 1 => 'yocto',
  5886. 2 => 'zepto',
  5887. 3 => 'atto',
  5888. 4 => 'femto',
  5889. 5 => 'pico',
  5890. 6 => 'nano',
  5891. 7 => 'micro',
  5892. 8 => 'milli',
  5893. 9 => 'units',
  5894. 10 => 'kilo',
  5895. 11 => 'mega',
  5896. 12 => 'giga',
  5897. 13 => 'tera',
  5898. 14 => 'exa',
  5899. 15 => 'peta',
  5900. 16 => 'zetta',
  5901. 17 => 'yotta',
  5902. },
  5903. 'SensorThresholdSeverity' => {
  5904. 1 => 'other',
  5905. 10 => 'minor',
  5906. 20 => 'major',
  5907. 30 => 'critical',
  5908. },
  5909. 'SensorThresholdRelation' => {
  5910. 1 => 'lessThan',
  5911. 2 => 'lessOrEqual',
  5912. 3 => 'greaterThan',
  5913. 4 => 'greaterOrEqual',
  5914. 5 => 'equalTo',
  5915. 6 => 'notEqualTo',
  5916. },
  5917. },
  5918. 'CISCO-L2L3-INTERFACE-CONFIG-MIB' => {
  5919. 'CL2L3InterfaceMode' => {
  5920. 1 => 'routed',
  5921. 2 => 'switchport',
  5922. },
  5923. },
  5924. };
  5925. package NWC::Device;
  5926. use strict;
  5927. use IO::File;
  5928. use File::Basename;
  5929. use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
  5930. {
  5931. our $mode = undef;
  5932. our $plugin = undef;
  5933. our $blacklist = undef;
  5934. our $session = undef;
  5935. our $rawdata = {};
  5936. our $info = [];
  5937. our $extendedinfo = [];
  5938. our $summary = [];
  5939. our $statefilesdir = '/var/tmp/check_nwc_health';
  5940. our $oidtrace = [];
  5941. }
  5942. sub new {
  5943. my $class = shift;
  5944. my %params = @_;
  5945. my $self = {
  5946. productname => 'unknown',
  5947. };
  5948. bless $self, $class;
  5949. if (! ($self->opts->hostname || $self->opts->snmpwalk)) {
  5950. die "wie jetzt??!?!";
  5951. } else {
  5952. if ($self->opts->servertype && $self->opts->servertype eq 'linuxlocal') {
  5953. } else {
  5954. $self->check_snmp_and_model();
  5955. }
  5956. if ($self->opts->servertype) {
  5957. $self->{productname} = 'cisco' if $self->opts->servertype eq 'cisco';
  5958. $self->{productname} = 'huawei' if $self->opts->servertype eq 'huawei';
  5959. $self->{productname} = 'hp' if $self->opts->servertype eq 'hp';
  5960. $self->{productname} = 'brocade' if $self->opts->servertype eq 'brocade';
  5961. $self->{productname} = 'netscreen' if $self->opts->servertype eq 'netscreen';
  5962. $self->{productname} = 'linuxlocal' if $self->opts->servertype eq 'linuxlocal';
  5963. $self->{productname} = 'procurve' if $self->opts->servertype eq 'procurve';
  5964. }
  5965. if (! $NWC::Device::plugin->check_messages()) {
  5966. if ($self->opts->verbose && $self->opts->verbose) {
  5967. printf "I am a %s\n", $self->{productname};
  5968. }
  5969. # Brocade 4100 SilkWorm also sold as IBM 2005-B32 & EMC DS-4100
  5970. # Brocade 4900 Switch also sold as IBM 2005-B64(3) & EMC DS4900B
  5971. # Brocade M4700 (McData name Sphereon 4700) also sold as IBM 2026-432 & EMC DS-4700M
  5972. if ($self->{productname} =~ /Cisco/i) {
  5973. bless $self, 'NWC::Cisco';
  5974. $self->debug('using NWC::Cisco');
  5975. } elsif ($self->{productname} =~ /NetScreen/i) {
  5976. bless $self, 'NWC::NetScreen';
  5977. $self->debug('using NWC::NetScreen');
  5978. } elsif ($self->{productname} =~ /Nortel/i) {
  5979. bless $self, 'NWC::Nortel';
  5980. $self->debug('using NWC::Nortel');
  5981. } elsif ($self->{productname} =~ /Allied Telesyn Ethernet Switch/i) {
  5982. bless $self, 'NWC::AlliedTelesyn';
  5983. $self->debug('using NWC::AlliedTelesyn');
  5984. } elsif ($self->{productname} =~ /DS_4100/i) {
  5985. bless $self, 'NWC::Brocade';
  5986. $self->debug('using NWC::Brocade');
  5987. } elsif ($self->{productname} =~ /Connectrix DS_4900B/i) {
  5988. bless $self, 'NWC::Brocade';
  5989. $self->debug('using NWC::Brocade');
  5990. } elsif ($self->{productname} =~ /EMC\s*DS.*4700M/i) {
  5991. bless $self, 'NWC::Brocade';
  5992. $self->debug('using NWC::Brocade');
  5993. } elsif ($self->{productname} =~ /EMC\s*DS-24M2/i) {
  5994. bless $self, 'NWC::Brocade';
  5995. $self->debug('using NWC::Brocade');
  5996. } elsif ($self->{productname} =~ /Fibre Channel Switch/i) {
  5997. bless $self, 'NWC::Brocade';
  5998. $self->debug('using NWC::Brocade');
  5999. } elsif ($self->{productname} =~ /^(GS|FS)/i) {
  6000. bless $self, 'NWC::Netscreen';
  6001. $self->debug('using NWC::Netscreen');
  6002. } elsif ($self->{productname} =~ /SecureOS/i) {
  6003. bless $self, 'NWC::SecureOS';
  6004. $self->debug('using NWC::SecureOS');
  6005. } elsif ($self->{productname} =~ /Linux.*((el6.f5.x86_64)|(el5.1.0.f5app)) .*/i) {
  6006. bless $self, 'NWC::F5';
  6007. $self->debug('using NWC::F5');
  6008. } elsif ($self->{productname} =~ /Procurve/i) {
  6009. bless $self, 'NWC::HP';
  6010. $self->debug('using NWC::F5');
  6011. } elsif ($self->{productname} =~ /linuxlocal/i) {
  6012. bless $self, 'Server::Linux';
  6013. $self->debug('using Server::Linux');
  6014. } else {
  6015. $self->add_message(CRITICAL,
  6016. sprintf('unknown device%s', $self->{productname} eq 'unknown' ?
  6017. '' : '('.$self->{productname}.')'));
  6018. }
  6019. if ($self->mode =~ /device::walk/) {
  6020. if ($self->can("trees")) {
  6021. my @trees = $self->trees;
  6022. my $name = $0;
  6023. $name =~ s/.*\///g;
  6024. $name = sprintf "/tmp/snmpwalk_%s_%s", $name, $self->opts->hostname;
  6025. printf "rm -f %s\n", $name;
  6026. foreach ($self->trees) {
  6027. printf "snmpwalk -On -v%s -c %s %s %s >> %s\n",
  6028. $self->opts->protocol,
  6029. $self->opts->community,
  6030. $self->opts->hostname,
  6031. $_, $name;
  6032. }
  6033. }
  6034. exit 0;
  6035. } elsif ($self->mode =~ /device::uptime/) {
  6036. $self->{uptime} = $self->get_snmp_object('MIB-II', 'sysUpTime', 0);
  6037. if ($self->{uptime} =~ /\((\d+)\)/) {
  6038. # Timeticks: (20718727) 2 days, 9:33:07.27
  6039. $self->{uptime} = $1 / 100;
  6040. } elsif ($self->{uptime} =~ /(\d+)\s*days.*?(\d+):(\d+):(\d+)\.(\d+)/) {
  6041. # Timeticks: 2 days, 9:33:07.27
  6042. $self->{uptime} = $1 * 24 * 3600 + $2 * 3600 + $3 * 60 + $4;
  6043. } elsif ($self->{uptime} =~ /(\d+):(\d+):(\d+)\.(\d+)/) {
  6044. # Timeticks: 9:33:07.27
  6045. $self->{uptime} = $1 * 3600 + $2 * 60 + $3;
  6046. } elsif ($self->{uptime} =~ /(\d+)\s*hours.*?(\d+):(\d+)\.(\d+)/) {
  6047. # Timeticks: 3 hours, 42:17.98
  6048. $self->{uptime} = $1 * 3600 + $2 * 60 + $3;
  6049. }
  6050. $self->{uptime} /= 60;
  6051. my $info = sprintf 'device is up since %d minutes', $self->{uptime};
  6052. $self->add_info($info);
  6053. $self->set_thresholds(warning => '15:', critical => '5:');
  6054. $self->add_message($self->check_thresholds($self->{uptime}), $info);
  6055. $self->add_perfdata(
  6056. label => 'uptime',
  6057. value => $self->{uptime},
  6058. warning => $self->{warning},
  6059. critical => $self->{critical},
  6060. );
  6061. my ($code, $message) = $self->check_messages(join => ', ', join_all => ', ');
  6062. $NWC::Device::plugin->nagios_exit($code, $message);
  6063. }
  6064. $self->{method} = 'snmp';
  6065. }
  6066. }
  6067. if ($self->opts->blacklist &&
  6068. -f $self->opts->blacklist) {
  6069. $self->opts->blacklist = do {
  6070. local (@ARGV, $/) = $self->opts->blacklist; <> };
  6071. }
  6072. $NWC::Device::statefilesdir = $self->opts->statefilesdir;
  6073. return $self;
  6074. }
  6075. sub check_snmp_and_model {
  6076. # uptime pruefen
  6077. # dann whoami
  6078. my $self = shift;
  6079. if ($self->opts->snmpwalk) {
  6080. my $response = {};
  6081. if (! -f $self->opts->snmpwalk) {
  6082. $self->add_message(CRITICAL,
  6083. sprintf 'file %s not found',
  6084. $self->opts->snmpwalk);
  6085. } elsif (-x $self->opts->snmpwalk) {
  6086. my $cmd = sprintf "%s -On -v%s -c%s %s 1.3.6.1.4.1.232 2>&1",
  6087. $self->opts->snmpwalk,
  6088. $self->opts->protocol,
  6089. $self->opts->community,
  6090. $self->opts->hostname;
  6091. open(WALK, "$cmd |");
  6092. while (<WALK>) {
  6093. if (/^.*?\.(232\.[\d\.]+) = .*?: (\-*\d+)/) {
  6094. $response->{'1.3.6.1.4.1.'.$1} = $2;
  6095. } elsif (/^.*?\.(232\.[\d\.]+) = .*?: "(.*?)"/) {
  6096. $response->{'1.3.6.1.4.1.'.$1} = $2;
  6097. $response->{'1.3.6.1.4.1.'.$1} =~ s/\s+$//;
  6098. }
  6099. }
  6100. close WALK;
  6101. } else {
  6102. $self->opts->override_opt('hostname', 'walkhost');
  6103. open(MESS, $self->opts->snmpwalk);
  6104. while(<MESS>) {
  6105. # SNMPv2-SMI::enterprises.232.6.2.6.7.1.3.1.4 = INTEGER: 6
  6106. if (/^([\d\.]+) = .*?INTEGER: .*\((\-*\d+)\)/) {
  6107. # .1.3.6.1.2.1.2.2.1.8.1 = INTEGER: down(2)
  6108. $response->{$1} = $2;
  6109. } elsif (/^([\d\.]+) = .*?Opaque:.*?Float:.*?([\-\.\d]+)/) {
  6110. # .1.3.6.1.4.1.2021.10.1.6.1 = Opaque: Float: 0.938965
  6111. $response->{$1} = $2;
  6112. } elsif (/^([\d\.]+) = STRING:\s*$/) {
  6113. $response->{$1} = "";
  6114. } elsif (/^([\d\.]+) = \w+: (\-*\d+)/) {
  6115. $response->{$1} = $2;
  6116. } elsif (/^([\d\.]+) = \w+: "(.*?)"/) {
  6117. $response->{$1} = $2;
  6118. $response->{$1} =~ s/\s+$//;
  6119. } elsif (/^([\d\.]+) = \w+: (.*)/) {
  6120. $response->{$1} = $2;
  6121. $response->{$1} =~ s/\s+$//;
  6122. } elsif (/^([\d\.]+) = (\-*\d+)/) {
  6123. $response->{$1} = $2;
  6124. } elsif (/^([\d\.]+) = "(.*?)"/) {
  6125. $response->{$1} = $2;
  6126. $response->{$1} =~ s/\s+$//;
  6127. }
  6128. }
  6129. close MESS;
  6130. }
  6131. foreach my $oid (keys %$response) {
  6132. if ($oid =~ /^\./) {
  6133. my $nodot = $oid;
  6134. $nodot =~ s/^\.//g;
  6135. $response->{$nodot} = $response->{$oid};
  6136. delete $response->{$oid};
  6137. }
  6138. }
  6139. map { $response->{$_} =~ s/^\s+//; $response->{$_} =~ s/\s+$//; }
  6140. keys %$response;
  6141. #printf "%s\n", Data::Dumper::Dumper($response);
  6142. $self->set_rawdata($response);
  6143. #if (! $self->get_snmp_object('MIB-II', 'sysDescr', 0)) {
  6144. # $self->add_rawdata('1.3.6.1.2.1.1.1.0', 'Cisco');
  6145. #}
  6146. $self->whoami();
  6147. } else {
  6148. if (eval "require Net::SNMP") {
  6149. my %params = ();
  6150. my $net_snmp_version = Net::SNMP->VERSION(); # 5.002000 or 6.000000
  6151. #$params{'-translate'} = [
  6152. # -all => 0x0
  6153. #];
  6154. $params{'-timeout'} = $self->opts->timeout;
  6155. $params{'-hostname'} = $self->opts->hostname;
  6156. $params{'-version'} = $self->opts->protocol;
  6157. if ($self->opts->port) {
  6158. $params{'-port'} = $self->opts->port;
  6159. }
  6160. if ($self->opts->protocol eq '3') {
  6161. $params{'-username'} = $self->opts->username;
  6162. if ($self->opts->authpassword) {
  6163. $params{'-authpassword'} = $self->opts->authpassword;
  6164. }
  6165. if ($self->opts->authprotocol) {
  6166. $params{'-authprotocol'} = $self->opts->authprotocol;
  6167. }
  6168. if ($self->opts->privpassword) {
  6169. $params{'-privpassword'} = $self->opts->privpassword;
  6170. }
  6171. if ($self->opts->privprotocol) {
  6172. $params{'-privprotocol'} = $self->opts->privprotocol;
  6173. }
  6174. } else {
  6175. $params{'-community'} = $self->opts->community;
  6176. }
  6177. my ($session, $error) = Net::SNMP->session(%params);
  6178. if (! defined $session) {
  6179. $self->add_message(CRITICAL,
  6180. sprintf 'cannot create session object: %s', $error);
  6181. $self->debug(Data::Dumper::Dumper(\%params));
  6182. } else {
  6183. my $max_msg_size = $session->max_msg_size();
  6184. $session->max_msg_size(4 * $max_msg_size);
  6185. $NWC::Device::session = $session;
  6186. my $sysUpTime = '1.3.6.1.2.1.1.3.0';
  6187. if (my $uptime = $self->get_snmp_object('MIB-II', 'sysUpTime', 0)) {
  6188. $self->debug(sprintf 'snmp agent answered: %s', $uptime);
  6189. $self->whoami();
  6190. } else {
  6191. $self->add_message(CRITICAL,
  6192. 'could not contact snmp agent');
  6193. #$session->close;
  6194. }
  6195. }
  6196. } else {
  6197. $self->add_message(CRITICAL,
  6198. 'could not find Net::SNMP module');
  6199. }
  6200. }
  6201. }
  6202. sub whoami {
  6203. my $self = shift;
  6204. my $productname = undef;
  6205. my $sysDescr = '1.3.6.1.2.1.1.1.0';
  6206. my $dummy = '1.3.6.1.2.1.1.5.0';
  6207. if ($productname = $self->get_snmp_object('MIB-II', 'sysDescr', 0)) {
  6208. $self->{productname} = $productname;
  6209. } else {
  6210. $self->add_message(CRITICAL,
  6211. 'snmpwalk returns no product name (sysDescr)');
  6212. if (! $self->opts->snmpwalk) {
  6213. $NWC::Device::session->close;
  6214. }
  6215. }
  6216. $self->debug('whoami: '.$self->{productname});
  6217. }
  6218. sub get_snmp_object {
  6219. my $self = shift;
  6220. my $mib = shift;
  6221. my $mo = shift;
  6222. my $index = shift;
  6223. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6224. exists $NWC::Device::mibs_and_oids->{$mib}->{$mo}) {
  6225. my $oid = $NWC::Device::mibs_and_oids->{$mib}->{$mo}.
  6226. (defined $index ? '.'.$index : '');
  6227. my $response = $self->get_request(-varbindlist => [$oid]);
  6228. if (defined $response->{$oid}) {
  6229. if (my @symbols = $self->make_symbolic($mib, $response, [[$index]])) {
  6230. $response->{$oid} = $symbols[0]->{$mo};
  6231. }
  6232. }
  6233. return $response->{$oid};
  6234. }
  6235. return undef;
  6236. }
  6237. sub get_single_request_iq {
  6238. my $self = shift;
  6239. my %params = @_;
  6240. my @oids = ();
  6241. my $result = $self->get_request_iq(%params);
  6242. foreach (keys %{$result}) {
  6243. return $result->{$_};
  6244. }
  6245. return undef;
  6246. }
  6247. sub get_request_iq {
  6248. my $self = shift;
  6249. my %params = @_;
  6250. my @oids = ();
  6251. my $mib = $params{'-mib'};
  6252. foreach my $oid (@{$params{'-molist'}}) {
  6253. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6254. exists $NWC::Device::mibs_and_oids->{$mib}->{$oid}) {
  6255. push(@oids, (exists $params{'-index'}) ?
  6256. $NWC::Device::mibs_and_oids->{$mib}->{$oid}.'.'.$params{'-index'} :
  6257. $NWC::Device::mibs_and_oids->{$mib}->{$oid});
  6258. }
  6259. }
  6260. return $self->get_request(
  6261. -varbindlist => \@oids);
  6262. }
  6263. sub valid_response {
  6264. my $self = shift;
  6265. my $mib = shift;
  6266. my $oid = shift;
  6267. my $index = shift;
  6268. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6269. exists $NWC::Device::mibs_and_oids->{$mib}->{$oid}) {
  6270. # make it numerical
  6271. my $oid = $NWC::Device::mibs_and_oids->{$mib}->{$oid};
  6272. if (defined $index) {
  6273. $oid .= '.'.$index;
  6274. }
  6275. my $result = $self->get_request(
  6276. -varbindlist => [$oid]
  6277. );
  6278. if (!defined($result) ||
  6279. ! defined $result->{$oid} ||
  6280. $result->{$oid} eq 'noSuchInstance' ||
  6281. $result->{$oid} eq 'noSuchObject' ||
  6282. $result->{$oid} eq 'endOfMibView') {
  6283. return undef;
  6284. } else {
  6285. $self->add_rawdata($oid, $result->{$oid});
  6286. return $result->{$oid};
  6287. }
  6288. } else {
  6289. return undef;
  6290. }
  6291. }
  6292. sub debug {
  6293. my $self = shift;
  6294. my $format = shift;
  6295. $self->{trace} = -f "/tmp/check_nwc_health.trace" ? 1 : 0;
  6296. if ($self->opts->verbose && $self->opts->verbose > 10) {
  6297. printf("%s: ", scalar localtime);
  6298. printf($format, @_);
  6299. printf "\n";
  6300. }
  6301. if ($self->{trace}) {
  6302. my $logfh = new IO::File;
  6303. $logfh->autoflush(1);
  6304. if ($logfh->open("/tmp/check_nwc_health.trace", "a")) {
  6305. $logfh->printf("%s: ", scalar localtime);
  6306. $logfh->printf($format, @_);
  6307. $logfh->printf("\n");
  6308. $logfh->close();
  6309. }
  6310. }
  6311. }
  6312. sub blacklist {
  6313. my $self = shift;
  6314. my $type = shift;
  6315. my $name = shift;
  6316. $self->{blacklisted} = $self->is_blacklisted($type, $name);
  6317. }
  6318. sub add_blacklist {
  6319. my $self = shift;
  6320. my $list = shift;
  6321. $NWC::Device::blacklist = join('/',
  6322. (split('/', $self->opts->blacklist), $list));
  6323. }
  6324. sub is_blacklisted {
  6325. my $self = shift;
  6326. my $type = shift;
  6327. my $name = shift;
  6328. my $blacklisted = 0;
  6329. # $name =~ s/\:/-/g;
  6330. foreach my $bl_items (split(/\//, $self->opts->blacklist)) {
  6331. if ($bl_items =~ /^(\w+):([\:\d\-,]+)$/) {
  6332. my $bl_type = $1;
  6333. my $bl_names = $2;
  6334. foreach my $bl_name (split(/,/, $bl_names)) {
  6335. if ($bl_type eq $type && $bl_name eq $name) {
  6336. $blacklisted = 1;
  6337. }
  6338. }
  6339. } elsif ($bl_items =~ /^(\w+)$/) {
  6340. my $bl_type = $1;
  6341. if ($bl_type eq $type) {
  6342. $blacklisted = 1;
  6343. }
  6344. }
  6345. }
  6346. return $blacklisted;
  6347. }
  6348. sub mode {
  6349. my $self = shift;
  6350. return $NWC::Device::mode;
  6351. }
  6352. sub add_message {
  6353. my $self = shift;
  6354. my $level = shift;
  6355. my $message = shift;
  6356. $NWC::Device::plugin->add_message($level, $message)
  6357. unless $self->{blacklisted};
  6358. if (exists $self->{failed}) {
  6359. if ($level == UNKNOWN && $self->{failed} == OK) {
  6360. $self->{failed} = $level;
  6361. } elsif ($level > $self->{failed}) {
  6362. $self->{failed} = $level;
  6363. }
  6364. }
  6365. }
  6366. sub check_messages {
  6367. my $self = shift;
  6368. return $NWC::Device::plugin->check_messages(@_);
  6369. }
  6370. sub clear_messages {
  6371. my $self = shift;
  6372. return $NWC::Device::plugin->clear_messages(@_);
  6373. }
  6374. sub add_perfdata {
  6375. my $self = shift;
  6376. $NWC::Device::plugin->add_perfdata(@_);
  6377. }
  6378. sub set_thresholds {
  6379. my $self = shift;
  6380. $NWC::Device::plugin->set_thresholds(@_);
  6381. }
  6382. sub check_thresholds {
  6383. my $self = shift;
  6384. my @params = @_;
  6385. ($self->{warning}, $self->{critical}) =
  6386. $NWC::Device::plugin->get_thresholds(@params);
  6387. return $NWC::Device::plugin->check_thresholds(@params);
  6388. }
  6389. sub get_thresholds {
  6390. my $self = shift;
  6391. my @params = @_;
  6392. my @thresholds = $NWC::Device::plugin->get_thresholds(@params);
  6393. my($warning, $critical) = $NWC::Device::plugin->get_thresholds(@params);
  6394. $self->{warning} = $thresholds[0];
  6395. $self->{critical} = $thresholds[1];
  6396. return @thresholds;
  6397. }
  6398. sub has_failed {
  6399. my $self = shift;
  6400. return $self->{failed};
  6401. }
  6402. sub add_info {
  6403. my $self = shift;
  6404. my $info = shift;
  6405. $info = $self->{blacklisted} ? $info.' (blacklisted)' : $info;
  6406. $self->{info} = $info;
  6407. push(@{$NWC::Device::info}, $info);
  6408. }
  6409. sub annotate_info {
  6410. my $self = shift;
  6411. my $annotation = shift;
  6412. my $lastinfo = pop(@{$NWC::Device::info});
  6413. $lastinfo .= sprintf ' (%s)', $annotation;
  6414. push(@{$NWC::Device::info}, $lastinfo);
  6415. }
  6416. sub add_extendedinfo {
  6417. my $self = shift;
  6418. my $info = shift;
  6419. $self->{extendedinfo} = $info;
  6420. return if ! $self->opts->extendedinfo;
  6421. push(@{$NWC::Device::extendedinfo}, $info);
  6422. }
  6423. sub get_extendedinfo {
  6424. my $self = shift;
  6425. return join(' ', @{$NWC::Device::extendedinfo});
  6426. }
  6427. sub add_summary {
  6428. my $self = shift;
  6429. my $summary = shift;
  6430. push(@{$NWC::Device::summary}, $summary);
  6431. }
  6432. sub get_summary {
  6433. my $self = shift;
  6434. return join(', ', @{$NWC::Device::summary});
  6435. }
  6436. sub opts {
  6437. my $self = shift;
  6438. return $NWC::Device::plugin->opts();
  6439. }
  6440. sub set_rawdata {
  6441. my $self = shift;
  6442. $NWC::Device::rawdata = shift;
  6443. }
  6444. sub add_rawdata {
  6445. my $self = shift;
  6446. my $oid = shift;
  6447. my $value = shift;
  6448. $NWC::Device::rawdata->{$oid} = $value;
  6449. }
  6450. sub rawdata {
  6451. my $self = shift;
  6452. return $NWC::Device::rawdata;
  6453. }
  6454. sub add_oidtrace {
  6455. my $self = shift;
  6456. my $oid = shift;
  6457. $self->debug("cache: ".$oid);
  6458. push(@{$NWC::Device::oidtrace}, $oid);
  6459. }
  6460. sub get_snmp_table_attributes {
  6461. my $self = shift;
  6462. my $mib = shift;
  6463. my $table = shift;
  6464. my $indices = shift || [];
  6465. my @entries = ();
  6466. my $augmenting_table;
  6467. if ($table =~ /^(.*?)\+(.*)/) {
  6468. $table = $1;
  6469. $augmenting_table = $2;
  6470. }
  6471. my $entry = $table;
  6472. $entry =~ s/Table/Entry/g;
  6473. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6474. exists $NWC::Device::mibs_and_oids->{$mib}->{$table}) {
  6475. my $toid = $NWC::Device::mibs_and_oids->{$mib}->{$table}.'.';
  6476. my $toidlen = length($toid);
  6477. my @columns = grep {
  6478. substr($NWC::Device::mibs_and_oids->{$mib}->{$_}, 0, $toidlen) eq
  6479. $NWC::Device::mibs_and_oids->{$mib}->{$table}.'.'
  6480. } keys %{$NWC::Device::mibs_and_oids->{$mib}};
  6481. if ($augmenting_table &&
  6482. exists $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table}) {
  6483. my $toid = $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table}.'.';
  6484. my $toidlen = length($toid);
  6485. push(@columns, grep {
  6486. substr($NWC::Device::mibs_and_oids->{$mib}->{$_}, 0, $toidlen) eq
  6487. $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table}.'.'
  6488. } keys %{$NWC::Device::mibs_and_oids->{$mib}});
  6489. }
  6490. return @columns;
  6491. } else {
  6492. return ();
  6493. }
  6494. }
  6495. sub get_request {
  6496. my $self = shift;
  6497. my %params = @_;
  6498. my @notcached = ();
  6499. foreach my $oid (@{$params{'-varbindlist'}}) {
  6500. $self->add_oidtrace($oid);
  6501. if (! exists NWC::Device::rawdata->{$oid}) {
  6502. push(@notcached, $oid);
  6503. }
  6504. }
  6505. if (! $self->opts->snmpwalk && (scalar(@notcached) > 0)) {
  6506. my $result = ($NWC::Device::session->version() == 0) ?
  6507. $NWC::Device::session->get_request(
  6508. -varbindlist => \@notcached,
  6509. )
  6510. :
  6511. $NWC::Device::session->get_request( # get_bulk_request liefert next
  6512. #-nonrepeaters => scalar(@notcached),
  6513. -varbindlist => \@notcached,
  6514. );
  6515. foreach my $key (%{$result}) {
  6516. $self->add_rawdata($key, $result->{$key});
  6517. }
  6518. }
  6519. my $result = {};
  6520. map { $result->{$_} = $NWC::Device::rawdata->{$_} }
  6521. @{$params{'-varbindlist'}};
  6522. return $result;
  6523. }
  6524. # Level1
  6525. # get_snmp_table_objects('MIB-Name', 'Table-Name', 'Table-Entry', [indices])
  6526. #
  6527. # returns array of hashrefs
  6528. # evt noch ein weiterer parameter fuer ausgewaehlte oids
  6529. #
  6530. sub get_snmp_table_objects {
  6531. my $self = shift;
  6532. my $mib = shift;
  6533. my $table = shift;
  6534. my $indices = shift || [];
  6535. my @entries = ();
  6536. my $augmenting_table;
  6537. $self->debug(sprintf "get_snmp_table_objects %s %s", $mib, $table);
  6538. if ($table =~ /^(.*?)\+(.*)/) {
  6539. $table = $1;
  6540. $augmenting_table = $2;
  6541. }
  6542. my $entry = $table;
  6543. $entry =~ s/Table/Entry/g;
  6544. if (scalar(@{$indices}) == 1) {
  6545. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6546. exists $NWC::Device::mibs_and_oids->{$mib}->{$table}) {
  6547. my $toid = $NWC::Device::mibs_and_oids->{$mib}->{$table}.'.';
  6548. my $toidlen = length($toid);
  6549. my @columns = map {
  6550. $NWC::Device::mibs_and_oids->{$mib}->{$_}
  6551. } grep {
  6552. substr($NWC::Device::mibs_and_oids->{$mib}->{$_}, 0, $toidlen) eq
  6553. $NWC::Device::mibs_and_oids->{$mib}->{$table}.'.'
  6554. } keys %{$NWC::Device::mibs_and_oids->{$mib}};
  6555. if ($augmenting_table &&
  6556. exists $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table}) {
  6557. my $toid = $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table}.'.';
  6558. my $toidlen = length($toid);
  6559. push(@columns, map {
  6560. $NWC::Device::mibs_and_oids->{$mib}->{$_}
  6561. } grep {
  6562. substr($NWC::Device::mibs_and_oids->{$mib}->{$_}, 0, $toidlen) eq
  6563. $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table}.'.'
  6564. } keys %{$NWC::Device::mibs_and_oids->{$mib}});
  6565. }
  6566. my $result = $self->get_entries(
  6567. -startindex => $indices->[0]->[0],
  6568. -endindex => $indices->[0]->[0],
  6569. -columns => \@columns,
  6570. );
  6571. @entries = $self->make_symbolic($mib, $result, $indices);
  6572. }
  6573. } elsif (scalar(@{$indices}) > 1) {
  6574. # man koennte hier pruefen, ob die indices aufeinanderfolgen
  6575. # und dann get_entries statt get_table aufrufen
  6576. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6577. exists $NWC::Device::mibs_and_oids->{$mib}->{$table}) {
  6578. my $result = {};
  6579. $result = $self->get_table(
  6580. -baseoid => $NWC::Device::mibs_and_oids->{$mib}->{$table});
  6581. if ($augmenting_table &&
  6582. exists $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table}) {
  6583. my $augmented_result = $self->get_table(
  6584. -baseoid => $NWC::Device::mibs_and_oids->{$mib}->{$augmenting_table});
  6585. map { $result->{$_} = $augmented_result->{$_} }
  6586. keys %{$augmented_result};
  6587. }
  6588. # now we have numerical_oid+index => value
  6589. # needs to become symboic_oid => value
  6590. #my @indices =
  6591. # $self->get_indices($NWC::Device::mibs_and_oids->{$mib}->{$entry});
  6592. @entries = $self->make_symbolic($mib, $result, $indices);
  6593. }
  6594. } else {
  6595. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6596. exists $NWC::Device::mibs_and_oids->{$mib}->{$table}) {
  6597. $self->debug(sprintf "get_snmp_table_objects calls get_table %s",
  6598. $NWC::Device::mibs_and_oids->{$mib}->{$table});
  6599. my $result = $self->get_table(
  6600. -baseoid => $NWC::Device::mibs_and_oids->{$mib}->{$table});
  6601. $self->debug(sprintf "get_snmp_table_objects get_table returns %d oids",
  6602. scalar(keys %{$result}));
  6603. # now we have numerical_oid+index => value
  6604. # needs to become symboic_oid => value
  6605. my @indices =
  6606. $self->get_indices(
  6607. -baseoid => $NWC::Device::mibs_and_oids->{$mib}->{$entry},
  6608. -oids => [keys %{$result}]);
  6609. $self->debug(sprintf "get_snmp_table_objects get_table returns %d indices",
  6610. scalar(@indices));
  6611. @entries = $self->make_symbolic($mib, $result, \@indices);
  6612. @entries = map { $_->{indices} = shift @indices; $_ } @entries;
  6613. }
  6614. }
  6615. return @entries;
  6616. }
  6617. # make_symbolic
  6618. # mib is the name of a mib (must be in mibs_and_oids)
  6619. # result is a hash-key oid->value
  6620. # indices is a array ref of array refs. [[1],[2],...] or [[1,0],[1,1],[2,0]..
  6621. sub make_symbolic {
  6622. my $self = shift;
  6623. my $mib = shift;
  6624. my $result = shift;
  6625. my $indices = shift;
  6626. my @entries = ();
  6627. foreach my $index (@{$indices}) {
  6628. # skip [], [[]], [[undef]]
  6629. if (ref($index) eq "ARRAY") {
  6630. if (scalar(@{$index}) == 0) {
  6631. next;
  6632. } elsif (!defined $index->[0]) {
  6633. next;
  6634. }
  6635. }
  6636. my $mo = {};
  6637. my $idx = join('.', @{$index}); # index can be multi-level
  6638. foreach my $symoid
  6639. (keys %{$NWC::Device::mibs_and_oids->{$mib}}) {
  6640. my $oid = $NWC::Device::mibs_and_oids->{$mib}->{$symoid};
  6641. if (ref($oid) ne 'HASH') {
  6642. my $fulloid = $oid . '.'.$idx;
  6643. if (exists $result->{$fulloid}) {
  6644. if (exists $NWC::Device::mibs_and_oids->{$mib}->{$symoid.'Definition'}) {
  6645. if (ref($NWC::Device::mibs_and_oids->{$mib}->{$symoid.'Definition'}) eq 'HASH') {
  6646. if (exists $NWC::Device::mibs_and_oids->{$mib}->{$symoid.'Definition'}->{$result->{$fulloid}}) {
  6647. $mo->{$symoid} = $NWC::Device::mibs_and_oids->{$mib}->{$symoid.'Definition'}->{$result->{$fulloid}};
  6648. } else {
  6649. $mo->{$symoid} = 'unknown_'.$result->{$fulloid};
  6650. }
  6651. } elsif ($NWC::Device::mibs_and_oids->{$mib}->{$symoid.'Definition'} =~ /^(.*?)::(.*)/) {
  6652. my $mib = $1;
  6653. my $definition = $2;
  6654. if (exists $NWC::Device::definitions->{$mib} && exists $NWC::Device::definitions->{$mib}->{$definition}
  6655. && exists $NWC::Device::definitions->{$mib}->{$definition}->{$result->{$fulloid}}) {
  6656. $mo->{$symoid} = $NWC::Device::definitions->{$mib}->{$definition}->{$result->{$fulloid}};
  6657. } else {
  6658. $mo->{$symoid} = 'unknown_'.$result->{$fulloid};
  6659. }
  6660. } else {
  6661. $mo->{$symoid} = 'unknown_'.$result->{$fulloid};
  6662. # oder $NWC::Device::mibs_and_oids->{$mib}->{$symoid.'Definition'}?
  6663. }
  6664. } else {
  6665. $mo->{$symoid} = $result->{$fulloid};
  6666. }
  6667. }
  6668. }
  6669. }
  6670. push(@entries, $mo);
  6671. }
  6672. return @entries;
  6673. }
  6674. # Level2
  6675. # - get_table from Net::SNMP
  6676. # - get all baseoid-matching oids from rawdata
  6677. sub get_table {
  6678. my $self = shift;
  6679. my %params = @_;
  6680. $self->add_oidtrace($params{'-baseoid'});
  6681. if (! $self->opts->snmpwalk) {
  6682. my @notcached = ();
  6683. $self->debug(sprintf "get_table %s", Data::Dumper::Dumper(\%params));
  6684. my $result = $NWC::Device::session->get_table(%params);
  6685. $self->debug(sprintf "get_table returned %d oids", scalar(keys %{$result}));
  6686. if (scalar(keys %{$result}) == 0) {
  6687. $self->debug(sprintf "get_table error: %s",
  6688. $NWC::Device::session->error());
  6689. $self->debug("get_table error: try fallback");
  6690. $params{'-maxrepetitions'} = 1;
  6691. $self->debug(sprintf "get_table %s", Data::Dumper::Dumper(\%params));
  6692. $result = $NWC::Device::session->get_table(%params);
  6693. $self->debug(sprintf "get_table returned %d oids", scalar(keys %{$result}));
  6694. if (scalar(keys %{$result}) == 0) {
  6695. $self->debug(sprintf "get_table error: %s",
  6696. $NWC::Device::session->error());
  6697. $self->debug("get_table error: no more fallbacks. Try --protocol 1");
  6698. }
  6699. }
  6700. foreach my $key (keys %{$result}) {
  6701. $self->add_rawdata($key, $result->{$key});
  6702. }
  6703. }
  6704. return $self->get_matching_oids(
  6705. -columns => [$params{'-baseoid'}]);
  6706. }
  6707. sub get_entries {
  6708. my $self = shift;
  6709. my %params = @_;
  6710. # [-startindex]
  6711. # [-endindex]
  6712. # -columns
  6713. my $result = {};
  6714. if (! $self->opts->snmpwalk) {
  6715. my %newparams = ();
  6716. $newparams{'-startindex'} = $params{'-startindex'}
  6717. if defined $params{'-startindex'};
  6718. $newparams{'-endindex'} = $params{'-endindex'}
  6719. if defined $params{'-startindex'};
  6720. $newparams{'-columns'} = $params{'-columns'};
  6721. $result = $NWC::Device::session->get_entries(%newparams);
  6722. foreach my $key (keys %{$result}) {
  6723. $self->add_rawdata($key, $result->{$key});
  6724. }
  6725. } else {
  6726. my $preresult = $self->get_matching_oids(
  6727. -columns => $params{'-columns'});
  6728. foreach (keys %{$preresult}) {
  6729. $result->{$_} = $preresult->{$_};
  6730. }
  6731. my @to_del = ();
  6732. if ($params{'-startindex'}) {
  6733. foreach my $resoid (keys %{$result}) {
  6734. foreach my $oid (@{$params{'-columns'}}) {
  6735. my $poid = $oid.'.';
  6736. my $lpoid = length($poid);
  6737. if (substr($resoid, 0, $lpoid) eq $poid) {
  6738. my $oidpattern = $poid;
  6739. $oidpattern =~ s/\./\\./g;
  6740. if ($resoid =~ /^$oidpattern.(.+)$/) {
  6741. if ($1 < $params{'-startindex'}) {
  6742. push(@to_del, $oid);
  6743. }
  6744. }
  6745. }
  6746. }
  6747. }
  6748. }
  6749. if ($params{'-endindex'}) {
  6750. foreach my $resoid (keys %{$result}) {
  6751. foreach my $oid (@{$params{'-columns'}}) {
  6752. my $poid = $oid.'.';
  6753. my $lpoid = length($poid);
  6754. if (substr($resoid, 0, $lpoid) eq $poid) {
  6755. my $oidpattern = $poid;
  6756. $oidpattern =~ s/\./\\./g;
  6757. if ($resoid =~ /^$oidpattern.(.+)$/) {
  6758. if ($1 > $params{'-endindex'}) {
  6759. push(@to_del, $oid);
  6760. }
  6761. }
  6762. }
  6763. }
  6764. }
  6765. }
  6766. foreach (@to_del) {
  6767. delete $result->{$_};
  6768. }
  6769. }
  6770. return $result;
  6771. }
  6772. # Level2
  6773. # helper function
  6774. sub get_matching_oids {
  6775. my $self = shift;
  6776. my %params = @_;
  6777. my $result = {};
  6778. $self->debug(sprintf "get_matching_oids %s", Data::Dumper::Dumper(\%params));
  6779. foreach my $oid (@{$params{'-columns'}}) {
  6780. my $oidpattern = $oid;
  6781. $oidpattern =~ s/\./\\./g;
  6782. map { $result->{$_} = $NWC::Device::rawdata->{$_} }
  6783. grep /^$oidpattern(?=\.|$)/, keys %{$NWC::Device::rawdata};
  6784. }
  6785. $self->debug(sprintf "get_matching_oids returns %d from %d oids",
  6786. scalar(keys %{$result}), scalar(keys %{$NWC::Device::rawdata}));
  6787. return $result;
  6788. }
  6789. sub valdiff {
  6790. my $self = shift;
  6791. my $pparams = shift;
  6792. my %params = %{$pparams};
  6793. my @keys = @_;
  6794. my $now = time;
  6795. my $last_values = $self->load_state(%params) || eval {
  6796. my $empty_events = {};
  6797. foreach (@keys) {
  6798. $empty_events->{$_} = 0;
  6799. }
  6800. $empty_events->{timestamp} = 0;
  6801. if ($self->opts->lookback) {
  6802. $empty_events->{lookback_history} = {};
  6803. }
  6804. $empty_events;
  6805. };
  6806. foreach (@keys) {
  6807. if ($self->opts->lookback) {
  6808. # find a last_value in the history which fits lookback best
  6809. # and overwrite $last_values->{$_} with historic data
  6810. if (exists $last_values->{lookback_history}->{$_}) {
  6811. foreach my $date (sort {$a <=> $b} keys %{$last_values->{lookback_history}->{$_}}) {
  6812. if ($date >= ($now - $self->opts->lookback)) {
  6813. $last_values->{$_} = $last_values->{lookback_history}->{$_}->{$date};
  6814. $last_values->{timestamp} = $date;
  6815. last;
  6816. } else {
  6817. delete $last_values->{lookback_history}->{$_}->{$date};
  6818. }
  6819. }
  6820. }
  6821. }
  6822. $last_values->{$_} = 0 if ! exists $last_values->{$_};
  6823. if ($self->{$_} >= $last_values->{$_}) {
  6824. $self->{'delta_'.$_} = $self->{$_} - $last_values->{$_};
  6825. } else {
  6826. # vermutlich db restart und zaehler alle auf null
  6827. $self->{'delta_'.$_} = $self->{$_};
  6828. }
  6829. $self->debug(sprintf "delta_%s %f", $_, $self->{'delta_'.$_});
  6830. }
  6831. $self->{'delta_timestamp'} = $now - $last_values->{timestamp};
  6832. $params{save} = eval {
  6833. my $empty_events = {};
  6834. foreach (@keys) {
  6835. $empty_events->{$_} = $self->{$_};
  6836. }
  6837. $empty_events->{timestamp} = $now;
  6838. if ($self->opts->lookback) {
  6839. $empty_events->{lookback_history} = $last_values->{lookback_history};
  6840. foreach (@keys) {
  6841. $empty_events->{lookback_history}->{$_}->{$now} = $self->{$_};
  6842. }
  6843. }
  6844. $empty_events;
  6845. };
  6846. $self->save_state(%params);
  6847. }
  6848. sub create_statefilesdir {
  6849. my $self = shift;
  6850. if (! -d $NWC::Device::statefilesdir) {
  6851. if (! -d dirname($NWC::Device::statefilesdir)) {
  6852. mkdir dirname($NWC::Device::statefilesdir);
  6853. }
  6854. mkdir $NWC::Device::statefilesdir;
  6855. } elsif (! -w $NWC::Device::statefilesdir) {
  6856. $self->schimpf();
  6857. }
  6858. }
  6859. sub schimpf {
  6860. my $self = shift;
  6861. printf "statefilesdir %s is not writable.\nYou didn't run this plugin as root, didn't you?\n", $NWC::Device::statefilesdir;
  6862. }
  6863. sub save_state {
  6864. my $self = shift;
  6865. my %params = @_;
  6866. my $extension = "";
  6867. $self->create_statefilesdir();
  6868. mkdir $NWC::Device::statefilesdir unless -d $NWC::Device::statefilesdir;
  6869. my $statefile = sprintf "%s/%s_%s",
  6870. $NWC::Device::statefilesdir, $self->opts->hostname, $self->opts->mode;
  6871. #$extension .= $params{differenciator} ? "_".$params{differenciator} : "";
  6872. $extension .= $params{name} ? '_'.$params{name} : '';
  6873. $extension =~ s/\//_/g;
  6874. $extension =~ s/\(/_/g;
  6875. $extension =~ s/\)/_/g;
  6876. $extension =~ s/\*/_/g;
  6877. $extension =~ s/\s/_/g;
  6878. $statefile .= $extension;
  6879. $statefile = lc $statefile;
  6880. open(STATE, ">$statefile");
  6881. if ((ref($params{save}) eq "HASH") && exists $params{save}->{timestamp}) {
  6882. $params{save}->{localtime} = scalar localtime $params{save}->{timestamp};
  6883. }
  6884. printf STATE Data::Dumper::Dumper($params{save});
  6885. close STATE;
  6886. $self->debug(sprintf "saved %s to %s",
  6887. Data::Dumper::Dumper($params{save}), $statefile);
  6888. }
  6889. sub load_state {
  6890. my $self = shift;
  6891. my %params = @_;
  6892. my $extension = "";
  6893. my $statefile = sprintf "%s/%s_%s",
  6894. $NWC::Device::statefilesdir, $self->opts->hostname, $self->opts->mode;
  6895. #$extension .= $params{differenciator} ? "_".$params{differenciator} : "";
  6896. $extension .= $params{name} ? '_'.$params{name} : '';
  6897. $extension =~ s/\//_/g;
  6898. $extension =~ s/\(/_/g;
  6899. $extension =~ s/\)/_/g;
  6900. $extension =~ s/\*/_/g;
  6901. $extension =~ s/\s/_/g;
  6902. $statefile .= $extension;
  6903. $statefile = lc $statefile;
  6904. if ( -f $statefile) {
  6905. our $VAR1;
  6906. eval {
  6907. require $statefile;
  6908. };
  6909. if($@) {
  6910. printf "rumms\n";
  6911. }
  6912. $self->debug(sprintf "load %s", Data::Dumper::Dumper($VAR1));
  6913. return $VAR1;
  6914. } else {
  6915. return undef;
  6916. }
  6917. }
  6918. sub dumper {
  6919. my $self = shift;
  6920. my $object = shift;
  6921. my $run = $object->{runtime};
  6922. delete $object->{runtime};
  6923. printf STDERR "%s\n", Data::Dumper::Dumper($object);
  6924. $object->{runtime} = $run;
  6925. }
  6926. sub no_such_mode {
  6927. my $self = shift;
  6928. my %params = @_;
  6929. printf "Mode %s is not implemented for this type of device\n",
  6930. $self->opts->mode;
  6931. exit 0;
  6932. }
  6933. # get_cached_table_entries
  6934. # get_table nur die table-basoid
  6935. # mit liste von indices
  6936. # get_entries -startindex x -endindex x konsekutive indices oder einzeln
  6937. sub get_table_entries {
  6938. my $self = shift;
  6939. my $mib = shift;
  6940. my $table = shift;
  6941. my $elements = shift;
  6942. my $oids = {};
  6943. my $entry;
  6944. if (exists $NWC::Device::mibs_and_oids->{$mib} &&
  6945. exists $NWC::Device::mibs_and_oids->{$mib}->{$table}) {
  6946. foreach my $key (keys %{$NWC::Device::mibs_and_oids->{$mib}}) {
  6947. if ($NWC::Device::mibs_and_oids->{$mib}->{$key} =~
  6948. /^$NWC::Device::mibs_and_oids->{$mib}->{$table}/) {
  6949. $oids->{$key} = $NWC::Device::mibs_and_oids->{$mib}->{$key};
  6950. }
  6951. }
  6952. }
  6953. ($entry = $table) =~ s/Table/Entry/g;
  6954. return $self->get_entries($oids, $entry);
  6955. }
  6956. sub xget_entries {
  6957. my $self = shift;
  6958. my $oids = shift;
  6959. my $entry = shift;
  6960. my $fallback = shift;
  6961. my @params = ();
  6962. my @indices = $self->get_indices($oids->{$entry});
  6963. foreach (@indices) {
  6964. my @idx = @{$_};
  6965. my %params = ();
  6966. my $maxdimension = scalar(@idx) - 1;
  6967. foreach my $idxnr (1..scalar(@idx)) {
  6968. $params{'index'.$idxnr} = $_->[$idxnr - 1];
  6969. }
  6970. foreach my $oid (keys %{$oids}) {
  6971. next if $oid =~ /Table$/;
  6972. next if $oid =~ /Entry$/;
  6973. # there may be scalar oids ciscoEnvMonTemperatureStatusValue = curr. temp.
  6974. next if ($oid =~ /Value$/ && ref ($oids->{$oid}) eq 'HASH');
  6975. if (exists $oids->{$oid.'Value'}) {
  6976. $params{$oid} = $self->get_object_value(
  6977. $oids->{$oid}, $oids->{$oid.'Value'}, @idx);
  6978. } else {
  6979. $params{$oid} = $self->get_object($oids->{$oid}, @idx);
  6980. }
  6981. }
  6982. push(@params, \%params);
  6983. }
  6984. if (! $fallback && scalar(@params) == 0) {
  6985. if ($NWC::Device::session) {
  6986. my $table = $entry;
  6987. $table =~ s/(.*)\.\d+$/$1/;
  6988. my $result = $self->get_table(
  6989. -baseoid => $oids->{$table}
  6990. );
  6991. if ($result) {
  6992. foreach my $key (keys %{$result}) {
  6993. $self->add_rawdata($key, $result->{$key});
  6994. }
  6995. @params = $self->get_entries($oids, $entry, 1);
  6996. }
  6997. #printf "%s\n", Data::Dumper::Dumper($result);
  6998. }
  6999. }
  7000. return @params;
  7001. }
  7002. sub get_indices {
  7003. my $self = shift;
  7004. my %params = @_;
  7005. # -baseoid : entry
  7006. # find all oids beginning with $entry
  7007. # then skip one field for the sequence
  7008. # then read the next numindices fields
  7009. my $entrypat = $params{'-baseoid'};
  7010. $entrypat =~ s/\./\\\./g;
  7011. my @indices = map {
  7012. /^$entrypat\.\d+\.(.*)/ && $1;
  7013. } grep {
  7014. /^$entrypat/
  7015. } keys %{$NWC::Device::rawdata};
  7016. my %seen = ();
  7017. my @o = map {[split /\./]} sort grep !$seen{$_}++, @indices;
  7018. return @o;
  7019. }
  7020. sub get_size {
  7021. my $self = shift;
  7022. my $entry = shift;
  7023. my $entrypat = $entry;
  7024. $entrypat =~ s/\./\\\./g;
  7025. my @entries = grep {
  7026. /^$entrypat/
  7027. } keys %{$NWC::Device::rawdata};
  7028. return scalar(@entries);
  7029. }
  7030. sub get_object {
  7031. my $self = shift;
  7032. my $object = shift;
  7033. my @indices = @_;
  7034. #my $oid = $object.'.'.join('.', @indices);
  7035. my $oid = $object;
  7036. $oid .= '.'.join('.', @indices) if (@indices);
  7037. return $NWC::Device::rawdata->{$oid};
  7038. }
  7039. sub get_object_value {
  7040. my $self = shift;
  7041. my $object = shift;
  7042. my $values = shift;
  7043. my @indices = @_;
  7044. my $key = $self->get_object($object, @indices);
  7045. if (defined $key) {
  7046. return $values->{$key};
  7047. } else {
  7048. return undef;
  7049. }
  7050. }
  7051. #SNMP::Utils::counter([$idxs1, $idxs2], $idx1, $idx2),
  7052. # this flattens a n-dimensional array and returns the absolute position
  7053. # of the element at position idx1,idx2,...,idxn
  7054. # element 1,2 in table 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2 is at pos 6
  7055. sub get_number {
  7056. my $self = shift;
  7057. my $indexlists = shift; #, zeiger auf array aus [1, 2]
  7058. my @element = @_;
  7059. my $dimensions = scalar(@{$indexlists->[0]});
  7060. my @sorted = ();
  7061. my $number = 0;
  7062. if ($dimensions == 1) {
  7063. @sorted =
  7064. sort { $a->[0] <=> $b->[0] } @{$indexlists};
  7065. } elsif ($dimensions == 2) {
  7066. @sorted =
  7067. sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @{$indexlists};
  7068. } elsif ($dimensions == 3) {
  7069. @sorted =
  7070. sort { $a->[0] <=> $b->[0] ||
  7071. $a->[1] <=> $b->[1] ||
  7072. $a->[2] <=> $b->[2] } @{$indexlists};
  7073. }
  7074. foreach (@sorted) {
  7075. if ($dimensions == 1) {
  7076. if ($_->[0] == $element[0]) {
  7077. last;
  7078. }
  7079. } elsif ($dimensions == 2) {
  7080. if ($_->[0] == $element[0] && $_->[1] == $element[1]) {
  7081. last;
  7082. }
  7083. } elsif ($dimensions == 3) {
  7084. if ($_->[0] == $element[0] &&
  7085. $_->[1] == $element[1] &&
  7086. $_->[2] == $element[2]) {
  7087. last;
  7088. }
  7089. }
  7090. $number++;
  7091. }
  7092. return ++$number;
  7093. }
  7094. sub mib {
  7095. my $self = shift;
  7096. my $mib = shift;
  7097. my $condition = {
  7098. 0 => 'other',
  7099. 1 => 'ok',
  7100. 2 => 'degraded',
  7101. 3 => 'failed',
  7102. };
  7103. my $MibRevMajor = $mib.'.1.0';
  7104. my $MibRevMinor = $mib.'.2.0';
  7105. my $MibRevCondition = $mib.'.3.0';
  7106. return (
  7107. $self->SNMP::Utils::get_object($MibRevMajor),
  7108. $self->SNMP::Utils::get_object($MibRevMinor),
  7109. $self->SNMP::Utils::get_object_value($MibRevCondition, $condition));
  7110. };
  7111. ;
  7112. package main;
  7113. #! /usr/bin/perl
  7114. use strict;
  7115. use vars qw ($PROGNAME $REVISION $CONTACT $TIMEOUT $STATEFILESDIR $needs_restart %commandline);
  7116. $PROGNAME = "check_nwc_health";
  7117. $REVISION = '$Revision: 1.4.9.1 $';
  7118. $CONTACT = 'gerhard.lausser@consol.de';
  7119. $TIMEOUT = 60;
  7120. $STATEFILESDIR = '/var/tmp/check_nwc_health';
  7121. use constant OK => 0;
  7122. use constant WARNING => 1;
  7123. use constant CRITICAL => 2;
  7124. use constant UNKNOWN => 3;
  7125. use constant DEPENDENT => 4;
  7126. my @modes = (
  7127. ['device::uptime',
  7128. 'uptime', undef,
  7129. 'Check the uptime of the device' ],
  7130. ['device::hardware::health',
  7131. 'hardware-health', undef,
  7132. 'Check the status of environmental equipment (fans, temperatures, power)' ],
  7133. ['device::hardware::load',
  7134. 'cpu-load', undef,
  7135. 'Check the CPU load of the device' ],
  7136. ['device::hardware::memory',
  7137. 'memory-usage', undef,
  7138. 'Check the memory usage of the device' ],
  7139. # ['device::interfaces::traffic',
  7140. # 'interface-traffic', undef,
  7141. # 'Check the in- and outgoing traffic on interfaces' ],
  7142. ['device::interfaces::usage',
  7143. 'interface-usage', undef,
  7144. 'Check the utilization of interfaces' ],
  7145. ['device::interfaces::errors',
  7146. 'interface-errors', undef,
  7147. 'Check the error-rate of interfaces (errors+discards per sec)' ],
  7148. ['device::interfaces::operstatus',
  7149. 'interface-status', undef,
  7150. 'Check the status of interfaces' ],
  7151. ['device::interfaces::list',
  7152. 'list-interfaces', undef,
  7153. 'Show the interfaces of the device and update the name cache' ],
  7154. ['device::interfaces::listdetail',
  7155. 'list-interfaces-detail', undef,
  7156. 'Show the interfaces of the device and some details' ],
  7157. ['device::shinken::interface',
  7158. 'create-shinken-service', undef,
  7159. 'Create a Shinken service definition' ],
  7160. ['device::hsrp::state',
  7161. 'hsrp-state', undef,
  7162. 'Check the state in a HSRP group' ],
  7163. ['device::hsrp::failover',
  7164. 'hsrp-failover', undef,
  7165. 'Check if a HSRP group\'s nodes have changed their roles' ],
  7166. ['device::hsrp::list',
  7167. 'list-hsrp-groups', undef,
  7168. 'Show the HSRP groups configured on this device' ],
  7169. ['device::walk',
  7170. 'walk', undef,
  7171. 'Show snmpwalk command with the oids necessary for a simulation' ],
  7172. );
  7173. my $modestring = "";
  7174. my $longest = length ((reverse sort {length $a <=> length $b} map { $_->[1] } @modes)[0]);
  7175. my $format = " %-".
  7176. (length ((reverse sort {length $a <=> length $b} map { $_->[1] } @modes)[0])).
  7177. "s\t(%s)\n";
  7178. foreach (@modes) {
  7179. $modestring .= sprintf $format, $_->[1], $_->[3];
  7180. }
  7181. $modestring .= sprintf "\n";
  7182. my $plugin = Nagios::MiniPlugin->new(
  7183. shortname => '',
  7184. usage => 'Usage: %s [ -v|--verbose ] [ -t <timeout> ] '.
  7185. '--hostname <network-component> --community <snmp-community>'.
  7186. ' ...]',
  7187. version => $REVISION,
  7188. blurb => 'This plugin checks various parameters of network components ',
  7189. url => 'http://labs.consol.de/nagios/check_nwc_health',
  7190. timeout => 60,
  7191. shortname => '',
  7192. );
  7193. $plugin->add_arg(
  7194. spec => 'blacklist|b=s',
  7195. help => '--blacklist
  7196. Blacklist some (missing/failed) components',
  7197. required => 0,
  7198. default => '',
  7199. );
  7200. #$plugin->add_arg(
  7201. # spec => 'customthresholds|c=s',
  7202. # help => '--customthresholds
  7203. # Use custom thresholds for certain temperatures',
  7204. # required => 0,
  7205. #);
  7206. #$plugin->add_arg(
  7207. # spec => 'perfdata=s',
  7208. # help => '--perfdata=[short]
  7209. # Output performance data. If your performance data string becomes
  7210. # too long and is truncated by Nagios, then you can use --perfdata=short
  7211. # instead. This will output temperature tags without location information',
  7212. # required => 0,
  7213. #);
  7214. $plugin->add_arg(
  7215. spec => 'hostname|H=s',
  7216. help => '--hostname
  7217. Hostname or IP-address of the switch or router',
  7218. required => 0,
  7219. );
  7220. $plugin->add_arg(
  7221. spec => 'port=i',
  7222. help => '--port
  7223. The SNMP port to use (default: 161)',
  7224. required => 0,
  7225. default => 161,
  7226. );
  7227. $plugin->add_arg(
  7228. spec => 'protocol|P=s',
  7229. help => '--protocol
  7230. The SNMP protocol to use (default: 2c, other possibilities: 1,3)',
  7231. required => 0,
  7232. default => '2c',
  7233. );
  7234. $plugin->add_arg(
  7235. spec => 'community|C=s',
  7236. help => '--community
  7237. SNMP community of the server (SNMP v1/2 only)',
  7238. required => 0,
  7239. default => 'public',
  7240. );
  7241. $plugin->add_arg(
  7242. spec => 'username=s',
  7243. help => '--username
  7244. The securityName for the USM security model (SNMPv3 only)',
  7245. required => 0,
  7246. );
  7247. $plugin->add_arg(
  7248. spec => 'authpassword=s',
  7249. help => '--authpassword
  7250. The authentication password for SNMPv3',
  7251. required => 0,
  7252. );
  7253. $plugin->add_arg(
  7254. spec => 'authprotocol=s',
  7255. help => '--authprotocol
  7256. The authentication protocol for SNMPv3 (md5|sha)',
  7257. required => 0,
  7258. );
  7259. $plugin->add_arg(
  7260. spec => 'privpassword=s',
  7261. help => '--privpassword
  7262. The password for authPriv security level',
  7263. required => 0,
  7264. );
  7265. $plugin->add_arg(
  7266. spec => 'privprotocol=s',
  7267. help => '--privprotocol
  7268. The private protocol for SNMPv3 (des|aes|aes128|3des|3desde)',
  7269. required => 0,
  7270. );
  7271. $plugin->add_arg(
  7272. spec => 'warning=s',
  7273. help => '--warning
  7274. The warning threshold',
  7275. required => 0,
  7276. );
  7277. $plugin->add_arg(
  7278. spec => 'mode=s',
  7279. help => "--mode
  7280. A keyword which tells the plugin what to do
  7281. $modestring",
  7282. required => 1,
  7283. );
  7284. $plugin->add_arg(
  7285. spec => 'name=s',
  7286. help => "--name
  7287. The name of an interface",
  7288. required => 0,
  7289. );
  7290. $plugin->add_arg(
  7291. spec => 'regexp',
  7292. help => "--regexp
  7293. A flag indicating that --name is a regular expression",
  7294. required => 0,
  7295. );
  7296. $plugin->add_arg(
  7297. spec => 'ifspeedin=i',
  7298. help => "--ifspeedin
  7299. Override the ifspeed oid of an interface (only inbound)",
  7300. required => 0,
  7301. );
  7302. $plugin->add_arg(
  7303. spec => 'ifspeedout=i',
  7304. help => "--ifspeedout
  7305. Override the ifspeed oid of an interface (only outbound)",
  7306. required => 0,
  7307. );
  7308. $plugin->add_arg(
  7309. spec => 'ifspeed=i',
  7310. help => "--ifspeed
  7311. Override the ifspeed oid of an interface",
  7312. required => 0,
  7313. );
  7314. $plugin->add_arg(
  7315. spec => 'units=s',
  7316. help => "--units
  7317. One of %, B, KB, MB, GB, Bit, KBi, MBi, GBi. (used for e.g. mode interface-usage)",
  7318. required => 0,
  7319. );
  7320. $plugin->add_arg(
  7321. spec => 'role=s',
  7322. help => "--role
  7323. The role of this device in a hsrp group (active/standby/listen)",
  7324. required => 0,
  7325. );
  7326. $plugin->add_arg(
  7327. spec => 'lookback=s',
  7328. help => "--lookback
  7329. The amount of time you want to look back when calculating average rates.
  7330. Use it for mode interface-errors or interface-usage. Without --lookback
  7331. the time between two runs of check_nwc_health is the base for calculations.
  7332. If you want your checkresult to be based for example on the past hour,
  7333. use --lookback 3600. ",
  7334. required => 0,
  7335. );
  7336. $plugin->add_arg(
  7337. spec => 'critical=s',
  7338. help => '--critical
  7339. The critical threshold',
  7340. required => 0,
  7341. );
  7342. $plugin->add_arg(
  7343. spec => 'servertype=s',
  7344. help => '--servertype
  7345. The type of the network device: cisco (default). Use it if auto-detection
  7346. is not possible',
  7347. required => 0,
  7348. );
  7349. $plugin->add_arg(
  7350. spec => 'statefilesdir=s',
  7351. help => '--statefilesdir
  7352. An alternate directory where the plugin can save files',
  7353. required => 0,
  7354. );
  7355. $plugin->add_arg(
  7356. spec => 'snmpwalk=s',
  7357. help => '--snmpwalk
  7358. A file with the output of a snmpwalk (used for simulation)
  7359. Use it instead of --hostname',
  7360. required => 0,
  7361. );
  7362. $plugin->add_arg(
  7363. spec => 'snmphelp',
  7364. help => '--snmphelp
  7365. Output the list of OIDs you need to walk for a simulation file',
  7366. required => 0,
  7367. );
  7368. $plugin->getopts();
  7369. if ($plugin->opts->snmphelp) {
  7370. my @subtrees = ("1");
  7371. foreach my $mib (keys %{$NWC::Device::mibs_and_oids}) {
  7372. foreach my $table (grep {/Table$/} keys %{$NWC::Device::mibs_and_oids->{$mib}}) {
  7373. push(@subtrees, $NWC::Device::mibs_and_oids->{$mib}->{$table});
  7374. }
  7375. }
  7376. printf "snmpwalk -On ... %s\n", join(" ", @subtrees);
  7377. printf "snmpwalk -On ... %s\n", join(" ", @subtrees);
  7378. exit 0;
  7379. }
  7380. if ($plugin->opts->community) {
  7381. if ($plugin->opts->community =~ /^snmpv3(.)(.+)/) {
  7382. my $separator = $1;
  7383. my ($authprotocol, $authpassword, $privprotocol, $privpassword, $username) =
  7384. split(/$separator/, $2);
  7385. $plugin->override_opt('authprotocol', $authprotocol)
  7386. if defined($authprotocol) && $authprotocol;
  7387. $plugin->override_opt('authpassword', $authpassword)
  7388. if defined($authpassword) && $authpassword;
  7389. $plugin->override_opt('privprotocol', $privprotocol)
  7390. if defined($privprotocol) && $privprotocol;
  7391. $plugin->override_opt('privpassword', $privpassword)
  7392. if defined($privpassword) && $privpassword;
  7393. $plugin->override_opt('username', $username)
  7394. if defined($username) && $username;
  7395. $plugin->override_opt('protocol', '3') ;
  7396. }
  7397. }
  7398. if ($plugin->opts->snmpwalk) {
  7399. $plugin->override_opt('hostname', 'snmpwalk.file')
  7400. }
  7401. if (! $plugin->opts->statefilesdir) {
  7402. if (exists $ENV{OMD_ROOT}) {
  7403. $plugin->override_opt('statefilesdir', $ENV{OMD_ROOT}."/var/tmp/check_nwc_health");
  7404. } else {
  7405. $plugin->override_opt('statefilesdir', $STATEFILESDIR);
  7406. }
  7407. }
  7408. $plugin->{messages}->{unknown} = []; # wg. add_message(UNKNOWN,...)
  7409. $plugin->{info} = []; # gefrickel
  7410. if ($plugin->opts->mode =~ /^my-([^\-.]+)/) {
  7411. my $param = $plugin->opts->mode;
  7412. $param =~ s/\-/::/g;
  7413. push(@modes, [$param, $plugin->opts->mode, undef, 'my extension']);
  7414. } elsif ($plugin->opts->mode eq 'encode') {
  7415. my $input = <>;
  7416. chomp $input;
  7417. $input =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;
  7418. printf "%s\n", $input;
  7419. exit 0;
  7420. } elsif ((! grep { $plugin->opts->mode eq $_ } map { $_->[1] } @modes) &&
  7421. (! grep { $plugin->opts->mode eq $_ } map { defined $_->[2] ? @{$_->[2]} : () } @modes)) {
  7422. printf "UNKNOWN - mode %s\n", $plugin->opts->mode;
  7423. $plugin->opts->print_help();
  7424. exit 3;
  7425. }
  7426. if ($plugin->opts->name && $plugin->opts->name =~ /(%22)|(%27)/) {
  7427. my $name = $plugin->opts->name;
  7428. $name =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;
  7429. $plugin->override_opt('name', $name);
  7430. }
  7431. $SIG{'ALRM'} = sub {
  7432. printf "UNKNOWN - check_nwc_health timed out after %d seconds\n",
  7433. $plugin->opts->timeout;
  7434. exit $ERRORS{UNKNOWN};
  7435. };
  7436. alarm($plugin->opts->timeout);
  7437. $NWC::Device::plugin = $plugin;
  7438. $NWC::Device::mode = (
  7439. map { $_->[0] }
  7440. grep {
  7441. ($plugin->opts->mode eq $_->[1]) ||
  7442. ( defined $_->[2] && grep { $plugin->opts->mode eq $_ } @{$_->[2]})
  7443. } @modes
  7444. )[0];
  7445. my $server = NWC::Device->new( runtime => {
  7446. plugin => $plugin,
  7447. options => {
  7448. servertype => $plugin->opts->servertype,
  7449. verbose => $plugin->opts->verbose,
  7450. customthresholds => $plugin->opts->get('customthresholds'),
  7451. blacklist => $plugin->opts->blacklist,
  7452. # celsius => $CELSIUS,
  7453. # perfdata => $PERFDATA,
  7454. # extendedinfo => $EXTENDEDINFO,
  7455. # hwinfo => $HWINFO,
  7456. # noinstlevel => $NOINSTLEVEL,
  7457. },
  7458. },);
  7459. #$server->dumper();
  7460. if (! $plugin->check_messages()) {
  7461. $server->init();
  7462. if (! $plugin->check_messages()) {
  7463. $plugin->add_message(OK, $server->get_summary())
  7464. if $server->get_summary();
  7465. $plugin->add_message(OK, $server->get_extendedinfo())
  7466. if $server->get_extendedinfo();
  7467. }
  7468. } else {
  7469. $plugin->add_message(CRITICAL, 'wrong device');
  7470. }
  7471. my ($code, $message) = $plugin->check_messages(join => ', ', join_all => ', ');
  7472. $message .= sprintf "\n%s\n", join("\n", @{$NWC::Device::info})
  7473. if $plugin->opts->verbose >= 1;
  7474. #printf "%s\n", Data::Dumper::Dumper($plugin->{info});
  7475. $plugin->nagios_exit($code, $message);