-
Résolution d’adresse de machine (en fonction du nom).
- Version classique :
int nomVersAdresse(char *hote,struct sockaddr_storage *padresse)
{
/* On regarde deja s'il s'agit d'une adresse IP */
struct sockaddr_in *ipv4_sock=(struct sockaddr_in *)padresse;
unsigned char *ipv4=(unsigned char *)&ipv4_sock->sin_addr;
if(padresse->ss_family!=AF_INET6){
int size=inet_pton(AF_INET,hote,ipv4);
if(size>0){
padresse->ss_family=AF_INET;
return 0;
}
}
struct sockaddr_in6 *ipv6_sock=(struct sockaddr_in6 *)padresse;
unsigned char *ipv6=(unsigned char *)&ipv6_sock->sin6_addr;
if(padresse->ss_family!=AF_INET){
int size=inet_pton(AF_INET6,hote,ipv6);
if(size>0){
padresse->ss_family=AF_INET6;
return 0;
}
}
/* Sinon on cherche l'adresse via le DNS */
if(padresse->ss_family!=AF_INET){
struct hostent *h=gethostbyname2(hote,AF_INET6);
if(h!=NULL){
memcpy(ipv6,h->h_addr_list[0],h->h_length);
padresse->ss_family=AF_INET6;
return 0;
}
}
if(padresse->ss_family!=AF_INET6){
struct hostent *h=gethostbyname2(hote,AF_INET);
if(h!=NULL){
memcpy(ipv4,h->h_addr_list[0],h->h_length);
padresse->ss_family=AF_INET;
return 0;
}
}
return -1;
}
- Version moderne :
int nomVersAdresse(char *hote,struct sockaddr_storage *padresse)
{
struct addrinfo *resultat,*origine;
statut=getaddrinfo(hote,NULL,NULL,&origine);
if(statut==EAI_NONAME) return -1;
if(statut<0){ perror("nomVersAdresse.getaddrinfo"); exit(EXIT_FAILURE); }
struct addrinfo *p;
for(p=origine,resultat=origine;p!=NULL;p=p->ai_next)
if(p->ai_family==AF_INET6){ resultat=p; break; }
memcpy(padresse,resultat->ai_addr,resultat->ai_addrlen);
return 0;
}
- Résolution d’adresse de machine (en fonction du descripteur).
- Version classique :
int socketVersNom(int s,char *nom)
{
struct sockaddr_storage adresse;
struct sockaddr *padresse=(struct sockaddr *)&adresse;
socklen_t taille=sizeof adresse;
int statut;
struct hostent *machine;
/* Recupere l'adresse de la socket distante */
statut=getpeername(s,padresse,&taille);
if(statut<0){
perror("socketVersNom.getpeername");
exit(-1);
}
/* Recupere le nom de la machine */
void *ip;
int taille_ip;
int taille_nom;
if(padresse->sa_family==AF_INET){
struct sockaddr_in *ipv4=(struct sockaddr_in *)padresse;
ip=(void *)&ipv4->sin_addr;
taille_ip=sizeof(ipv4->sin_addr);
taille_nom=INET_ADDRSTRLEN;
}
if(padresse->sa_family==AF_INET6){
struct sockaddr_in6 *ipv6=(struct sockaddr_in6 *)padresse;
ip=(void *)&ipv6->sin6_addr;
taille_ip=sizeof(ipv6->sin6_addr);
taille_nom=INET6_ADDRSTRLEN;
}
machine=gethostbyaddr(ip,taille_ip,padresse->sa_family);
if(machine==NULL){
inet_ntop(padresse->sa_family,ip,nom,taille_nom);
return -1;
}
else{
strcpy(nom,machine->h_name);
return 0;
}
}
- Version moderne :
void socketVersClient(int s,char **hote,char **service){
struct sockaddr_storage adresse;
socklen_t taille=sizeof adresse;
int statut;
/* Recupere l'adresse de la socket distante */
statut=getpeername(s,(struct sockaddr *)&adresse,&taille);
if(statut<0){ perror("socketVersNom.getpeername"); exit(EXIT_FAILURE); }
/* Recupere le nom de la machine */
*hote=malloc(MAX_TAMPON);
if(*hote==NULL){ perror("socketVersClient.malloc"); exit(EXIT_FAILURE); }
*service=malloc(MAX_TAMPON);
if(*service==NULL){ perror("socketVersClient.malloc"); exit(EXIT_FAILURE); }
getnameinfo((struct sockaddr *)&adresse,sizeof adresse,*hote,MAX_TAMPON,*service,MAX_TAMPON,0);
}
- Résolution de nom de service :
int cherchePortTCP(char *nom)
{
struct servent *pinfo;
pinfo=getservbyname(nom,"tcp");
return ntohs(pinfo->s_port);
}