2016-09-12 13 views
7

Następująca funkcja określa, czy dany ciąg znaków jest prawidłową nazwą urządzenia sieciowego.Ifreq's ifr_names są niepoprawne?


int isValidNDevice(char *name) { 

    char data[4096]; 
    struct ifconf ifc; 
    struct ifreq *ifr; 
    int sk; 
    int nIntfcs; 

    sk = socket(AF_INET, SOCK_DGRAM, 0); 
    if(sk < 0) 
    { 
     perror("socket"); 
     return 0; 
    } 

    ifc.ifc_len = sizeof(data); 
    ifc.ifc_buf = (caddr_t)data; 
    if(ioctl(sk, SIOCGIFCONF, &ifc) < 0) 
    { 
     perror("ioctl(SIOCGIFCONF)"); 
     return 0; 
    } 

    ifr = (struct ifreq*)data; 
    nIntfcs = ifc.ifc_len/sizeof(struct ifreq); 
    for(int i=0; i < nIntfcs; i++) 
    { 
     safe_printf("%s\n", (&ifr[i])->ifr_name); 
     if (!strcmp((&ifr[i])->ifr_name, name)) { 
      return 1; 
     } 
    } 

    return 0; 
} 

Kiedy uruchomić tę funkcję, otrzymuję następujący wynik.


lo0

stf0

2> s

en1j


Kod ten działał dobrze kilka miesięcy temu. Co się zmieniło? Czy robię coś niepoprawnie?

OS: OSX El Capitan

+0

Ah, więc to Mac OS. Ponieważ dla Linuksa twój kod jest poprawny, ale Mac jest inny, widziałeś [ten kod] (https://gist.github.com/OrangeTide/909204) (linie 57-63)? Chociaż może łatwiej użyć po prostu 'getifaddrs()' lub nawet 'if_nameindex()' (nie jestem pewny czy ten ostatni jest obsługiwany w Mac OS). –

+0

Czy możesz dołączyć minimalny, ale kompletny program, który kompiluje i uruchamia twój problem? Będziesz miał znacznie większą szansę na uzyskanie pomocy. Zobacz także http://stackoverflow.com/help/mcve – sigjuice

+3

nIntfcs = ifc.ifc_len/sizeof (struct ifreq) nie jest poprawna w systemie OS X, ponieważ zwracane wartości ifreqs nie mają takiego samego rozmiaru jak Linux. Pomocne może być odwołanie się do kodu Apple [ifconfig] (https://opensource.apple.com/source/network_cmds/network_cmds-306/ifconfig.tproj/ifconfig.c). – sigjuice

Odpowiedz

1

Tablica struktur zwracanych przez SIOCGIFCONF IOCTL nie są tej samej wielkości w OSX. Będą one miały pole ifr->ifr_addr.sa_len, które będzie różne dla każdej struktury. Zmodyfikowana funkcja, aby się tym zająć. Mam nadzieję, że pomaga:

int isValidNDevice(char *name) { 

    char data[4096]; 
    struct ifconf ifc; 
    struct ifreq *ifr; 
    int sk,length; 

    sk = socket(AF_INET, SOCK_DGRAM, 0); 
    if(sk < 0) 
    { 
     perror("socket"); 
     return 0; 
    } 

    ifc.ifc_len = sizeof(data); 
    ifc.ifc_buf = (caddr_t)data; 
    if(ioctl(sk, SIOCGIFCONF, &ifc) < 0) 
    { 
     perror("ioctl(SIOCGIFCONF)"); 
     return 0; 
    } 

    ifr = (struct ifreq*)data; 
    for(int i=0;i<ifc.ifc_len;) 
    { 
     length=IFNAMSIZ + ifr->ifr_addr.sa_len; 
     printf("%s\n", ifr->ifr_name); 
     if (!strcmp(ifr->ifr_name,name)) { 
      printf("Interface Found!\n"); 
      return 1; 
     } 
     ifr=(struct ifr*)((char*)ifr+length); 
     i+=length; 
    } 

    return 0; 
} 
+0

Dzięki za odpowiedź! Wciąż chciałbym wiedzieć, co się zmieniło. Mój opublikowany kod działał dobrze kilka miesięcy temu. – Roecrew

Powiązane problemy