2012-01-27 12 views
7

Sto usando il seguente codice per recuperare tutti gli indirizzi MAC per il computer corrente:C/C++ Linux MAC Address di tutte le interfacce

ifreq ifr; 
ifconf ifc; 
char buf[1024]; 

int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 
if (sock == -1) { ... }; 

ifc.ifc_len = sizeof(buf); 
ifc.ifc_buf = buf; 
if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { ... } 

ifreq *it = ifc.ifc_req; 
const ifreq* const end = it + (ifc.ifc_len/sizeof(ifreq)); 

for (; it != end; ++it) { 
    strcpy(ifr.ifr_name, it->ifr_name); 
    if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { 
     if (!(ifr.ifr_flags & IFF_LOOPBACK)) { 
      if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { 
       unsigned char mac_address[6]; 
       memcpy(mac_address, ifr.ifr_hwaddr.sa_data, 6); 
       ... 
      } 
     } 
    } 
    else { ... } 
} 

Eseguendo semplici ifconfig comando di shell posso vedere lo, eth0 e wlan0. Vorrei recuperare gli indirizzi MAC per eth0 e wlan0 dal mio codice C/C++. Ma viene restituito solo wlan0 - manca eth0 (ho ifr_names lo, lo, wlan0). Probabilmente perché eth0 non è attivo (nessun cavo ethernet collegato, con cavo viene restituito). Posso in qualche modo alterare il comando ioctl (SIOCGIFCONF) per recuperare eth0 anche se è "disattivato"?

posso ottenere il suo indirizzo HW utilizzando direttamente

struct ifreq s; 
    int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 

    strcpy(s.ifr_name, "eth0"); 
    if (0 == ioctl(fd, SIOCGIFHWADDR, &s)) { ... } 

ma cosa succede se il nome non sarebbe eth0, ma qualcosa d'altro (eth1, em0, ...)? Mi piacerebbe averli tutti. Grazie per l'aiuto.

risposta

9

Si dovrebbe smettere di utilizzare net-tools e l'interfaccia ioctl arcaica e iniziare a utilizzare le moderne interfacce Netlink/sysfs. Non ci sono meno di 5 possibilità:

  • scrivere il proprio codice Netlink-interfacciamento
  • il proprio codice NL, in combinazione utilizzando libmnl (-> vedi rtnl-link-discarica in Examples
  • o utilizzare librerie autonome come libnl3
  • parse uscita testo del ip -o link (-o è quello di ottenere l'output destinato per l'analisi del testo, a differenza di ifconfig)
  • o utilizzare sysfs e appena lo ok al /sys/class/net/eth0/address
0

Forse non elegante, ma è possibile acquisire & analizzare i risultati di ifconfig, dal momento che sembra proprio quello che stai cercando.

+0

Grazie, che è sempre una soluzione, ma avrei preferito usare qualche soluzione C, l'analisi dei risultati ifconfig può essere problematico, formato può essere differente con differenti versioni di Linux, ecc – user1173626

1

è possibile trovare una soluzione qui: Get mac address given a specific interface

Si può solo saltare la parte specifica interfaccia.

+0

Grazie, ma io sono Non sono sicuro di capire cosa intendi. Nel tuo esempio di codice tutto riguarda la richiesta di parametri dell'interfaccia con nome argv [1] - che può essere ad esempio eth0 come nel mio secondo snippet di codice. Va bene. Ma ho bisogno di elencare tutte le interfacce. Saltando la parte "specifica" come suggerisci, cosa resterà? Ho bisogno di ottenere un elenco di interfacce che chiederò per i dettagli (MAC), è corretto? Per quanto ho capito, è quello che faccio chiamando SIOCGIFCONF. Ma eth0 non è nella lista. – user1173626

+0

Che ne dici di combinare queste due risposte: analizza i risultati di ifconfig JUST per i nomi (penso che sarebbe abbastanza indipendente dalla piattaforma) e utilizza questo approccio per cercare l'indirizzo MAC per ogni nome che trovi. –

+0

Oppure prendi il codice sorgente per ifconfig e guarda come trova questi nomi. –

Problemi correlati