#!/usr/bin/perl -w
#
# Check Cisco ISDN Calls 
#
# Plugin uses SNMP connection to router.
#
# Copyright (C) 2009 by Herbert Stadler
# email: hestadler@gmx.at
#
# Used MIB: CISCO-CALL-HISTORY-MIB
# OID:      1.3.6.1.4.1.9.9.27
#
#
#
# License Information:
# 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 3 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, see <http://www.gnu.org/licenses/>. 
#
#

############################################################################


use POSIX;
use strict;
use Getopt::Long;
#use Data::Dumper;

use lib ".";
use lib "/usr/lib/nagios/plugins";
use lib "/usr/lib64/nagios/plugins";
use lib "/usr/local/nagios/libexec";

use utils qw(%ERRORS);
use SNMP;
use Net::SNMP qw(oid_lex_sort oid_base_match :debug);


use constant TRANSLATE_OIDs		=> 0;
use constant DEFAULT_CHECKPERIOD	=> 3600;
use constant NOT_AVAILABLE       	=> "---N/A---";


my ($opt_version,$opt_help,$opt_verbose);
my ($opt_timeout,$opt_license);
my ($opt_hostname,$opt_community,$opt_port,$opt_snmpvers);
my ($opt_snmpdebug,$opt_snmptimeout,$opt_warn,$opt_crit);
my ($opt_desthosts,$opt_checkperiod);

my ($PROGNAME,$REVISION);
my ($state,$msg);
my ($g_snmpdebug);

my $DEFAULT_TIMEOUT		=30;
my $DEFAULT_SNMPTIMEOUT		=2;

my $sysUpTime			= "1.3.6.1.2.1.1.3";
my $sysDescr 			= "1.3.6.1.2.1.1.1";
my $sysLocation			= "1.3.6.1.2.1.1.6";


# MIB OID's of CISCO-CALL-HISTORY-MIB
my $HistoryMib                 = "1.3.6.1.4.1.9.9.27";
my $HistoryMibObjects          = $HistoryMib   . ".1"; 
my $History                    = $HistoryMibObjects . ".1"; 
my $HistoryTableMaxLength      = $History      . ".1";
my $HistoryRetainTimer         = $History      . ".2";
my $HistoryTable               = $History      . ".3";
my $HistoryEntry               = $HistoryTable . ".1";
my $HistoryStartTime           = $HistoryEntry . ".1";
my $HistoryIndex               = $HistoryEntry . ".2";
my $HistoryCallingNumber       = $HistoryEntry . ".3";
my $HistoryCalledNumber        = $HistoryEntry . ".4";
my $HistoryInterfaceNumber     = $HistoryEntry . ".5";
my $HistoryDestinationAddress  = $HistoryEntry . ".6";
my $HistoryDestinationHostName = $HistoryEntry . ".7";
my $HistoryCallDisconnectCause = $HistoryEntry . ".8";
my $HistoryCallConnectionTime  = $HistoryEntry . ".9";
my $HistoryCallDisconnectTime  = $HistoryEntry . ".10";
my $HistoryDialReason          = $HistoryEntry . ".11";
my $HistoryConnectTimeOfDay    = $HistoryEntry . ".12";
my $HistoryDisconnectTimeOfDay = $HistoryEntry . ".13";
my $HistoryTransmitPackets     = $HistoryEntry . ".14";
my $HistoryTransmitBytes       = $HistoryEntry . ".15";
my $HistoryReceivePackets      = $HistoryEntry . ".16";
my $HistoryReceiveBytes        = $HistoryEntry . ".17";

my %Val_HistoryCallDisconnectCause = (
     1 => "other",
     2 => "normalDisconnectSent",
     3 => "normalDisconnectReceived",
     4 => "networkOutOfOrder",
     5 => "callRejected",
     6 => "userBusy",
     7 => "noCircuitChannelAvailable",
     8 => "interworkingError",
   );

