/* ***********************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 "Reseau.h"
#include "Debug.h"
#include "Com/Initialisation_Com.h"
#include "Semaphore.h"
#include "Liste_Equipement.h"

#ifdef         __WINDOWS_ENABLE
#define INADDR_NONE 0xffffffff

int inet_aton(const char *cp, struct in_addr *addr)
{
	ERROR_if (cp == NULL);
	ERROR_if (addr == NULL);
  	addr->s_addr = inet_addr(cp);
  	return (addr->s_addr == INADDR_NONE) ? 0 : 1;
}

gboolean getmac(pcap_t* ha)
{
	ERROR_if (ha == NULL);
	PPACKET_OID_DATA    pOidData;
	CHAR pAddr[sizeof(PACKET_OID_DATA)+5];
		
 	ZeroMemory(pAddr, sizeof(PACKET_OID_DATA)+5);
 	pOidData = (PPACKET_OID_DATA) pAddr;
 	pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
 	pOidData->Length = 6;
 	if(PacketRequest(ha->adapter, FALSE, pOidData)){
		memcpy (Mon_Adresse_MAC, pOidData->Data, ETH_ALEN);
		return TRUE;
  	}
	else
		return FALSE;
}
#endif


void Get_My_MAC (void)
{
#ifndef         __WINDOWS_ENABLE
	struct ifreq ifr;
	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\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));
	}
	ifr.ifr_addr.sa_family = AF_INET;
	sprintf (ifr.ifr_name, Info_Demarrage.Interface);
	if (ioctl (Socket, SIOCGIFHWADDR, &ifr) == -1) {
		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));
	}
	memcpy (Mon_Adresse_MAC, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
	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
	pcap_t      *hadapter;
		
	hadapter = pcap_open_live(Info_Demarrage.nom, 0, 0, 0, 0);
  	if(!getmac(hadapter))
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "getmac FAILED");
	pcap_close(hadapter);
#endif
}


void Get_My_Ip (void)
{
#ifndef         __WINDOWS_ENABLE
	struct ifreq ifr;
	struct sockaddr_in sin;
	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\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));

	}
	strcpy (ifr.ifr_name, Info_Demarrage.Interface);
	if (ioctl (Socket, SIOCGIFADDR, &ifr) == -1) {
		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));

	}
	memcpy (&sin, &ifr.ifr_addr, sizeof (struct sockaddr_in));
	memcpy (Mon_Adresse_Ip, &sin.sin_addr.s_addr, IP_ADDR_LEN);
	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
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_if_t * alldevs = NULL;
	pcap_if_t * d = NULL;
	pcap_addr_t *a = NULL;
	int resultat,nb_Interface=0;
	 

	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){
			if (strlen(d->description)<TAILLE_NOM_INTERFACE_STRUCT_NOUVELLE_INTERFACE)
				resultat = strcmp(d->description,Info_Demarrage.Interface);
			else
				resultat = strncmp(d->description,Info_Demarrage.Interface,TAILLE_NOM_INTERFACE_STRUCT_NOUVELLE_INTERFACE - 1);
			if (resultat==0){
				a=d->addresses;
				if ((a)&&(a->addr->sa_family==AF_INET)&&(a->addr)){
					memcpy (Mon_Adresse_Ip, &((struct sockaddr_in *)(a->addr))->sin_addr , IP_ADDR_LEN);
				
					if (strlen(d->name)>TAILLE_NOM_ID_STRUCT_NOUVELLE_INTERFACE){
						strncpy(Info_Demarrage.nom, d->name,TAILLE_NOM_ID_STRUCT_NOUVELLE_INTERFACE-1);
						Info_Demarrage.nom[TAILLE_NOM_ID_STRUCT_NOUVELLE_INTERFACE-1] = 0;
					}
					else
						strcpy (Info_Demarrage.nom, d->name);
					nb_Interface++;
				}
			}
		}
	}
	if (nb_Interface == 0)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "No interfaces found!");

	pcap_freealldevs(alldevs);
#endif
}

unsigned short ckecksum (char *donnee, int longueur, int valeur)
{
	ERROR_if (donnee == NULL);
	int       i;
	int       somme;
	int       Nombre;

	i = 0;
	somme = 0;
	while (i < longueur) {
		if (longueur == (i + 1)) {
			donnee[i + 1] = 0;
		}
		Nombre = (((donnee[i] << 8) & 0xFF00) + (donnee[i + 1] & 0xFF));
		somme = somme + Nombre;
		i = i + 2;
	}
	while ((somme >> 16) != 0) {
		somme = (somme >> 16) + (somme & 0xffff);
	}
	somme = (0xFFFF - (somme & 0xFFFF)) - valeur;
	if ((valeur != 0) && (somme < 0))
		somme--;
	return (unsigned short) somme;
}


void ckecksum_r (struct Struct_Liste_Equipement *Equip,char *donnee, int longueur, int valeur)
{
	ERROR_if (Equip == NULL);
	ERROR_if (donnee == NULL);
	Equip->ck_i = 0;
	Equip->ck_somme = 0;
	while (Equip->ck_i < longueur) {
		if (longueur == (Equip->ck_i + 1)) {
			donnee[Equip->ck_i + 1] = 0;
		}
		Equip->ck_Nombre = (((donnee[Equip->ck_i] << 8) & 0xFF00) + (donnee[Equip->ck_i + 1] & 0xFF));
		Equip->ck_somme = Equip->ck_somme + Equip->ck_Nombre;
		Equip->ck_i = Equip->ck_i + 2;
	}
	while ((Equip->ck_somme >> 16) != 0) {
		Equip->ck_somme = (Equip->ck_somme >> 16) + (Equip->ck_somme & 0xffff);
	}
	Equip->ck_somme = (0xFFFF - (Equip->ck_somme & 0xFFFF)) - valeur;
	if ((valeur != 0) && (Equip->ck_somme < 0))
		Equip->ck_somme--;
	Equip->CheckSum_Calc = (unsigned short) Equip->ck_somme;
	return;
}


/*int waiting_service (int sock, int event)
{
	struct pollfd fds;
	int       resultat;

	bzero (&fds, sizeof fds);
	fds.events = event;
	fds.fd = sock;	
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "waiting_service : (%d)", sock);
	if ((resultat = poll (&fds, 1, 1000)) > 0) {
		if ((fds.revents & POLLERR) == POLLERR) {
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "waiting_service Socket error : (%d)", sock);
			return ERREUR_SOCK;
		}
		if ((fds.revents & POLLHUP) == POLLHUP) {
			debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "waiting_service Socket error : (%d)", sock);
			return ERREUR_SOCK;
		}
		debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "waiting_service : (%d) pret", sock);
		return DONNEE_PRET;
	}
	else {
		if (resultat != 0) {
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
		}
		debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "waiting_service : (%d) Attendre 1 secondes", sock);
		return ATTENDRE;
	}
	return DONNEE_PRET;   
}*/


