#!/usr/bin/perl -W # # Maximilian Wilhelm # -- Tue 04 Apr 2017 07:00:50 PM CEST # use strict; # Should we check the OSPF process for IPv4 or IPv6? my $cmds = { "-4" => "birdc", "-6" => "birdc6", }; # Default to Legacy IP my $cmd = $cmds->{"-4"}; if ($ARGV[0]) { unless (defined $cmds->{$ARGV[0]}) { print STDERR "Usage: $0 [ -4 | -6 ]\n"; exit (1); } $cmd = $cmds->{$ARGV[0]}; } my $code = 0; my $msg = ""; if (not open (INTERFACES, "$cmd show ospf interface |")) { print "Failed to read OSPFv4 interfaces: $!\n"; exit (2); } if (not open (NEIGHBORS, "$cmd show ospf neighbors |")) { print "Failed to read OSPFv4 neighbors: $!\n"; exit (2); } # Store any configured OSPF interfaces my $interfaces = {}; my $interface = undef; while (my $line = ) { chomp ($line); # Create entry in interface hash if ($line =~ /^Interface (.+) \(/) { $interface = $1; $interfaces->{$interface} = {}; } # Store Type and State attributes elsif ($line =~ m/(Type|State): (.+)$/) { $interfaces->{$interface}->{$1} = $2; } } close (INTERFACES); # Delete any stub interfaces from our list for my $iface (keys %{$interfaces}) { if ($interfaces->{$iface}->{State} =~ m/\(stub\)/) { delete $interfaces->{$iface}; } } my @ok = (); my @broken = (); my @down = (); # Check all neighor states while (my $line = ) { chomp ($line); if ($line =~ m@^([[:xdigit:].:]+)\s+(\d+)\s+([[:alnum:]/-]+)\s+([0-9:]+)\s+([[:alnum:]_.-]+)\s+([[:xdigit:].:]+)@) { my ($peer, $state, $ifname) = ($1, $3, $5); my $interface = $interfaces->{$ifname}; # Mark interfaces as "up" in bird $interface->{up} = 1; # State FULL is awesome. if ($state =~ m@Full@) { push @ok, "$ifname/$peer"; } # In broadcast areas there are only two FULL sessions (to the DR and BDR), # all other sessions will be 2-Way/Other which is perfectly fine. elsif ($state eq "2-Way/Other" and $interface->{Type} eq "broadcast") { push @ok, "$ifname/$peer"; } # Everything else is considered broken. # Likely some ExStart/* etc. pointing to possible MTU troubles. else { push @broken, "$ifname/$peer:$state"; } } } close (NEIGHBORS); # Check for any interfaces which should have (at least) an OSPF peer # but don't appear in the neighbors list for my $iface (keys %{$interfaces}) { if (not defined $interfaces->{$iface}->{up}) { push @down, $iface; } } # Any down interfaces? if (@down) { $code = 2; $msg .= "DOWN: " . join (', ', @down) . " "; } # Any broken sessions? if (@broken) { # Issue a warning when there are issues.. if ($code < 2) { $code = 1 } $msg .= "BROKEN: " . join (', ', @broken) . " "; } print $msg . "OK: " . join (', ', @ok) . "\n"; exit ($code);