/* ***********************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 "Snmp.h"
#include "Debug.h"
#include "Com/Commun.h"
#include "Com/Communication.h"
#include "Com/Initialisation_Com.h"
#include "Semaphore.h"
#include "Macro.h"

#ifdef        __SNMP_ENABLE

struct Struct_Liste_Snmp Liste_Snmp[] = {
	{SNMP_SYSTEM_LOGICAL_STORAGE, 10, {1, 3, 6, 1, 2, 1, 25, 2, 3, 1}},
	{SNMP_SOFTWARE, 10, {1, 3, 6, 1, 2, 1, 25, 4, 2, 1}},
	{SNMP_NETWORK_TCPIP_TCP_CONNECTIONS, 9, {1, 3, 6, 1, 2, 1, 6, 13, 1}},
	{SNMP_NETWORK_ROUTES, 9, {1, 3, 6, 1, 2, 1, 4, 21, 1}},
	{SNMP_NETWORK_ARP, 9, {1, 3, 6, 1, 2, 1, 4, 22, 1}},
	{SNMP_SYSTEM_DEVICE, 10, {1, 3, 6, 1, 2, 1, 25, 3, 2, 1}},
	{SNMP_SYSTEM_SERVICE, 11, {1, 3, 6, 1, 4, 1, 77, 1, 2, 3, 1}},
	{SNMP_NETWORK_INTERFACES_BASIC, 9, {1, 3, 6, 1, 2, 1, 2, 2, 1}},
	{SNMP_NETWORK_TCPIP_UDP_SERVICES, 9, {1, 3, 6, 1, 2, 1, 7, 5, 1}},
	{SNMP_BRIDGE_FORWARDING_DATABASE, 10, {1, 3, 6, 1, 2, 1, 17, 4, 3, 1}},
	{SNMP_BRIDGE_STATIC_DATABASE, 10, {1, 3, 6, 1, 2, 1, 17, 5, 1, 1}}
};


struct Struct_Objet_Snmp Liste_Objet_Snmp[] = {

	{SNMP_SYSTEM_NAME, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 1, 5}},
	{SNMP_DESCRIPTION, 8, CHAINE_MAX, {1, 3, 6, 1, 2, 1, 1, 1}},
	{SNMP_CONTACT, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 1, 4}},
	{SNMP_LOCATION, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 1, 6}},
	{SNMP_UPTIME, 9, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 25, 1, 1}},
	{SNMP_RAM, 9, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 25, 2, 2}},

	{SNMP_IP_FORWARDING, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 1}},
	{SNMP_DEFAULT_TTL, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 2}},
	{SNMP_REASSEMBLY_TIMEOUT, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 13}},
	{SNMP_NEEDED_TO_BE_REASSEMBLED, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 14}},
	{SNMP_REASSEMBLED, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 15}},
	{SNMP_REASSEMBLY_FAILURES, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 16}},
	{SNMP_SUCCESSFULLY_FRAGMENTED, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 17}},
	{SNMP_FRAGMENTATION_FAILURES, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 18}},
	{SNMP_CREATED_FRAGMENTS, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 19}},
	{SNMP_DISCARDED_ROUTING_ENTRIES, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 23}},

	{SNMP_ALL, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 3}},
	{SNMP_FORWARDED, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 6}},
	{SNMP_DELIVERED, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 9}},
	{SNMP_HEADER_ERRORS, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 4}},
	{SNMP_ADDRESS_ERRORS, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 5}},
	{SNMP_UNKNOWN_PROTOCOLS, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 7}},
	{SNMP_INPUT_BUFFER_ERRORS, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 8}},

	{SNMP_REQUESTED, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 10}},
	{SNMP_OUTPUT_BUFFER_ERRORS, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 11}},
	{SNMP_NOT_ROUTED, 8, CHAINE_NORMALE, {1, 3, 6, 1, 2, 1, 4, 12}},

	{SNMP_MEM_TOTAL_SWAP, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 3}},
	{SNMP_MEM_AVAILABLE_SWAP, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 4}},
	{SNMP_MEM_TOTAL_REAL, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 5}},
	{SNMP_MEM_AVAILABLE_REAL, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 6}},
	{SNMP_MEM_TOTAL_FREE, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 11}},
	{SNMP_MEM_SHARED, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 13}},
	{SNMP_MEM_BUFFER, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 14}},
	{SNMP_MEM_CACHED, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 15}},
	{SNMP_MEM_SWAP_ERROR, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 100}},
	{SNMP_MEM_SWAP_ERROR_MSG, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 4, 101}},

	{SNMP_CPU_RAW_USER, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 11, 50}},
	{SNMP_CPU_RAW_NICE, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 11, 51}},
	{SNMP_CPU_RAW_SYSTEM, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 11, 52}},
	{SNMP_CPU_RAW_IDLE, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 11, 53}},
	{SNMP_CPU_RAW_WAIT, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 11, 54}},
	{SNMP_CPU_RAW_KERNEL, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 11, 55}},
	{SNMP_CPU_RAW_INTERRUPT, 9, CHAINE_NORMALE, {1 ,3 ,6, 1, 4, 1, 2021, 11, 56}}
};


gboolean Demande_Snmp (struct Struct_Liste_Equipement *Equipement, gint Id_Snmp)
{
	ERROR_if (Equipement == NULL);
	PROTECT_CODE(Semaphore_Snmp);
	netsnmp_session session, *ss = NULL;
	netsnmp_pdu *pdu = NULL, *response = NULL;
	netsnmp_variable_list *vars = NULL;
	size_t    rootlen;
	int       status;
	gchar     Texte[SPRINT_MAX_LEN], *Debut_Info = NULL;

	Debut_Info = NULL;
	SOCK_STARTUP;
	snmp_sess_init (&session);

	session.version = SNMP_VERSION_1;
	session.peername = Equipement->Adresse_Ip_Char;
	session.remote_port = SNMP_PORT;
	session.timeout = TIME_OUT_SNMP;
	session.community = Info_Demarrage.Communaute_Snmp;
	session.community_len = strlen (session.community);
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Open Session %s  Id_Snmp %d", Equipement->Adresse_Ip_Char, Id_Snmp);
	ss = snmp_open (&session);
	if (ss == NULL) {
		debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Failed : Open session");
		SOCK_CLEANUP;
		DEPROTECT_CODE(Semaphore_Snmp);
		return FALSE;
	}
	pdu = snmp_pdu_create (SNMP_MSG_GETNEXT);
	snmp_add_null_var (pdu, Liste_Objet_Snmp[Id_Snmp].objid_mib, Liste_Objet_Snmp[Id_Snmp].Taille_oid);
	rootlen = Liste_Objet_Snmp[Id_Snmp].Taille_oid;
	status = snmp_synch_response (ss, pdu, &response);
	if (status == STAT_SUCCESS) {
		if (response->errstat == SNMP_ERR_NOERROR) {
			vars = response->variables;
			if ((vars->name_length < rootlen) || (memcmp (Liste_Objet_Snmp[Id_Snmp].objid_mib, vars->name, rootlen * sizeof (oid)) != 0)) {
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s  Id_Snmp %d (vars->name_length < rootlen) || (memcmp (Liste_Objet_Snmp[Id_Snmp].objid_mib, vars->name, rootlen * sizeof (oid)) != 0)", Equipement->Adresse_Ip_Char, Id_Snmp);
				snmp_free_pdu (response);
				snmp_close (ss);
				SOCK_CLEANUP;
				DEPROTECT_CODE(Semaphore_Snmp);
				return FALSE;
			}
			snprint_variable (Texte, sizeof (Texte), vars->name, vars->name_length, vars);
			ERROR_if (Texte == NULL);
			ERROR_if (strlen (Texte) >= SPRINT_MAX_LEN);
			Debut_Info = index (Texte, '=');    
			ERROR_if (Debut_Info == NULL);
			ERROR_if (strlen (Debut_Info) == 0);
			if (Debut_Info != NULL)
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Retour Snmp : (%d)[%s]", strlen (Debut_Info), Debut_Info);
			else
				debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s][%s]", session.peername, Texte);
		}
		else {
			Debut_Info = "None";
			if (response->errstat == SNMP_ERR_NOSUCHNAME)
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s]End of MIB", session.peername);
			else
				debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s]Error in packet. Reason: %s", session.peername, snmp_errstring (response->errstat));
		}
	
		snmp_free_pdu (response);
		snmp_close (ss);
		SOCK_CLEANUP;

		switch (Id_Snmp) {
		    case SNMP_SYSTEM_NAME:
			    Traitement_Chaine_Snmp (SNMP_SYSTEM_NAME, Debut_Info, Equipement->Snmp.System_Name);
			    break;
		    case SNMP_DESCRIPTION:
			    Traitement_Chaine_Snmp (SNMP_DESCRIPTION, Debut_Info, Equipement->Snmp.Description);
			    break;
		    case SNMP_CONTACT:
			    Traitement_Chaine_Snmp (SNMP_CONTACT, Debut_Info, Equipement->Snmp.Contact);
			    break;
		    case SNMP_LOCATION:
			    Traitement_Chaine_Snmp (SNMP_LOCATION, Debut_Info, Equipement->Snmp.Location);
			    break;
		    case SNMP_UPTIME:
			    Traitement_Timeticks_Snmp (SNMP_UPTIME, Debut_Info, Equipement->Snmp.Uptime);
			    break;
		    case SNMP_RAM:
			    Equipement->Snmp.Ram = Traitement_Integer_Snmp (SNMP_RAM, Debut_Info);
			    break;
		    case SNMP_IP_FORWARDING:
			    Traitement_Integer_Conv_Chaine_Snmp (SNMP_IP_FORWARDING, Debut_Info, Equipement->Snmp.Ip_Forwarding);
			    break;
		    case SNMP_DEFAULT_TTL:
			    Equipement->Snmp.Default_TTL = Traitement_Integer_Snmp (SNMP_DEFAULT_TTL, Debut_Info);
			    break;
		    case SNMP_REASSEMBLY_TIMEOUT:
			    Equipement->Snmp.Reassembly_Timeout = Traitement_Integer_Snmp (SNMP_REASSEMBLY_TIMEOUT, Debut_Info);
			    break;
		    case SNMP_NEEDED_TO_BE_REASSEMBLED:
			    Equipement->Snmp.Need_To_Be_Reassembled = Traitement_Counter_Snmp (SNMP_NEEDED_TO_BE_REASSEMBLED, Debut_Info);
			    break;
		    case SNMP_REASSEMBLED:
			    Equipement->Snmp.Reassembled = Traitement_Counter_Snmp (SNMP_REASSEMBLED, Debut_Info);
			    break;
		    case SNMP_REASSEMBLY_FAILURES:
			    Equipement->Snmp.Reassembly_Failures = Traitement_Counter_Snmp (SNMP_REASSEMBLY_FAILURES, Debut_Info);
			    break;
		    case SNMP_SUCCESSFULLY_FRAGMENTED:
			    Equipement->Snmp.Successfully_Fragmented = Traitement_Counter_Snmp (SNMP_SUCCESSFULLY_FRAGMENTED, Debut_Info);
			    break;
		    case SNMP_FRAGMENTATION_FAILURES:
			    Equipement->Snmp.Fragmentation_Failures = Traitement_Counter_Snmp (SNMP_FRAGMENTATION_FAILURES, Debut_Info);
			    break;
		    case SNMP_CREATED_FRAGMENTS:
			    Equipement->Snmp.Created_Fragments = Traitement_Counter_Snmp (SNMP_CREATED_FRAGMENTS, Debut_Info);
			    break;
		    case SNMP_DISCARDED_ROUTING_ENTRIES:
			    Equipement->Snmp.Discarded_Routing_Entries = Traitement_Counter_Snmp (SNMP_DISCARDED_ROUTING_ENTRIES, Debut_Info);
			    break;
		    case SNMP_ALL:
			    Equipement->Snmp.All = Traitement_Counter_Snmp (SNMP_ALL, Debut_Info);
			    break;
		    case SNMP_FORWARDED:
			    Equipement->Snmp.Forwarded = Traitement_Counter_Snmp (SNMP_FORWARDED, Debut_Info);
			    break;
		    case SNMP_DELIVERED:
			    Equipement->Snmp.Delivered = Traitement_Counter_Snmp (SNMP_DELIVERED, Debut_Info);
			    break;
		    case SNMP_HEADER_ERRORS:
			    Equipement->Snmp.Header_Errors = Traitement_Counter_Snmp (SNMP_HEADER_ERRORS, Debut_Info);
			    break;
		    case SNMP_ADDRESS_ERRORS:
			    Equipement->Snmp.Address_Errors = Traitement_Counter_Snmp (SNMP_ADDRESS_ERRORS, Debut_Info);
			    break;
		    case SNMP_UNKNOWN_PROTOCOLS:
			    Equipement->Snmp.Unknown_Protocol = Traitement_Counter_Snmp (SNMP_UNKNOWN_PROTOCOLS, Debut_Info);
			    break;
		    case SNMP_INPUT_BUFFER_ERRORS:
			    Equipement->Snmp.Input_Buffer_Errors = Traitement_Counter_Snmp (SNMP_INPUT_BUFFER_ERRORS, Debut_Info);
			    break;
		    case SNMP_REQUESTED:
			    Equipement->Snmp.Requested = Traitement_Counter_Snmp (SNMP_REQUESTED, Debut_Info);
			    break;
		    case SNMP_OUTPUT_BUFFER_ERRORS:
			    Equipement->Snmp.Output_Buffer_Errors = Traitement_Counter_Snmp (SNMP_OUTPUT_BUFFER_ERRORS, Debut_Info);
			    break;
		    case SNMP_NOT_ROUTED:
			    Equipement->Snmp.Not_Routed = Traitement_Counter_Snmp (SNMP_NOT_ROUTED, Debut_Info);
			    break;
			case SNMP_MEM_TOTAL_SWAP:
			    Equipement->Snmp.Mem_Total_Swap = Traitement_Integer_Snmp (SNMP_MEM_TOTAL_SWAP, Debut_Info);
			    break;
			case SNMP_MEM_AVAILABLE_SWAP:
			    Equipement->Snmp.Mem_Available_Swap = Traitement_Integer_Snmp (SNMP_MEM_AVAILABLE_SWAP, Debut_Info);
			    break;
			case SNMP_MEM_TOTAL_REAL:
			    Equipement->Snmp.Mem_Total_Real = Traitement_Integer_Snmp (SNMP_MEM_TOTAL_REAL, Debut_Info);
			    break;
			case SNMP_MEM_AVAILABLE_REAL:
			    Equipement->Snmp.Mem_Available_Real = Traitement_Integer_Snmp (SNMP_MEM_AVAILABLE_REAL, Debut_Info);
			    break;
			case SNMP_MEM_TOTAL_FREE:
			    Equipement->Snmp.Mem_Total_Free = Traitement_Integer_Snmp (SNMP_MEM_TOTAL_FREE, Debut_Info);
			    break;
			case SNMP_MEM_SHARED:
			    Equipement->Snmp.Mem_Shared = Traitement_Integer_Snmp (SNMP_MEM_SHARED, Debut_Info);
			    break;
			case SNMP_MEM_BUFFER:
			    Equipement->Snmp.Mem_Buffer = Traitement_Integer_Snmp (SNMP_MEM_BUFFER, Debut_Info);
			    break;
			case SNMP_MEM_CACHED:
			    Equipement->Snmp.Mem_Cached = Traitement_Integer_Snmp (SNMP_MEM_CACHED, Debut_Info);
			    break;
			case SNMP_MEM_SWAP_ERROR:
			    Equipement->Snmp.Mem_Swap_Error = Traitement_Integer_Snmp (SNMP_MEM_SWAP_ERROR, Debut_Info);
			    break;
			case SNMP_MEM_SWAP_ERROR_MSG:
				Traitement_Chaine_Snmp (SNMP_MEM_SWAP_ERROR_MSG, Debut_Info, Equipement->Snmp.Mem_Swap_Error_Message);
			    break;
			 case SNMP_CPU_RAW_USER:
			    Equipement->Snmp.Cpu_Raw_User = Traitement_Counter_Snmp (SNMP_CPU_RAW_USER, Debut_Info);
			    break;
			 case SNMP_CPU_RAW_NICE:
			    Equipement->Snmp.Cpu_Raw_Nice = Traitement_Counter_Snmp (SNMP_CPU_RAW_NICE, Debut_Info);
			    break;
			 case SNMP_CPU_RAW_SYSTEM:
			    Equipement->Snmp.Cpu_Raw_System = Traitement_Counter_Snmp (SNMP_CPU_RAW_SYSTEM, Debut_Info);
			    break;
			 case SNMP_CPU_RAW_IDLE:
			    Equipement->Snmp.Cpu_Raw_Idle = Traitement_Counter_Snmp (SNMP_CPU_RAW_IDLE, Debut_Info);
			    break;
			 case SNMP_CPU_RAW_WAIT:
			    Equipement->Snmp.Cpu_Raw_Wait = Traitement_Counter_Snmp (SNMP_CPU_RAW_WAIT, Debut_Info);
			    break;
			 case SNMP_CPU_RAW_KERNEL:
			    Equipement->Snmp.Cpu_Raw_Kernel = Traitement_Counter_Snmp (SNMP_CPU_RAW_KERNEL, Debut_Info);
			    break;
			 case SNMP_CPU_RAW_INTERRUPT:
			    Equipement->Snmp.Cpu_Raw_Interrupt = Traitement_Counter_Snmp (SNMP_CPU_RAW_INTERRUPT, Debut_Info);
			    break;
		    default:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Id_Snmp (%d) inconnu ", Id_Snmp);
		}
		DEPROTECT_CODE(Semaphore_Snmp);
		return TRUE;
	}
	else {
		if (status == STAT_TIMEOUT)
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Timeout: No Response from %s", session.peername);
		else
			debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s]ERROR", session.peername);
	
		snmp_free_pdu (response);
		snmp_close (ss);
		SOCK_CLEANUP;
		DEPROTECT_CODE(Semaphore_Snmp);
		return FALSE;
	}
	return FALSE;
}



void Traitement_Chaine_Snmp (gint Id_Snmp, gchar * Chaine_Brut, gchar * Stock)
{
#define   DEBUT_STRING  "= STRING: "
	gint      Taille;

	if (Chaine_Brut == NULL)
		return;
	if (strncmp (Chaine_Brut, DEBUT_STRING, (sizeof (DEBUT_STRING) - 1)) == 0) {
		Taille = strlen (Chaine_Brut + sizeof (DEBUT_STRING) - 1);
		if (Taille <= 0) {
			Stock = NULL;
			return;
		}
		if (Taille > (Liste_Objet_Snmp[Id_Snmp].Taille_Chaine_Max - 1))
			Taille = Liste_Objet_Snmp[Id_Snmp].Taille_Chaine_Max - 1;
		strncpy (Stock, Chaine_Brut + sizeof (DEBUT_STRING) - 1, Taille);
		Stock[Taille] = 0;
	}
}


void Traitement_Timeticks_Snmp (gint Id_Snmp, gchar * Chaine_Brut, gchar * Stock)
{
#define   DEBUT_TIMETICKS  "= Timeticks: "
	gint      Taille;

	if (Chaine_Brut == NULL)
		return;
	if (strncmp (Chaine_Brut, DEBUT_TIMETICKS, (sizeof (DEBUT_TIMETICKS) - 1)) == 0) {
		Taille = strlen (Chaine_Brut + sizeof (DEBUT_TIMETICKS) - 1);
		if (Taille <= 0) {
			Stock = NULL;
			return;
		}
		if (Taille > (Liste_Objet_Snmp[Id_Snmp].Taille_Chaine_Max - 1))
			Taille = Liste_Objet_Snmp[Id_Snmp].Taille_Chaine_Max - 1;
		strncpy (Stock, Chaine_Brut + sizeof (DEBUT_TIMETICKS) - 1, Taille);
		Stock[Taille] = 0;
	}
}


gint Traitement_Counter_Snmp (gint Id_Snmp, gchar * Chaine_Brut)
{
#define   DEBUT_COUNTER  "= Counter32: "
	gint      Nb;

	if (Chaine_Brut == NULL)
		return -1;
	if (strncmp (Chaine_Brut, DEBUT_COUNTER, (sizeof (DEBUT_COUNTER) - 1)) == 0) {
		if (sscanf (Chaine_Brut, "= Counter32: %i", &Nb) != 1)
			return -1;
		return Nb;
	}
	return -1;
}


void Traitement_Integer_Conv_Chaine_Snmp (gint Id_Snmp, gchar * Chaine_Brut, gchar * Stock)
{
#define   DEBUT_INTEGER  "= INTEGER: "
	gint      Taille;

	if (Chaine_Brut == NULL)
		return;
	if (strncmp (Chaine_Brut, DEBUT_INTEGER, (sizeof (DEBUT_INTEGER) - 1)) == 0) {
		Taille = strlen (Chaine_Brut + sizeof (DEBUT_INTEGER) - 1);
		if (Taille <= 0) {
			Stock = NULL;
			return;
		}
		if (Taille > (Liste_Objet_Snmp[Id_Snmp].Taille_Chaine_Max - 1))
			Taille = Liste_Objet_Snmp[Id_Snmp].Taille_Chaine_Max - 1;
		strncpy (Stock, Chaine_Brut + sizeof (DEBUT_INTEGER) - 1, Taille);
		Stock[Taille] = 0;
	}
}

gint Traitement_Integer_Snmp (gint Id_Snmp, gchar * Chaine_Brut)
{
#define   DEBUT_INTEGER  "= INTEGER: "
	gint      Nb;

	if (Chaine_Brut == NULL)
		return -1;
	if (strncmp (Chaine_Brut, DEBUT_INTEGER, (sizeof (DEBUT_INTEGER) - 1)) == 0) {
		if (sscanf (Chaine_Brut, "= INTEGER: %d", &Nb) != 1)
			return -1;
		return Nb;
	}
	return -1;
}


void Demande_Snmp_Equipement (struct Struct_Liste_Equipement *Equipement)
{
	gint      i;

	ERROR_if (Equipement == NULL);
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Debut Demande_Snmp_Equipement : %s", Equipement->Adresse_Ip_Char);
	if (Demande_Snmp (Equipement, SNMP_SYSTEM_NAME)) {
		Equipement->Snmp_Ouvert = TRUE;
		for (i = 1; i < NB_TOTAL_ID_SNMP_SCALAIRE; i++)
			Demande_Snmp (Equipement, i);
	}
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fin Demande_Snmp_Equipement : %s", Equipement->Adresse_Ip_Char);
}



#define HOST_RESSOURCE "HOST-RESOURCES-TYPES::"

gboolean Envoie_Snmp_Liste (struct Struct_Liste_Equipement *Equipement, gint Id_Snmp)
{
	ERROR_if (Equipement == NULL);
	PROTECT_CODE(Semaphore_Snmp);
	netsnmp_session session, *ss = NULL;
	netsnmp_pdu *pdu = NULL, *response = NULL;
	netsnmp_variable_list *vars = NULL;
	oid       name[MAX_OID_LEN];
	size_t    name_length;
	oid       root[MAX_OID_LEN];
	size_t    rootlen;
	gint      status, IndexTableau, Taille, ligne, Ancienne_Colonne;
	gboolean  Fin, Donnee_Presente;
	gchar     Texte[SPRINT_MAX_LEN], *Debut_Info = NULL;
	struct struct_Retour_Liste_SNMP Message;
	
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s  [%d]",Equipement->Adresse_Ip_Char,Id_Snmp);
	bzero (&Message, sizeof (struct struct_Retour_Liste_SNMP));

	Message.ID_Reseau = Info_Demarrage.ID_Reseau;
	memcpy (Message.ID_Equipement, Equipement->ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN + 1);
	Message.ID_Snmp = Id_Snmp;
	IndexTableau = 0;

	SOCK_STARTUP;
	bzero (&session, sizeof (netsnmp_session));
	snmp_sess_init (&session);

	session.version = SNMP_VERSION_1;
	session.peername = Equipement->Adresse_Ip_Char;
	session.remote_port = SNMP_PORT;
	session.timeout = 400000;
	session.community = Info_Demarrage.Communaute_Snmp;
	session.community_len = strlen (session.community);
	ss = snmp_open (&session);
	if (ss == NULL) {
		debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Failed : Open session");
		SOCK_CLEANUP;
		DEPROTECT_CODE(Semaphore_Snmp);
		return FALSE;
	}
	memmove (root, Liste_Snmp[Id_Snmp].objid_mib, Liste_Snmp[Id_Snmp].Taille_oid * sizeof (oid));
	rootlen = Liste_Snmp[Id_Snmp].Taille_oid;
	memmove (name, root, rootlen * sizeof (oid));
	name_length = rootlen;
	Ancienne_Colonne = 0;
	ligne = 0;
	Donnee_Presente = FALSE;
	Fin = FALSE;
	while (!Fin) {
		pdu = snmp_pdu_create (SNMP_MSG_GETNEXT);
		snmp_add_null_var (pdu, name, name_length);
		status = snmp_synch_response (ss, pdu, &response);
		if (status == STAT_SUCCESS) {
			if (response->errstat == SNMP_ERR_NOERROR) {
				vars = response->variables;
				if ((vars->name_length < rootlen) || (memcmp (root, vars->name, rootlen * sizeof (oid)) != 0)) {
					Fin = TRUE;
					snmp_free_pdu (response);
					continue;
				}
				snprint_variable (Texte, sizeof (Texte), vars->name, vars->name_length, vars);
				Debut_Info = strstr (Texte, " = ");
				if (Debut_Info == NULL) {
					Fin = TRUE;
					snmp_free_pdu (response);
					continue;
				}
				Debut_Info = Debut_Info + strlen (" = ");
				if (index (Debut_Info, ':') != NULL)
					Debut_Info = index (Debut_Info, ':') + 2;
				if (strncmp (Debut_Info, HOST_RESSOURCE, strlen (HOST_RESSOURCE)) == 0)
					Debut_Info = Debut_Info + strlen (HOST_RESSOURCE);
				if (Debut_Info[0]=='"')
					Debut_Info++;
				if (Debut_Info[strlen(Debut_Info)-1]=='"')
					Debut_Info[strlen(Debut_Info)-1] = '\0';
				Message.Liste_Donnee[IndexTableau].Colonne = (gint) vars->name[rootlen];
				if (Ancienne_Colonne != (gint) vars->name[rootlen]) {
					Ancienne_Colonne = (gint) vars->name[rootlen];
					ligne = 0;
				}
				Message.Liste_Donnee[IndexTableau].Ligne = ligne;
				ligne++;
				Taille = strlen (Debut_Info);
				if (Taille > CHAINE_NORMALE - 1)
					Taille = CHAINE_NORMALE - 1;
				strncpy (Message.Liste_Donnee[IndexTableau].Info, Debut_Info, Taille);
				Message.Liste_Donnee[IndexTableau].Info[Taille] = 0;
				Donnee_Presente = TRUE;
				IndexTableau++;
				if (IndexTableau == NB_MAX_LIGNE_LISTE_SNMP) {
					Message.Tout_Donnee_Transferer = FALSE;
					Communication_Envoie_Donnee (RETOUR_LISTE_SNMP, (gpointer *) & Message, sizeof (Message));
					bzero (&Message, sizeof (struct struct_Retour_Liste_SNMP));
				
					Message.ID_Reseau = Info_Demarrage.ID_Reseau;
					memcpy (Message.ID_Equipement, Equipement->ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN + 1);
					Message.ID_Snmp = Id_Snmp;
					IndexTableau = 0;
					Donnee_Presente = FALSE;
				}

				if ((vars->type != SNMP_ENDOFMIBVIEW) && (vars->type != SNMP_NOSUCHOBJECT) && (vars->type != SNMP_NOSUCHINSTANCE)) {
					memmove ((char *) name, (char *) vars->name, vars->name_length * sizeof (oid));
					name_length = vars->name_length;
				}
				else
					Fin = TRUE;

			}
			else {
				if (response->errstat == SNMP_ERR_NOSUCHNAME) {
					debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s]End of MIB", session.peername);
					snmp_free_pdu (response);
					snmp_close (ss);
					SOCK_CLEANUP;
					DEPROTECT_CODE(Semaphore_Snmp);
					return TRUE;
				}
				else {
					debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s]Error in packet. Reason: %s", session.peername, snmp_errstring (response->errstat));
					snmp_free_pdu (response);
					snmp_close (ss);
					SOCK_CLEANUP;
					DEPROTECT_CODE(Semaphore_Snmp);
					return TRUE;
				}
			}
		}
		else {
			if (status == STAT_TIMEOUT) {
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Timeout: No Response from %s", session.peername);
				snmp_free_pdu (response);
				snmp_close (ss);
				SOCK_CLEANUP;
				DEPROTECT_CODE(Semaphore_Snmp);
				return FALSE;
			}
			else {
				debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s]ERROR", session.peername);
				snmp_free_pdu (response);
				snmp_close (ss);
				SOCK_CLEANUP;
				DEPROTECT_CODE(Semaphore_Snmp);
				return TRUE;
			}
		}
		snmp_free_pdu (response);

	}
	snmp_close (ss);
	SOCK_CLEANUP;

	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s  [%d] Tout_Donnee_Transfere",Equipement->Adresse_Ip_Char,Id_Snmp);
	Message.Tout_Donnee_Transferer = TRUE;
	Communication_Envoie_Donnee (RETOUR_LISTE_SNMP, (gpointer *) & Message, sizeof (Message));
	DEPROTECT_CODE(Semaphore_Snmp);
	return TRUE;
}


void Thread_Demande_Interface_Liste_Snmp (gpointer * Donnee_Clone){
	struct struct_Demande_Liste_SNMP *Message = (struct struct_Demande_Liste_SNMP *) Donnee_Clone;
	struct Struct_Liste_Equipement *Equipement = NULL;
	gint      ID_Equipement;

#ifdef __LOG_ENABLE
	Create_Log(CATEG_THREAD_SNMP_LISTE,NULL,Equipement,TRUE);
#endif
	ERROR_if (Donnee_Clone == NULL);

	Recherche_Index_Equipement (Message->ID_Equipement,TRUE, &ID_Equipement);
	if (ID_Equipement == EQUIPEMENT_UNKNOWN) {
		debug_printf (D_WARN_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Demande_Interface_Liste_Snmp (Equipment unknown)");
		MYFREE(Donnee_Clone); 
		Stop_Thread (NULL);
	}
	if (ID_Equipement == EQUIPEMENT_NO_IP) {
		debug_printf (D_WARN_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Demande_Interface_Liste_Snmp (no IP)");
		MYFREE(Donnee_Clone); 
		Stop_Thread (NULL);
	}
	Retour_Pointeur_Equipement (&Equipement,ID_Equipement);
	Envoie_Snmp_Liste(Equipement,Message->ID_Snmp);
	MYFREE(Donnee_Clone); 
	Stop_Thread (NULL);
}


void Thread_Demande_Interface_Liste_Snmp_All (gpointer * Donnee_Clone){
	struct struct_Demande_Liste_SNMP *Message = (struct struct_Demande_Liste_SNMP *) Donnee_Clone;
	struct struct_Del_Glist_SNMP Message_Supp_Glist;
	struct Struct_Liste_Equipement *Equipement = NULL;
	gint      ID_Equipement,i;

#ifdef __LOG_ENABLE
	Create_Log(CATEG_THREAD_SNMP_LISTE_ALL,NULL,Equipement,TRUE);
#endif
	ERROR_if (Donnee_Clone == NULL);

	Recherche_Index_Equipement (Message->ID_Equipement,TRUE, &ID_Equipement);
	if (ID_Equipement == EQUIPEMENT_UNKNOWN) {
		debug_printf (D_WARN_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Demande_Interface_Liste_Snmp (Equipment unknown)");
		MYFREE(Donnee_Clone); 
		Stop_Thread (NULL);
	}
	if (ID_Equipement == EQUIPEMENT_NO_IP) {
		debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Demande_Interface_Liste_Snmp (no IP)");
		MYFREE(Donnee_Clone); 
		Stop_Thread (NULL);
	}
	Retour_Pointeur_Equipement (&Equipement,ID_Equipement);
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "");
		
	for (i = 0; i < 8; i++){
		debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "[%s]  ID_Snmp(%d)", Equipement->Adresse_Ip_Char,i);
	
		bzero (&Message_Supp_Glist, sizeof (struct struct_Del_Glist_SNMP));
	
		Message_Supp_Glist.ID_Reseau = Info_Demarrage.ID_Reseau;
		memcpy (Message_Supp_Glist.ID_Equipement, Equipement->ID_Equipement, MAC_ADDR_LEN + IP_ADDR_LEN + 1);
		Message_Supp_Glist.ID_Snmp = i;
		Communication_Envoie_Donnee (DEL_GLIST_SNMP, (gpointer *) & Message_Supp_Glist, sizeof (Message_Supp_Glist));
	
		if (!Envoie_Snmp_Liste(Equipement,i)){
			MYFREE(Donnee_Clone); 
			Stop_Thread (NULL);
		}
	}
	MYFREE(Donnee_Clone); 
	Stop_Thread (NULL);
}


void Thread_Demande_Interface_Snmp_Scalaire (gpointer * Donnee_Clone){
	struct struct_Demande_SNMP_Scalaire *Message = (struct struct_Demande_SNMP_Scalaire *) Donnee_Clone;
	struct struct_Retour_SNMP_Scalaire Message_Retour;
	struct Struct_Liste_Equipement *Equipement = NULL;
	gint      ID_Equipement,i;

#ifdef __LOG_ENABLE
	Create_Log(CATEG_THREAD_SNMP_SCALAIRE,NULL,Equipement,TRUE);
#endif
	ERROR_if (Donnee_Clone == NULL);

	MYFREE(Donnee_Clone); 
	Stop_Thread (NULL);
}

void Initialisation_Snmp (void)
{
	init_snmp ("autoscan-network-daemon");
}

#endif

void Demande_Envoie_Snmp_Scalaire (gpointer * Donnee)
{
#ifdef        __SNMP_ENABLE
	struct struct_Demande_SNMP_Scalaire *Copie_Donnee = NULL;
		
	ERROR_if (Donnee == NULL);

	MALLOC(Copie_Donnee,sizeof(struct struct_Demande_SNMP_Scalaire));
	memcpy(Copie_Donnee,Donnee,sizeof(struct struct_Demande_SNMP_Scalaire));
	demmarrage_Thread (&Thread_Demande_Interface_Snmp_Scalaire, Copie_Donnee);
#endif
}

void Demande_Envoie_Liste_Snmp_All (gpointer * Donnee)
{
#ifdef        __SNMP_ENABLE
	struct struct_Demande_Liste_SNMP_All *Copie_Donnee = NULL;
		
	ERROR_if (Donnee == NULL);

	MALLOC(Copie_Donnee,sizeof(struct struct_Demande_Liste_SNMP_All));

	memcpy(Copie_Donnee,Donnee,sizeof(struct struct_Demande_Liste_SNMP_All));

	demmarrage_Thread (&Thread_Demande_Interface_Liste_Snmp_All, Copie_Donnee);
#endif
}

void Demande_Envoie_Liste_Snmp (gpointer * Donnee)
{
#ifdef        __SNMP_ENABLE
	struct struct_Demande_Liste_SNMP *Copie_Donnee = NULL;
		
	ERROR_if (Donnee == NULL);

	MALLOC(Copie_Donnee,sizeof(struct struct_Demande_Liste_SNMP));

	memcpy(Copie_Donnee,Donnee,sizeof(struct struct_Demande_Liste_SNMP));

	demmarrage_Thread (&Thread_Demande_Interface_Liste_Snmp, Copie_Donnee);
#endif
}
