2013-03-26 12 views
6
#include <stdio.h> 
    #include <string.h> /* for strncpy */ 
    #include <sys/types.h> 
    #include <sys/socket.h> 
    #include <sys/ioctl.h> 
    #include <netinet/in.h> 
    #include <net/if.h> 

    int 
    main() 
    { 
    int fd; 
    struct ifreq ifr; 

    fd = socket(AF_INET, SOCK_DGRAM, 0); 

    /* I want to get an IPv4 IP address */ 
    ifr.ifr_addr.sa_family = AF_INET; 

    /* I want IP address attached to "eth0" */ 
    strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1); 

    ioctl(fd, SIOCGIFADDR, &ifr); 

    close(fd); 

    /* display result */ 
    char* ipaddr; 
    ipaddr = inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr); 
    printf("%s\n", ipaddr); 

    return 0; 
    } 

per questa linea:errore di segmentazione per inet_ntoa

 ipaddr = inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr);   

ottengo

iptry.c: In function ‘main’: 
iptry.c:31:9: warning: assignment makes pointer from integer without a cast [enabled by default] 

e per

 printf("%s\n", ipaddr); 

ottengo segmentation fault.

Cosa c'è di sbagliato in questo?

+2

in linux, 'inet_ntoa' è definito nell'intestazione' ', forse avete bisogno di' # include' quella? – Petesh

+1

Viene visualizzato anche un avviso _ dichiarazione di funzione implicita? – hmjd

+0

cosa intendi con la dichiarazione di funzione implicita? – user138126

risposta

19

inet_ntoa è definito nell'intestazione <arpa/inet.h>,
necessità di #include, in caso contrario, ci saranno errori

+4

Com'è che il compilatore non ha lanciato un avviso se non ha incluso l'intestazione giusta ?? – Nikkolasg

1

inet_ntoa non richiede un puntatore, ma il valore

char* ipaddr; 
ipaddr = inet_ntoa(((struct sockaddr_in)(ifr.ifr_addr))->sin_addr); 

Se sin_addr è un puntatore, è necessario dereferenziarlo.

inet_ntoa sarà tornare NULL se c'è un errore, quindi cercando di printf un NULL sarà cuase un errore di segmentazione ...

Cercare here per informazioni e here per l'uomo-pagina.

+0

come modificare il codice? – user138126

+0

Come ho dichiarato nella mia risposta e se si verificano errori, leggere la documentazione, SEMPRE! –

+0

'sin_addr' non è un puntatore, e tutto sembra ok – user138126

1

Se non si desidera visualizzare l'avviso, solo il cast del valore di ritorno di inet_ntoa

ipaddr = (char *) inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr); 

L'errore di segmentazione è probabilmente perché alcune delle funzioni precedente restituisce un errore (valore nullo) e si didn controllalo

Lo stesso codice funzionava nella mia Linux Box.

+0

non riesci ancora a capire il problema – user138126

+0

fd è un descrittore di file valido? ioctl ha restituito -1 o qualsiasi altra cosa? ifr contiene valori validi? inet_ntoa ha restituito un puntatore nullo? rispondi alle domande e otterrai il problema –

+0

fd è valido, iotcl restituisce 0, inet_ntoa restituisce un valore valido, come controllare ifr? – user138126