#! /usr/bin/perl -w
#
################################################################
# Changelog
################################################################
# Version 1.0.4.5
# 2024.01.25
# changed volumestatus "Checking..." to WARNING
################################################################
# Version 1.0.4.4
# 2023.03.02
# Adaptation to version QTS 5.0.x
################################################################
# Version 1.0.4.3
# 2021.12.14
# rewrite mode switch
# as bugfixes
################################################################
# Version 1.0.4.2
# 2020.01.25
# added mode memory
# some bugfixes
################################################################
# Version 1.0.4.1
# 2018.09.28
# change from cpu-temp to sys-temp
################################################################
# Version 1.0.4
# 2016.03.19
# works with Monitoring::Plugin and Nagios::Plugin
# added warnig if SmartInfoStatus not 'GOOD'
# some new environment features
################################################################
# Version 1.0.3
# 2014.09.30
# version skipped
################################################################
# Version 1.0.2
# 2014.06.10
# added smart info to plugin output
# thanks to
# http://exchange.nagios.org/directory/Reviews/dit_w/1#/
################################################################
# Version 1.0.1
# 2014.02.19
# change some vars from my to our
# thanks to
# http://exchange.nagios.org/directory/Reviews/navi/1
################################################################
# Version 1.0
# 2013.01.19
################################################################

use strict ;
use warnings ;

use Data::Dumper;
use Net::SNMP qw(oid_lex_sort oid_base_match) ;

our $PROGNAME = 'check_qnapdisk' ;
our $VERSION = '1.0.4.5' ;
my $usage="Usage: $PROGNAME [-h] [-V] -H hostname [-t timeout] [-r retries] 
[-C community] [-p port] [-w warning] [-c critical] [-T C | F ] [-g temp_warning] 
[-l temp_critical] [-v verbose] [-d debug] [-M mode]";

my $blurb="'This plugin checks all disk slots on your QNAP NAS host with snmp 
and will output OK, UNKNOWN, WARNING or CRITICAL if the resulting 
number is over the specified thresholds. Enable on your QNAP NAS 
the snmpd (see the QNAP adminguide too).";

my $shortname="QNAP";

my $extra="   THRESHOLDs for -w and -c are specified 'min:max' or 'min:' or ':max' (or 'max'). 
   If specified '\@min:max', a warning status will be generated if the count 
   *is* inside the specified range.\n   example : $PROGNAME -H 'ip-address or 
   [DNS|host]name' -t 5 -r 2 -C public -p 161 -w 2: -c 1: -T C -g 25 -l 35 -v -M disk";

our $np;
if ( eval{require Nagios::Plugin} ) {
	$np = Nagios::Plugin->new(
		usage => $usage,
		version => $VERSION,
		blurb => $blurb,
		shortname => $shortname,
		extra => $extra,
		);
	}
elsif ( eval{require Monitoring::Plugin} ) {
	$np = Monitoring::Plugin->new(
		usage => $usage,
		version => $VERSION,
		blurb => $blurb,
		shortname => $shortname,
		extra => $extra,
		);
	} 
else {
	print "can't load Nagios::Plugin or Monitoring::Plugin\n";
	exit 3;
	}

$np->add_arg(
	spec => 'warning|w=s',
	help => qq{-w, --warning=INTEGER,[INTEGER] Maximum number of allowable result, 
                outside of which a warning will be generated. If omitted, no warning is generated.},
	default => '0:',
	required => 0,
	);

$np->add_arg(
	spec => 'critical|c=s',
	help => qq{-c, --critical=INTEGER,[INTEGER] Maximum number of the generated result,
                outside of which a critical will be generated.},
	default => '0:',
	required => 0,
	);

$np->add_arg(
	spec => 'temperature|T=s',
	help => qq{-T, --temperature=STRING, Specify to use Celsius (default) or Fahrenheit.}, 
	default => 'C',
	required => 0,
	);

$np->add_arg(
	spec => 'temp_warning|g=s',
	help => qq{-g, --temp_warning=INTEGER,[INTEGER] Specify the warning maximum degrees.},
	default => "0:",
	required => 0,
	);

