/* ***********************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 <errno.h>
#include <time.h>
#include "Scan_Signature.h"
#include "Debug.h"
#include "Info.h"
#include "Liste_Equipement.h"
#include "Com/Initialisation_Com.h"
#include "Macro.h"
#include <pthread.h>

char      Syn_Normal[] = { 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x06, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00 };
char      Syn_Null[] = { 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x06, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00 };
char      Syn_ECN[] = { 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x06, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x42, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00 };
char      Syn_FIN_URG_PSH[] = { 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x06, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2b, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00 };
char      Ack[] = { 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x06, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x10, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00 };
char      Fin[] = { 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x06, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00 };
char      Udp_30[] = { 0x45, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x26, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee };
char      Icmp_Timestamp[] = { 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8b, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
char      Ping_31[] = { 0x45, 0x00, 0x00, 0x3B, 0x00, 0x01, 0x00, 0x00, 0x4C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x01, 0xF0, 0xDB, 0x44, 0x6A, 0x7C, 0x9F, 0x0C, 0x8D, 0x1F, 0x5d, 0xE3, 0x55, 0x4F, 0x59, 0xA4, 0x15, 0xC3, 0xEF, 0xC7, 0xB1, 0xFF, 0x1c, 0x63, 0x28, 0x88, 0x73, 0x90, 0xD3, 0xBB };
char      Ping_2[] = { 0x45, 0x00, 0x00, 0x3B,	0x00, 0x01,	0x40, 0x00,	0x01,	0x01,	0x00, 0x00,	0x00, 0x00, 0x00, 0x00,	0xe0, 0x00, 0x00, 0x01,	0x08, 0x00,	0x00, 0x00,	0x00, 0x00,	0x00, 0x01,	0x3e, 0x01, 0xF0, 0xDB, 0x44, 0x6A, 0x7C, 0x9F, 0x0C, 0x8D, 0x1F, 0x5d, 0xE3, 0x55, 0x4F, 0x59, 0xA4, 0x15, 0xC3, 0xEF, 0xC7, 0xB1, 0xFF, 0x1c, 0x63, 0x28, 0x88, 0x73, 0x90, 0xD3, 0xBB };


gboolean Traitement_ScanOS_ICMP (struct Struct_Liste_Equipement *Equipement, struct struct_trame *Packet, unsigned char Taille_Trame, unsigned short Taille_Ip, unsigned char Type_ICMP, unsigned char Code_ICMP)
{
	unsigned short Icmp_Id, Icmp_Seq, Port_Destination, Port_Source, Id_Ip;
	gint      Id_Reponse_Trame;

	ERROR_if (Equipement == NULL);
	ERROR_if (Packet == NULL);

	if (Equipement->Scan_Signature) {
		Id_Reponse_Trame = 0;
		if ((Type_ICMP == ECHO_PING_REPLY) && (Code_ICMP == ICMP_CODE_0)) {
			memcpy (&Icmp_Id, &Packet->Datagramme[Taille_Ip + 4], 2);
			Icmp_Id = htons (Icmp_Id);
			memcpy (&Icmp_Seq, &Packet->Datagramme[Taille_Ip + 6], 2);
			Icmp_Seq = htons (Icmp_Seq);
			if ((Equipement->Scan_OS[TRAME_PING_31].Id == Icmp_Id) && (Equipement->Scan_OS[TRAME_PING_31].Seq == Icmp_Seq)) {
				Id_Reponse_Trame = TRAME_PING_31;
			}
		}
		if ((Type_ICMP == DESTINATION_UNREACHABLE) && (Code_ICMP == PORT_UNREACHABLE)) {
			memcpy (&Id_Ip, &Packet->Datagramme[Taille_Ip + 12], 2);
			Id_Ip = htons (Id_Ip);
			memcpy (&Port_Source, &Packet->Datagramme[Taille_Ip + 28], 2);
			Port_Source = htons (Port_Source);
			memcpy (&Port_Destination, &Packet->Datagramme[Taille_Ip + 30], 2);
			Port_Destination = htons (Port_Destination);
			if ((Equipement->Scan_OS[TRAME_UDP_30].Id == Id_Ip) && (Equipement->Scan_OS[TRAME_UDP_30].Port_Scan = Port_Source) && (Equipement->Scan_OS[TRAME_UDP_30].Port_Client = Port_Destination)) {
				Id_Reponse_Trame = TRAME_UDP_30;
			}
		}
		if ((Type_ICMP == TIMESTAMP_REPLY) && (Code_ICMP == ICMP_CODE_0)) {
			memcpy (&Icmp_Id, &Packet->Datagramme[Taille_Ip + 4], 2);
			Icmp_Id = htons (Icmp_Id);
			memcpy (&Icmp_Seq, &Packet->Datagramme[Taille_Ip + 6], 2);
			Icmp_Seq = htons (Icmp_Seq);
			if ((Equipement->Scan_OS[TRAME_ICMP_TIMESTAMP].Id == Icmp_Id) && (Equipement->Scan_OS[TRAME_ICMP_TIMESTAMP].Seq == Icmp_Seq)) {
				Id_Reponse_Trame = TRAME_ICMP_TIMESTAMP;
			}
		}
		if (Id_Reponse_Trame != 0) {
			Equipement->Scan_OS[Id_Reponse_Trame].Reponse_Scan = TRUE;
		
			Equipement->Reponse_Signature_Debug[Id_Reponse_Trame].Time_Fin = time(NULL);
			Equipement->Reponse_Signature_Debug[Id_Reponse_Trame].Temps_Reponse  = (gint) difftime(Equipement->Reponse_Signature_Debug[Id_Reponse_Trame].Time_Fin , Equipement->Reponse_Signature_Debug[Id_Reponse_Trame].Time_Debut);
		
			Equipement->Reponse_Signature[Id_Reponse_Trame].TaillePacketReponse = Taille_Trame;
			Equipement->Reponse_Signature[Id_Reponse_Trame].HeaderLengthIP = Taille_Ip;
			Equipement->Reponse_Signature[Id_Reponse_Trame].DSF = Packet->Datagramme[1];
			memcpy (&Equipement->Reponse_Signature[Id_Reponse_Trame].TailleTotal, &Packet->Datagramme[2], 2);
			Equipement->Reponse_Signature[Id_Reponse_Trame].TailleTotal = htons (Equipement->Reponse_Signature[Id_Reponse_Trame].TailleTotal);
			memcpy (&Id_Ip, &Packet->Datagramme[4], 2);
			Id_Ip = htons (Id_Ip);
			if (Id_Ip == 0)
				Equipement->Reponse_Signature[Id_Reponse_Trame].Id = 0;
			else
				Equipement->Reponse_Signature[Id_Reponse_Trame].Id = 1;
			memcpy (&Equipement->Reponse_Signature[Id_Reponse_Trame].Flags_IP_Offset, &Packet->Datagramme[6], 2);
			Equipement->Reponse_Signature[Id_Reponse_Trame].Flags_IP_Offset = htons (Equipement->Reponse_Signature[Id_Reponse_Trame].Flags_IP_Offset);
			Equipement->Reponse_Signature[Id_Reponse_Trame].TTL = Packet->Datagramme[8];
			Nouveau_Octet_Recu (Taille_Trame);
			return TRUE;
		}
	}
	return FALSE;
}

gboolean Traitement_ScanOS_TCP (struct Struct_Liste_Equipement * Equipement, struct struct_trame * Packet, unsigned char Taille_Trame, unsigned short Taille_Ip, gint Port_Source, gint Port_Destination)
{
	gint      i;
	unsigned short Id_Ip;
	unsigned int NumAckEnCours;

	ERROR_if (Equipement == NULL);
	ERROR_if (Packet == NULL);

	if (Equipement->Scan_Signature) {
		for (i = 0; i < NB_SCAN_OS; i++) {
			if ((Equipement->Scan_OS[i].Port_Scan == Port_Source) && (Equipement->Scan_OS[i].Port_Client == Port_Destination)) {
				Equipement->Scan_OS[i].Reponse_Scan = TRUE;
			
				Equipement->Reponse_Signature_Debug[i].Time_Fin = time(NULL);
				Equipement->Reponse_Signature_Debug[i].Temps_Reponse  = (gint) difftime(Equipement->Reponse_Signature_Debug[i].Time_Fin , Equipement->Reponse_Signature_Debug[i].Time_Debut);
			
				Equipement->Reponse_Signature[i].TaillePacketReponse = Taille_Trame;
			
				Equipement->Reponse_Signature[i].HeaderLengthIP = Taille_Ip;
				Equipement->Reponse_Signature[i].DSF = Packet->Datagramme[1];
				memcpy (&Equipement->Reponse_Signature[i].TailleTotal, &Packet->Datagramme[2], 2);
				Equipement->Reponse_Signature[i].TailleTotal = htons (Equipement->Reponse_Signature[i].TailleTotal);
				memcpy (&Id_Ip, &Packet->Datagramme[4], 2);
				Id_Ip = htons (Id_Ip);
				if (Id_Ip == 0)
					Equipement->Reponse_Signature[i].Id = 0;
				else
					Equipement->Reponse_Signature[i].Id = 1;
				memcpy (&Equipement->Reponse_Signature[i].Flags_IP_Offset, &Packet->Datagramme[6], 2);
				Equipement->Reponse_Signature[i].Flags_IP_Offset = htons (Equipement->Reponse_Signature[i].Flags_IP_Offset);
				Equipement->Reponse_Signature[i].TTL = Packet->Datagramme[8];
			
				memcpy (&NumAckEnCours, &Packet->Datagramme[Taille_Ip + 4], 4);
				if (NumAckEnCours == 0)
					Equipement->Reponse_Signature[i].NumSeq = 0;
				else
					Equipement->Reponse_Signature[i].NumSeq = 1;
				Equipement->Reponse_Signature[i].HeaderLengthTCP = Packet->Datagramme[Taille_Ip + 12];
				Equipement->Reponse_Signature[i].Flags_TCP = Packet->Datagramme[Taille_Ip + 13];
				memcpy (&Equipement->Reponse_Signature[i].WindowSize, &Packet->Datagramme[Taille_Ip + 14], 2);
				Equipement->Reponse_Signature[i].WindowSize = htons (Equipement->Reponse_Signature[i].WindowSize);
				Nouveau_Octet_Recu (Taille_Trame);
				return TRUE;
			}
		}
		return TRUE; 
	}
	return FALSE;
}


#ifndef         __WINDOWS_ENABLE
void Envoyer_Donnee_UDP_Detect_Os (struct Struct_Liste_Equipement *Equip, gint Num_Port, gint Socket, struct sockaddr *sock,int tentative)
#else
void Envoyer_Donnee_UDP_Detect_Os (struct Struct_Liste_Equipement *Equip, gint Num_Port, pcap_t * captureHandle,int tentative)
#endif
{
	ERROR_if (Equip == NULL);
	usleep (SURCHARGE_EQUIPEMENT);	
	if (tentative==0){
		Equip->Reponse_Signature_Debug[TRAME_UDP_30].Num_Port_Utiliser = Num_Port ;
		Equip->Reponse_Signature_Debug[TRAME_UDP_30].Time_Debut = time(NULL);
	}	
	
	if (!(Equip->Scan_OS[TRAME_UDP_30].Reponse_Scan)) {
		bzero (&Equip->PacketOs, sizeof (struct struct_trame));
		Equip->Id_Ip = (unsigned short) rand_r(&graine_rand_r);//random ();
		Equip->Port = ((unsigned short) rand_r(&graine_rand_r));//random ());
		Equip->Port = (Equip->Port & 0x0FFF) + 0xF000;
		Equip->Scan_OS[TRAME_UDP_30].Id = Equip->Id_Ip;
		Equip->Scan_OS[TRAME_UDP_30].Port_Scan = Num_Port;
		Equip->Scan_OS[TRAME_UDP_30].Port_Client = Equip->Port;
		memcpy (&Equip->PacketOs.Dest_MAC, &Equip->Adresse_MAC, ETH_ALEN);
		memcpy (&Equip->PacketOs.Source_MAC, Mon_Adresse_MAC, ETH_ALEN);
		Equip->PacketOs.Proto = htons (TRAME_IP);
		memcpy (&Equip->PacketOs.Datagramme, Udp_30, 58);
		Equip->PacketOs.Datagramme[4] = (Equip->Id_Ip >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[5] = Equip->Id_Ip & 0xFF;
		memcpy (&Equip->PacketOs.Datagramme[12], &Mon_Adresse_Ip, IP_ADDR_LEN);
		memcpy (&Equip->PacketOs.Datagramme[16], &Equip->Adresse_Ip, IP_ADDR_LEN);
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[0], 20, 0);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[10], &Equip->CheckSum_Calc, 2);
		Equip->PacketOs.Datagramme[20] = (Equip->Port >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[21] = Equip->Port & 0xFF;
		Equip->PacketOs.Datagramme[22] = (Num_Port >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[23] = Num_Port & 0xFF;
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[12], 46, 38 + 17);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[26], &Equip->CheckSum_Calc, 2);
		Nouveau_Octet_Envoye (72);
#ifndef         __WINDOWS_ENABLE
		if ((sendto (Socket, &Equip->PacketOs, 72, 0, sock, sizeof (struct sockaddr))) < 0) {
			if ((errno != EPIPE) && (errno != ESPIPE))
				debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
		}
#else
 		if (pcap_sendpacket(captureHandle,(u_char *) &Equip->PacketOs, 72) != 0)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error sending the packet: \n", pcap_geterr(captureHandle));
#endif		
	}
}

#ifndef         __WINDOWS_ENABLE
void Envoyer_Donnee_Ping_Detect_Os (struct Struct_Liste_Equipement *Equip, gint Socket, struct sockaddr *sock,int tentative)
#else
void Envoyer_Donnee_Ping_Detect_Os (struct Struct_Liste_Equipement *Equip, pcap_t * captureHandle ,int tentative)
#endif
{
	ERROR_if (Equip == NULL);
#ifndef         __WINDOWS_ENABLE
	ERROR_if (sock == NULL);
#else
	ERROR_if (captureHandle == NULL);
#endif
	usleep (SURCHARGE_EQUIPEMENT);	
	if (tentative==0){
		Equip->Reponse_Signature_Debug[TRAME_PING_31].Num_Port_Utiliser = -1;
		Equip->Reponse_Signature_Debug[TRAME_PING_31].Time_Debut = time(NULL);
	}	
	
	if (!(Equip->Scan_OS[TRAME_PING_31].Reponse_Scan)) {
		bzero (&Equip->PacketOs, sizeof (struct struct_trame));
		Equip->Icmp_Id = (unsigned short) rand_r(&graine_rand_r);
		Equip->Icmp_Seq = 1;
		Equip->Scan_OS[TRAME_PING_31].Id = Equip->Icmp_Id;
		Equip->Scan_OS[TRAME_PING_31].Seq = Equip->Icmp_Seq;
		memcpy (&Equip->PacketOs.Dest_MAC, &Equip->Adresse_MAC, ETH_ALEN);
		memcpy (&Equip->PacketOs.Source_MAC, Mon_Adresse_MAC, ETH_ALEN);
		Equip->PacketOs.Proto = htons (TRAME_IP);
		memcpy (&Equip->PacketOs.Datagramme, Ping_31, 59);
		memcpy (&Equip->PacketOs.Datagramme[12], &Mon_Adresse_Ip, IP_ADDR_LEN);
		memcpy (&Equip->PacketOs.Datagramme[16], &Equip->Adresse_Ip, IP_ADDR_LEN);
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[0], 20, 0);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[10], &Equip->CheckSum_Calc, 2);
		Equip->PacketOs.Datagramme[24] = (Equip->Icmp_Id >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[25] = Equip->Icmp_Id & 0xFF;
		Equip->PacketOs.Datagramme[26] = (Equip->Icmp_Seq >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[27] = Equip->Icmp_Seq & 0xFF;
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[20], 39, 0);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[22], &Equip->CheckSum_Calc, 2);
		Nouveau_Octet_Envoye (73);
#ifndef         __WINDOWS_ENABLE
		if ((sendto (Socket, &Equip->PacketOs, 73, 0, sock, sizeof (struct sockaddr))) < 0) {
			if ((errno != EPIPE) && (errno != ESPIPE))
				debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
		}
#else
 		if (pcap_sendpacket(captureHandle,(u_char *) &Equip->PacketOs, 73) != 0)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error sending the packet: \n", pcap_geterr(captureHandle));
#endif
	}
}


#ifndef         __WINDOWS_ENABLE
void Envoyer_Donnee_ICMP_TimeStamp_Detect_Os (struct Struct_Liste_Equipement *Equip, gint Socket, struct sockaddr *sock,int tentative)
#else
void Envoyer_Donnee_ICMP_TimeStamp_Detect_Os (struct Struct_Liste_Equipement *Equip, pcap_t * captureHandle,int tentative)
#endif
{
	ERROR_if (Equip == NULL);
#ifndef         __WINDOWS_ENABLE
	ERROR_if (sock == NULL);
#else
	ERROR_if (captureHandle == NULL);
#endif
	usleep (SURCHARGE_EQUIPEMENT);	
	if (tentative==0){
		Equip->Reponse_Signature_Debug[TRAME_ICMP_TIMESTAMP].Num_Port_Utiliser = -1;
		Equip->Reponse_Signature_Debug[TRAME_ICMP_TIMESTAMP].Time_Debut = time(NULL);
	}	
	
	if (!(Equip->Scan_OS[TRAME_ICMP_TIMESTAMP].Reponse_Scan)) {
		bzero (&Equip->PacketOs, sizeof (struct struct_trame));
		Equip->Id_Ip = (unsigned short) rand_r(&graine_rand_r);
		Equip->Icmp_Id = (unsigned short) rand_r(&graine_rand_r);
		Equip->Icmp_Seq = (unsigned short) rand_r(&graine_rand_r);
		Equip->Scan_OS[TRAME_ICMP_TIMESTAMP].Id = Equip->Icmp_Id;
		Equip->Scan_OS[TRAME_ICMP_TIMESTAMP].Seq = Equip->Icmp_Seq;
		memcpy (&Equip->PacketOs.Dest_MAC, &Equip->Adresse_MAC, ETH_ALEN);
		memcpy (&Equip->PacketOs.Source_MAC, Mon_Adresse_MAC, ETH_ALEN);
		Equip->PacketOs.Proto = htons (TRAME_IP);
		memcpy (&Equip->PacketOs.Datagramme, Icmp_Timestamp, 40);
		Equip->PacketOs.Datagramme[4] = (Equip->Id_Ip >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[5] = Equip->Id_Ip & 0xFF;
		memcpy (&Equip->PacketOs.Datagramme[12], &Mon_Adresse_Ip, IP_ADDR_LEN);
		memcpy (&Equip->PacketOs.Datagramme[16], &Equip->Adresse_Ip, IP_ADDR_LEN);
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[0], 20, 0);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[10], &Equip->CheckSum_Calc, 2);
		Equip->PacketOs.Datagramme[24] = (Equip->Icmp_Id >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[25] = Equip->Icmp_Id & 0xFF;
		Equip->PacketOs.Datagramme[26] = (Equip->Icmp_Seq >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[27] = Equip->Icmp_Seq & 0xFF;
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[20], 20, 0);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[22], &Equip->CheckSum_Calc, 2);
		Nouveau_Octet_Envoye (54);
#ifndef         __WINDOWS_ENABLE
		if ((sendto (Socket, &Equip->PacketOs, 54, 0, sock, sizeof (struct sockaddr))) < 0) {
			if ((errno != EPIPE) && (errno != ESPIPE))
				debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
		}
#else
 		if (pcap_sendpacket(captureHandle,(u_char *) &Equip->PacketOs, 54) != 0)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error sending the packet: \n", pcap_geterr(captureHandle));
#endif
	}
}


#ifndef         __WINDOWS_ENABLE
void Envoyer_Donnee_TCP_Detect_Os (struct Struct_Liste_Equipement *Equip, gint Num_Port, gint Socket, struct sockaddr *sock, gint Num_Trame,int tentative)
#else
void Envoyer_Donnee_TCP_Detect_Os (struct Struct_Liste_Equipement *Equip, gint Num_Port,  pcap_t * captureHandle, gint Num_Trame,int tentative)
#endif
{
	ERROR_if (Equip == NULL);
#ifndef         __WINDOWS_ENABLE
	ERROR_if (sock == NULL);
#else
	ERROR_if (captureHandle == NULL);
#endif
	usleep (SURCHARGE_EQUIPEMENT);	
	if (tentative==0){
		Equip->Reponse_Signature_Debug[Num_Trame].Num_Port_Utiliser = Num_Port;
		Equip->Reponse_Signature_Debug[Num_Trame].Time_Debut = time(NULL);
	}	
	if (!(Equip->Scan_OS[Num_Trame].Reponse_Scan)) {
		bzero (&Equip->PacketOs, sizeof (struct struct_trame));
		Equip->Id_Ip = (unsigned short) rand_r(&graine_rand_r);
		Equip->Port = ((unsigned short) rand_r(&graine_rand_r));
		Equip->Port = (Equip->Port & 0x0FFF) + 0xF000;
		Equip->Scan_OS[Num_Trame].Port_Scan = Num_Port;
		Equip->Scan_OS[Num_Trame].Port_Client = Equip->Port;
		switch (Num_Trame) {
		    case TRAME_SYN_NORMAL_OUVERT:
		    case TRAME_SYN_NORMAL_FERMER:
			    Equip->trame = Syn_Normal;
			    break;
		    case TRAME_SYN_NULL_OUVERT:
		    case TRAME_SYN_NULL_FERMER:
			    Equip->trame = Syn_Null;
			    break;
		    case TRAME_SYN_ECN_OUVERT:
		    case TRAME_SYN_ECN_FERMER:
			    Equip->trame = Syn_ECN;
			    break;
		    case TRAME_SYN_FIN_URG_PSH_OUVERT:
		    case TRAME_SYN_FIN_URG_PSH_FERMER:
			    Equip->trame = Syn_FIN_URG_PSH;
			    break;
		    case TRAME_ACK_OUVERT:
		    case TRAME_ACK_FERMER:
			    Equip->trame = Ack;
			    break;
		    case TRAME_FIN_OUVERT:
		    case TRAME_FIN_FERMER:
			    Equip->trame = Fin;
			    break;
		    default:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Num trame %d", Num_Trame);
		}
		Equip->MonNumSeq = htonl ((int) rand_r(&graine_rand_r));
		memcpy (&Equip->PacketOs.Dest_MAC, &Equip->Adresse_MAC, ETH_ALEN);
		memcpy (&Equip->PacketOs.Source_MAC, Mon_Adresse_MAC, ETH_ALEN);
		Equip->PacketOs.Proto = htons (TRAME_IP);
		memcpy (&Equip->PacketOs.Datagramme, Equip->trame, 40);
		Equip->PacketOs.Datagramme[4] = (Equip->Id_Ip >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[5] = Equip->Id_Ip & 0xFF;
		memcpy (&Equip->PacketOs.Datagramme[12], &Mon_Adresse_Ip, IP_ADDR_LEN);
		memcpy (&Equip->PacketOs.Datagramme[16], &Equip->Adresse_Ip, IP_ADDR_LEN);
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[0], 20, 0);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[10], &Equip->CheckSum_Calc, 2);
		Equip->PacketOs.Datagramme[20] = (Equip->Port >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[21] = Equip->Port & 0xFF;
		Equip->PacketOs.Datagramme[22] = (Num_Port >> 8) & 0xFF;
		Equip->PacketOs.Datagramme[23] = Num_Port & 0xFF;
		memcpy (&Equip->PacketOs.Datagramme[24], &Equip->MonNumSeq, 4);
		ckecksum_r(Equip,&Equip->PacketOs.Datagramme[12], 24, 26);
		Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
		memcpy (&Equip->PacketOs.Datagramme[36], &Equip->CheckSum_Calc, 2);
		Nouveau_Octet_Envoye (54);
#ifndef         __WINDOWS_ENABLE
		if ((sendto (Socket, &Equip->PacketOs, 54, 0, sock, sizeof (struct sockaddr))) < 0) {
			if ((errno != EPIPE) && (errno != ESPIPE))
				debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
		}
#else
 		if (pcap_sendpacket(captureHandle,(u_char *) &Equip->PacketOs, 54) != 0)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error sending the packet: \n", pcap_geterr(captureHandle));
#endif
	}
}

void Test_Retour_Scan_Equipement (struct Struct_Liste_Equipement *Equip)
{
	ERROR_if (Equip == NULL);
	for (Equip->i = 0; Equip->i < NB_SCAN_OS; Equip->i++)
		if (!Equip->Scan_OS[Equip->i].Reponse_Scan){
			Equip->Test_Retour_Scan_Equip = FALSE;
			return;
		}
	Equip->Test_Retour_Scan_Equip = TRUE;
	return;
}

void Envoie_Trames_Scanne_Os (struct Struct_Liste_Equipement *Equip, gint Port_Ouvert, gint Port_Fermer)
{
	#define AUCUNE_REPONSE -2

	ERROR_if (Equip == NULL);
	Equip->Scan_Signature = TRUE;
	Efface_Reponse_Signature (Equip);
	for (Equip->i = 0; Equip->i < NB_SCAN_OS; Equip->i++){
		Equip->Scan_OS[Equip->i].Reponse_Scan = FALSE;
		Equip->Reponse_Signature_Debug[Equip->i].Num_Port_Utiliser = AUCUNE_REPONSE;
		Equip->Reponse_Signature_Debug[Equip->i].Time_Debut = AUCUNE_REPONSE;
		Equip->Reponse_Signature_Debug[Equip->i].Time_Fin = AUCUNE_REPONSE;
		Equip->Reponse_Signature_Debug[Equip->i].Temps_Reponse = AUCUNE_REPONSE;
	}
	if (Port_Ouvert==-1) 
		for (Equip->i = 0; Equip->i < 6; Equip->i++)
			Equip->Scan_OS[Equip->i].Reponse_Scan = TRUE;
	if (Port_Fermer==-1) 
		for (Equip->i = 6; Equip->i < 12; Equip->i++)
			Equip->Scan_OS[Equip->i].Reponse_Scan = TRUE;
#ifndef         __WINDOWS_ENABLE
	strcpy (Equip->sock.sa_data, Info_Demarrage.Interface);
	Equip->sock.sa_family = AF_INET;
	if ((Equip->IdSocket = socket_control (AF_INET, SOCK_PACKET, htons (ETH_P_ALL))) < 0)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s\nSocket ouvert[%d]  Thread[%d][%d]\n Nb equipement (%d)", strerror (errno), Nb_Socket_Ouverte, Info_Demarrage.Nb_Thread_Max, Info_Demarrage.Nb_Thread_Max - Valeur_Semaphore (&Semaphore_Thread_Scan), g_list_length (GList_Equipement));
#else
	if ( (Equip->captureHandle = pcap_open(Info_Demarrage.nom, 65535, PCAP_OPENFLAG_PROMISCUOUS, 1, NULL,  Equip->errbuf ) ) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Unable to open the adapter. %s is not supported by WinPcap\n", Info_Demarrage.nom);
#endif
	

#ifndef         __WINDOWS_ENABLE
	Envoyer_Donnee_TCP_Detect_Passerelle_Routeur(Equip, Equip->IdSocket, &Equip->sock);
#else
	Envoyer_Donnee_TCP_Detect_Passerelle_Routeur(Equip, Equip->captureHandle);
#endif
	Equip->Tentative = 0;	
	Equip->Tentative_UDP = 65530;
	do {
#ifndef         __WINDOWS_ENABLE
	
		for (Equip->i = 0; Equip->i < 6; Equip->i++)
			Envoyer_Donnee_TCP_Detect_Os (Equip, Port_Ouvert, Equip->IdSocket, &Equip->sock, Equip->i,Equip->Tentative);
	
		for (Equip->i = 6; Equip->i < 12; Equip->i++)
			Envoyer_Donnee_TCP_Detect_Os (Equip, Port_Fermer, Equip->IdSocket, &Equip->sock, Equip->i,Equip->Tentative);
		Envoyer_Donnee_ICMP_TimeStamp_Detect_Os (Equip, Equip->IdSocket, &Equip->sock,Equip->Tentative);
		Envoyer_Donnee_Ping_Detect_Os (Equip, Equip->IdSocket, &Equip->sock,Equip->Tentative);
		Envoyer_Donnee_UDP_Detect_Os (Equip, Equip->Tentative_UDP, Equip->IdSocket, &Equip->sock,Equip->Tentative);
#else
	
		for (Equip->i = 0; Equip->i < 6; Equip->i++)
			Envoyer_Donnee_TCP_Detect_Os (Equip, Port_Ouvert, Equip->captureHandle, Equip->i,Equip->Tentative);
	
		for (Equip->i = 6; Equip->i < 12; Equip->i++)
			Envoyer_Donnee_TCP_Detect_Os (Equip, Port_Fermer, Equip->captureHandle, Equip->i,Equip->Tentative);
		Envoyer_Donnee_ICMP_TimeStamp_Detect_Os (Equip, Equip->captureHandle,Equip->Tentative);
		Envoyer_Donnee_Ping_Detect_Os (Equip, Equip->captureHandle,Equip->Tentative);
		Envoyer_Donnee_UDP_Detect_Os (Equip, Equip->Tentative_UDP, Equip->captureHandle,Equip->Tentative);
#endif
		Equip->Tentative_UDP++;
		if ((!Info_Demarrage.Normal_Mode) && (Equip->Tentative == 2))
			break;
		switch (Equip->Tentative) {
		    case 0:
			    sleep (1);
			    break;
		    case 1:
			    debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Tentative 2");
			    sleep (1);
			    break;
		    case 2:
			    debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Tentative 3");
			    sleep (2);
			    break;
		    case 3:
			    debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Tentative 4");
			    sleep (3);
			    break;
		    case 4:
			    debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Tentative 5");
			    sleep (4);
			    break;
		    case 5:
			    debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Attend reponse");
			    sleep (4);
			    break;
		}
		Equip->Tentative++; 
		Test_Retour_Scan_Equipement(Equip); 
	}
	while (!(Equip->Test_Retour_Scan_Equip) && (Equip->Tentative != 6));
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Scanne OS fini");

	for (Equip->i = 0; Equip->i < NB_SCAN_OS; Equip->i++){
			if (Equip->Reponse_Signature_Debug[Equip->i].Temps_Reponse==AUCUNE_REPONSE){
				Equip->Reponse_Signature_Debug[Equip->i].Time_Fin = time(NULL);
				Equip->Reponse_Signature_Debug[Equip->i].Temps_Reponse  = (gint) difftime(Equip->Reponse_Signature_Debug[Equip->i].Time_Fin , Equip->Reponse_Signature_Debug[Equip->i].Time_Debut);
			}
	}
#ifndef         __WINDOWS_ENABLE
	if (close_control (Equip->IdSocket) < 0)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s\nSocket ouvert[%d]  Thread[%d][%d]\n Nb equipement (%d)", strerror (errno), Nb_Socket_Ouverte, Info_Demarrage.Nb_Thread_Max, Info_Demarrage.Nb_Thread_Max - Valeur_Semaphore (&Semaphore_Thread_Scan), g_list_length (GList_Equipement));
#else
	pcap_close(Equip->captureHandle);
#endif
}


void Ping_Detect (void)
{
	unsigned short Icmp_Id, Icmp_Seq;
	struct struct_trame PacketOs;
	unsigned short CheckSum_Calc;
#ifdef __LOG_ENABLE
	struct struct_Cle_Privee *Donnee_Cle = NULL;	
#endif
	
#ifdef __LOG_ENABLE
	Create_Log(CATEG_PING_DETECT,NULL,NULL,TRUE);
#endif
#ifndef         __WINDOWS_ENABLE
	struct sockaddr sock;
	int       Socket;
	
	strcpy (sock.sa_data, Info_Demarrage.Interface);
	sock.sa_family = AF_INET;
	
	if ((Socket = socket_control (AF_INET, SOCK_PACKET, htons (ETH_P_ALL))) < 0)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s\n", strerror (errno));
#else
	pcap_t    * captureHandle;
	char errbuf[PCAP_ERRBUF_SIZE];
	
	if ( (captureHandle = pcap_open(Info_Demarrage.nom, 65535, PCAP_OPENFLAG_PROMISCUOUS, 1, NULL,  errbuf ) ) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Unable to open the adapter. %s is not supported by WinPcap\n", Info_Demarrage.nom);
#endif
	
	bzero (&PacketOs, sizeof (struct struct_trame));
	Icmp_Id = (unsigned short) rand_r(&graine_rand_r);//random ();
	Icmp_Seq = 1;
	PacketOs.Dest_MAC[0] = 0x01;
	PacketOs.Dest_MAC[1] = 0x00;
	PacketOs.Dest_MAC[2] = 0x5E;
	PacketOs.Dest_MAC[3] = 0x00;
	PacketOs.Dest_MAC[4] = 0x00;
	PacketOs.Dest_MAC[5] = 0x01;
	memcpy (&PacketOs.Source_MAC, Mon_Adresse_MAC, ETH_ALEN);
	PacketOs.Proto = htons (TRAME_IP);
	memcpy (&PacketOs.Datagramme, Ping_2, 59);
	memcpy (&PacketOs.Datagramme[12], &Mon_Adresse_Ip, IP_ADDR_LEN);
	CheckSum_Calc = htons (ckecksum (&PacketOs.Datagramme[0], 20, 0));
	memcpy (&PacketOs.Datagramme[10], &CheckSum_Calc, 2);
	PacketOs.Datagramme[24] = (Icmp_Id >> 8) & 0xFF;
	PacketOs.Datagramme[25] = Icmp_Id & 0xFF;
	PacketOs.Datagramme[26] = (Icmp_Seq >> 8) & 0xFF;
	PacketOs.Datagramme[27] = Icmp_Seq & 0xFF;
	CheckSum_Calc = ckecksum (&PacketOs.Datagramme[20], 39, 0);
	CheckSum_Calc = htons (CheckSum_Calc);
	memcpy (&PacketOs.Datagramme[22], &CheckSum_Calc, 2);
	Nouveau_Octet_Envoye (73);
#ifndef         __WINDOWS_ENABLE
	if ((sendto (Socket, &PacketOs, 73, 0, &sock, sizeof (struct sockaddr))) < 0) {
		if ((errno != EPIPE) && (errno != ESPIPE))
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
	}
	if (close_control (Socket) < 0)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s\nSocket ouvert[%d]  Thread[%d][%d]\n Nb equipement (%d)", strerror (errno), Nb_Socket_Ouverte, Info_Demarrage.Nb_Thread_Max, Info_Demarrage.Nb_Thread_Max - Valeur_Semaphore (&Semaphore_Thread_Scan), g_list_length (GList_Equipement));
#else
	 if (pcap_sendpacket(captureHandle,(u_char *) &PacketOs, 73) != 0)
	 	debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error sending the packet: \n", pcap_geterr(captureHandle));
	pcap_close(captureHandle);
#endif
	Stop_Thread (NULL);
}


#ifndef         __WINDOWS_ENABLE
void Envoyer_Donnee_TCP_Detect_Passerelle_Routeur (struct Struct_Liste_Equipement *Equip,gint Socket, struct sockaddr *sock)
#else
void Envoyer_Donnee_TCP_Detect_Passerelle_Routeur (struct Struct_Liste_Equipement *Equip,pcap_t * captureHandle)
#endif
{
	
	ERROR_if (Equip == NULL);
#ifndef         __WINDOWS_ENABLE
	ERROR_if (sock == NULL);
#else
	ERROR_if (captureHandle == NULL);
#endif
	usleep (SURCHARGE_EQUIPEMENT);	
	bzero (&Equip->PacketOs, sizeof (struct struct_trame));
	Equip->Id_Ip = (unsigned short) rand_r(&graine_rand_r);
	Equip->Port_Source_Test_GateWay = ((unsigned short) rand_r(&graine_rand_r));
	Equip->Port_Source_Test_GateWay = (Equip->Port_Source_Test_GateWay & 0x0FFF) + 0xF000;
	Equip->Port_Destination_Test_GateWay = ((unsigned short) rand_r(&graine_rand_r));
	Equip->Port_Destination_Test_GateWay = (Equip->Port_Destination_Test_GateWay & 0x0FFF) + 0xF000;
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Envoie Trame Detect passerelle Routeur (%s)    port (%d)(%d)", Equip->Adresse_Ip_Char, Equip->Port_Source_Test_GateWay, Equip->Port_Destination_Test_GateWay);
	Equip->MonNumSeq = htonl ((int) rand_r(&graine_rand_r));
	memcpy (&Equip->PacketOs.Dest_MAC, &Equip->Adresse_MAC, ETH_ALEN);
	memcpy (&Equip->PacketOs.Source_MAC, Mon_Adresse_MAC, ETH_ALEN);
	Equip->PacketOs.Proto = htons (TRAME_IP);
	memcpy (&Equip->PacketOs.Datagramme, Syn_Normal, 40);
	Equip->PacketOs.Datagramme[4] = (Equip->Id_Ip >> 8) & 0xFF;
	Equip->PacketOs.Datagramme[5] = Equip->Id_Ip & 0xFF;
	memcpy (&Equip->PacketOs.Datagramme[12], &Mon_Adresse_Ip, IP_ADDR_LEN);
	memcpy (&Equip->PacketOs.Datagramme[16], &Mon_Adresse_Ip, IP_ADDR_LEN);
	ckecksum_r(Equip,&Equip->PacketOs.Datagramme[0], 20, 0);
	Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
	memcpy (&Equip->PacketOs.Datagramme[10], &Equip->CheckSum_Calc, 2);
	Equip->PacketOs.Datagramme[20] = (Equip->Port_Source_Test_GateWay >> 8) & 0xFF;
	Equip->PacketOs.Datagramme[21] = Equip->Port_Source_Test_GateWay & 0xFF;
	Equip->PacketOs.Datagramme[22] = (Equip->Port_Destination_Test_GateWay >> 8) & 0xFF;
	Equip->PacketOs.Datagramme[23] = Equip->Port_Destination_Test_GateWay & 0xFF;
	memcpy (&Equip->PacketOs.Datagramme[24], &Equip->MonNumSeq, 4);
	ckecksum_r(Equip,&Equip->PacketOs.Datagramme[12], 24, 26);
	Equip->CheckSum_Calc = htons (Equip->CheckSum_Calc);
	memcpy (&Equip->PacketOs.Datagramme[36], &Equip->CheckSum_Calc, 2);
	Nouveau_Octet_Envoye (54);
#ifndef         __WINDOWS_ENABLE
	if ((sendto (Socket, &Equip->PacketOs, 54, 0, sock, sizeof (struct sockaddr))) < 0) {
		if ((errno != EPIPE) && (errno != ESPIPE))
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
	}
#else
	 if (pcap_sendpacket(captureHandle,(u_char *) &Equip->PacketOs, 54) != 0)
	 	debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error sending the packet: \n", pcap_geterr(captureHandle));
#endif
}



void Ping_equipement (struct Struct_Liste_Equipement *Equipement)
{
	ERROR_if (Equipement == NULL);
	PROTECT_CODE(Semaphore_Ping_Equipement);
	struct struct_trame PacketOs;
	unsigned short Icmp_Id, Icmp_Seq;

#ifndef         __WINDOWS_ENABLE
	struct sockaddr sock;
	int       Socket;

	strcpy (sock.sa_data, Info_Demarrage.Interface);
	sock.sa_family = AF_INET;
	if ((Socket = socket_control (AF_INET, SOCK_PACKET, htons (ETH_P_ALL))) < 0){
		DEPROTECT_CODE(Semaphore_Ping_Equipement);	
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s\n", strerror (errno));
	}
#else
	pcap_t    * captureHandle;
	char errbuf[PCAP_ERRBUF_SIZE];
 	
	if ( (captureHandle = pcap_open(Info_Demarrage.nom, 65535, PCAP_OPENFLAG_PROMISCUOUS, 1, NULL,  errbuf ) ) == NULL){
		DEPROTECT_CODE(Semaphore_Ping_Equipement);
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Unable to open the adapter. %s is not supported by WinPcap\n", Info_Demarrage.nom);
	}
#endif
	
	bzero (&PacketOs, sizeof (struct struct_trame));
	Icmp_Id = (unsigned short) rand_r(&graine_rand_r);
	Icmp_Seq = 1;
	memcpy (&PacketOs.Dest_MAC, &Equipement->Adresse_MAC, ETH_ALEN);
	memcpy (&PacketOs.Source_MAC, Mon_Adresse_MAC, ETH_ALEN);
	PacketOs.Proto = htons (TRAME_IP);
	memcpy (&PacketOs.Datagramme, Ping_2, 59);
	memcpy (&PacketOs.Datagramme[12], &Mon_Adresse_Ip, IP_ADDR_LEN);
	memcpy (&PacketOs.Datagramme[16], &Equipement->Adresse_Ip, IP_ADDR_LEN);
	ckecksum_r(Equipement,&PacketOs.Datagramme[0], 20, 0);
	Equipement->CheckSum_Calc = htons (Equipement->CheckSum_Calc);
	memcpy (&PacketOs.Datagramme[10], &Equipement->CheckSum_Calc, 2);
	PacketOs.Datagramme[24] = (Icmp_Id >> 8) & 0xFF;
	PacketOs.Datagramme[25] = Icmp_Id & 0xFF;
	PacketOs.Datagramme[26] = (Icmp_Seq >> 8) & 0xFF;
	PacketOs.Datagramme[27] = Icmp_Seq & 0xFF;
	ckecksum_r(Equipement,&PacketOs.Datagramme[20], 39, 0);
	Equipement->CheckSum_Calc = htons (Equipement->CheckSum_Calc);
	memcpy (&PacketOs.Datagramme[22], &Equipement->CheckSum_Calc, 2);
	Nouveau_Octet_Envoye (73);
#ifndef         __WINDOWS_ENABLE
	if ((sendto (Socket, &PacketOs, 73, 0, &sock, sizeof (struct sockaddr))) < 0) {
		if ((errno != EPIPE) && (errno != ESPIPE)){
			DEPROTECT_CODE(Semaphore_Ping_Equipement);
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
		}
	}
	if (close_control (Socket) < 0){
		DEPROTECT_CODE(Semaphore_Ping_Equipement);
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s\nSocket ouvert[%d]  Thread[%d][%d]\n Nb equipement (%d)", strerror (errno), Nb_Socket_Ouverte, Info_Demarrage.Nb_Thread_Max, Info_Demarrage.Nb_Thread_Max - Valeur_Semaphore (&Semaphore_Thread_Scan), g_list_length (GList_Equipement));
	}
#else
	if (pcap_sendpacket(captureHandle,(u_char *) &PacketOs, 73) != 0){
		DEPROTECT_CODE(Semaphore_Ping_Equipement); 	
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error sending the packet: \n", pcap_geterr(captureHandle));
	}
	pcap_close(captureHandle);
#endif
	DEPROTECT_CODE(Semaphore_Ping_Equipement);
}
