2010-07-28 17 views
1

J'ai travaillé à un petit tutoriel sur la façon de construire un sniffer de base pour Linux. J'ai tout réussi, et je veux maintenant ajouter le mapping IP-to-host.strlen() Refuse de lire la chaîne de struct hostent *

Tout fonctionnait avant ajouté cette fonction:

void IPtoHostname(char *ipaddress, char *hostname){ 
    struct hostent *host; 
    in_addr_t ip = inet_addr(ipaddress); 
    if (!hostname){ 
     puts("Can't allocate memory..."); 
     exit(-1); 
    } 
    host = gethostbyaddr((char *)&ip, 32, AF_INET); 
    hostname = strdup(host->h_name); 
} 

Cela prend essentiellement une adresse IP de chaîne ("192.168.28.18") ipaddress et Remplit que le nom d'hôte IP ("who.cares.com ") dans nom d'hôte.

Qu'est-ce qui se passe est que strlenREFUSE me donner quoi que ce soit (je sais strdup œuvres, et je l'ai testé moi-même) et segfaults. J'ai utilisé GDB, et la chaîne se termine par un caractère nul et ce n'est pas NULL.

J'ai également testé à l'aide d'une affectation de chaîne brute avec une struct statique:

void IPtoHostname(char *ipaddress, char *hostname){ 
    static struct hostent *host; 
    in_addr_t ip = inet_addr(ipaddress); 
    if (!hostname){ 
     puts("Can't allocate memory..."); 
     exit(-1); 
    } 
    host = gethostbyaddr((char *)&ip, 32, AF_INET); 
    hostname = host->h_name; 
} 

Et toujours pas de dés. Donc, quoi de neuf strlen?

+0

L'erreur est probablement dans le code qui appelle cette fonction, comme suggéré par la réponse de George. Dans un futur post a [MCVE] (http://stackoverflow.com/help/mcve) –

Répondre

0

Wow ... Ne combattez jamais Posix. J'ai finalement écrit ma fonction à ceci:

#define MAXHOST 256 

char *IPtoHostname(char *ipaddress){ 
    struct in_addr iaddr; 
    inet_pton(AF_INET, ipaddress, &iaddr); 
    struct sockaddr_in saddr; 
    saddr.sin_family = AF_INET; 
    saddr.sin_addr = iaddr; 

    char *hostname = (char *)malloc(sizeof(char) * MAXHOST); 
    if (getnameinfo((struct sockaddr*)&saddr, 32, hostname, MAXHOST, NULL, 0, 0) == -1){ 
     puts("Cannot reverse engineer IP"); 
     return; 
    } 
    return hostname; 
} 

Et ça marche!

4

Rien ne va plus avec strlen. Vous devez transmettre le nom d'hôte char **, puis définir un nom d'hôte égal à host-> h_name, en supposant que vous faites votre strlen en dehors de IPToHostName. Vous définissez une copie locale du pointeur de votre nom d'hôte.

Vous avez donc quelque chose comme ceci:

char myip[] = "123.45.67.89"; 
char *myhost = NULL; 

IPToHostname(myip, myhost); /* this sets its own local copy of myhost, which is on the stack */ 

/* At this point, myhost is still null!! */ 

Si vous changez à être comme le code ci-dessous, il va probablement faire ce que vous voulez.

void IPtoHostname(char *ipaddress, char **hostname) 
{ 
    assert(hostname); /* you'll need to include assert.h for this - it'll abort your program in debug mode if hostname is null */ 

    struct hostent *host; 
    in_addr_t ip = inet_addr(ipaddress); 
    if (!hostname) 
    { 
     puts("Can't allocate memory..."); 
     exit(-1); 
    } 
    host = gethostbyaddr((char *)&ip, 32, AF_INET); 
    *hostname = strdup(host->h_name); 
} 

char myip[] = "123.45.67.89"; 
char *myhost = NULL; 

IPtoHostname(myip, &myhost); 
+0

En fait, il s'avère que gethostbyaddr était en faute ici. Merci pour le conseil, cependant. – new123456

+1

'if (! Hostname)' est redondant si vous avez déjà 'assert (nom d'hôte)' (ou l'assert est redondant, dans les deux cas) –