$np->add_arg(
	spec => 'temp_critical|l=s',
	help => qq{-l, --temp_critical=INTEGER,[INTEGER] Specify the critical maximum degrees.},
	default => "0:",
	required => 0,
	);

$np->add_arg(
	spec => 'port|p=s',
	help => qq{-p, --port=INTEGER, Specify the snmp port on the command line, default 161.},
	default => 161,
	required => 1,
	);

$np->add_arg(
	spec => 'retries|r=s',
	help => qq{-r, --retries=INTEGER, Specify the number of retries the command line, default 2.},
	default => 2,
	required => 1,
	);

$np->add_arg(
	spec => 'community|C=s',
	help => qq{-C, --community=STRING, Specify the snmp v2 community name, default public.},
	default => "public",
	required => 0,
	);

$np->add_arg(
	spec => 'mode|M=s',
	help => qq{-M, --mode=STRING, reads the values from snmp table from mode, 
                availaible modes are disk, vol[+], cpu[+], fan[+], mem[+], all default: disk.},
	default => "disk",
	required => 0,
	);

$np->add_arg(
	spec => 'host|H=s',
	help => qq{-H, --host=STRING, Specify the host on the command line.},
	required => 1,
	);

$np->add_arg(
	spec => 'debug|d',
	help => qq{-d, --debug , enable debug},
	required => 0,
	);

$np->getopts;

# start counting down to timeout
alarm $np->opts->timeout;

####################################### 
### main
####################################### 



my $OID_disk = '.1.3.6.1.4.1.24681.1.2.11.1'; # oid tree for diskslots
my $OID_cpu = '.1.3.6.1.4.1.24681.1.2.1';     # oid tree for cpu usage
#my $OID_cpu_temp ='.1.3.6.1.4.1.24681.1.2.5'; # oid cpu temp, dosn't work for all models
my $OID_sys_temp ='.1.3.6.1.4.1.24681.1.2.6'; # oid sys temp
my $OID_fan = '1.3.6.1.4.1.24681.1.2.15';     # oid tree for fan speed
my $OID_vol = '1.3.6.1.4.1.24681.1.2.17';     # oid tree for volumes
my $OID_mem = '1.3.6.1.2.1.25.2.3.1';     # oid tree for memory
my ($session,$error)=open_snmp_session2($np->opts->host);
my $ex_msg = openconn();
my $ex_code = -1 ;
my $MODE=$np->opts->mode;
my ($vmsg);
if ($np->opts->verbose) {
	$vmsg .= "\n=================";
	}	

if ($MODE =~ /all|disk/i){ 
	my ($disk_code,$disk_msg) = diskmode($OID_disk);
	print "DEBUG=>Disk:$disk_code,$disk_msg\n" if defined $np->opts->debug;
	$ex_code = $disk_code if $MODE =~ /all|disk/i;
	$ex_msg .= $disk_msg if $MODE =~ /all|disk/i;
	print "DEBUG=>ALL:$ex_code,$ex_msg\n" if defined $np->opts->debug;
}

if ($MODE =~ /all|vol/i){
	my ($vol_code,$vol_msg ) = volmode($OID_vol);
	print "DEBUG=>Volume:$vol_code,$vol_msg\n" if defined $np->opts->debug;
	$ex_code = $vol_code if $MODE =~ /all|vol/i;
	$ex_msg .= $vol_msg if $MODE =~ /all|vol/i;
	print "DEBUG=>ALL:$ex_code,$ex_msg\n" if defined $np->opts->debug;
}

if ($MODE =~ /all|cpu/i){
	my ($cpu_code,$cpu_msg ) = cpumode($OID_cpu,$OID_sys_temp);
	print "DEBUG=>CPU:$cpu_code,$cpu_msg\n" if defined $np->opts->debug;
	$ex_code = $cpu_code if $MODE =~ /all|cpu/i;
	$ex_msg .= $cpu_msg if $MODE =~ /all|cpu/i;
	print "DEBUG=>ALL:$ex_code,$ex_msg\n" if defined $np->opts->debug;
}


