/* ***********************IMPORTANT *********************************************
 *  Copyright (C) 2004-2007 Thierry Lagarde <tlagarde@users.sourceforge.net>
 *  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 2 of the License.
 *
 *
 *                      ********************
 *
 *
 *  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 Library General Public License for more details.
 *
 *
 *                      ********************
 *
 *
 * You are highly encouraged to send your changes to <tlagarde@users.sourceforge.net>
 * for possible incorporation into the main distribution.
 * By sending these changes to <tlagarde@users.sourceforge.net>,
 * it is assumed that you are offering <tlagarde@users.sourceforge.net>
 * the unlimited, non-exclusive right to reuse, modify, and relicense the code.
 *
 *
 *                      ********************
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **************************************************************************************/
#include "Liste_Equipement.h"
#include "Liste_Sous_Reseau.h"
#include "Debug.h"
#include "Scan_Equipement.h"
#include "Thread.h"
#include "Info.h"
#include "Scan_Port.h"
#include "Intrus.h"
#include "Semaphore.h"
#include "Macro.h"
#include <time.h>



void Efface_Reponse_Signature (struct Struct_Liste_Equipement *Equip)
{
	ERROR_if (Equip == NULL);
	for (Equip->i = 0; Equip->i < NB_SCAN_OS; Equip->i++) {
		bzero (&Equip->Reponse_Signature[Equip->i], sizeof (struct struct_Reponse));
		bzero (&Equip->Reponse_Signature_Debug[Equip->i], sizeof (struct struct_Reponse_debug));
		bzero (&Equip->Scan_OS[Equip->i], sizeof (struct struct_Scan_Os));
	}
}


void Equipement_Arreter (struct Struct_Liste_Equipement *Equipement)
{
	struct struct_Retour_Rachaichir_Etat_Equipement Message;

	ERROR_if (Equipement == NULL);
	if (Equipement->Equipement_Allumer) {
		Equipement->Equipement_Allumer = FALSE;
	
		time (&Equipement->Derniere_Modification_Etat_Equipement);
		bzero (&Message, sizeof (struct struct_Retour_Rachaichir_Etat_Equipement));
		Message.ID_Reseau = Info_Demarrage.ID_Reseau;
		memcpy (Message.ID_Equipement, Equipement->ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN + 1);
		Message.Equipement_Allumer = FALSE;
		Message.Derniere_Modification_Etat_Equipement = Equipement->Derniere_Modification_Etat_Equipement;
		Communication_Envoie_Donnee (RETOUR_RAFRAICHIR_ETAT_EQUIMEMENT, (gpointer *) & Message, sizeof (Message));
	
	
	}
}

void Reception_Donnee_Equipement_Connu (struct Struct_Liste_Equipement *Equipement)
{
	struct struct_Retour_Rachaichir_Etat_Equipement Message;
	time_t64  Time_Actuelle;

	ERROR_if (Equipement == NULL);
	if (!Equipement->Rafraichissement_Etat_En_Cours) {
		if (!Equipement->Equipement_Allumer) {
			time (&Time_Actuelle);
			if (Time_Actuelle > Equipement->Derniere_Modification_Etat_Equipement + 10) {
				Equipement->Equipement_Allumer = TRUE;
				Equipement->Alerte_Equipement_Active = FALSE;
			
				time (&Equipement->Derniere_Modification_Etat_Equipement);
				bzero (&Message, sizeof (struct struct_Retour_Rachaichir_Etat_Equipement));
				Message.ID_Reseau = Info_Demarrage.ID_Reseau;
				memcpy (Message.ID_Equipement, Equipement->ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN + 1);
				Message.Equipement_Allumer = TRUE;
				Message.Derniere_Modification_Etat_Equipement = Equipement->Derniere_Modification_Etat_Equipement;
				Communication_Envoie_Donnee (RETOUR_RAFRAICHIR_ETAT_EQUIMEMENT, (gpointer *) & Message, sizeof (Message));
			}
		}
		if (Equipement->Notification_Equipement)
			Equipement->Compteur_Notification = 0;
	}
	else
		Equipement->Equipement_Allumer = TRUE;
}

void Retour_Pointeur_Equipement (struct Struct_Liste_Equipement **Equipement, gint Index_Equipement)
{
	ERROR_if (Equipement == NULL);
	PROTECT_CODE(Semaphore_Equipement);
	*Equipement = g_list_nth_data (GList_Equipement, Index_Equipement);
	DEPROTECT_CODE(Semaphore_Equipement);
}

void Recherche_Index_Equipement (unsigned char *ID_Equipement, gboolean No_ip, int *Index)
{
	ERROR_if (ID_Equipement == NULL);
	ERROR_if (Index == NULL);
	PROTECT_CODE(Semaphore_Equipement);
	struct Struct_Liste_Equipement *Equipement = NULL; 
	gint      Nb_Objet_Liste;//,i   
	
	Nb_Objet_Liste = g_list_length (GList_Equipement);
	for ((*Index) = 0; (*Index) < Nb_Objet_Liste; (*Index)++) {
		Equipement = g_list_nth_data (GList_Equipement, (*Index));
		if ((No_ip) && (memcmp (Equipement->ID_Equipement, ID_Equipement, MAC_ADDR_LEN) == 0) && (Equipement->ID_Equipement[6] == 0)) {
			(*Index) = EQUIPEMENT_NO_IP;
			DEPROTECT_CODE(Semaphore_Equipement);
			return ;//EQUIPEMENT_NO_IP;
		}
		if (memcmp (Equipement->ID_Equipement, ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN + 1) == 0) {
			DEPROTECT_CODE(Semaphore_Equipement);
			return;//i;
		}
	}
	(*Index) = EQUIPEMENT_UNKNOWN;
	DEPROTECT_CODE(Semaphore_Equipement);
	return;
}


