#!/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 traffic 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_critical_tv_traffic	= undef;	# Critical traffic for a TV channel
my $o_warning_tv_traffic	= undef;	# Warning traffic for a TV channel
my $o_critical_radio_traffic	= undef;	# Critical traffic for a Radio channel
my $o_warning_radio_traffic	= undef;	# Warning traffic for a Radio channel


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

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

# Subroutine: Print Usage
sub print_usage {
    print "Usage: $0 [-v] -H <host> -p <port> --w_tv <warning for tv> --c_tv <critical for tv> --w_radio <warning for radio> --c_radio <critical for radio> \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_tv
   Warning traffic TV channel
--c_tv
   Critical traffic TV channel
--w_radio
   Warning traffic Radio channel
--c_radio
   Critical traffic Radio channel
-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,
	        				'c_tv:i'        => \$o_critical_tv_traffic,
	        				'w_tv:i'        => \$o_warning_tv_traffic,
	        				'c_radio:i'     => \$o_critical_radio_traffic,
	        				'w_radio:i'     => \$o_warning_radio_traffic
	);

	# 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_critical_tv_traffic) ) {
		print_usage();
		exit $ERRORS{"UNKNOWN"};
	}

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

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

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

}


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

check_options();

# Check gobal timeout 
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 - Traffic channels  ==========================
# ============================================================================

# Define variables
my $output			= "";			
my $final_status		= 0;
my ($num_tv_channels,$num_radio_channels,$traffic_tv_ok,$traffic_tv_warning,$traffic_tv_critical,$traffic_radio_ok,$traffic_radio_warning,$traffic_radio_critical)	= (0,0,0,0,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 $traffic = $channel->findnodes('./traffic');
	my $name = $channel->findnodes('./name');
	my $service_type = $channel->findnodes('./service_type');
	$traffic = int($traffic->string_value());
	
	# Check TV traffic
	if($service_type =~ /Television/){
		$num_tv_channels++;

		#Traffic above warning threshold = Oke
		if($traffic > $o_warning_tv_traffic){$traffic_tv_ok++;}
		#Traffic lower then warning threshold and above critical = Warning
		if($traffic <= $o_warning_tv_traffic && $traffic > $o_critical_tv_traffic){$traffic_tv_warning++;$final_status = &set_status(1,$final_status);}
		#Traffic lower then critical threshold = Critical
		if($traffic <= $o_critical_tv_traffic){$traffic_tv_critical++;$final_status = &set_status(2,$final_status);}
	}

	# Check Radio traffic
	if($service_type =~ /Radio/){
		$num_radio_channels++;

		#Traffic above warning threshold = Oke
		if($traffic > $o_warning_radio_traffic){$traffic_radio_ok++;}
		#Traffic lower then warning threshold and above critical = Warning
		if($traffic <= $o_warning_radio_traffic && $traffic > $o_critical_radio_traffic){$traffic_radio_warning++;$final_status = &set_status(1,$final_status);}
		#Traffic lower then critical threshold = Critical
		if($traffic <= $o_critical_radio_traffic){$traffic_radio_critical++;$final_status = &set_status(2,$final_status);}
	}
}


if($num_tv_channels == 0 && $num_radio_channels == 0){
	$output = "No channel data found";
	$final_status = &set_status(2,$final_status);
}else{
	$output = "Traffic (Ok/Warning/Critical): ".$num_tv_channels." TV channels = ".$traffic_tv_ok."/".$traffic_tv_warning."/".$traffic_tv_critical." - ".$num_radio_channels." Radio channels = ".$traffic_radio_ok."/".$traffic_radio_warning."/".$traffic_radio_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"};