if ($MODE =~ /all|fan/i){
	my ($fan_code,$fan_msg) = fanmode($OID_fan) if $MODE =~ /all|fan/i;
	print "DEBUG=>FAN:$fan_code,$fan_msg\n" if defined $np->opts->debug;
	$ex_code = $fan_code if $MODE =~ /all|fan/i;
	$ex_msg .= $fan_msg if $MODE =~ /all|fan/i;
	print "DEBUG=>ALL:$ex_code,$ex_msg\n" if defined $np->opts->debug;
}

if ( $MODE =~ /all|mem/i) {
	my ($mem_code,$mem_msg) = memmode($OID_mem);
	print "DEBUG=>MEM:$mem_code,$mem_msg\n" if defined $np->opts->debug;
	$ex_code = $mem_code if $MODE =~ /all|mem/i;
	$ex_msg .= $mem_msg if $MODE =~ /all|mem/i;
	print "DEBUG=>ALL:$ex_code,$ex_msg\n" if defined $np->opts->debug;
}

$session->close();
$ex_msg =~ s/\,\ $|\,$//;
$ex_msg .= $vmsg."\n" if defined $vmsg;
print "DEBUG=>ALL:$ex_code,$ex_msg\n" if defined $np->opts->debug;

$ex_code = 3 if (!defined $ex_code);
$np->nagios_exit( $ex_code, "$ex_msg" ) ;

########################################
# functions
########################################