gint Recherche_Equipement(unsigned char *ID_Equipement,struct Struct_Liste_Equipement **Equipement){
	unsigned char Adresse_MAC_Char[17 + 1];
	
	sprintf (Adresse_MAC_Char, "%02X:%02X:%02X:%02X:%02X:%02X", ID_Equipement[0], ID_Equipement[1], ID_Equipement[2], ID_Equipement[3], ID_Equipement[4], ID_Equipement[5]);
	Adresse_MAC_Char[17] = 0;


	PROTECT_CODE(Semaphore_Equipement);
	*Equipement = g_hash_table_lookup(Hash_Mac_Equipement,Adresse_MAC_Char);
	DEPROTECT_CODE(Semaphore_Equipement);
	
	if ((*Equipement) == NULL)
		return EQUIPEMENT_UNKNOWN;

	if ((*Equipement)->ID_Equipement[6] == 0)
		return EQUIPEMENT_NO_IP; 
	
	if (memcmp ((*Equipement)->ID_Equipement, ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN ) == 0)
		return EQUIPEMENT_KNOWN; 
	
	return EQUIPEMENT_UNKNOWN;
}

struct Struct_Liste_Equipement *Recherche_MAC_Gateway (unsigned char *MAC)
{
	struct Struct_Liste_Equipement *Equipement = NULL;
	gint      Nb_Objet_Liste, i;

	ERROR_if (MAC == NULL);
	PROTECT_CODE(Semaphore_Equipement);
	Nb_Objet_Liste = g_list_length (GList_Equipement);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Equipement = g_list_nth_data (GList_Equipement, i);
		if ((Equipement->Scan_Signature)
			&& (memcmp (Equipement->Adresse_MAC, MAC, MAC_ADDR_LEN) == 0)) {
			DEPROTECT_CODE(Semaphore_Equipement);
			return Equipement;
		}
	}
	DEPROTECT_CODE(Semaphore_Equipement);
	return NULL;	
}

struct Struct_Liste_Equipement *Ajout_Equipement (unsigned char *ID_Equipement)
{
	struct Struct_Liste_Equipement *Equipement = NULL;

	ERROR_if (ID_Equipement == NULL);
	MALLOC(Equipement,sizeof (struct Struct_Liste_Equipement));
	memcpy (Equipement->ID_Equipement, ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN + 1);
	memcpy (Equipement->Adresse_MAC, ID_Equipement, MAC_ADDR_LEN);
	memcpy (Equipement->Adresse_Ip, &ID_Equipement[MAC_ADDR_LEN], 4);
	sprintf (Equipement->Adresse_MAC_Char, "%02X:%02X:%02X:%02X:%02X:%02X", Equipement->Adresse_MAC[0], Equipement->Adresse_MAC[1], Equipement->Adresse_MAC[2], Equipement->Adresse_MAC[3], Equipement->Adresse_MAC[4], Equipement->Adresse_MAC[5]);
	sprintf (Equipement->Adresse_Ip_Char, "%d.%d.%d.%d", Equipement->Adresse_Ip[0], Equipement->Adresse_Ip[1], Equipement->Adresse_Ip[2], Equipement->Adresse_Ip[3]);
	Equipement->Scan_Port_En_Cours = FALSE;
	Equipement->Equipement_Restaurer = FALSE;
	Equipement->Equipement_Rescanner_En_Cours = FALSE;
	Equipement->Equipement_Allumer = TRUE;
	Equipement->Derniere_Modification_Etat_Equipement = 0;
	Equipement->Notification_Equipement = FALSE;
	Equipement->Compteur_Notification = 0;
	Equipement->Alerte_Equipement_Active = FALSE;
	Equipement->GList_Port = NULL;
	Equipement->Scanne_Port_En_Cours = FALSE;
	Equipement->Scan_Signature = FALSE;
	Equipement->Intrus = Alerte_Intrusion;
	Equipement->Marquage_Change_Ip = FALSE;
#ifdef __LOG_ENABLE

	Create_Log_Equipement(Equipement);
#endif
	if (Alerte_Intrusion)
		Envoie_Alerte_Intrusion (ID_Equipement);

	PROTECT_CODE(Semaphore_Equipement);
	G_LIST_APPEND (GList_Equipement, Equipement);
	g_hash_table_insert(Hash_Mac_Equipement,Equipement->Adresse_MAC_Char,Equipement);
	DEPROTECT_CODE(Semaphore_Equipement);
	
	if (Recherche_Index_Sous_Reseau (Equipement->Adresse_Ip) == -1)
		Ajout_Sous_Reseau (Equipement->Adresse_Ip, TRUE);

	Creer_Liste_Port_Equipement (Equipement);
	Nb_Machine_Dans_La_Liste++;

	DEPROTECT_CODE(Semaphore_Nouveau_Equipement);
	return Equipement;
}

void Initialisation_Liste_Equipement (void)
{
	GList_Equipement = NULL;
	Hash_Mac_Equipement = g_hash_table_new((GHashFunc)g_str_hash,(GEqualFunc)g_str_equal);
}
