Le mécanisme pour obtenir des adresses MAC est entièrement différent sur les systèmes d'exploitation dérivés de BSD que sur Linux. Cela inclut OS X.
Code est ici j'utiliser qui fonctionne sur Linux et OS X, et probablement sur les BSDs aussi:
#if defined(HAVE_SIOCGIFHWADDR)
bool get_mac_address(char* mac_addr, const char* if_name = "eth0")
{
struct ifreq ifinfo;
strcpy(ifinfo.ifr_name, if_name);
int sd = socket(AF_INET, SOCK_DGRAM, 0);
int result = ioctl(sd, SIOCGIFHWADDR, &ifinfo);
close(sd);
if ((result == 0) && (ifinfo.ifr_hwaddr.sa_family == 1)) {
memcpy(mac_addr, ifinfo.ifr_hwaddr.sa_data, IFHWADDRLEN);
return true;
}
else {
return false;
}
}
#elif defined(HAVE_GETIFADDRS)
bool get_mac_address(char* mac_addr, const char* if_name = "en0")
{
ifaddrs* iflist;
bool found = false;
if (getifaddrs(&iflist) == 0) {
for (ifaddrs* cur = iflist; cur; cur = cur->ifa_next) {
if ((cur->ifa_addr->sa_family == AF_LINK) &&
(strcmp(cur->ifa_name, if_name) == 0) &&
cur->ifa_addr) {
sockaddr_dl* sdl = (sockaddr_dl*)cur->ifa_addr;
memcpy(mac_addr, LLADDR(sdl), sdl->sdl_alen);
found = true;
break;
}
}
freeifaddrs(iflist);
}
return found;
}
#else
# error no definition for get_mac_address() on this platform!
#endif
Il est à vous de trouver comment obtenir le droit HAVE_*
macro défini pour la plate-forme. Il m'arrive d'utiliser autoconf pour cela, mais vous pouvez avoir une autre façon de gérer les différences de plate-forme.
Notez que le paramètre de nom d'interface par défaut pour ces fonctions est la valeur par défaut pour la première interface Ethernet sur les boîtes Linux et OS X. Vous devrez peut-être surcharger ceci pour d'autres systèmes d'exploitation, ou passer une autre valeur si vous êtes intéressé par l'adresse MAC pour une interface différente.