gboolean attendre_Donnee_Ecriture (int sock, int temp)
{
	fd_set fd_read,fd_write;
	socklen_t lon; 
    struct timeval tv;
	int retval,valopt,NbSeconde; 
	
	NbSeconde = 0; 
	while (NbSeconde<temp){
	
	
	
	
	
		FD_ZERO(&fd_write);
		FD_SET(sock, &fd_write);
	
   		tv.tv_sec = 1;
    	tv.tv_usec = 0;
 		retval = select(sock + 1,NULL, &fd_write, NULL, &tv);
    	if (retval==1){
		
    		lon = sizeof(int); 
    		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
				debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error in getsockopt() %d - %s\n", errno, strerror(errno)); 
        		return FALSE;
			} 
			if (valopt) { 
				debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error in delayed connection() %d - %s",valopt, strerror(valopt)); 
				return FALSE;
			} 
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Ecriture Possible sur la socket (%d)",sock);
			return TRUE;
		}
    	else {
			debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Impossible écrure depuis 1 secondes  retval=%d sur %d",retval,sock);
			sleep(1);
		}
		NbSeconde++;
	}
	return FALSE;
}


int attendre_Donnee_Lecture (int sock, int temp)
{
#ifndef         __WINDOWS_ENABLE
	fd_set fd_read,fd_write;
	socklen_t lon; 
    struct timeval tv;
	int retval,valopt,NbSeconde; 
	
	NbSeconde = 0; 
	while (NbSeconde<temp){
	
	
	
		FD_ZERO(&fd_read);
		FD_SET(sock, &fd_read);
	
	
	
   		tv.tv_sec = 1;
    	tv.tv_usec = 0;
 		retval = select(sock + 1,&fd_read, NULL, NULL, &tv);
    	if (retval==1){
		
    		lon = sizeof(int); 
    		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
				debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error in getsockopt() %d - %s\n", errno, strerror(errno)); 
        		return SOCK_ERROR;
			} 
		
			if (valopt) { 
				switch (valopt){
					case 104 : 
										debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Connection reinitialiser par l'hote mais des données sont peut etre presente (%d)  %d - %s",sock ,valopt, strerror(valopt));
										return SOCK_RESET_BY_PEER;
										break;
					case 32 :    
										debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "tcpwrapped ??? %d - %s",valopt, strerror(valopt));
										return SOCK_BROKEN_PIPE;
					default:		
										debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error in delayed connection() %d - %s",valopt, strerror(valopt)); 
										return -valopt;
					}
			} 
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Donnee presente sur la socket (%d)",sock);
			return SOCK_OK;
		}
    	else {
			debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Aucune donnée depuis 1 secondes  retval=%d sur %d",retval,sock);
			sleep(1);
		}
		NbSeconde++;
	}
	return SOCK_ERROR;
