123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- #!/usr/bin/perl -W
- #
- # Maximilian Wilhelm <max@rfc2324.org>
- # -- 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 = <INTERFACES>) {
- 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 = <NEIGHBORS>) {
- 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);
|