#!/usr/bin/perl -w
use Getopt::Std;
use Net::SNMP qw(:snmp);
#    ---------------------------------------------------------------------------
#    Checkpoint Firewall-1 check
#    Copyright 2010 Lionel Cottin (cottin@free.fr)
#    ---------------------------------------------------------------------------
#    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/>.
#    ---------------------------------------------------------------------------
#
my $version = "0.1";
my $release = "2010/06/18";

#
# Interesting MIB entries
# -----------------------
my $oid_fw_state       = "1.3.6.1.4.1.2620.1.1.1.0";    # "Installed"
my $oid_fw_name        = "1.3.6.1.4.1.2620.1.1.2.0";    # Policy name
my $oid_fw_conns       = "1.3.6.1.4.1.2620.1.1.25.3.0"; # Connections
my $oid_svn_status     = "1.3.6.1.4.1.2620.1.6.102.0";  # "OK" svn status
my $oid_ha_installed   = "1.3.6.1.4.1.2620.1.5.2.0";    # "1" = yes
my $oid_ha_active      = "1.3.6.1.4.1.2620.1.5.5.0";    # "yes"
my $oid_ha_mode        = "1.3.6.1.4.1.2620.1.5.6.0";    # "active" / standby
my $oid_ha_block_state = "1.3.6.1.4.1.2620.1.5.7.0";    # "OK" : HA blocking state
my $oid_ha_status      = "1.3.6.1.4.1.2620.1.5.102.0";  # "OK" : HA status
my $oid_ps_status      = "1.3.6.1.4.1.2620.1.9.102.0";  # "OK" : policy server status
my $oid_ps_users       = "1.3.6.1.4.1.2620.1.9.5.0";    # Logged users
my $oid_ps_license     = "1.3.6.1.4.1.2620.1.9.4.0";    # Licensed users

#-------------------------------------------------------------------------------
#    Global variable declarations
#-------------------------------------------------------------------------------
my @str = ("OK", "WARNING", "CRITICAL", "UNKNOWN"); # Nagios status strings
my (
  $usage,     # Help message
  $hostname,  # Target host
  $community, # SNMP community (v2c only)
  $base_oid,  # Base OID
  $state,     # Nagios status: 3=unknown, 2=critical, 1=warning, 0=ok, -1=error
  $short,     # Message for $SERVICEOUTPUT$
  $result,    # Temp variable to store SNMP results
  $message,   # Final message to print out
  $mode,      # Probe mode
  @oids,      # oid table for SNMP requests
  $fw         # Firewall hash to store values
);

#-------------------------------------------------------------------------------
#    Global variable initializations
#-------------------------------------------------------------------------------
$usage = <<"EOF";
usage:  $0 [-h] -H <hostname> -C <community> -m <mode> [-d]

Version: $version
Released on: $release

Nagios check for Checkpoint firewalls using SNMP version 2c

 FW1  probe ensures a policy is installed
 HA   probe ensures HA is in active or standby mode
 VPN1 probe ensures Policy server is Up and license is not violated

[-h]             : Print this message
[-d]             : enable debug output
[-H] <hostname>  : IP Address or Hostname
[-C] <community> : SNMP Community String  (default = "public")
[-m] <mode>      : Choose the mode from one of the following:
                        1       -> SVN + FW1
                        2       -> SVN + FW1 + HA
                        3       -> SVN + FW1 + PS
                        4       -> SVN + FW1 + PS + HA
 
EOF

#-------------------------------------------------------------------------------
#                              Input Phase
#-------------------------------------------------------------------------------
die $usage if (!getopts('hH:C:m:d') || $opt_h);
die $usage if (!$opt_H || !$opt_C || !$opt_m || $opt_h);
$hostname = $opt_H;
$community = $opt_C || "public"; undef $opt_C; #use twice to remove Perl warning
$mode = $opt_m;

if ($opt_d) {
  print "Target hostname  : $hostname\n";
  print "SNMPv2 community : $community\n";
  print "Mode             : $mode\n";
}

#-------------------------------------------------------------------------------
# Open an SNMPv2 session with the remote agent
#-------------------------------------------------------------------------------
my ($session, $error) = Net::SNMP->session(
        -version     => 'snmpv2c',
        -nonblocking => 1,
        -timeout     => 2,
        -hostname    => $hostname,
        -community   => $community
);

if (!defined($session)) {
  printf("ERROR: %s.\n", $error);
  exit (-1);
}

