1package Classes::Cisco::CISCOENTITYALARMMIB::Component::AlarmSubsystem;
2our @ISA = qw(Monitoring::GLPlugin::SNMP::Item);
3use strict;
4
5sub init {
6  my ($self) = @_;
7  my $alarms = {};
8  $self->get_snmp_tables('CISCO-ENTITY-ALARM-MIB', [
9    ['alarms', 'ceAlarmTable', 'Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::Alarm', sub { my ($o) = @_; $o->{parent} = $self; $self->filter_name($o->{entPhysicalIndex})}],
10    ['alarmdescriptionmappings', 'ceAlarmDescrMapTable', 'Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmDescriptionMapping' ],
11    ['alarmdescriptions', 'ceAlarmDescrTable', 'Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmDescription' ],
12    ['alarmfilterprofiles', 'ceAlarmFilterProfileTable', 'Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmFilterProfile' ],
13    ['alarmhistory', 'ceAlarmHistTable', 'Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmHistory', sub { my ($o) = @_; $o->{parent} = $self; $self->filter_name($o->{entPhysicalIndex})}],
14  ]);
15  $self->get_snmp_tables('ENTITY-MIB', [
16    ['entities', 'entPhysicalTable', 'Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::PhysicalEntity'],
17  ]);
18  $self->get_snmp_objects('CISCO-ENTITY-ALARM-MIB', qw(
19      ceAlarmCriticalCount ceAlarmMajorCount ceAlarmMinorCount
20      ceAlarmFilterProfileIndexNext
21  ));
22  foreach (qw(ceAlarmCriticalCount ceAlarmMajorCount ceAlarmMinorCount)) {
23    $self->{$_} ||= 0;
24  }
25  @{$self->{alarms}} = grep {
26      $_->{ceAlarmSeverity} ne 'none' &&
27      $_->{ceAlarmSeverity} ne 'info'
28  } @{$self->{alarms}};
29  foreach my $alarm (@{$self->{alarms}}) {
30    foreach my $entity (@{$self->{entities}}) {
31      if ($alarm->{entPhysicalIndex} eq $entity->{entPhysicalIndex}) {
32        $alarm->{entity} = $entity;
33      }
34    }
35  }
36}
37
38sub check {
39  my ($self) = @_;
40  if (scalar(@{$self->{alarms}}) == 0) {
41    $self->add_info('no alarms');
42    $self->add_ok();
43  } else {
44    foreach (@{$self->{alarms}}) {
45      $_->check();
46    }
47    foreach (@{$self->{alarmhistory}}) {
48      $_->check();
49    }
50    if (! $self->check_messages()) { # blacklisted des ganze glump
51      $self->add_info('no alarms');
52      $self->add_ok();
53    }
54  }
55}
56
57package Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::Alarm;
58our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
59use strict;
60
61sub finish {
62  my ($self) = @_;
63  $self->{entPhysicalIndex} = $self->{flat_indices};
64  $self->{ceAlarmTypes} = [];
65  if ($self->{ceAlarmList}) {
66    my $index = 0;
67    foreach my $octet (unpack('H2', $self->{ceAlarmList})) {
68      my $hexoctet = hex($octet) & 0xff;
69      if ($hexoctet) {
70        my $base = 8 * $index;
71        foreach my $bit (0..7) {
72          my $mask = (2 ** $bit) & 0xff;
73          if ($hexoctet & $mask) {
74            push(@{$self->{ceAlarmTypes}}, $base + $bit);
75          }
76        }
77      }
78      $index++;
79    }
80  }
81  $self->{ceAlarmTypes} = join(",", @{$self->{ceAlarmTypes}}); # weil sonst der drecks-dump nicht funktioniert.
82}
83
84sub check {
85  my ($self) = @_;
86  my $location = exists $self->{entity} ?
87      $self->{entity}->{entPhysicalDescr} : "unknown";
88  if (length($self->{ceAlarmTypes})) {
89    my @descriptorindexes = map {
90        $_->{ceAlarmDescrIndex}
91    } grep {
92        $self->{entity}->{entPhysicalVendorType} eq $_->{ceAlarmDescrVendorType}
93    } @{$self->{parent}->{alarmdescriptionmappings}};
94    if (@descriptorindexes) {
95      my $ceAlarmDescrIndex = $descriptorindexes[0];
96      my @descriptions = grep {
97        $_->{ceAlarmDescrIndex} == $ceAlarmDescrIndex;
98      } @{$self->{parent}->{alarmdescriptions}};
99      foreach my $ceAlarmType (split(",", $self->{ceAlarmTypes})) {
100        foreach my $alarmdesc (@descriptions) {
101          if ($alarmdesc->{ceAlarmDescrAlarmType} == $ceAlarmType) {
102            $self->add_info(sprintf "%s alarm '%s' in entity %d (%s)",
103                $alarmdesc->{ceAlarmDescrSeverity},
104                $alarmdesc->{ceAlarmDescrText},
105                $self->{entPhysicalIndex},
106                $location);
107            if ($alarmdesc->{ceAlarmDescrSeverity} eq "none") {
108              # A value of '0' indicates that there the corresponding physical entity currently is not asserting any alarms.
109            } elsif ($alarmdesc->{ceAlarmDescrSeverity} eq "critical") {
110              $self->add_critical();
111            } elsif ($alarmdesc->{ceAlarmDescrSeverity} eq "major") {
112              $self->add_critical();
113            } elsif ($alarmdesc->{ceAlarmDescrSeverity} eq "minor") {
114              $self->add_warning();
115            } elsif ($alarmdesc->{ceAlarmDescrSeverity} eq "info") {
116              $self->add_ok();
117            }
118          }
119        }
120      }
121    }
122  }
123  delete $self->{parent}; # brauch ma nimmer, daad eh sched bon dump scheebern
124}
125
126
127package Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::PhysicalEntity;
128our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
129use strict;
130
131sub finish {
132  my ($self) = @_;
133  $self->{entPhysicalIndex} = $self->{flat_indices};
134}
135
136package Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmDescription;
137our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
138
139sub finish {
140  my ($self) = @_;
141  $self->{ceAlarmDescrIndex} = $self->{indices}->[0];
142  $self->{ceAlarmDescrAlarmType} = $self->{indices}->[1];
143}
144
145
146package Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmDescriptionMapping;
147our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
148
149sub finish {
150  my ($self) = @_;
151  $self->{ceAlarmDescrIndex} = $self->{indices}->[0];
152}
153
154package Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmFilterProfile;
155our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
156
157package Classes::Cisco::CISCOENTITYSENSORMIB::Component::AlarmSubsystem::AlarmHistory;
158our @ISA = qw(Monitoring::GLPlugin::SNMP::TableItem);
159
160sub finish {
161  my ($self) = @_;
162  $self->{ceAlarmHistTimeStamp} = time - $self->uptime() + $self->timeticks($self->{ceAlarmHistTimeStamp});
163  $self->{ceAlarmHistTimeStampLocal} = scalar localtime $self->{ceAlarmHistTimeStamp};
164}
165
166sub check {
167  my ($self) = @_;
168  my $vendortype = "unknown";
169  my @entities = grep {
170    $_->{entPhysicalIndex} == $self->{ceAlarmHistEntPhysicalIndex};
171  } @{$self->{parent}->{entities}};
172  if (@entities) {
173    $vendortype = $entities[0]->{entPhysicalVendorType};
174    $self->{ceAlarmHistEntPhysicalDescr} = $entities[0]->{entPhysicalDescr};
175  }
176  my @descriptorindexes = map {
177      $_->{ceAlarmDescrIndex}
178  } grep {
179      $vendortype eq $_->{ceAlarmDescrVendorType}
180  } @{$self->{parent}->{alarmdescriptionmappings}};
181  if (@descriptorindexes) {
182    my $ceAlarmDescrIndex = $descriptorindexes[0];
183    my @descriptions = grep {
184      $_->{ceAlarmDescrIndex} == $ceAlarmDescrIndex;
185    } @{$self->{parent}->{alarmdescriptions}};
186    foreach my $alarmdesc (@descriptions) {
187      if ($alarmdesc->{ceAlarmDescrAlarmType} == $self->{ceAlarmHistAlarmType}) {
188        $self->{ceAlarmHistAlarmDescrText} = $alarmdesc->{ceAlarmDescrText};
189      }
190    }
191  }
192  delete $self->{parent};
193}
194
195__END__
196
197ceAlarmTable
198"This table specifies alarm control and status information
199related to each physical entity contained by the system,
200including the alarms currently being asserted by each physical
201entity capable of generating alarms."
202
203ceAlarmEntry
204INDEX { entPhysicalIndex }
205"Alarm control and status information related to the
206corresponding physical entity, including a list of those
207alarms currently being asserted by that physical entity."
208
209ceAlarmSeverity
210"This object specifies the highest severity alarm currently
211being asserted by the corresponding physical entity. A value
212of '0' indicates that there the corresponding physical entity
213currently is not asserting any alarms."
214
215ceAlarmFilterProfile
216"This object specifies the alarm filter profile associated
217with the corresponding physical entity. An alarm filter
218profile controls which alarm types the agent will monitor
219and signal for the corresponding physical entity.
220
221If the value of this object is '0', then the agent monitors
222and signals all alarms associated with the corresponding
223physical entity."
224
225ceAlarmList
226If an alarm is being asserted by the physical entity, then the
227corresponding bit in the alarm list is set to a one. Observe
228that if the physical entity is not currently asserting any
229alarms, then the list will have a length of zero."
230
23101 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
23232 octets
233An OCTET STRING represents an alarm list, in which each
234bit represents an alarm type. The bits in the first octet
235represent alarm types identified by the integer values 1
236through 8, inclusive, The bits in the second octet represent
237alarm types identified by the integer values 9 through 16,
238inclusive, and so forth.
239Alternativ:
240http://webcache.googleusercontent.com/search?q=cache:H9-CC7j7rxQJ:trbonet.com/download/HelpFile/TRBOnet_Watch_User_Guide_1.9_ENG.pdf+&cd=13&hl=de&ct=clnk&gl=de
2414. How to read a list of alarms from a ceAlarmList (ceAlarmTable, Oid: 1.3.6.1.4.1.9.9.138.1.2.5.1.3)
242
243This line consists of 32 bytes in hexadecimal format. Type of alarm is encoded by ordinal bit.
244
245The encoding line may look like this:
246
24700 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
248
249I.e. 13 * 8 + 3(00001000) = 107 (PeerDisconnected Alarm).
250rechtes bit von oktett 0 = fehler 0
251rechtes bit von oktett 1 = fehler 9
252also ist rechtes bit von oktett 13 der fehler 104
253zweitrechtes bit von oktett 13 der fehler 105 ...
254
255Other types of alarms are defined similarly. If no alarms are set, the line will have zero length.
256
257
258
259jetzt wirds dreckig:
260
261AlarmTable
262Ein Entry gehoert zu einem entPhysicalIndex
263Ein Entry hat ceAlarmList und daraus abgeleitet ceAlarmTypes
264
265Entites
266Ein physical Entity hat eindeutig entPhysicalIndex
267und hat einen entPhysicalVendorType, also die Bauteilbezeichnung
268
269ceAlarmDescrMapTable ist eine stupide durchnumerierte Tabelle, die
270ceAlarmDescrIndex und ceAlarmDescrVendorType- Paerchen buendelt
271
272
273AlarmTable
274mit entPhysicalIndex wird entPhysicalVendorType ermittelt
275
276ceAlarmDescrMapTable
277mit entPhysicalVendorType=ceAlarmDescrVendorType wird ceAlarmDescrIndex ermittelt
278
279ceAlarmDescrTable
280mit ceAlarmDescrIndex = ceAlarmDescrIndex &&
281 ceAlarmTypes aus AlarmTable = ceAlarmDescrAlarmType
282wird ceAlarmDescrText geholt
283
284