$ENV{'PATH'}='';
$ENV{'BASH_ENV'}=''; 
$ENV{'ENV'}='';
$PROGNAME = "check_cisco_isdn";
$REVISION = "1.0";

# Array for ISDN Destination Hosts
my $h_desthosts={};

# Parameters for warning & critical
my $h_para={};

# checking commandline arguments
my $arg_status = check_args();
if ($arg_status){
  print "ERROR: some arguments wrong\n";
  exit ($ERRORS{"UNKNOWN"});
}

if ($opt_snmpdebug) {
  my $module="Net::SNMP";
  printf( "%-20s  Version: %s\n", $module, $module->VERSION );
}

# set alarmhandler for timeouthandling
$SIG{'ALRM'} = sub {
  print ("ERROR: plugin timed out after $opt_timeout seconds \n");
  exit ($ERRORS{"UNKNOWN"});
};

alarm($opt_timeout);

my ($snmp_session,$snmp_error)=open_snmp_session($opt_hostname);
if ( ! defined ($snmp_session)) {
  print "ERROR: Could not open connection: $snmp_error \n";
  exit ($ERRORS{'UNKNOWN'});
}

# Do not convert TimeTicks in a TimeFormat
$snmp_session->translate([ '-timeticks'=>0,'-endofmibview'=>0,'-nosuchobject'=>0,'-nosuchinstance'=>0 ]);

if ( $opt_verbose ) {
  printf("SNMP TranslateMask: %d\n", $snmp_session->translate());
}

# Get some single OID's
my $a_oids=();
push (@{$a_oids},$sysUpTime);
push (@{$a_oids},$sysDescr);
push (@{$a_oids},$sysLocation);
push (@{$a_oids},$HistoryTableMaxLength);
push (@{$a_oids},$HistoryRetainTimer);
my $h_ValOid=get_request($a_oids); 

#  get Cisco History Table
my $h_HistTable=get_table_request($HistoryTable);

$snmp_session->close;

if ( $opt_verbose ) {
  print_Single_OIDs($h_ValOid);
  print_History_Table($h_HistTable);
  printf ("\nNumber of DestinationHosts: %d\n",scalar keys %{$h_desthosts});
  if ( keys %{$h_desthosts}) {
    foreach my $key (keys %{$h_desthosts}) {
      printf ("ISDN DestinationHost: %s\n",$key);
    }
  }
}

# Array for indexvalues OID's
my $a_index=();
foreach my $key (keys (%{$h_HistTable})) {
  if ( oid_base_match($HistoryCallConnectionTime,$key)) {
    my $diff=Oid_Base_Subtract($HistoryCallConnectionTime,$key);
    next if ( ! defined ($diff));

    push (@{$a_index},$diff);
    if ( $opt_verbose ) {
      printf ("Index-Values: %s\n",$diff);
    }
  }
}

# Hashes for open & closed history values
my $h_open={};
my $h_closed={};

# loop over all "index values" and process the history entries
foreach my $key (oid_lex_sort(@{$a_index})) {
  if ( defined ($h_HistTable->{$HistoryCallConnectionTime.".".$key})){
    # Connection opened
    if ( defined ($h_HistTable->{$HistoryCallDisconnectTime.".".$key})){
      # already history, DisconnectTime available
      fill_array($h_closed,$HistoryDestinationHostName,$key,"DestinationHostName");
      my $timeopen=$h_HistTable->{$HistoryCallDisconnectTime.".".$key} - $h_HistTable->{$HistoryCallConnectionTime.".".$key};
      fill_array_abs($h_closed,$timeopen,$key,"TimeOpen");
      fill_array($h_closed,$HistoryDisconnectTimeOfDay,$key,"DisconnectTimeOfDay");
      fill_array($h_closed,$HistoryCallConnectionTime,$key,"ConnectionTime");
      fill_array($h_closed,$HistoryCallDisconnectTime,$key,"DisconnectTime");

    }else{

      # still open
      fill_array($h_open,$HistoryDestinationHostName,$key,"DestinationHostName");
      my $timeopen=$h_ValOid->{$sysUpTime.".0"} - $h_HistTable->{$HistoryCallConnectionTime.".".$key};
      fill_array_abs($h_open,$timeopen,$key,"TimeOpen");
      fill_array($h_open,$HistoryCallConnectionTime,$key,"ConnectionTime");
      fill_array_abs($h_open,$h_ValOid->{$sysUpTime.".0"},$key,"DisconnectTime");
    }
  }
}

