2011-07-13 24 views
7

estoy usando este fragmento de código que he encontrado en http://www.kutukupret.com/2009/09/28/gethostbyname-vs-getaddrinfo/ para realizar búsquedas DNS¿Qué pasa con gethostbyname?

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[ ]) { 
    struct hostent *h; 

    /* error check the command line */ 
    if(argc != 2) { 
     fprintf(stderr, "Usage: %s hostname\n", argv[0]); 
     exit(1); 
    } 

    /* get the host info */ 
    if((h=gethostbyname(argv[1])) == NULL) { 
     herror("gethostbyname(): "); 
     exit(1); 
    } 
    else  
     printf("Hostname: %s\n", h->h_name); 

    printf("IP Address: %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));  
    return 0; 
} 

Estoy frente a un hecho raro

./test www.google.com 
Hostname: www.l.google.com 
IP Address: 209.85.148.103 

funciona bien, pero si trato de resolver una dirección IP incompleta me sale este

./test 10.1.1 
Hostname: 10.1.1 
IP Address: 10.1.0.1 

yo esperaría que un error como el siguiente

./test www.google 
gethostbyname(): : Unknown host 

pero el programa parece funcionar.

¿Alguna idea de por qué?

+0

Acabo de probar el código de http://en.wikipedia.org/wiki/Getaddrinfo para getaddrinfo, pero el alféizar 10.1.1 se resuelve en 10.1.0.1 ... ¿Es un error? ¿Me estoy perdiendo de algo? –

Respuesta

17

No es una función() error, sino más bien una característica de inet_aton:

DESCRIPCIÓN

La función inet_aton() convierte la cadena especificada, en la notación estándar a Internet, a una dirección de red, y almacena la dirección en la estructura provista.

valores especificados usando notación de punto tomar una de las siguientes formas:

abcd Cuando se especifican cuatro partes, cada una se interpreta como un byte de datos y se asigna, de izquierda a derecha, a los cuatro bytes de una dirección de internet.

A.B.C Cuando se especifica una dirección de tres partes, la última parte se interpreta como una cantidad de 16 bits y se coloca en los dos bytes de la derecha de la dirección de red. Esto hace que el formato de dirección de tres partes sea conveniente para especificar direcciones de red Clase B como 128.net.host.

Puede leer más acerca de esto there, por ejemplo.

+0

¿Hay algo que diga que se supone que 'gethostbyname' llama' inet_aton'? – cHao

+1

@ cHao: cuando a gethostbyname() se le asigna un punto como parámetro (como en el escenario de OP), entonces usa inet_aton(): "Si el nombre es una dirección IPv4 o IPv6, no se realiza la búsqueda y gethostbyname() simplemente copia el nombre en el h_name fi campo y su estructura in_addr equivalente en el campo h_addr_list [0] de la estructura de hostent devuelta " –

7

POSIX.2004 dice:

El nombre de argumento de gethostbyname() deberá ser un nombre de nodo; el comportamiento de gethostbyname() cuando se pasa una cadena de dirección numérica no se especifica. Para IPv4, una cadena de dirección numérica estará en la notación decimal con puntos que se describe en inet_addr().

Así, al mirarlo desde el punto de vista de POSIX, no se puede esperar nada cuando pasa una dirección IP.

En mi sistema, el man page dice esto:

Si el nombre es una dirección IPv4 o IPv6, sin operaciones de búsqueda se lleva a cabo y gethostbyname() simplemente nombre de copias en el campo h_name y su equivalente estructura in_addr en el campo h_addr_list [0] de la estructura de Hostent devuelta.

No dice nada acerca de lo que sucede si se le pasa una dirección IP incompleta, así que cualquier cosa podría suceder, incluyendo el comportamiento que ha observado.

Para obtener más información sobre cómo se implementa gethostbyname en su sistema, puede verificar la documentación de la función y/o el código fuente (si está disponible).

+3

Excepto que de 'inet_addr'," abc Cuando se especifica una dirección de tres partes, la última parte debe interpretarse como una cantidad de 16 bits y colocarse en los dos bytes más a la derecha de la dirección de red. Esto hace que la dirección de tres partes formato conveniente para especificar direcciones de red Clase B como "128.net.host". Entonces, Linux dice cómo se trata una dirección IP con puntos, y 'inet_addr' define que' 10.1.1' es una dirección con puntos que significa lo mismo que '10.1 .0.1', y por lo tanto, el comportamiento observado de la persona que pregunta se define y espera en Linux. –

+0

@Steve: interesante. Me alegro de haber aprendido algo nuevo. –