#else
	fd_set ensemble;
	struct timeval tv;
	int retval,NbSeconde;
 
	NbSeconde = 0;
	while (NbSeconde<temp){
		FD_ZERO(&ensemble);
		FD_SET(sock, &ensemble);
		
   		tv.tv_sec = 1;
    	tv.tv_usec = 0;
 		retval = select(sock + 1, &ensemble , NULL , NULL, &tv);
   		 if (retval){
       	
			return SOCK_OK;
		}
    	else{
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Pas de données depuis 1 secondes\n");
			NbSeconde++;
		}
	}
	return SOCK_ERROR;
#endif
}

#ifndef         __WINDOWS_ENABLE
void set_NonBlock (int sock,int block)
{
	int       flags;

	if (block == SOCKET_NON_BLOQUANT){
		if ((flags = fcntl (sock, F_GETFL)) == -1)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
		if (fcntl (sock, F_SETFL, flags | O_NONBLOCK) == -1)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
	}

}
#else
void set_NonBlock (int sock,int block){
	if (ioctlsocket(sock, FIONBIO, (unsigned long *)&block))
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "network: cannot block socket");
}
#endif


gboolean connection_Serveur (unsigned char *Ip, int Port, int sock)
{
	struct sockaddr_in SocketAddr;

    ERROR_if (Ip == NULL);
	memset (&SocketAddr, 0, sizeof (struct sockaddr_in));
	if (inet_aton(Ip,&SocketAddr.sin_addr)==0)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "inet_aton()");
	SocketAddr.sin_family = AF_INET;
	SocketAddr.sin_port = htons (Port);
	if (connect (sock, (struct sockaddr *) &SocketAddr, sizeof (struct sockaddr)) < 0) {
#ifndef         __WINDOWS_ENABLE
		if (errno != EINPROGRESS) {
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s : Equipement : [%s] port:[%d] ", strerror (errno), Ip, Port);
			return FALSE;
		}
		debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Socket avec etat en progression : [%s] port:[%d]  socket (%d)",Ip, Port,sock);
#else
		if (WSAGetLastError() != WSAEWOULDBLOCK) {
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "connect() [%s] port:[%d]  (%d) failed with error %d   %d",Ip, Port,sock, WSAGetLastError(),SOCKET_ERROR);
			return FALSE;
		}
		debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Socket avec etat en progression : [%s] port:[%d]  (%d)",Ip, Port,sock);