# Now we start with error checking 
# --------------------------------

# Array for entries for the defined checkperiod
my $h_chkperiod={};

my $sw_first_line=1;
# connections still open
foreach my $dest (keys %{$h_open}) {
  if ( scalar keys %{$h_desthosts} > 0 ) {
    # check if single "Destinations" exits
    next if ( ! exists($h_desthosts->{$dest}));
  }

  foreach my $timestamp (keys %{$h_open->{$dest}}) {
    my $time_sec = $h_open->{$dest}{$timestamp}{TimeOpen} / 100;
    if ( $opt_verbose ) {
      if ( $sw_first_line == 1 ) {
        $sw_first_line = 0;
        printf ("\n");
      }
      printf ("LineOpen  : %-20s, %0.2f sec\n",$dest,$time_sec);
    }
    Check_Time_Window ($dest,$h_open->{$dest}{$timestamp}{ConnectionTime},$h_open->{$dest}{$timestamp}{DisconnectTime});
  }
}

$sw_first_line = 1;
# connections already closed
foreach my $dest (keys %{$h_closed}) {
  if ( scalar keys %{$h_desthosts} > 0 ) {
    next if ( ! exists($h_desthosts->{$dest}));
  }

  foreach my $timestamp (keys %{$h_closed->{$dest}}) {
    my $time_sec = $h_closed->{$dest}{$timestamp}{TimeOpen} / 100;
    my $dtofday  = $h_closed->{$dest}{$timestamp}{DisconnectTimeOfDay};
    if ( $opt_verbose ) {
      if ( $sw_first_line == 1 ) {
        $sw_first_line = 0;
        printf ("\n");
      }
      printf ("LineClosed: %-20s, %0.2f sec, %s\n",$dest,$time_sec,$dtofday);
    }
    Check_Time_Window ($dest,$h_closed->{$dest}{$timestamp}{ConnectionTime},$h_closed->{$dest}{$timestamp}{DisconnectTime});
  }
}

# set standard values for program exit
$msg = "ISDN OK - No Problems found";
$state = $ERRORS{'OK'};

my $l_tmsg;

foreach my $dest (keys %{$h_chkperiod}) {

  my $time_sec = $h_chkperiod->{$dest}{TimeOpen} / 100;

  if ( $opt_verbose ) {
    printf ("TotalValues: %s, %0.2f secs\n",$dest, $time_sec);
  }

  if ( $time_sec < $h_para->{IdsnOpenTimeWarn} ) {
    # everything ok
    my $l_tmess=sprintf("OK:%s:%d sec",$dest,$time_sec);
    Set_Error_Msg ($ERRORS{'OK'},$l_tmess);
  }elsif ( $time_sec < $h_para->{IdsnOpenTimeCrit} ) {
    # in warning area
    my $l_tmess=sprintf("W:%s:%d sec",$dest,$time_sec);
    Set_Error_Msg ($ERRORS{'WARNING'},$l_tmess);
  } else {
    # in critical area
    my $l_tmess=sprintf("C:%s:%d sec",$dest,$time_sec);
    Set_Error_Msg ($ERRORS{'CRITICAL'},$l_tmess);
  }
}


# and now "over and out"

if ( $state != $ERRORS{'OK'} ) {
  if ( $state == $ERRORS{'CRITICAL'} ) {
    $msg="ISDN CRITICAL - ".$l_tmsg;
  } elsif ( $state == $ERRORS{'WARNING'} ) {
    $msg="ISDN WARNING - ".$l_tmsg;
  } else {
    $msg="ISDN UNKNOWN - ".$l_tmsg;
  }
}

