#!/usr/bin/perl

# v0.7 Programme de Guillaume Lehmann.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# PREMIER MODULE DE SCAN DES MACHINES #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#




use Net::SNMP ;
use Time::localtime ;


while (TRUE) {
    
# Nettoyer l'affichage de la console.
    print ".. Debut du programme\n" ;

# Si verrou de blocage de SurvScan.pl ferm,Ai(B, on lance le scan.
    open (VERROUPRE, 'VerrouSurvScanPre') || die "Probl,Ah(Bme ,A`(B l'ouverture du fichier verrou de SurvScanPre" ;
    $ValeurVerrouPre = <VERROUPRE> ;
    close (VERROUPRE) ;
    if ($ValeurVerrouPre == 0) {
	
# Nettoyage du fichier ResSurvScanPre.txt.
	open (FICHIER, '>ResSurvScanPre.txt') || die "!! Probl,Ah(Bme ,A`(B l'ouverture du fichier" ;
	print FICHIER "" ;
	close (FICHIER) ;


	open (LISTE, 'ConfSurvScanPre.txt') || die "!! Probl,Ah(Bme ,A`(B l'ouverture du fichier" ;
	
	while ($InfoMachine = <LISTE>) {
# R,Ai(Bcup,Ai(Bration des ,Ai(Bl,Ai(Bments d'informations sur la machine ,A`(B controler. La boucle if est l,A`(B pour s'assurer que l'on ne lis pas une ligne vide ou invalide dans le fichier.
	    if (($AdresseIPAgent, $NomAgent, $CommunauteAgent, $NumPortAgent, $SiteAgent) = $InfoMachine =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*(\w*)\s*(\w*)\s*(\d*)\s*(\w*)$/) {

# Ouverture de la session SNMP
		($Session, $Erreur) = Net::SNMP->session(
							 -hostname =>  $AdresseIPAgent,
							 -community => $CommunauteAgent,
							 -port => 161,
							 -timeout => 10,
							 -retries => 2
							 ) ;
		
		
		$SysUpTime = "1.3.6.1.2.1.1.3.0" ;
		
# Si $NumPortAgent ,Ai(Bgal 0, alors ne pas faire les analyses qui suivent qui sont propres ,A`(B un port.
		if ($NumPortAgent != 0) {
		    $NbErreurEntree = "1.3.6.1.2.1.2.2.1.14.$NumPortAgent" ;
		    $NbErreurSortie = "1.3.6.1.2.1.2.2.1.20.$NumPortAgent" ;
		    $EtatPort = "1.3.6.1.2.1.2.2.1.8.$NumPortAgent" ;
		    $DebitEntree = "1.3.6.1.2.1.2.2.1.10.$NumPortAgent" ;
		    $DebitSortie = "1.3.6.1.2.1.2.2.1.16.$NumPortAgent" ;
		}
#################
# INITIALISATION
		$ResNbErreurEntree->{$NbErreurEntree} = 0 ;
		$ResNbErreurSortie->{$NbErreurSortie} = 0 ;
		$ResDebitEntree->{$DebitEntree} = 0 ;
		$ResDebitSortie->{$DebitSortie} = 0 ;
		$ResEtatPort->{$EtatPort} = 1 ;
#################




# Envoie de la requete SNMP et r,Ai(Bcup,Ai(Bration du r,Ai(Bsultat.
		$ResRequete = $Session->get_request($SysUpTime) ;
		
		if (!defined($ResRequete)) {
		    $Etat = "DOWN" ;
		}
		else {
		    $Etat = "UP" ;
		    if ($NumPortAgent != 0) {
			$ResEtatPort = $Session->get_request($EtatPort) ;
			if ($ResEtatPort->{$EtatPort} == 3) { # Si ,Ai(Btat "testing", alors on dit "down".
			    $ResEtatPort->{$EtatPort} = 2 ;
			}
			if ($ResEtatPort->{$EtatPort} == 1) { # Seulement si le port est activ,Ai(B on rel,Ah(Bve les compteurs.
			    $ResNbErreurEntree = $Session->get_request($NbErreurEntree) ;
			    $ResNbErreurSortie = $Session->get_request($NbErreurSortie) ;
			    $ResDebitEntree = $Session->get_request($DebitEntree) ;
			    $ResDebitSortie = $Session->get_request($DebitSortie) ;
			}
		    }
		} # fin du else "Etat machine UP"
		
# Remplacer les param,Ah(Btres vides par 0 pour ,Ai(Bviter les probl,Ah(Bmes dans les expressions r,Ai(Bguli,Ah(Bres futures.
		if ($ResNbErreurEntree->{$NbErreurEntree} == "") {
		    $ResNbErreurEntree->{$NbErreurEntree} = 0 ;
		}
		if ($ResNbErreurSortie->{$NbErreurSortie} == "") {
		    $ResNbErreurSortie->{$NbErreurSortie} = 0 ;
		}
		if ($ResDebitEntree->{$DebitEntree} == "") {
		    $ResDebitEntree->{$DebitEntree} = 0 ;
		}
		if ($ResDebitSortie->{$DebitSortie} == "") {
		    $ResDebitSortie->{$DebitSortie} = 0 ;
		}
		if ($ResEtatPort->{$EtatPort} == "") {
		    $ResEtatPort->{$EtatPort} = "1" ;
		}    


##############################
# R,AI(BCUP,AI(BRER LA DATE COURANTE #
		$DateAnnee = localtime->year + 1900 ;
		$DateMois = localtime->mon + 1 ;
		$DateJour = localtime->mday ;
		$DateHeure = localtime->hour ;
		$DateMinute = localtime->min ;
		$DateSeconde = localtime->sec ;
		
# Convertir les mois/jours/heures/minutes qui sont sur un chiffre en 2 chiffres.
		if ($DateMois =~ /^.$/) {
		    $DateMois = "0".$DateMois ;
		}
		if ($DateJour =~ /^.$/) {
		    $DateJour= "0".$DateJour ;
		}
		if ($DateHeure =~ /^.$/) {
		    $DateHeure= "0".$DateHeure ;
		}
		if ($DateMinute =~ /^.$/) {
		    $DateMinute= "0".$DateMinute ;
		}
		if ($DateSeconde =~ /^.$/) {
		    $DateSeconde= "0".$DateSeconde ;
		}

		$DateAlarme = $DateAnnee.$DateMois.$DateJour.$DateHeure.$DateMinute.$DateSeconde ;
##############################




############################
# ,AI(BCRITURE DANS LE FICHIER #
# Ouverture du fichier r,Ai(Bsultat.
		open (FICHIER, '>> ResSurvScanPre.txt') || die "!! probl,Ah(Bme ,A`(B l'ouverture du fichier r,Ai(Bsultat" ;

# Une unique ligne est consacr,Ai(Be ,A`(B chaque machine surveill,Ai(Be. Toutes les infos y sont.
		print FICHIER "", $AdresseIPAgent, " ", $NomAgent, " ", $Etat, " ", $ResNbErreurEntree->{$NbErreurEntree}, " ", $ResNbErreurSortie->{$NbErreurSortie}, " ", $ResDebitEntree->{$DebitEntree}, " ", $ResDebitSortie->{$DebitSortie}, " ", $DateAlarme, " ", $NumPortAgent, " ", $SiteAgent, " ", $ResEtatPort->{$EtatPort}, "\n" ;

# Fermeture du fichier contentant les r,Ai(Bsultats de l'analyse.
		close(FICHIER) ;
############################




# Fermeture de la session SNMP pour la surveillance d'une certaine machine.
		$Session->close ;
	    } # fin de la boucle if qui s'assurait que la ligne lue dans le fichier n',Ai(Btait pas vide ou invalide.

	    else { # Si la ligne n'est pas correcte le signaler sauf si c'est un commentaire.
		($Commentaire) = $InfoMachine =~ /^(\w{2})/ ;
		if ($Commentaire ne "ZZ") {
		    print "!! La ligne suivante contient une erreur de syntaxe est ne sera pas interpr,Ai(Bt,Ai(Be\n$InfoMachine\n" ;
		}
	    }

# Une pause avant de passer ,A`(B la machine suivante.
# sleep 1 ;

	}
	close(LISTE) ;




##################################
# OUVRIR LE VERROU POUR SURVSCAN #
	open (VERROUPRE, '> VerrouSurvScanPre') || die "Probl,Ah(Bme ,A`(B l'ouverture du fichier verrou de SurvScanPre" ;
	print VERROUPRE "1" ;
	close (VERROUPRE) ;
##################################


    } # fin du if verrou de blocage de SurvScan.pl ferm,Ai(B.
    else { # Si verrou d,Ai(Bj,A`(B ouvert, on ne fait rien.
	print ".. Verrou ouvert pour l'execution => attente\n" ;

    }    
    print ".. Fin du programme.\n\n" ;
    # Que ce soit apr,Ah(Bs ex,Ai(Bcution ou en attente de l'ouverture du verrou, on attend quelques secondes.
    sleep 20 ;

} # fin du while