#-------------------------------------------------------------------------------
# Get some SNMP data now
#-------------------------------------------------------------------------------
@oids = (
  $oid_fw_state,
  $oid_fw_name,
  $oid_fw_conns,
  $oid_svn_status,
  $oid_ha_installed,
  $oid_ha_active,
  $oid_ha_mode,
  $oid_ha_block_state,
  $oid_ha_status,
  $oid_ps_status,
  $oid_ps_users,
  $oid_ps_license
);
$result = $session->get_request(
          -varbindlist  => \@oids,
          -callback     => [\&cb_get, {}],
        );
if (!defined($result)) {
  printf("ERROR: %s.\n", $session->error);
  $session->close;
  exit (-1);
}
snmp_dispatcher();
undef $result;

#-------------------------------------------------------------------------------
# Process results
#-------------------------------------------------------------------------------
$state = 0;

# check for SVN status
my $state_svn = 0;
$state_svn = 2 if ( $fw{"svn_status"} ne "OK" ); # Raise to CRITICAL is SVN is not OK
$short = "Firewall Status [ SVN:$fw{\"svn_status\"} ";

# check for HA status
my $state_ha = 0;
if ($mode =~ /(2|4)/) {
  if (  $fw{"ha_installed"} == 1 &&
        $fw{"ha_active"} eq "yes" &&
        $fw{"ha_block_state"} eq "OK" &&
        $fw{"ha_status"} eq "OK" ) {
    $short = $short . "HA:OK($fw{\"ha_mode\"}) ";
  } else {
    $state_ha = 2;
    $short = $short . "HA:CRITICAL($fw{\"ha_status\"}) ";
  }     
}  

# check for FW1 status
my $state_fw = 0;
$state_fw = 2 if ( $fw{"fw_state"} ne "Installed" );
$short = $short . "FW1:$str[$state_fw]($fw{\"fw_name\"}) ";
$perf = "connections=$fw{\"fw_conns\"}";

# check for PS status
my $state_ps = 0;
if ($mode =~ /(3|4)/) {
  if (  $fw{"ps_status"} eq "OK" &&
        $fw{"ps_license"} >= $fw{"ps_users"} ) {
    $short = $short . "PS:OK($fw{\"ps_users\"}users) ";
    $perf = $perf . " users=$fw{\"ps_users\"}";
  } else {
    $state_ps = 2;
    $short = $short . "PS:CRITICAL($fw{\"ps_status\"}) ";
  }
}

if ( $state_svn == 2 ||
     $state_ha  == 2 ||
     $state_fw  == 2 ||
     $state_ps  == 2 ) {
  $short = $short . "]: CRITICAL";
  $state = 2;
} else {
  $short = $short . "]: OK";
  $state = 0;
}

$message = $short . " | " . $perf;
print "$message\n";
exit $state;

#-------------------------------------------------------------------------------
# Subroutines
#-------------------------------------------------------------------------------
sub cb_get
{
  my ($session) = @_;
  my $result = $session->var_bind_list();
  if (!defined $result) {
     printf "ERROR: Get request failed for host '%s': %s.\n",
            $session->hostname(), $session->error();
     exit -1;
  }
  for my $oid ( oid_lex_sort(keys ( %{$result} )) ) {
    print "Found oid=$oid\tval=$result->{$oid}\n" if $opt_d;
    #--------------------------------------------------------------------------------
    # Let's fill the fw hash to make things clean
    #--------------------------------------------------------------------------------
    if ($oid =~ /^$oid_fw_state$/)       { $fw{"fw_state"}       = $result->{$oid} };
    if ($oid =~ /^$oid_fw_name$/)        { $fw{"fw_name"}        = $result->{$oid} };
    if ($oid =~ /^$oid_fw_conns$/)       { $fw{"fw_conns"}       = $result->{$oid} };
    if ($oid =~ /^$oid_svn_status$/)     { $fw{"svn_status"}     = $result->{$oid} };
    if ($oid =~ /^$oid_ha_installed$/)   { $fw{"ha_installed"}   = $result->{$oid} };
    if ($oid =~ /^$oid_ha_active$/)      { $fw{"ha_active"}      = $result->{$oid} };
    if ($oid =~ /^$oid_ha_mode$/)        { $fw{"ha_mode"}        = $result->{$oid} };
    if ($oid =~ /^$oid_ha_block_state$/) { $fw{"ha_block_state"} = $result->{$oid} };
    if ($oid =~ /^$oid_ha_status$/)      { $fw{"ha_status"}      = $result->{$oid} };
    if ($oid =~ /^$oid_ps_status$/)      { $fw{"ps_status"}      = $result->{$oid} };
    if ($oid =~ /^$oid_ps_users$/)       { $fw{"ps_users"}       = $result->{$oid} };
    if ($oid =~ /^$oid_ps_license$/)     { $fw{"ps_license"}     = $result->{$oid} };
  }
}