print "$msg\n";
exit ($state);




#--------------------------------------------------------------------------#
# S U B R O U T I N E S                                                    #
#--------------------------------------------------------------------------#

#--------------------------------------------------------------------------
sub Check_Time_Window {
#--------------------------------------------------------------------------
  my ($Destination,$ConnectionTime,$DisconnectTime)=@_;

  # this is our reference time
  my $timenow=$h_ValOid->{$sysUpTime.".0"};
  my $windowstart=$timenow - ($opt_checkperiod * 100);

  if ( $DisconnectTime < $windowstart ) {
    # out of TimeWindow back to where we came from
    return;
  }

  my $open_hsec;

  if ( $ConnectionTime < $windowstart ) {
    # we have to calculate the difference now
    $open_hsec = $DisconnectTime - $windowstart;
  }else{
    # we can take the whole time
    $open_hsec = $DisconnectTime - $ConnectionTime;
  }

  # Add up all "open seconds" in the TimeWindow
  if ( ! exists ($h_chkperiod->{$Destination}{TimeOpen})) {
    $h_chkperiod->{$Destination}{TimeOpen}=0;
  }

  if ( $opt_verbose ) {
    printf ("Adding %s, %0.02f secs\n",$Destination,$open_hsec/100);
  }
 
  $h_chkperiod->{$Destination}{TimeOpen}+=$open_hsec;
}

#--------------------------------------------------------------------------
sub Get_DestinationHostName {
#--------------------------------------------------------------------------
  my ($index)=@_;

  # give back the DestinationHostname
  if ( defined ($h_HistTable->{$HistoryDestinationHostName.".".$index})){
    return($h_HistTable->{$HistoryDestinationHostName.".".$index});
  }

  if ( $opt_verbose ) {
    printf("DestinationHostName not found for index: %s\n",$index);
  }

  # sometimes the OID's for the Hostnames are not filled, so we return
  # the telephonenumber

  if ( defined ($h_HistTable->{$HistoryCallingNumber.".".$index})){
    if ( $h_HistTable->{$HistoryCallingNumber.".".$index} ne NOT_AVAILABLE ){
      return($h_HistTable->{$HistoryCallingNumber.".".$index});
    }
  }

  if ( defined ($h_HistTable->{$HistoryCalledNumber.".".$index})){
    if ( $h_HistTable->{$HistoryCalledNumber.".".$index} ne NOT_AVAILABLE ){
      return($h_HistTable->{$HistoryCalledNumber.".".$index});
    }
  }

  return("");
}

#--------------------------------------------------------------------------
sub fill_array {
#--------------------------------------------------------------------------
  my ($h_array,$source,$index,$fnam)=@_;

  if ( defined ($h_HistTable->{$source.".".$index})){
    my ($timestamp,$other)=split('\.',$index);
    my $dhn=Get_DestinationHostName($index);
    $h_array->{$dhn}{$timestamp}{$fnam}=$h_HistTable->{$source.".".$index};
  }
}