#endif
	}
	return TRUE;
}

unsigned char *resoudre_DNS (char *Serveur,unsigned char *Adresse_Ip)
{
	struct sockaddr_in SocketAddr;
		
	ERROR_if (Serveur == NULL);
#ifndef         __WINDOWS_ENABLE
	int       ret, err;
	char     *ptr = NULL;
	char      buf[1024];
	struct hostent h, *host = NULL, *hostent = NULL;
	
	PROTECT_CODE (Semaphore_DNS);
	ret = gethostbyname_r (Serveur, &h, buf, sizeof (buf), &host, &err);
	if (host == NULL) {
		switch (err) {
		    case HOST_NOT_FOUND:
			    debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "L'hôte indiqué est inconnu. [%s]", Serveur);
			    break;
		    case NO_ADDRESS:
			    debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Le nom est valide mais ne possède pas d'adresse IP. [%s]", Serveur);
			    break;
		    case NO_RECOVERY:
			    debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Une erreur fatale du serveur de noms est apparue. [%s]", Serveur);
			    break;
		    case TRY_AGAIN:
			    debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Aucune connection Ã  internet. [%s]", Serveur);
			    break;
		    default:
			    debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Erreur Inconnue [%s]", Serveur);
			    break;
		}
		DEPROTECT_CODE (Semaphore_DNS);	
		return NULL;
	}
#else
	struct hostent *host = NULL;
 
	PROTECT_CODE (Semaphore_DNS);
	if ((host = gethostbyname (Serveur)) == NULL) {
		DEPROTECT_CODE (Semaphore_DNS);
		return NULL;
	}
#endif

	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Nom Officiel : %s  taille : %d \n", host->h_name, host->h_length);
	memset (&SocketAddr, 0, sizeof (struct sockaddr_in));
	memcpy (&SocketAddr.sin_addr.s_addr, host->h_addr, host->h_length);
	strcpy (Adresse_Ip, inet_ntoa (SocketAddr.sin_addr));
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Adresse resolu : %s\n",Adresse_Ip);
	DEPROTECT_CODE (Semaphore_DNS);
	return Adresse_Ip;
}

