#!/usr/bin/perl -wT
#
# check_dlswcircuit.pl - nagios plugin 
# 
# Checks if a Cisco Dlsw circuit is connected.
#
#
# Copyright (C) 2000 Carsten Foss & Christoph Kron
# 
# Basically this is an adapted version of Christoph Kron's (ck@zet.net) check_ifoperstatus.pl plugin.
# most of the thanks should go to him.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# Arguments : -s <SourceMac> -d <DestMac> -c <READCOMMUNITY> -p <PORT> <HOSTNAME or IP-Addr>
#		-
# Source & Dest Mac/Sap arguments must be given in Hex as this example : 40.00.01.37.45.01.ss (Where ss is the sap) 
#
# Sample command line : check_dlswcircuit.pl -s 40.00.01.37.45.01.04 -d 40.00.02.37.45.02.04 -c secret 1.2.3.4
#
# Sample host.cfg entry :
#service[Dlsw-xx]=NCP1-NCP2;0;24x7;3;5;1;router-admins;240;24x7;1;1;0;;check_dlswcircuit!-s 40.00.01.37.45.01.04!-d 40.00..01.37.45.02.04!-c secret!1.2.3.4
# remember to add the service to commands.cfg , something like this:
# command[check_dlswcircuit]=$USER1$/check_dlswcircuit.pl $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$
#
# Report bugs to: cfo@dmdata.dk
#
# 11.03.2000 Version 1.0

require 5.004;
use strict;
use lib utils.pm ;
use Plugin;
use Plugin::Parameter qw($helpparameterlist $versionparameterlist $hostnameparameter
			 $communityparameter $portparameter $timeoutparameter
			 $verboseparameter);

use Net::SNMP;

use vars qw($opt_H $opt_C $opt_p $opt_t $opt_v $opt_s $opt_d $PROGNAME);
use utils qw(%ERRORS);

my $checkmac = sub { my ($opt, $parameter, $plugin) = @_;
		     if (!defined $$opt) {
		       $plugin->usage();
		       &utils::usage("$main::PROGNAME UNKNOWN: Option (--" . $parameter->name() .") required but not set\n");
		     }
		     my @macs = ("$$opt" =~ m/:/)?(split /:/, "$$opt"):(split /\./, "$$opt");
		     if (@macs == 6) {
		     NOTVALID: {
			 foreach my $mac (@macs) {
			   if ("$mac" !~ m/^[[:xdigit:]]{1,2}$/) { last NOTVALID; }
			 }
			 # All OK
			 return;
		       }
		     }
		     $plugin->usage();
		     &utils::usage("$PROGNAME UNKNOWN: Option (--" . $parameter->name() . ") invalid mac address $$opt\n");
		   };
my $sourcemacparameter = new Plugin::Parameter(-name => "sourcemac", -flags => [ 's', 'sourcemac' ],
					       -optional => "no", -valueoptional => "no", -type => "MACADDRESS",
					       -checker => $checkmac,
					       -description => "The source mac/sap address of the DLSW circuit");
my $destmacparameter = new Plugin::Parameter(-name => "sourcemac", -flags => [ 'd', 'destmac' ],
					     -optional => "no", -valueoptional => "no", -type => "MACADDRESS",
					     -checker => $checkmac,
					     -description => "The destination mac/sap address of the DLSW circuit");
$portparameter->default("snmp");
my @commandparameterlist = ( $hostnameparameter,
			     $communityparameter,
			     $sourcemacparameter,
			     $destmacparameter,
			     $portparameter,
			     $timeoutparameter,
			     $verboseparameter );

my $plugin = new Plugin(-revision => '$Revision: 1.1.1.1 $',
			-copyright => " 2000 Carsten Foss,2004 Howard Wilkinson <howard\@cohtech.com>",
			-shortcomment => "Perl Check Cisco Dlsw Circuit State plugin for Nagios. Checks operational status of specified DLSW Circuit.",
			-longcomment => "Source and Destination Mac/Sap arguments must be given in Hex as in this example: 40::01:37:45:01:ss (Where ss is the sap). A '.' can be used as a separator rather than a ':' if required.",
			-parameterlists => [ \@commandparameterlist, $helpparameterlist, $versionparameterlist ]);

my $status;
my $TIMEOUT = 15;

my %dlswCircuitStatus = ('1','disconnected',
			 '2','circuitStart',
			 '3','resolvePending',
			 '4','circuitPending',
			 '5','circuitEstablished',
			 '6','connectPending',
			 '7','contactPending',
			 '8','connected',
			 '9','disconnectPending',
			 '10','haltPending',
			 '11','haltPendingNoack',
			 '13','circuitRestart',
			 '14','restartPending');

#Dlsw Circuit Oid enterprises.9.10.9.1.5.2.1.17.6.0.96.148.47.230.166.4.6.64.0.1.55.69.2.4 = 8
my $enterpriseOid = "1.3.6.1.4.1";
my $ciscoDlswCircuitOid = ".9.10.9.1.5.2.1.17.";
my $unknownOid = "6.";

$plugin->init();

#
#Convert Source Mac & Sap
#
my $smacOid = "";
my $prefix = "";
my @tmparg = ("$opt_s" =~ m/:/)?(split /:/, "$opt_s"):(split /\./, "$opt_s");
foreach my $p (@tmparg) {
  my $q = hex($p);
  $smacOid = $smacOid . $prefix . $q;
  $prefix = ".";
}

#
#Convert Dest Mac & Sap
#
my $dmacOid = "";
$prefix = "";
@tmparg = ("$opt_d" =~ m/:/)?(split /:/, "$opt_d"):(split /\./, "$opt_d");
foreach my $p (@tmparg) {
  my $q = hex($p);
  $dmacOid = $dmacOid . $prefix . $q;
  $prefix = ".";
}

my $snmpoid = $enterpriseOid.$ciscoDlswCircuitOid.$unknownOid.$smacOid.$unknownOid.$dmacOid ;

my ($session, $error) = Net::SNMP->session(-hostname  => $opt_H,
					   -community => $opt_C,
					   -port      => $opt_p,
					   -timeout   => $opt_t,
					   -version   => "snmpv1");

my $state = "UNKNOWN";
my $answer = "";

if (!defined($session)) {
  $answer=$error;
  print ("$PROGNAME $state: $answer");
  exit $ERRORS{$state};
}

my @snmpoids = ( $snmpoid );
#push(@snmpoids,$snmpLocIfDescr);

my $response = $session->get_request(@snmpoids);

if (!defined $response) {
  $answer=$session->error;
  $session->close;
  $state = 'CRITICAL';
  print ("$PROGNAME $state: $answer, $opt_s - $opt_d");
  exit $ERRORS{$state};
}

$session->close;

$answer = sprintf("dlsw circuit %s - %s at host '%s',is %s\n", 
		  $opt_s,
		  $opt_d,
		  $opt_H,
		  $dlswCircuitStatus{$response->{$snmpoid}});

if ( $response->{$snmpoid} == 8 ) {
  $state = 'OK';
} else {
  $state = 'CRITICAL';
}

print ("$PROGNAME $state: $answer");
exit $ERRORS{$state};