#--------------------------------------------------------------------------
sub fill_array_abs {
#--------------------------------------------------------------------------
  my ($h_array,$source,$index,$fnam)=@_;

  if ( defined ($source)){
    my ($timestamp,$other)=split('\.',$index);
    my $dhn=Get_DestinationHostName($index);

#-- for debugging
    my $f_out=0;
    my $lxx="";

    if ( ! defined($dhn) ) {
      $f_out=1;
      $lxx.="dhn undefined,";
      $dhn="";
    }
    if ( ! defined($timestamp) ) {
      $f_out=1;
      $lxx.="timestamp undefined,";
      $timestamp="";
    }
    if ( ! defined($fnam) ) {
      $f_out=1;
      $lxx.="fnam undefined,";
      $fnam="";
    }
    if ( ! defined($source) ) {
      $f_out=1;
      $lxx.="source undefined,";
      $source="";
    }
    if ( $f_out == 1 ) {
      open (OUTD,">>/tmp/ISDN_Debugging.txt");
      printf(OUTD "lxx   :%s\n",$lxx||"");
      printf(OUTD "dhn:  :%s\n",$dhn||"");
      printf(OUTD "timest:%s\n",$timestamp||"");
      printf(OUTD "fnam  :%s\n",$fnam||"");
      printf(OUTD "source:%s\n",$source||"");
      foreach my $key (oid_lex_sort(keys (%{$h_HistTable}))) {
        printf (OUTD "%-50s: %s\n",$key,$h_HistTable->{$key});
      }
      printf(OUTD "%s\n","------------");
      close(OUTD);
    }
#-- for debugging

    $h_array->{$dhn}{$timestamp}{$fnam}=$source;
  }
}

#--------------------------------------------------------------------------
sub Make_Hex {
#--------------------------------------------------------------------------
  my ($str)=@_;

  $str =~ s/(.)/' %' . unpack("H8", $1)/eg;
  return($str);
}

#--------------------------------------------------------------------------
sub Oid_Base_Subtract {
#--------------------------------------------------------------------------
  my ($base, $oid)=@_;

  $base || return ($oid);
  $oid  || return (undef);

  $base =~ s/^\.//o;
  $oid  =~ s/^\.//o;

  $base = pack('N*', split('\.', $base));
  $oid  = pack('N*', split('\.', $oid));

  my $blength = length($base);

  if (! substr($oid, 0, $blength) eq $base) {
    return(undef);
  }

  # replace all with blanks
  substr($oid, 0, $blength,"");

  my $ret = join(".",unpack('N*',$oid));

  return($ret); 
}

#--------------------------------------------------------------------------
sub open_snmp_session {
#--------------------------------------------------------------------------
  my ($l_host)=@_;

  # open SNMP Session to Router
  my ($snmp_session,$snmp_error)=Net::SNMP->session(
	-hostname 	=> 	$l_host,
	-community 	=> 	$opt_community || 'public',
	-port		=>	$opt_port || 161,
	-timeout	=>	$opt_snmptimeout,
	-retries	=>	3,
	-debug		=>	$g_snmpdebug,
	-maxmsgsize	=>	32768,
	-version	=>	$opt_snmpvers,
	);
  return ($snmp_session,$snmp_error);
}

#--------------------------------------------------------------------------
sub Set_Error_Msg {
#--------------------------------------------------------------------------
  my ($l_StateNew,$l_messtxt)=@_;

  if ($l_StateNew == $ERRORS{'OK'}) {
    return;
  }

  # warning, critical, unknown Messages
  if ($state < $l_StateNew) {
    $state = $l_StateNew;
  }

  if (defined ($l_tmsg)){
    $l_tmsg.=",";
  }

  $l_tmsg.=$l_messtxt;
}


#--------------------------------------------------------------------------
sub get_table_request {
#--------------------------------------------------------------------------
  my ($l_oid)=@_;

  my $l_snmp_result=$snmp_session->get_table(
  	-baseoid 	=>	$l_oid
  	);

  if ($snmp_session->error_status != 0) {
    if ( $snmp_session->error=~/table is empty/ ) {
      return ($l_snmp_result);
    }
    printf ("ERROR %d: get_table_request: (%s) %s\n",$snmp_session->error_status,$l_oid,$snmp_session->error);
    $snmp_session->close;
    exit $ERRORS{'UNKNOWN'};
  }
  return ($l_snmp_result);
}

#--------------------------------------------------------------------------
sub get_request {
#--------------------------------------------------------------------------
  my ($l_oid)=@_;

  my $l_snmp_result=$snmp_session->get_next_request(
 	-varbindlist	=>	$l_oid,
  	);

  if ($snmp_session->error_status != 0) {
    print "ERROR %d get_request: ",$snmp_session->error_status,$snmp_session->error,"\n";
    $snmp_session->close;
    exit $ERRORS{'UNKNOWN'};
  }
  return ($l_snmp_result);
}

