ejecutar con compilar como comando archivo c linux mac-address

con - ¿Cómo obtener la dirección MAC de su máquina usando un programa C?



compilar y ejecutar c en linux gcc (10)

  1. En Linux, use el servicio de "Network Manager" sobre el DBus.

  2. También hay un buen programa shell que se puede invocar y obtener el resultado (use una función ejecutiva en C):

$ /sbin/ifconfig | grep HWaddr

Estoy trabajando en Ubuntu. ¿Cómo puedo obtener la dirección MAC de mi máquina o una interfaz decir eth0 usando el programa C?


Acabo de escribir uno y probarlo en gentoo en virtualbox.

// get_mac.c #include <stdio.h> //printf #include <string.h> //strncpy #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> //ifreq #include <unistd.h> //close int main() { int fd; struct ifreq ifr; char *iface = "enp0s3"; unsigned char *mac = NULL; memset(&ifr, 0, sizeof(ifr)); fd = socket(AF_INET, SOCK_DGRAM, 0); ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name , iface , IFNAMSIZ-1); if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) { mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; //display mac address printf("Mac : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X/n" , mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } close(fd); return 0; }


Ampliando la respuesta dada por @ user175104 ...

std::vector<std::string> GetAllFiles(const std::string& folder, bool recursive = false) { // uses opendir, readdir, and struct dirent. // left as an exercise to the reader, as it isn''t the point of this OP and answer. } bool ReadFileContents(const std::string& folder, const std::string& fname, std::string& contents) { // uses ifstream to read entire contents // left as an exercise to the reader, as it isn''t the point of this OP and answer. } std::vector<std::string> GetAllMacAddresses() { std::vector<std::string> macs; std::string address; // from: https://.com/questions/9034575/c-c-linux-mac-address-of-all-interfaces // ... just read /sys/class/net/eth0/address // NOTE: there may be more than one: /sys/class/net/*/address // (1) so walk /sys/class/net/* to find the names to read the address of. std::vector<std::string> nets = GetAllFiles("/sys/class/net/", false); for (auto it = nets.begin(); it != nets.end(); ++it) { // we don''t care about the local loopback interface if (0 == strcmp((*it).substr(-3).c_str(), "/lo")) continue; address.clear(); if (ReadFileContents(*it, "address", address)) { if (!address.empty()) { macs.push_back(address); } } } return macs; }


Desea echar un vistazo a la página de manual de getifaddrs(3) . Hay un ejemplo en C en la página de manual en sí que puedes usar. Desea obtener la dirección con el tipo AF_LINK .


Mucho mejor que toda esta locura de socket o shell es simplemente usar sysfs para esto:

la dirección file /sys/class/net/eth0/address lleva su dirección mac como una cadena simple que puede leer con fopen() / fscanf() / fclose() . Nada más fácil que eso.

Y si desea soportar otras interfaces de red además de eth0 (y probablemente lo desee), simplemente use opendir() / readdir() / closedir() en /sys/class/net/ .


Suponiendo que el código de C ++ (c ++ 11) también está bien y se conoce la interfaz.

#include <cstdint> #include <fstream> #include <streambuf> #include <regex> using namespace std; uint64_t getIFMAC(const string &ifname) { ifstream iface("/sys/class/net/"+ifname+"/address"); string str((istreambuf_iterator<char>(iface)), istreambuf_iterator<char>()); string hex = regex_replace(str, std::regex(":"), ""); return stoull(hex, 0, 16); } int main() { string iface="eth0"; printf("%s: mac=%016lX/n", iface.c_str(), getIFMAC(iface)); }


Una forma muy portátil es analizar el resultado de este comando.

ifconfig | awk ''$0 ~ /HWaddr/ { print $5 }''

Siempre que ifconfig se pueda ejecutar como el usuario actual (generalmente puede) y awk está instalado (a menudo lo es). Esto le dará la dirección MAC de la máquina.


Usando getifaddrs puede obtener la dirección MAC de la familia AF_PACKET .

Para mostrar la dirección MAC a cada interfaz, puede proceder de la siguiente manera:

#include <stdio.h> #include <ifaddrs.h> #include <netpacket/packet.h> int main (int argc, const char * argv[]) { struct ifaddrs *ifaddr=NULL; struct ifaddrs *ifa = NULL; int i = 0; if (getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); } else { for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if ( (ifa->ifa_addr) && (ifa->ifa_addr->sa_family == AF_PACKET) ) { struct sockaddr_ll *s = (struct sockaddr_ll*)ifa->ifa_addr; printf("%-8s ", ifa->ifa_name); for (i=0; i <s->sll_halen; i++) { printf("%02x%c", (s->sll_addr[i]), (i+1!=s->sll_halen)?'':'':''/n''); } } } freeifaddrs(ifaddr); } return 0; }


Necesita iterar sobre todas las interfaces disponibles en su máquina y usar ioctl con el indicador SIOCGIFHWADDR para obtener la dirección MAC. La dirección MAC se obtendrá como una matriz binaria de 6 octetos. También quiere omitir la interfaz de bucle invertido.

#include <sys/ioctl.h> #include <net/if.h> #include <unistd.h> #include <netinet/in.h> #include <string.h> int main() { struct ifreq ifr; struct ifconf ifc; char buf[1024]; int success = 0; int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) { /* handle error*/ }; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { /* handle error */ } struct ifreq* it = ifc.ifc_req; const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq)); for (; it != end; ++it) { strcpy(ifr.ifr_name, it->ifr_name); if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don''t count loopback if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { success = 1; break; } } } else { /* handle error */ } } unsigned char mac_address[6]; if (success) memcpy(mac_address, ifr.ifr_hwaddr.sa_data, 6); }


#include <sys/socket.h> #include <sys/ioctl.h> #include <linux/if.h> #include <netdb.h> #include <stdio.h> #include <string.h> int main() { struct ifreq s; int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); strcpy(s.ifr_name, "eth0"); if (0 == ioctl(fd, SIOCGIFHWADDR, &s)) { int i; for (i = 0; i < 6; ++i) printf(" %02x", (unsigned char) s.ifr_addr.sa_data[i]); puts("/n"); return 0; } return 1; }