diff options
Diffstat (limited to 'plugins-scripts')
-rw-r--r-- | plugins-scripts/check_ifoperstatus.pl | 156 |
1 files changed, 128 insertions, 28 deletions
diff --git a/plugins-scripts/check_ifoperstatus.pl b/plugins-scripts/check_ifoperstatus.pl index 46964677..b5d0bcd1 100644 --- a/plugins-scripts/check_ifoperstatus.pl +++ b/plugins-scripts/check_ifoperstatus.pl | |||
@@ -2,7 +2,7 @@ | |||
2 | # | 2 | # |
3 | # check_ifoperstatus.pl - nagios plugin | 3 | # check_ifoperstatus.pl - nagios plugin |
4 | # | 4 | # |
5 | # Copyright (C) 2000 Christoph Kron | 5 | # Copyright (C) 2000 Christoph Kron, |
6 | # Modified 5/2002 to conform to updated Nagios Plugin Guidelines | 6 | # Modified 5/2002 to conform to updated Nagios Plugin Guidelines |
7 | # Added support for named interfaces per Valdimir Ivaschenko (S. Ghosh) | 7 | # Added support for named interfaces per Valdimir Ivaschenko (S. Ghosh) |
8 | # | 8 | # |
@@ -21,10 +21,16 @@ | |||
21 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 21 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
22 | # | 22 | # |
23 | # | 23 | # |
24 | # Report bugs to: ck@zet.net, nagiosplug-help@lists.sf.net | 24 | # Report bugs to: nagiosplug-help@lists.sourceforge.net |
25 | # | 25 | # |
26 | # 11.01.2000 Version 1.0 | 26 | # 11.01.2000 Version 1.0 |
27 | # $Id$ | 27 | # $Id$ |
28 | # | ||
29 | # Patches from Guy Van Den Bergh to warn on ifadminstatus down interfaces | ||
30 | # instead of critical. | ||
31 | # | ||
32 | # Primary MIB reference - RFC 2863 | ||
33 | |||
28 | 34 | ||
29 | use POSIX; | 35 | use POSIX; |
30 | use strict; | 36 | use strict; |
@@ -42,7 +48,8 @@ my %ifOperStatus = ('1','up', | |||
42 | '3','testing', | 48 | '3','testing', |
43 | '4','unknown', | 49 | '4','unknown', |
44 | '5','dormant', | 50 | '5','dormant', |
45 | '6','notPresent'); | 51 | '6','notPresent', |
52 | '7','lowerLayerDown'); # down due to the state of lower layer interface(s) | ||
46 | 53 | ||
47 | my $state = "UNKNOWN"; | 54 | my $state = "UNKNOWN"; |
48 | my $answer = ""; | 55 | my $answer = ""; |
@@ -50,12 +57,16 @@ my $snmpkey = 0; | |||
50 | my $community = "public"; | 57 | my $community = "public"; |
51 | my $port = 161; | 58 | my $port = 161; |
52 | my @snmpoids; | 59 | my @snmpoids; |
53 | my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; | 60 | my $sysUptime = '1.3.6.1.2.1.1.3.0'; |
61 | my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; | ||
62 | my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; | ||
54 | my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; | 63 | my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; |
55 | my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; | 64 | my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; |
56 | my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; | 65 | my $snmpIfLastChange = '1.3.6.1.2.1.2.2.1.9'; |
57 | my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; | 66 | my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; |
67 | my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; | ||
58 | my $hostname; | 68 | my $hostname; |
69 | my $ifName; | ||
59 | my $session; | 70 | my $session; |
60 | my $error; | 71 | my $error; |
61 | my $response; | 72 | my $response; |
@@ -65,6 +76,9 @@ my $opt_h ; | |||
65 | my $opt_V ; | 76 | my $opt_V ; |
66 | my $ifdescr; | 77 | my $ifdescr; |
67 | my $key; | 78 | my $key; |
79 | my $lastc; | ||
80 | my $dormantWarn; | ||
81 | my $name; | ||
68 | 82 | ||
69 | 83 | ||
70 | 84 | ||
@@ -76,6 +90,8 @@ $SIG{'ALRM'} = sub { | |||
76 | #alarm($TIMEOUT); | 90 | #alarm($TIMEOUT); |
77 | 91 | ||
78 | 92 | ||
93 | ### Validate Arguments | ||
94 | |||
79 | $status = GetOptions( | 95 | $status = GetOptions( |
80 | "V" => \$opt_V, "version" => \$opt_V, | 96 | "V" => \$opt_V, "version" => \$opt_V, |
81 | "h" => \$opt_h, "help" => \$opt_h, | 97 | "h" => \$opt_h, "help" => \$opt_h, |
@@ -83,9 +99,12 @@ $status = GetOptions( | |||
83 | "C=s" =>\$community, "community=s" => \$community, | 99 | "C=s" =>\$community, "community=s" => \$community, |
84 | "k=i" =>\$snmpkey, "key=i",\$snmpkey, | 100 | "k=i" =>\$snmpkey, "key=i",\$snmpkey, |
85 | "d=s" =>\$ifdescr, "descr=s" => \$ifdescr, | 101 | "d=s" =>\$ifdescr, "descr=s" => \$ifdescr, |
102 | "l=s" => \$lastc, "lastchange=s" => \$lastc, | ||
86 | "p=i" =>\$port, "port=i",\$port, | 103 | "p=i" =>\$port, "port=i",\$port, |
87 | "H=s" => \$hostname, "hostname=s" => \$hostname, | 104 | "H=s" => \$hostname, "hostname=s" => \$hostname, |
88 | "I" => \$ifXTable, "ifmib" => \$ifXTable); | 105 | "I" => \$ifXTable, "ifmib" => \$ifXTable, |
106 | "n=s" => \$ifName, "name=s" => \$ifName, | ||
107 | "w=s" => \$dormantWarn, "warn=s" => \$dormantWarn ); | ||
89 | 108 | ||
90 | 109 | ||
91 | 110 | ||
@@ -111,6 +130,17 @@ if (! utils::is_hostname($hostname)){ | |||
111 | } | 130 | } |
112 | 131 | ||
113 | 132 | ||
133 | unless ($snmpkey > 0 || defined $ifdescr){ | ||
134 | printf "Either a valid snmpkey key (-k) or a ifDescr (-d) must be provided)\n"; | ||
135 | usage(); | ||
136 | exit $ERRORS{"UNKNOWN"}; | ||
137 | } | ||
138 | |||
139 | |||
140 | if (defined $name) { | ||
141 | $ifXTable=1; | ||
142 | } | ||
143 | |||
114 | if ( $snmp_version =~ /[12]/ ) { | 144 | if ( $snmp_version =~ /[12]/ ) { |
115 | ($session, $error) = Net::SNMP->session( | 145 | ($session, $error) = Net::SNMP->session( |
116 | -hostname => $hostname, | 146 | -hostname => $hostname, |
@@ -135,6 +165,12 @@ if ( $snmp_version =~ /[12]/ ) { | |||
135 | exit $ERRORS{$state}; | 165 | exit $ERRORS{$state}; |
136 | } | 166 | } |
137 | 167 | ||
168 | ## End validation | ||
169 | |||
170 | |||
171 | |||
172 | ## map ifdescr to ifindex - should look at being able to cache this value | ||
173 | |||
138 | if (defined $ifdescr) { | 174 | if (defined $ifdescr) { |
139 | # escape "/" in ifdescr - very common in the Cisco world | 175 | # escape "/" in ifdescr - very common in the Cisco world |
140 | $ifdescr =~ s/\//\\\//g; | 176 | $ifdescr =~ s/\//\\\//g; |
@@ -143,31 +179,32 @@ if (defined $ifdescr) { | |||
143 | # recommend use of SNMP v2 (get-bulk) | 179 | # recommend use of SNMP v2 (get-bulk) |
144 | if ($status==0) { | 180 | if ($status==0) { |
145 | $state = "UNKNOWN"; | 181 | $state = "UNKNOWN"; |
146 | printf "$state: could not retrive ifIndex - $status-$snmpkey\n"; | 182 | printf "$state: could not retrive snmpkey - $status-$snmpkey\n"; |
147 | $session->close; | 183 | $session->close; |
148 | exit $ERRORS{$state}; | 184 | exit $ERRORS{$state}; |
149 | } | 185 | } |
150 | } | 186 | } |
151 | if ( $snmpkey == 0 ) { | ||
152 | printf "ifIndex key cannot be 0\n"; | ||
153 | usage(); | ||
154 | exit $ERRORS{'UNKNOWN'}; | ||
155 | } | ||
156 | 187 | ||
157 | $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8' . "." . $snmpkey; | ||
158 | $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2' . "." . $snmpkey; | ||
159 | $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18' . "." . $snmpkey ; | ||
160 | 188 | ||
189 | ## Main function | ||
190 | |||
191 | $snmpIfAdminStatus = $snmpIfAdminStatus . "." . $snmpkey; | ||
192 | $snmpIfOperStatus = $snmpIfOperStatus . "." . $snmpkey; | ||
193 | $snmpIfDescr = $snmpIfDescr . "." . $snmpkey; | ||
194 | $snmpIfName = $snmpIfName . "." . $snmpkey ; | ||
195 | $snmpIfAlias = $snmpIfAlias . "." . $snmpkey ; | ||
161 | 196 | ||
197 | push(@snmpoids,$snmpIfAdminStatus); | ||
162 | push(@snmpoids,$snmpIfOperStatus); | 198 | push(@snmpoids,$snmpIfOperStatus); |
163 | push(@snmpoids,$snmpIfDescr); | 199 | push(@snmpoids,$snmpIfDescr); |
200 | push(@snmpoids,$snmpIfName) if (defined $ifXTable) ; | ||
164 | push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; | 201 | push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; |
165 | 202 | ||
166 | if (!defined($response = $session->get_request(@snmpoids))) { | 203 | if (!defined($response = $session->get_request(@snmpoids))) { |
167 | $answer=$session->error; | 204 | $answer=$session->error; |
168 | $session->close; | 205 | $session->close; |
169 | $state = 'CRITICAL'; | 206 | $state = 'WARNING'; |
170 | print ("$state: $answer for ifIndex $snmpkey\n"); | 207 | print ("$state: SNMP error: $answer\n"); |
171 | exit $ERRORS{$state}; | 208 | exit $ERRORS{$state}; |
172 | } | 209 | } |
173 | 210 | ||
@@ -178,31 +215,87 @@ push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; | |||
178 | $ifOperStatus{$response->{$snmpIfOperStatus}} | 215 | $ifOperStatus{$response->{$snmpIfOperStatus}} |
179 | ); | 216 | ); |
180 | 217 | ||
181 | $session->close; | ||
182 | 218 | ||
183 | if ( $response->{$snmpIfOperStatus} == 1 ) { | 219 | ## Check to see if ifName match is requested and it matches - exit if no match |
184 | $state = 'OK'; | 220 | ## not the interface we want to monitor |
221 | if ( defined $name && not ($response->{$snmpIfName} eq $name) ) { | ||
222 | $state = 'UNKNOWN'; | ||
223 | $answer = "Interface name ($name) doesn't match snmp value ($response->{$snmpIfName}) (index $snmpkey)"; | ||
224 | print ("$state: $answer"); | ||
225 | exit $ERRORS{$state}; | ||
226 | } | ||
227 | |||
228 | ## define the interface name | ||
229 | if (defined $ifXTable) { | ||
230 | $name = $response->{$snmpIfName} ." - " .$response->{$snmpIfAlias} ; | ||
231 | }else{ | ||
232 | $name = $response->{$snmpIfDescr} ; | ||
185 | } | 233 | } |
186 | else { | 234 | |
187 | $state = 'CRITICAL'; | 235 | ## if AdminStatus is down - some one made a consious effort to change config |
236 | ## | ||
237 | if ( not ($response->{$snmpIfAdminStatus} == 1) ) { | ||
238 | $state = 'WARNING'; | ||
239 | $answer = "Interface $name (index $snmpkey) is administratively down."; | ||
240 | |||
241 | } | ||
242 | ## Check operational status | ||
243 | elsif ( $response->{$snmpIfOperStatus} == 2 ) { | ||
244 | $state = 'CRITICAL'; | ||
245 | $answer = "Interface $name (index $snmpkey) is down."; | ||
246 | } elsif ( $response->{$snmpIfOperStatus} == 5 ) { | ||
247 | if (defined $dormantWarn ) { | ||
248 | if ($dormantWarn eq "w") { | ||
249 | $state = 'WARNNG'; | ||
250 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
251 | }elsif($dormantWarn eq "c") { | ||
252 | $state = 'CRITICAL'; | ||
253 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
254 | }elsif($dormantWarn eq "i") { | ||
255 | $state = 'OK'; | ||
256 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
257 | } | ||
258 | }else{ | ||
259 | # dormant interface - but warning/critical/ignore not requested | ||
260 | $state = 'CRITICAL'; | ||
261 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
262 | } | ||
263 | } elsif ( $response->{$snmpIfOperStatus} == 6 ) { | ||
264 | $state = 'CRITICAL'; | ||
265 | $answer = "Interface $name (index $snmpkey) notPresent - possible hotswap in progress."; | ||
266 | } elsif ( $response->{$snmpIfOperStatus} == 7 ) { | ||
267 | $state = 'CRITICAL'; | ||
268 | $answer = "Interface $name (index $snmpkey) down due to lower layer being down."; | ||
269 | |||
270 | } elsif ( $response->{$snmpIfOperStatus} == 3 || $response->{$snmpIfOperStatus} == 4 ) { | ||
271 | $state = 'CRITICAL'; | ||
272 | $answer = "Interface $name (index $snmpkey) down (testing/unknown)."; | ||
273 | |||
274 | } else { | ||
275 | $state = 'OK'; | ||
276 | $answer = "Interface $name (index $snmpkey) is up."; | ||
188 | } | 277 | } |
189 | 278 | ||
279 | |||
280 | |||
190 | print ("$state: $answer"); | 281 | print ("$state: $answer"); |
191 | exit $ERRORS{$state}; | 282 | exit $ERRORS{$state}; |
192 | 283 | ||
193 | 284 | ||
285 | ### subroutines | ||
286 | |||
194 | sub fetch_ifdescr { | 287 | sub fetch_ifdescr { |
195 | if (!defined ($response = $session->get_table($snmpIfDescr))) { | 288 | if (!defined ($response = $session->get_table($snmpIfDescr))) { |
196 | $answer=$session->error; | 289 | $answer=$session->error; |
197 | $session->close; | 290 | $session->close; |
198 | $state = 'CRITICAL'; | 291 | $state = 'CRITICAL'; |
199 | printf ("$state: $answer for $snmpIfDescr with snmp version $snmp_version\n"); | 292 | printf ("$state: SNMP error with snmp version $snmp_version ($answer)\n"); |
200 | $session->close; | 293 | $session->close; |
201 | exit $ERRORS{$state}; | 294 | exit $ERRORS{$state}; |
202 | } | 295 | } |
203 | 296 | ||
204 | foreach $key ( keys %{$response}) { | 297 | foreach $key ( keys %{$response}) { |
205 | if ($response->{$key} =~ /$ifdescr/) { | 298 | if ($response->{$key} =~ /^$ifdescr$/) { |
206 | $key =~ /.*\.(\d+)$/; | 299 | $key =~ /.*\.(\d+)$/; |
207 | $snmpkey = $1; | 300 | $snmpkey = $1; |
208 | #print "$ifdescr = $key / $snmpkey \n"; #debug | 301 | #print "$ifdescr = $key / $snmpkey \n"; #debug |
@@ -242,14 +335,21 @@ sub print_help { | |||
242 | printf " 2 for SNMP v2c\n"; | 335 | printf " 2 for SNMP v2c\n"; |
243 | printf " SNMP v2c will use get_bulk for less overhead\n"; | 336 | printf " SNMP v2c will use get_bulk for less overhead\n"; |
244 | printf " if monitoring with -d\n"; | 337 | printf " if monitoring with -d\n"; |
245 | printf " -k (--key) SNMP ifIndex value\n"; | 338 | printf " -k (--key) SNMP IfIndex value\n"; |
246 | printf " -d (--descr) SNMP ifDescr value\n"; | 339 | printf " -d (--descr) SNMP ifDescr value\n"; |
247 | printf " -p (--port) SNMP port (default 161)\n"; | 340 | printf " -p (--port) SNMP port (default 161)\n"; |
248 | printf " -I (--ifmib) Agent supports IFMIB ifXTable. Do not use if\n"; | 341 | printf " -I (--ifmib) Agent supports IFMIB ifXTable. Do not use if\n"; |
249 | printf " you don't know what this is.\n"; | 342 | printf " you don't know what this is. \n"; |
343 | printf " -n (--name) the value should match the returned ifName\n"; | ||
344 | printf " (Implies the use of -I)\n"; | ||
345 | printf " -w (--warn =i|w|c) ignore|warn|crit if the interface is dormant (default critical)\n"; | ||
250 | printf " -V (--version) Plugin version\n"; | 346 | printf " -V (--version) Plugin version\n"; |
251 | printf " -h (--help) usage help \n\n"; | 347 | printf " -h (--help) usage help \n\n"; |
252 | printf " -k or -d must be specified\n\n"; | 348 | printf " -k or -d must be specified\n\n"; |
349 | printf "Note: either -k or -d must be specified and -d is much more network \n"; | ||
350 | printf "intensive. Use it sparingly or not at all. -n is used to match against\n"; | ||
351 | printf "a much more descriptive ifName value in the IfXTable to verify that the\n"; | ||
352 | printf "snmpkey has not changed to some other network interface after a reboot.\n\n"; | ||
253 | print_revision($PROGNAME, '$Revision$'); | 353 | print_revision($PROGNAME, '$Revision$'); |
254 | 354 | ||
255 | } | 355 | } |