sub memmode {
# memory mode ##########################
# there are some different between
# /proc/meminfo and QNAP Webgui
########################################
 my $OID = shift;
 my %all = connection($OID);
if ($MODE eq 'mem') {
        $vmsg ='';
        }
 $np->shortname ('QNAPMEMORY') if $MODE =~ /^mem/i;
 my $msg='';
 my $nagios_view="\n";
 my $threshold_code=0;
 printdebughash(%all) if $np->opts->debug ;

 my $MTOTAL = $all{"$OID.5.1"} * $all{"$OID.4.1"};
 my $MUSED = $all{"$OID.6.1"} * $all{"$OID.4.1"};
 my $MFREE = ($all{"$OID.5.1"} - $all{"$OID.6.1"}) * $all{"$OID.4.1"};
 my $MBUFFER = $all{"$OID.6.6"} * $all{"$OID.4.6"};
 my $MCACHE = $all{"$OID.6.7"} * $all{"$OID.4.7"};
 my $MSHARED = $all{"$OID.5.8"} * $all{"$OID.4.8"};
 my $STOTAL = ($all{"$OID.5.3"} - $all{"$OID.5.1"}) * $all{"$OID.4.3"};
 my $SUSED = $all{"$OID.6.10"} * $all{"$OID.4.3"};
 my $SFREE = $STOTAL - $SUSED;
 my $TEST = $MBUFFER + $MCACHE + $MFREE;


 perfdata("MTOTAL","$MTOTAL",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("MUSED","$MUSED",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("MFREE","$MFREE",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("STOTAL","$STOTAL",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("SUSED","$SUSED",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("SFREE","$SFREE",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("MBUFFER","$MBUFFER",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("MCACHE","$MCACHE",0,0,0) if $MODE =~ /mem|all/i;
 perfdata("MSHARED","$MSHARED",0,0,0) if $MODE =~ /mem|all/i;

 my $oum = 'B';

 ($MTOTAL, $oum)  = recalc($MTOTAL);
 $msg .= sprintf ("[MEMORY] TOTAL: $MTOTAL $oum ");
 ($MUSED, $oum)  = recalc($MUSED);
 $msg .= sprintf ("- USED: $MUSED $oum ");
 ($MFREE, $oum)  = recalc($MFREE);
 $msg .= sprintf ("- FREE: $MFREE $oum ");
 ($STOTAL, $oum)  = recalc($STOTAL);
 $msg .= sprintf ("[SWAP] TOTAL: $STOTAL $oum ");
 ($SUSED, $oum)  = recalc($SUSED);
 $msg .= sprintf ("- USED: $SUSED $oum ");
 ($SFREE, $oum)  = recalc($SFREE);
 $msg .= sprintf ("- FREE: $SFREE $oum ");
 ($MBUFFER, $oum)  = recalc($MBUFFER);
 $msg .= sprintf ("[OTHER] BUFFER: $MBUFFER $oum ");
 ($MCACHE, $oum)  = recalc($MCACHE);
 $msg .= sprintf ("- CACHE: $MCACHE $oum ");
 ($MSHARED, $oum)  = recalc($MSHARED);
 $msg .= sprintf ("- SHARED: $MSHARED $oum,");

 ($TEST, $oum)  = recalc($TEST);
 print "TEST => $TEST $oum\n" if $np->opts->debug;


return ($threshold_code, $msg);
}


sub recalc {
 my $size = shift;
 my $count = 0;
 while ( $size >= 1024 ) {
  $size = $size / 1024 ;
  print "DEBUG $size\n" if $np->opts->debug ;
  $count++;
  }
 $size=sprintf("%.0f",$size) if $count < 3;
 $size=sprintf("%.1f",$size) if $count > 2;
 my %sizes=( 0 => 'B', 1 => 'KB', 2 => 'MB', 3 => 'GB', 4 => 'TB', 5 => 'PB' );
 my $oum = $sizes{$count};
return ($size,$oum);
}


sub volmode {
# volume mode ###################### QD-2
my $OID = shift;
my %all = connection($OID);
$np->shortname ('QNAPVOLUMES') if $MODE =~ /^vol/i;
my $msg='';
my %big_new = ();
my $max_vol = 0;
my $real_vol = 0;
my $nagios_view="\n";
my $threshold_code=0;


foreach my $key (sort keys %all)  {
	if ( length($key) >= 27){
 		my $new_key = substr ( $key , 27 , 10 );
 		my @change = split ( '\.' , $new_key );
 		$big_new{$change[1]}{$change[0]} = $all{$key};		
 		}else{
		$threshold_code=3;
		}
	}
foreach my $key ( sort keys %big_new ) {
        $max_vol++;
        for ( my $i = 1 ; $i <= 6 ; $i++ ) {
                if ( exists $big_new{$key}{$i} ) {
                        chomp $big_new{$key}{$i};
                        }
                }
        if ( exists $big_new{$key}{2} and exists $big_new{$key}{6}) {
		if ( $big_new{$key}{6} eq '' ){
			$big_new{$key}{6}='failed';
			}
                $msg .= sprintf ("Volume$key $big_new{$key}{2}:$big_new{$key}{6}, " );
		$nagios_view .= 'Volume'.$key.": $big_new{$key}{6}, ";
		if ( $big_new{$key}{6} ne 'Ready' ){
			$threshold_code=2;
			}
		if ( $big_new{$key}{6} eq 'Rebuilding...' ){
			$threshold_code=1;
			}
		if ( $big_new{$key}{6} eq 'Checking...' ){
			$threshold_code=1;
			}
		if ( $big_new{$key}{6} eq 'Warning' ){
			$threshold_code=1;
			}
		$real_vol++;
                } else {
                $msg .= sprintf ("$key: ");
                }
        if ( exists $big_new{$key}{3} and $big_new{$key}{3} ne '') {
		$nagios_view .= 'FS: '.$big_new{$key}{3}.', ';
                }else{
		$nagios_view .= 'FS: n.a., ';
		}
        if ( exists $big_new{$key}{4} and $big_new{$key}{4} ne '') {
		$nagios_view .= 'Size: '.$big_new{$key}{4}.', ';
		my @size=split(' ',$big_new{$key}{4});
		$big_new{$key}{sizevalue}=$size[0];
		$big_new{$key}{sizeoum}=$size[1];
		$big_new{$key}{sizevalue}=resizeoum($big_new{$key}{sizevalue},$big_new{$key}{sizeoum});
                }else{
		$nagios_view .= 'Size: n.a, ';
		$big_new{$key}{sizevalue}=0;
		$big_new{$key}{sizeoum}=0;
                }
        if ( exists $big_new{$key}{5} and $big_new{$key}{5} ne '') {
		$nagios_view .= 'Free: '.$big_new{$key}{5}."\n";
		my @free=split(' ',$big_new{$key}{5});
		$big_new{$key}{freevalue}=$free[0];
		$big_new{$key}{freeoum}=$free[1];
		$big_new{$key}{freevalue}=resizeoum($big_new{$key}{freevalue},$big_new{$key}{freeoum});
                }else{
		$nagios_view .= "Free: n.a\n";
		$big_new{$key}{freevalue}=0;
		$big_new{$key}{freeoum}=0;
		}
	}

if ($np->opts->verbose) {
	$vmsg .= "$nagios_view";
	}
my @state;	
for ( my $i = 1; $i <= $real_vol; $i++ ) {
	my $used=calculate_used($big_new{$i}{sizevalue},$big_new{$i}{freevalue});
	perfdata("Drive$i-Size","$big_new{$i}{sizevalue}",0,0,$max_vol) if $MODE =~ /all|\+$/i;
	perfdata("Drive$i-Free","$big_new{$i}{freevalue}",0,0,$max_vol) if $MODE =~ /all|\+$/i;
	perfdata("Drive$i-Used","$used",0,0,$max_vol) if $MODE =~ /all|\+$/i;
	perfdata("Drive$i-Size","$big_new{$i}{sizevalue}",$np->opts->warning,$np->opts->critical,0,$max_vol) if $MODE =~ /vol/i;
	perfdata("Drive$i-Free","$big_new{$i}{freevalue}",$np->opts->warning,$np->opts->critical,0,$max_vol) if $MODE =~ /vol/i;
	perfdata("Drive$i-Used","$used",0,0,$max_vol) if $MODE =~ /vol/i;
	}
printdebughash(%all) if $np->opts->debug ;
printdebughash(%big_new) if $np->opts->debug ;
return ($threshold_code,$msg);
}

sub resizeoum {
	my ($size,$oum)=@_;
	my %sizes=('KB' => 1024, 'MB' => 1024**2, 'GB' => 1024**3, 'TB' => 1024**4, 'PB' => 1024**5);
	if ($size =~ /\d+/ and $oum ne '') {
		$size = $size*$sizes{$oum};
		$size=sprintf("%.0f",$size);
		}
return $size;
}

sub calculate_used {
    my ($size,$free)=@_;
    my $used=0;
    if ($size =~ /\d+/ and $free =~ /\d+/ ){
	$used = $size - $free;
	}
return $used;
}



sub fanmode {
# fan mode ###################### QD-3
my $OID = shift;
my %all = connection($OID);
printdebughash(%all) if $np->opts->debug ;
$np->shortname ('QNAPFAN') if $MODE =~ /^fan/i;
my $msg='';
my %big_new = ();
my ($real_fan,$max_fan,$threshold_code)=(0,0,0,-1);
my $nagios_view="\n";
foreach my $key (sort keys %all)  {
 	my $new_key = substr ( $key , 27 , 10 ) if length($key) > 27;
 	my @change = split ( '\.' , $new_key ) if $new_key;
 	$big_new{$change[1]}{$change[0]} = $all{$key} if $new_key;
	$msg=', ' if $new_key;
 	}
foreach my $key ( sort keys %big_new ) {
        $max_fan++;
        for ( my $i = 1 ; $i <= 3 ; $i++ ) {
                if ( exists $big_new{$key}{$i} ) {
                        chomp $big_new{$key}{$i};
                        }
                }
        if ( exists $big_new{$key}{2} ) {
                $msg .= sprintf ("$big_new{$key}{2}:" );
		$nagios_view .= $big_new{$key}{2}.':';
		$real_fan++;
                } else {
                $msg .= sprintf ("$key:");
                }
        if ( exists $big_new{$key}{3} ) {
                $msg .= sprintf ("$big_new{$key}{3}, " );
		$nagios_view .= $big_new{$key}{3}. "\n";
                } else {
                $msg .= sprintf ("RPM n.a., ");
		$big_new{$key}{3}=0;
                }
	}
if ($np->opts->verbose) {
	$vmsg .= "$nagios_view";
	}
my @state;	
for ( my $i = 1; $i <= $real_fan; $i++ ) {
	$big_new{$i}{3} =~ s/\ RPM//;
	perfdata("FAN$i",$big_new{$i}{3},$np->opts->warning,$np->opts->critical,0,$max_fan);
	push @state, threshold($big_new{$i}{3},$np->opts->warning,$np->opts->critical) ;
	}
if ( (!defined $ex_code or $ex_code == -1) and $MODE =~ /^fan$|^fan\w+/i) {
	foreach my $state (@state){
		if ($threshold_code lt $state) {$threshold_code=$state;}
		}
	}
if ($msg eq '') {$msg .= ', no FAN RPM available'; $threshold_code=3}
#$threshold_code = $ex_code if defined $ex_code;
printdebughash(%big_new) if $np->opts->debug ;
return ($threshold_code,$msg);
}


sub cpumode {
# cpu mode ###################### QD-3
my ($OID_cpu,$OID_cputemp) = @_;
my %cpu = connection($OID_cpu);
if ($MODE eq 'cpu') {
        $vmsg ='';
        }
$np->shortname ('QNAPCPU') if $MODE =~ /^cpu/i;
my $cpu;
while ( my ($key,$value) = each %cpu ) {
	$cpu = $value;
	}
my %temp = connection($OID_cputemp);
my ($temp,$temp_cpu_max,$temp_cpu_min,$threshold_code)=(0,0,0,-1);
while ( my ($key,$value) = each %temp ) {
	my $t_temp = $value;
	chomp($t_temp);
	if ($t_temp eq ''){$t_temp="0 C/0 F";}
 	$t_temp =~ s/\ |C|F//g;
 	my @temp = split ('/' , $t_temp );
 	if ( $np->opts->temperature eq 'C' ) {
 		if ( $temp_cpu_max lt $temp[0] ) { $temp_cpu_max = $temp[0]; } 
 		if ( $temp_cpu_min gt $temp[0] ) { $temp_cpu_min = $temp[0]; }
		$temp=$temp[0]; 
 		}
 	if ( $np->opts->temperature eq 'F' ) {
 		if ( $temp_cpu_max lt $temp[1] ) { $temp_cpu_max = $temp[1]; } 
 		if ( $temp_cpu_min gt $temp[1] ) { $temp_cpu_min = $temp[1]; } 
		$temp=$temp[1]; 
 		}
	}
my $msg .= 'CPU '.$cpu.', Temp '.$temp.$np->opts->temperature;
my @return=split(' ',$cpu);
perfdata('CPU',$return[0],$np->opts->warning,$np->opts->critical,0,100);
perfdata('TMP',$temp,$np->opts->temp_warning,$np->opts->temp_critical,$temp_cpu_min,$temp_cpu_max);
	print "DEBUG=>ALL+CPU:$ex_code,$MODE\n" if defined $np->opts->debug;
if ((!defined $ex_code or $ex_code == -1) and $MODE =~ /cpu|cpu\+/i){
	print "DEBUG=>ALL+CPU:$ex_code,$ex_msg\n" if defined $np->opts->debug;
	my $threshold_code_cpu = threshold($return[0],$np->opts->warning,$np->opts->critical);
	my $threshold_code_temp = threshold($temp,$np->opts->temp_warning,$np->opts->temp_critical);
	if ( $threshold_code_temp < $threshold_code_cpu ) {
		$threshold_code	= $threshold_code_cpu;
		} 
	else {
		$threshold_code = $threshold_code_temp;
		}
	}
printdebughash(%cpu) if $np->opts->debug ;
printdebughash(%temp) if $np->opts->debug ;
return ($threshold_code,$msg);
}


sub diskmode {
# disk mode ######################
my $OID = shift;
my %all = connection($OID);
printdebughash(%all) if $np->opts->debug ;
$np->shortname ('QNAPDISK') if $MODE =~ /^disk/i;
my %qnap_states = ( 0 => 'ready' , -5 => 'no Disk' , -6 => 'invalid' , -9 => 'rwError' , -4 => 'unknown' );
my $min_disk = 0;
my $real_disk = 0;
my $max_disk = 0;
my @state = 0;
my $nagios_view = "\n"; 
my $temp_disk_max = 0; 
my $temp_disk_min = 900;
my $msg;

my %big_new = ();
foreach  my $key (sort keys %all)  {
 	my $new_key = substr ( $key , 28 , 10 );
 	my @change = split ( '\.' , $new_key );
 	$big_new{$change[1]}{$change[0]} = $all{$key};		
 	}

foreach my $key ( sort keys %big_new ) {
	$max_disk++;
 	for ( my $i = 1 ; $i <= 9 ; $i++ ) {
 		if ( exists $big_new{$key}{$i} ) {
			chomp $big_new{$key}{$i}; 
			}	
 		}
 	$msg .= sprintf ("Slot $key:" );
	if ( exists $big_new{$key}{4} ) {
 		$msg .= sprintf ("$qnap_states{$big_new{$key}{4}}, " );
	 	if ( $big_new{$key}{4} =~ /\d+/ and $big_new{$key}{4} != -5 ) {
 			$real_disk++;
			$min_disk = 1;
			# follow if disk not ready, ready is 0
			if ($big_new{$key}{4} == 0 ){
 				$state[$key] = 0;
				}else{
 				$state[$key] = 2;
				}
 			$nagios_view .= sprintf ("%s: %s, ",$big_new{$key}{2} , $qnap_states{$big_new{$key}{4}} );
	 		if ( exists $big_new{$key}{7} ) {
				$big_new{$key}{7} =~ s/Normal/Warning/;
 				$nagios_view .= sprintf ("SmartInfo: %s, ", $big_new{$key}{7} );
				if ( $big_new{$key}{7} !~ 'GOOD' ) {
					$state[$key]=1 if $state[$key] < 1; # necessary for state above
					$msg = sprintf ("%s SmartInfo: %s, ", $big_new{$key}{2},$big_new{$key}{7} ) . $msg ;
					}
 				}
 			if ( exists $big_new{$key}{5} ) {
 				$nagios_view .= sprintf ("Type: %s, ", $big_new{$key}{5} );
 				}
 			if ( exists $big_new{$key}{6} ) {
 				$nagios_view .= sprintf ("Size: %s, ", $big_new{$key}{6} );
 				}
 			if ( exists $big_new{$key}{3} ) {
				$big_new{$key}{3} =~ s/\ //g;
 				$nagios_view .= sprintf ("Temp: %s\n", $big_new{$key}{3} );
 				}

 			my $t_temp = $big_new{$key}{3};
 			$t_temp =~ s/\ |C|F|°//g;
 			my @temp = split ('/' , $t_temp );
 			if ( $np->opts->temperature eq 'C' ) {
 				if ( $temp_disk_max lt $temp[0] ) { $temp_disk_max = $temp[0]; } 
 				if ( $temp_disk_min gt $temp[0] ) { $temp_disk_min = $temp[0]; } 
 				}
 			if ( $np->opts->temperature eq 'F' ) {
 				if ( $temp_disk_max lt $temp[1] ) { $temp_disk_max = $temp[1]; } 
 				if ( $temp_disk_min gt $temp[1] ) { $temp_disk_min = $temp[1]; } 
 				}
 			}
 		elsif ( $big_new{$key}{4} == -5 ) {
 			$state[$key] = 0;
 			}
	 	elsif ( $big_new{$key}{4} != -5 and $big_new{$key}{4} != 0 ) {
 			$state[$key] = 2;
 			$real_disk++;
			$min_disk = 1;
 			}
 		}
	}
$msg .= "max. Temperature: ".$temp_disk_max.$np->opts->temperature.', ';

perfdata('Disk',$real_disk,$np->opts->warning,$np->opts->critical,$min_disk,$max_disk);
perfdata('Temp',$temp_disk_max,$np->opts->temp_warning,$np->opts->temp_critical,$temp_disk_min,$temp_disk_max);

printdebughash(%big_new) if $np->opts->debug;
 
if ($np->opts->verbose) {
	$vmsg .= "$nagios_view";
	}	

my $threshold_code_disk = threshold($real_disk,$np->opts->warning,$np->opts->critical);
my $threshold_code_temp = threshold($temp_disk_max,$np->opts->temp_warning,$np->opts->temp_critical) if defined $np->opts->temperature;

my $ex_code = $threshold_code_disk;
 
printdebughash(%$np) if $np->opts->debug and $threshold_code_temp != 0 ;
$ex_code = $threshold_code_temp if $threshold_code_temp != 0 ; 

printdebughash(%$np) if $np->opts->debug and $threshold_code_disk != 0 ;
$ex_code = $threshold_code_disk if $threshold_code_disk != 0 ;
foreach my $state (@state){
	if ($ex_code lt $state) {$ex_code=$state;}
	}

printdebughash(%$np) if $np->opts->debug;

return ($ex_code, "$msg" );
}

sub openconn { 
 # let's see if the qnap wants to speak with us
if (!defined ($session)) {
 	printf ("ERROR1: Could not open connection: %s\n", $error);
 	exit 3;
 	}

if (!defined $session) {
 	printf ("ERROR2: %s.\n", $error);
 	exit 3;
 	}

my $OID_Sysname = '.1.3.6.1.2.1.1.5.0'; 
#my $OID_Hardware = '.1.3.6.1.2.1.1.1.0';
my $OID_Hardware = '.1.3.6.1.2.1.47.1.1.1.1.7.1';
my $OID_OS = '.1.3.6.1.2.1.47.1.1.1.1.9.1';
my $OID_Serial = '.1.3.6.1.2.1.47.1.1.1.1.11.1'; # add v1.0.4
my @oids_sgos4 = ($OID_Hardware,$OID_Sysname,$OID_OS,$OID_Serial);
my $result = single_oid(@oids_sgos4);
my $msg;
if ( $result ne '' ){
	chomp($result->{$OID_OS});
	#$msg = $result->{$OID_Sysname}.', '.$result->{$OID_Hardware}.' OS:'.$result->{$OID_OS}.', '.$result->{$OID_Serial}.', ';
	$msg = sprintf ("%s, %s OS: %s, SN:%s, ",$result->{$OID_Sysname}, $result->{$OID_Hardware}, $result->{$OID_OS}, $result->{$OID_Serial});
	}
else {
	$msg = "Can\'t read $OID_Sysname $OID_Hardware\n";
	}
   $msg .= 'DEBUG:('.$VERSION.'), ' if $np->opts->debug;
return $msg;
}

sub single_oid {
# open the connection
my @OID_get = @_;
my $result = $session->get_request(-varbindlist => \@OID_get,);
my $error_message = $session->error();
print "DEBUG: $error_message\n" if defined $np->opts->debug;
if ($error_message){$result='';}
return $result;
}

sub connection {
# open the connection
my $OID_get = shift;
my $result_get = $session->get_table(-baseoid => $OID_get ) ;
my $error_message = $session->error();
print "$OID_get => $error_message\n" if defined $np->opts->debug;
my %all;
if ($error_message) {$all{$OID_get}='';} else {%all = %$result_get;}
return %all;
}

sub open_snmp_session2 {
# snmp params
my ($session, $error) = Net::SNMP->session(
	-hostname  => shift || $np->opts->host,
 	-community => shift || $np->opts->community,
 	-port      => shift || $np->opts->port,
 	-timeout   => shift || $np->opts->timeout,
 	-retries   => shift || $np->opts->retries,
 	);
#debug options are '0x02', '0x04' and more
$session->debug('0x02') if defined $np->opts->debug;
return ($session,$error)
}

sub threshold { 
# Threshold method
my ($check,$warn,$crit) = @_ ;
my $threshold_code = $np->check_threshold(
	check => $check,
     	warning => $warn,
     	critical => $crit,
   	);
return $threshold_code;
}

sub perfdata {
### Perfdata methode
my ($label, $value, $warn, $crit, $min, $max) = @_ ;
my $perfdata_code = $np->add_perfdata( 
 	label => "$label",
 	value => $value,
	warning => $warn,
     	critical => $crit,
 	min => $min,
 	max => $max,
 	);
return;
}

sub printdebughash {
# start function print hash
my %Nagioshash = @_ ;
print Dumper(\%Nagioshash);
return ;
}