#--------------------------------------------------------------------------
sub check_args {
#--------------------------------------------------------------------------
  Getopt::Long::Configure('bundling');
  GetOptions
	("V"   			=> \$opt_version,
	 "version"   		=> \$opt_version,
	 "L"   			=> \$opt_license, 
	 "license"   		=> \$opt_license, 
	 "v"   			=> \$opt_verbose, 
	 "verbose"   		=> \$opt_verbose, 
	 "D"   			=> \$opt_snmpdebug, 
	 "debug"     		=> \$opt_snmpdebug, 
	 "h|?" 			=> \$opt_help,
	 "help"   		=> \$opt_help,
	 "T=i" 			=> \$opt_snmptimeout, 
	 "snmptimeout=i" 	=> \$opt_snmptimeout, 
	 "t=i" 			=> \$opt_timeout, 
	 "timeout=i" 		=> \$opt_timeout, 
	 "H=s" 			=> \$opt_hostname, 
	 "hostname=s" 		=> \$opt_hostname, 
	 "C=s" 			=> \$opt_community, 
	 "community=s" 		=> \$opt_community, 
	 "p=i" 			=> \$opt_port, 
	 "port=i" 		=> \$opt_port, 
	 "s=s" 			=> \$opt_snmpvers, 
	 "snmpvers=s" 		=> \$opt_snmpvers, 
	 "w=s" 			=> \$opt_warn, 
	 "warn=s"     		=> \$opt_warn, 
	 "c=s" 			=> \$opt_crit, 
	 "crit=s"     		=> \$opt_crit, 
	 "I=s" 			=> \$opt_desthosts,
	 "idesthost=s" 		=> \$opt_desthosts,
	 "P=i" 			=> \$opt_checkperiod,
	 "chekperiod=i" 	=> \$opt_checkperiod,
	 );

  if ($opt_license) {
    print_gpl($PROGNAME,$REVISION);
    exit ($ERRORS{'OK'});
  }

  if ($opt_version) {
    print_revision($PROGNAME,$REVISION);
    exit ($ERRORS{'OK'});
  }

  if ($opt_help) {
    print_help();
    exit ($ERRORS{'OK'});
  }

  if ( ! defined($opt_hostname)){
    print "\nERROR: Hostname not defined\n\n";
    print_usage();
    exit ($ERRORS{'UNKNOWN'});
  }

  unless (defined $opt_snmpvers) {
    $opt_snmpvers = "snmpv2c";
  }
  if ( ($opt_snmpvers ne "snmpv1") && ($opt_snmpvers ne "snmpv2c") ){
    print "\nERROR: SNMP version unknown\n\n";
    print_usage();
    exit ($ERRORS{'UNKNOWN'});
  }

  unless (defined $opt_warn) {
    print "\nERROR: parameter -w <warn> not defined\n\n";
    print_usage();
    exit ($ERRORS{'UNKNOWN'});
  }

  unless (defined $opt_crit) {
    print "\nERROR: parameter -c <crit> not defined\n\n";
    print_usage();
    exit ($ERRORS{'UNKNOWN'});
  }

  unless (defined $opt_timeout) {
    $opt_timeout = $DEFAULT_TIMEOUT;
  }

  unless (defined $opt_snmptimeout) {
    $opt_snmptimeout = $DEFAULT_SNMPTIMEOUT;
  }

  unless (defined $opt_port) {
    $opt_port = 161;
  }

  unless (defined $opt_checkperiod) {
    $opt_checkperiod = DEFAULT_CHECKPERIOD;
  }

  if ($opt_snmpdebug) {
    $g_snmpdebug = DEBUG_ALL;
  }else{
    $g_snmpdebug = DEBUG_NONE;
  }

  if ($opt_desthosts) {
    my @a_dh=split(',',$opt_desthosts);
    foreach my $dh (@a_dh) {
      $h_desthosts->{$dh}="";
    }
  }

  my ($IsdnOpen); 

  ($IsdnOpen)=split(',',$opt_warn);
  $h_para->{IdsnOpenTimeWarn}=$IsdnOpen;

  ($IsdnOpen)=split(',',$opt_crit);
  $h_para->{IdsnOpenTimeCrit}=$IsdnOpen;

  return ($ERRORS{'OK'});
}

