#!/usr/bin/perl
# ============================================================================
# ============================== INFO ========================================
# ============================================================================
# Version	: 0.1
# Date		: Feb 9 2014
# Author	: Michiel Timmers ( michiel.timmers AT gmx.net)
# Licence 	: GPL - summary below
#
# ============================================================================
# ============================== SUMMARY =====================================
# ============================================================================
#
# Checks scrabling ratio from MuMuDVB xml file
#
# Check the http://exchange.nagios.org website for new versions.
# For comments, questions, problems and patches send me an 
# e-mail (michiel.timmmers AT gmx.net). 
#
# ============================================================================
# ============================== LICENCE =====================================
# ============================================================================
# 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/>
#
# ============================================================================
# ============================== HELP ========================================
# ============================================================================
# Help : ./check_mumudvb_scrambling.pl --help
#
# ============================================================================

use warnings;
use strict;
use Getopt::Long;
use XML::LibXML;

# ============================================================================
# ============================== NAGIOS VARIABLES ============================
# ============================================================================

my $TIMEOUT 				= 10;	# This is the global script timeout
my %ERRORS				= ('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
my @Nagios_state 			= ("UNKNOWN","OK","WARNING","CRITICAL"); # Nagios states coding


# ============================================================================
# ============================== OID VARIABLES ===============================
# ============================================================================

my $state_location     	= "/monitor/state.xml"; # state.xml location


# ============================================================================
# ============================== GLOBAL VARIABLES ============================
# ============================================================================

my $Version		= '0.1';	# Version number of this script
my $o_host		= undef; 	# Hostname
my $o_port	 	= undef; 	# Port
my $o_help		= undef; 	# Want some help ?
my $o_verb		= undef;	# Verbose mode
my $o_warning		= undef;	# Warning threshold ration
my $o_critical		= undef;	# Critical threshold ration



# ============================================================================
# ============================== SUBROUTINES (FUNCTIONS) =====================
# ============================================================================

# Subroutine: Print version
sub p_version { 
	print "check_mumudvb_scrambling version : $Version\n"; 
}

# Subroutine: Print Usage
sub print_usage {
    print "Usage: $0 [-v] -H <host> -p <port> -w <warning percentage> -c <critical percentage>\n";
}

# Subroutine: Check number
sub isnnum { # Return true if arg is not a number
	my $num = shift;
	if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;}
	return 1;
}

# Subroutine: Set final status
sub set_status { # Return worst status with this order : OK, unknown, warning, critical 
	my $new_status = shift;
	my $cur_status = shift;
	if ($new_status == 1 && $cur_status != 2) {$cur_status = $new_status;}
	if ($new_status == 2) {$cur_status = $new_status;}
	if ($new_status == 3 && $cur_status == 0) {$cur_status = $new_status;}
	return $cur_status;
}


# Subroutine: Print complete help
sub help {
	print "\nMuMuDVB Scrambling plugin for Nagios\nVersion: ",$Version,"\n\n";
	print_usage();
	print <<EOT;

Options:
-v, --verbose
   Print extra debugging information 
-h, --help
   Print this help message
-H, --hostname=HOST
   Hostname or IPv4/IPv6 address of host to check
-P, --port=PORT
   http port 
-w, --warning=PERCENTAGE
   Warning threshold for channel ratio scrambled
-c, --critical=PERCENTAGE
   Critical threshold for channel ratio scrambled
-V, --version
   Prints version number

Notes:
- Check the http://exchange.nagios.org website for new versions.
- For questions, problems and patches send me an e-mail (michiel.timmmers AT gmx.net).

EOT
}

# Subroutine: Verbose output
sub verb { 
	my $t=shift; 
	print $t,"\n" if defined($o_verb); 
}

# Subroutine: Verbose output
sub check_options {
	Getopt::Long::Configure ("bundling");
	GetOptions(
		'v'	=> \$o_verb,		'verbose'	=> \$o_verb,
	        'h'     => \$o_help,    	'help'        	=> \$o_help,
	        'H:s'   => \$o_host,		'hostname:s'	=> \$o_host,
	        'p:i'   => \$o_port,   		'port:i'	=> \$o_port,
		'w:i'   => \$o_warning,         'warning:i'     => \$o_warning,
		'c:i'   => \$o_critical,        'critical:i'    => \$o_critical
	);


	# Basic checks
	if (defined ($o_help) ) {
		help();
		exit $ERRORS{"UNKNOWN"};
	}

	# check host and filter 
	if ( ! defined($o_host) ) {
		print_usage();
		exit $ERRORS{"UNKNOWN"};
	}

	if ( ! defined($o_port) ) {
		print_usage();
		exit $ERRORS{"UNKNOWN"};
	}

	if ( ! defined($o_warning) ) {
		print_usage();
		exit $ERRORS{"UNKNOWN"};
	}

	if ( ! defined($o_critical) ) {
		print_usage();
		exit $ERRORS{"UNKNOWN"};
	}

}


# ============================================================================
# ============================== MAIN ========================================
# ============================================================================

check_options();

# Check gobal timeout if SNMP screws up
if (defined($TIMEOUT)) {
	verb("Alarm at ".$TIMEOUT);
	alarm($TIMEOUT);
}

# Report when the script gets "stuck" in a loop or takes to long
$SIG{'ALRM'} = sub {
	print "CRITICAL: Script timed out\n";
	exit $ERRORS{"CRITICAL"};
};

my $exit_val=undef;

# ============================================================================
# ===================== MuMuDVB - Scrambled channels  ========================
# ============================================================================

# Define variables
my $output			= "";			
my $final_status		= 0;
my ($num_channels,$scram_ok,$scram_warning,$scram_critical)	= (0,0,0,0);

my $filename = "http://".$o_host.":".$o_port.$state_location;
my $parser = XML::LibXML->new();
my $state    = $parser->parse_file($filename);

foreach my $channel ($state->findnodes('/mumudvb/channel')) {
	my $ratio_scrambled = $channel->findnodes('./ratio_scrambled');
	$ratio_scrambled = int($ratio_scrambled->string_value());
	$num_channels++;

	# Number of scrambled channels Ok
	if($ratio_scrambled < $o_warning){
		$scram_ok++;
	}

	# Number of scrambled channels Warning
	if($ratio_scrambled >= $o_warning && $ratio_scrambled < $o_critical){
		$scram_warning++;
		$final_status = &set_status(1,$final_status);
	}

	# Number of scrambled channels Warning
	if($ratio_scrambled >= $o_critical){
		$scram_critical++;
		$final_status = &set_status(2,$final_status);
	}

}



if($num_channels == 0){
	$output = "No channel data found";
	$final_status = &set_status(2,$final_status);
}else{
	$output = "Total channels: ".$num_channels." - Scrambled ratio (Ok/Warning(".$o_warning."%)/Critical(".$o_critical."%)) = ".$scram_ok."/".$scram_warning."/".$scram_critical;
}

if ($final_status == 3) {
	print $output," : UNKNOWN\n";
	exit $ERRORS{"UNKNOWN"};
}
	
if ($final_status == 2) {
	print $output," : CRITICAL\n";
	exit $ERRORS{"CRITICAL"};
}

if ($final_status == 1) {
	print $output," : WARNING\n";
	exit $ERRORS{"WARNING"};
}

print $output," : OK\n";
exit $ERRORS{"OK"};


# ============================================================================
# ============================== NO CHECK DEFINED ============================
# ============================================================================

print "Unknown check type : UNKNOWN\n";
exit $ERRORS{"UNKNOWN"};