int Creation_Socket_TCP (void)
{
	int Socket_Agent;
#ifndef         __WINDOWS_ENABLE
	Socket_Agent = socket_control (AF_INET, SOCK_STREAM, 0);
	ERROR_if (Socket_Agent == -1);
#else
	Socket_Agent = socket_control(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	ERROR_if (Socket_Agent == INVALID_SOCKET);
#endif
	debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Creation d'une socket TCP/IP  (%d)", Socket_Agent);
	return Socket_Agent;
}

int Connection_Equipement (unsigned char *Ip, char *Serveur, int Port, int Tentative,int NbmilliSecondeAttente,gboolean Block)
{
	ERROR_if ((Serveur == NULL)&&(Ip == NULL));
	int       IdSocket, TimeOut;
	gboolean  Connection_Accepter;
	unsigned char *Adresse_Ip_Utiliser = NULL,Adresse_Ip_Resolu[15 + 1];
#ifndef         __WINDOWS_ENABLE
	fd_set fd_read,fd_write;
	socklen_t lon; 
    struct timeval tv;
	int retval,valopt;
#else
 	fd_set ensemble;
    struct timeval tv;
	int retval;
#endif
	

	if (Ip == NULL) { 
	  if ((Adresse_Ip_Utiliser = resoudre_DNS (Serveur,Adresse_Ip_Resolu)) == NULL) 
		return (-1);
 	}
  	else
	  Adresse_Ip_Utiliser =Ip;

	IdSocket = Creation_Socket_TCP ();
  	if (!Block)
  		set_NonBlock(IdSocket,SOCKET_NON_BLOQUANT);

	Connection_Accepter = FALSE;
	if (connection_Serveur (Adresse_Ip_Utiliser, Port, IdSocket)){
	
		TimeOut = 0;
		do {
#ifndef         __WINDOWS_ENABLE
		
		
		
		
		
			FD_ZERO(&fd_write);
			FD_SET(IdSocket, &fd_write);
		
   			tv.tv_sec = 1;
    		tv.tv_usec = 0;
 			retval = select(IdSocket + 1,NULL,&fd_write, NULL, &tv);
    		if (retval==1){
			
    			lon = sizeof(int); 
    			if (getsockopt(IdSocket, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
					debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error in getsockopt() %d - %s\n", errno, strerror(errno)); 
        			return FALSE;
				}
				else {
					if (valopt) { 
						debug_printf ( D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error in delayed connection() %d - %s",valopt, strerror(valopt)); 
					}
					else {				
						debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Connection a la socket (%d)",IdSocket);
						Connection_Accepter = TRUE;
					}
				}
			}
    		else {
				debug_printf ( D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Connection impossible depuis 1 secondes  retval=%d  socket (%d)",retval,IdSocket);
				sleep(1);
			}
			
			
			/*bzero (&fds, sizeof fds);
			fds[0].events = POLLOUT;
			fds[0].fd = IdSocket;	
			if ((resultat = poll (&fds, 1, 1000)) > 0) {
				if (fds[0].revents & POLLOUT){
					debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Socket pret en ecriture");
					Connection_Accepter = TRUE;
				}
			}
			else {
				if (resultat != 0) 
					debug_printf (D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Socket error : (%d)  [%s]", socket,strerror (errno));
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Pas de données depuis 1 secondes");
			}*/
#else 
			FD_ZERO(&ensemble);
			FD_SET(IdSocket, &ensemble);
			
			if (NbmilliSecondeAttente==0){
   				tv.tv_sec = 1;
	    		tv.tv_usec = 0;
			}
			else{
   				tv.tv_sec = 0;
	    		tv.tv_usec = NbmilliSecondeAttente*1000;
			}
 			retval = select(IdSocket + 1, NULL, &ensemble, NULL, &tv);
    		if (retval){
				debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Socket prêt en en ecriture : %s    select retourne : %d",Adresse_Ip_Utiliser,retval);
				Connection_Accepter = TRUE;
			}
    		else
        		debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "On ne peut pas ecrire attend 1 secondes");
#endif
			debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Tentative [%s] Connection port %d : TimeOut n[%d]", Ip,Port,TimeOut);
			TimeOut++;
		} while ((!Connection_Accepter) && (TimeOut <= Tentative));
	}
	if (!Connection_Accepter) {
		debug_printf (D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Impossible de se connecter. Fermeture de la socket");
		if (close_control (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));
		return -1;
	}
	return IdSocket;
}

gint create_tcp_server (int Port, int Nb_Max_Client)
{
	int       Socket, optval;
	struct sockaddr_in SocketAddr;


	if (-1 == (Socket = socket (PF_INET, SOCK_STREAM, 0)))
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));

	optval = 1;
	setsockopt (Socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));

	memset ((char *) &SocketAddr, 0, sizeof (struct sockaddr_in));
	SocketAddr.sin_family = AF_INET;
	SocketAddr.sin_port = htons (Port);
	SocketAddr.sin_addr.s_addr = htonl (INADDR_ANY);
	if (-1 == (bind (Socket, (struct sockaddr *) &SocketAddr, sizeof (struct sockaddr_in))))
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));

	if (-1 == (listen (Socket, Nb_Max_Client)))
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
	return (Socket);
}