#--------------------------------------------------------------------------
sub print_usage {
#--------------------------------------------------------------------------
  print "Usage: $PROGNAME [-h] [-L] [-t <plugin-timeout>] [-T <snmp-timeout>] [-v] [-V] [-C <community>] [-p <port>] [-s snmpv1|snmpv2c] -H <hostname> [-I <ISDN Destination Hostname>] [-P <seconds>] -w <warning> -c <critical>\n";
}

#--------------------------------------------------------------------------
sub print_help {
#--------------------------------------------------------------------------
  print_revision($PROGNAME,$REVISION);
  printf ("\n");
  print_usage();
  printf ("\n");
  printf ("   Check ISDN Lines via SNMP\n");
  printf ("   using Cisco Mib CISCO-CALL-HISTORY\n\n");
  printf ("-t (--timeout)     Timeout in seconds (default = %d)\n",$DEFAULT_TIMEOUT);
  printf ("-T (--snmptimeout) SNMP CallTimeout in seconds (default = %d)\n",$DEFAULT_SNMPTIMEOUT);
  printf ("-H (--hostname)    Host to monitor\n");
  printf ("-I (--idesthost)   Check ISDN Destination Hostname (multiple possible)\n");
  printf ("-s (--snmpvers)    SNMP Version [snmpv1|snmpv2c]\n");
  printf ("-C (--community)   SNMP Community\n");
  printf ("-p (--port)        SNMP Port\n");
  printf ("-P (--checkperiod) Timewindow to check of open lines (default = %d secs)\n",DEFAULT_CHECKPERIOD);
  printf ("-w (--warn)        Parameters warning\n");
  printf ("-c (--crit)        Parameters critical\n");
  printf ("-h (--help)        Help\n");
  printf ("-V (--version)     Programm version\n");
  printf ("-v (--verbose)     Print some useful information\n");
  printf ("-L (--license)     Print license information\n");
  printf ("\n\n");
}

#--------------------------------------------------------------------------
sub print_Single_OIDs {
#--------------------------------------------------------------------------
  my ($table)=@_;

  printtable  ("CISCO ISDN OIDs");
  my $translated;
  foreach my $key (oid_lex_sort(keys (%{$table}))) {
    $translated=$key;
    if (TRANSLATE_OIDs) {
      $translated=SNMP::translateObj($translated); 
    }
    printtabular($translated,$table->{$key});
  }
}

#--------------------------------------------------------------------------
sub print_History_Table {
#--------------------------------------------------------------------------
  my ($table)=@_;

  printtable  ("CISCO ISDN History Table");
  my $translated;
  foreach my $key (oid_lex_sort(keys (%{$table}))) {
    $translated=$key;
    if (TRANSLATE_OIDs) {
      $translated=SNMP::translateObj($translated); 
    }
    printtabular($translated,$table->{$key});
  }
}

#--------------------------------------------------------------------------
sub printhead {
#--------------------------------------------------------------------------
  my ($l_head)=@_;

  printf ("\n%-40s\n",$l_head);
}

#--------------------------------------------------------------------------
sub printtable {
#--------------------------------------------------------------------------
  my ($l_head)=@_;

  printf ("\n%-40s\n",$l_head);
  my $len=length($l_head);
  my $line="=" x $len;
  printf ("%-40s\n",$line);
}

#--------------------------------------------------------------------------
sub printscalar {
#--------------------------------------------------------------------------
  my ($l_arg,$l_val)=@_;

  printf ("%-35s: %-30s\n",$l_arg,$l_val);
}

