/* ***********************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.
 **************************************************************************************/
#ifndef         __WINDOWS_ENABLE
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/sockios.h>
#else
#include <pcap.h>
#include <remote-ext.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#include <errno.h>
#include "Initialisation_Com.h"
#include "Commun.h"
#include "../Debug.h"
#include "../Declaration_Constante.h"
#include "../Notification_Equipement.h"
#include "../Notification_Port.h"
#include "Reseau.h"
#include "Thread_Detect.h"
#include "Thread.h"
#include "../Info.h"
#include "Semaphore.h"
#include "Scan_Signature.h"
#include "Scan_Service.h"

void Envoie_Version_Agent (void)
{
	struct struct_Agent_Version Message;
	gint      pid;

	pid = getpid ();
	ERROR_if (strlen (VERSION_AGENT) > TAILLE_MAX_VERSION_AGENT);
	strcpy (Message.Version, VERSION_AGENT);
	Message.Taille_Struct = sizeof(struct struct_ALL);
	Message.pid = pid;
	Communication_Envoie_Donnee (AGENT_VERSION, (gpointer *) & Message, sizeof (Message));
}

void Demarrage_Agent (gpointer * Donnee)
{
	ERROR_if (Donnee == NULL);
	memcpy (&Info_Demarrage, Donnee, sizeof (struct struct_Demarrage_Agent));
	if (Info_Demarrage.Normal_Mode){
		Time_Out_Service = 8;
		Time_Out_Connect_Service = 8;
	}
	else {
		Time_Out_Connect_Service = 4;
		Time_Out_Service = 4;
	}
	Debug = Info_Demarrage.Niveau_Debugage;
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Interface : %s  [%s]\n",Info_Demarrage.Interface,Info_Demarrage.nom);

#ifdef __DEBUG_COM
	Log_Send = Create_Log(CATEG_COMM_SEND,Info_Demarrage.nom,NULL,FALSE);
	Log_Recv = Create_Log(CATEG_COMM_RECV,Info_Demarrage.nom,NULL,FALSE);
#endif
	Get_My_Ip ();
	Get_My_MAC ();
	
	Initialisation_Semaphore_Gestion_Thread ();
	demmarrage_Thread (&Boucle_Scan, NULL); 

	if (Nb_Machine_Dans_La_Liste!=0){
		Scan_Machine_Local_Fait = TRUE;
		Start_Scan_Plage();
	}	
	demmarrage_Thread (&Thread_Detect, NULL);
	demmarrage_Thread (&Thread_Notification_Equipement, NULL);
	demmarrage_Thread (&Thread_Notification_Port, NULL);
	demmarrage_Thread (&Info_Agent, NULL);	 
	demmarrage_Thread (&Thread_Rafraichir_Tout_Equipement, NULL);
	demmarrage_Thread (&Ping_Detect, NULL);	 
	Demarrage_Complet_Agent = TRUE;  
}

void Envoie_Liste_Interface (gpointer * Donnee)
{
#ifndef         __WINDOWS_ENABLE
	FILE     *Fichier_Interface = NULL;
	struct struct_Nouvelle_Interface Message;
	struct struct_Fin_Liste_Interface Message_Fin;
	struct ifreq ifr;
	struct sockaddr_in sin;
	struct in_addr in;
	gchar     buf[512], *Interface = NULL, *fin = NULL;
	int       Socket;

	ERROR_if (Donnee == NULL);
	if ((Fichier_Interface = fopen ("/proc/net/dev", "r")) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "/proc/net/dev : %s", strerror (errno));
	fgets (buf, sizeof (buf), Fichier_Interface);
	fgets (buf, sizeof (buf), Fichier_Interface);
	while (fgets (buf, sizeof (buf), Fichier_Interface)) {
		Interface = buf;
		while (Interface[0] == ' ')
			Interface++;
		fin = index (buf, ':');
		fin[0] = 0;
		debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Interface : %s", Interface);
		if (strcmp (Interface, "lo") != 0) {
		
			Socket = socket_control (AF_INET, SOCK_STREAM, 0);
			if (Socket == -1) {
				debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
				continue;
			}
			strcpy (ifr.ifr_name, Interface);
			if (ioctl (Socket, SIOCGIFADDR, &ifr) != -1) {
			
				if (strlen(Interface)>TAILLE_NOM_INTERFACE_STRUCT_NOUVELLE_INTERFACE)
					Interface[TAILLE_NOM_INTERFACE_STRUCT_NOUVELLE_INTERFACE-1] = 0;
				strcpy (Message.Interface, Interface);
			
				memcpy (&sin, &ifr.ifr_addr, sizeof (struct sockaddr_in));
				in.s_addr = sin.sin_addr.s_addr;
				strcpy (Message.Ip, inet_ntoa (in));
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Nouvelle Interface : interface[%s] ip[%s]", Message.Interface,Message.Ip);
				Communication_Envoie_Donnee (NOUVELLE_INTERFACE, (gpointer *) & Message, sizeof (Message));
			}
			close_control (Socket);
		}
	}
	Communication_Envoie_Donnee (FIN_LISTE_INTERFACE, (gpointer *) & Message_Fin, sizeof (Message_Fin));
#else
	struct struct_Nouvelle_Interface Message;
	struct struct_Fin_Liste_Interface Message_Fin;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_if_t * alldevs = NULL;
	pcap_if_t * d = NULL;
	pcap_addr_t *a = NULL;
	int nb_Interface=0;
	 
	
	ERROR_if (Donnee == NULL);
	if (pcap_findalldevs(&alldevs, errbuf) == -1)
    	debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error in pcap_findalldevs: %s", errbuf);

    
    for(d= alldevs; d != NULL; d= d->next){
		if (d->description){
			a=d->addresses;
			if ((a)&&(a->addr->sa_family==AF_INET)&&(a->addr)){
			
          	
			
			
				if (strlen(d->description)>TAILLE_NOM_INTERFACE_STRUCT_NOUVELLE_INTERFACE){
					strncpy(Message.Interface, d->description,TAILLE_NOM_INTERFACE_STRUCT_NOUVELLE_INTERFACE-1);
					Message.Interface[TAILLE_NOM_INTERFACE_STRUCT_NOUVELLE_INTERFACE-1] = 0;
					}
				else
					strcpy (Message.Interface, d->description);
			
				strcpy (Message.Ip, inet_ntoa(((struct sockaddr_in *)(a->addr))->sin_addr));
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Nouvelle Interface : interface[%s] ip[%s]", Message.Interface,Message.Ip);
				Communication_Envoie_Donnee (NOUVELLE_INTERFACE, (gpointer *) & Message, sizeof (Message));
			}
		}
		nb_Interface++;
	}

    if (nb_Interface == 0)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "No interfaces found! Make sure WinPcap is installed");
	 

    pcap_freealldevs(alldevs);

	Communication_Envoie_Donnee (FIN_LISTE_INTERFACE, (gpointer *) & Message_Fin, sizeof (Message_Fin));
#endif
}