#--------------------------------------------------------------------------
sub printtabular {
#--------------------------------------------------------------------------
  my ($l_arg,$l_val)=@_;

  printf ("%-50s: %s\n",$l_arg,$l_val);
}


#--------------------------------------------------------------------------
sub print_gpl {
#--------------------------------------------------------------------------
  print <<EOD;

  Copyright (C) 2009 by Herbert Stadler
  email: hestadler\@gmx.at

  License Information:
  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 3 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, see <http://www.gnu.org/licenses/>. 

EOD

}

#--------------------------------------------------------------------------
sub print_revision {
#--------------------------------------------------------------------------
  my ($l_prog,$l_revision)=@_;

  print <<EOD

$l_prog $l_revision, Copyright (C) 2009 Herbert Stadler

This program comes with ABSOLUTELY NO WARRANTY; 
for details type "$l_prog -L".
EOD
}



=head1 NAME

 check_cisco_isdn

=head1 DESCRIPTION

 Checking Cisco ISDN Lines via SNMP protocol.

 Plugin created for Nagios Monitoring.

=head1 SYNOPSIS

 check_cisco_isdn -H <hostname> 

 for more information call:

     check_cisco_isdn -h


=head1 AUTHOR

 Herbert Stadler, Austria (hestadler@gmx.at)
 May 2009

 This plugin is a contribution to the nagios community.

=head1 REQUIRED SOFTWARE

 from search.cpan.org
   Net::SNMP Package   	e.g: Net-SNMP-5.2.0.tar.gz

 Used MIB (not necessary for executing the script)
    CISCO-CALL-HISTORY-MIB

    easy to find on "http://tools.cisco.com" 

=head1 HOW TO CHECK THE ROUTER-SNMP FUNCTIONALITY

 snmpwalk <routerip> -v 1 -c public 1.3.6.1.4.1.9.9.27

 should return a lot of lines

=head1 CHECK ROUTER CONFIGURATION

 please check the following router parameters:

 HistoryTableMaxLength
      "The upper limit on the number of entries that the
      HistoryTable may contain. A value of 0
      will prevent any history from being retained. When
      this table is full, the oldest entry will be deleted
      and the new one will be created."

 HistoryRetainTimer
      "The minimum amount of time that an HistoryEntry
      will be maintained before being deleted. A value of
      0 will prevent any history from being retained, but
      will not prevent callCompletion traps being genarated."

=head1 CHECK PLUGIN FUNCTIONALITY VIA COMMANDLINE

 example:

 /<plugin_path>/check_cisco_isdn -H 10.37.116.2 -w 10 -c 20 -C public -v -P 300

 Checking of last 300 seconds if isdn-line is longer than 10/20 seconds open.
 
 Normally the router returns a lot of "ISDN-Destinations" if you want to check only one destination use parameter "-I". Multiple Entries are possible separated by ",".

 /<plugin_path>/check_cisco_isdn -H 10.37.116.2 -w 10 -c 20 -C public -v -P 300 -I <ISDN Destination Hostname>


=head1 CONFIGURATION IN NAGIOS

 Copy this plugin to the nagios plugin installation directory 
 e.g.: /usr/lib(64)/nagios/plugins

 COMMAND DEFINITION:

 # "check_cisco_isdn" command definition

 define command{
    command_name    check_cisco_isdn
    command_line    $USER1$/check_cisco_isdn -H $HOSTADDRESS$ -w "$ARG1$" -c "$ARG2$" -P "$ARG3$" -C "$ARG4$"
    }


=head1 PLUGIN HISTORY

 Version 1.0 - 2009-05-18	first release

=head1 COPYRIGHT AND DISCLAIMER

 Copyright (C) 2009 by Herbert Stadler
 email: hestadler@gmx.at

 License Information:
 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 3 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, see <http://www.gnu.org/licenses/>. 
 

=cut
