Obtenir une adresse MAC

J’ai besoin d’une méthode multi-plateforme pour déterminer l’adresse MAC d’un ordinateur au moment de l’exécution. Pour Windows, le module ‘wmi’ peut être utilisé et la seule méthode sous Linux que je pourrais trouver était d’exécuter ifconfig et d’exécuter une regex à travers sa sortie. Je n’aime pas utiliser un paquetage qui ne fonctionne que sur un système d’exploitation, et l’parsing de la sortie d’un autre programme ne semble pas très élégante, sans parler des erreurs.

Est-ce que quelqu’un connaît une méthode multi-plateforme (windows et linux) pour obtenir l’adresse MAC? Sinon, est-ce que quelqu’un connaît des méthodes plus élégantes que celles que j’ai énumérées ci-dessus?

Python 2.5 inclut une implémentation uuid qui (dans au moins une version) nécessite l’adresse mac. Vous pouvez importer la fonction de recherche de mac dans votre propre code facilement:

from uuid import getnode as get_mac mac = get_mac() 

La valeur de retour est l’adresse mac en tant qu’entier 48 bits.

La solution python pure pour ce problème sous Linux pour obtenir le MAC pour une interface locale spécifique, initialement publié en tant que commentaire par vishnubob et amélioré par Ben Mackey dans cette recette active

 #!/usr/bin/python import fcntl, socket, struct def getHwAddr(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15])) return ':'.join(['%02x' % ord(char) for char in info[18:24]]) print getHwAddr('eth0') 

netifaces est un bon module à utiliser pour obtenir l’adresse mac (et d’autres adresses). Il est plus efficace que d’utiliser socket ou uuid.

 >>> import netifaces >>> netifaces.interfaces() ['lo', 'eth0', 'tun2'] >>> netifaces.ifaddresses('eth0')[netifaces.AF_LINK] [{'addr': '08:00:27:50:f2:51', 'broadcast': 'ff:ff:ff:ff:ff:ff'}] 

  • emplacement pypi

  • Bonne introduction aux netifaces

Une autre chose à noter est que uuid.getnode() peut uuid.getnode() l’addr MAC en renvoyant un nombre aléatoire de 48 bits, ce qui peut ne pas être ce que vous attendez. De plus, il n’y a pas d’indication explicite indiquant que l’adresse MAC a été simulée, mais vous pouvez la détecter en appelant getnode() deux fois et en getnode() si le résultat varie. Si la même valeur est renvoyée par les deux appels, vous avez l’adresse MAC, sinon vous obtenez une adresse falsifiée.

 >>> print uuid.getnode.__doc__ Get the hardware address as a 48-bit positive integer. The first time this runs, it may launch a separate program, which could be quite slow. If all attempts to obtain the hardware address fail, we choose a random 48-bit number with its eighth bit set to 1 as recommended in RFC 4122. 

Parfois, nous avons plus d’une interface réseau.

Une méthode simple pour trouver l’adresse mac d’une interface spécifique est:

 def getmac(interface): try: mac = open('/sys/class/net/'+interface+'/address').readline() except: mac = "00:00:00:00:00:00" return mac[0:17] 

appeler la méthode est simple

 myMAC = getmac("wlan0") 

En utilisant ma réponse d’ici: https://stackoverflow.com/a/18031868/2362361

Il serait important de savoir à quelle iface vous voulez que le MAC puisque beaucoup peuvent exister (bluetooth, plusieurs nics, etc.).

Cela fait le travail lorsque vous connaissez l’IP de l’iface dont vous avez besoin pour le MAC, en utilisant netifaces (disponible dans PyPI):

 import netifaces as nif def mac_for_ip(ip): 'Returns a list of MACs for interfaces that have given IP, returns None if not found' for i in nif.interfaces(): addrs = nif.ifaddresses(i) try: if_mac = addrs[nif.AF_LINK][0]['addr'] if_ip = addrs[nif.AF_INET][0]['addr'] except IndexError, KeyError: #ignore ifaces that dont have MAC or IP if_mac = if_ip = None if if_ip == ip: return if_mac return None 

Essai:

 >>> mac_for_ip('169.254.90.191') '2c:41:38:0a:94:8b' 

Notez que vous pouvez créer votre propre bibliothèque multiplate-forme en python en utilisant les importations conditionnelles. par exemple

 import platform if platform.system() == 'Linux': import LinuxMac mac_address = LinuxMac.get_mac_address() elif platform.system() == 'Windows': # etc 

Cela vous permettra d’utiliser des appels os.system ou des bibliothèques spécifiques à la plate-forme.

Pour Linux, permettez-moi d’introduire un script shell qui affichera l’adresse mac et permettra de la changer (reniflage MAC).

  ifconfig eth0 | grep HWaddr |cut -dH -f2|cut -d\ -f2 00:26:6c:df:c3:95 

Couper les arguments peut se révéler (je ne suis pas un expert) essayez:

 ifconfig etho | grep HWaddr eth0 Link encap:Ethernet HWaddr 00:26:6c:df:c3:95 

Pour changer MAC, nous pouvons faire:

 ifconfig eth0 down ifconfig eth0 hw ether 00:80:48:BA:d1:30 ifconfig eth0 up 

va changer l’adresse mac à 00: 80: 48: BA: d1: 30 (temporairement, restaurera à un réel au redémarrage).

Je ne connais pas de manière unifiée, mais voici quelque chose que vous pourriez trouver utile:

http://www.codeguru.com/Cpp/IN/network/networkinformation/article.php/c5451

Ce que je ferais dans ce cas serait de les envelopper dans une fonction, et en fonction du système d’exploitation, il exécuterait la commande appropriée, parsingrait selon les besoins et ne renverrait que l’adresse MAC que vous souhaitez. C’est bien sûr tout de même, sauf que vous n’avez à le faire qu’une fois, et il semble plus propre que le code principal.

Vous pouvez le faire avec psutil qui est multi-plateforme:

 import psutil mac_addresses = [] nics = psutil.net_if_addrs() nics.pop('lo') # remove loopback since it doesnt have a real mac address for i in nics: for j in nics[i]: if j.family == 17: # AF_LINK mac_addresses.append(j.address) 

Le package getmac multi-plateforme fonctionnera pour cela, si cela ne vous dérange pas de prendre une dépendance. Il fonctionne avec Python 2.6+ et 3.2+. Il essaiera différentes méthodes jusqu’à obtenir une adresse ou retourner None.

 from getmac import get_mac_address eth_mac = get_mac_address(interface="eth0") win_mac = get_mac_address(interface="Ethernet 3") ip_mac = get_mac_address(ip="192.168.0.1") ip6_mac = get_mac_address(ip6="::1") host_mac = get_mac_address(hostname="localhost") updated_mac = get_mac_address(ip="10.0.0.1", network_request=True) 

Disclaimer: Je suis l’auteur du package.

Pour Linux, vous pouvez récupérer l’adresse MAC à l’aide d’un ioctl SIOCGIFHWADDR.

 struct ifreq ifr; uint8_t macaddr[6]; if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) return -1; strcpy(ifr.ifr_name, "eth0"); if (ioctl(s, SIOCGIFHWADDR, (void *)&ifr) == 0) { if (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER) { memcpy(macaddr, ifr.ifr_hwaddr.sa_data, 6); return 0; ... etc ... 

Vous avez marqué la question "python". Je ne connais pas de module Python existant pour obtenir cette information. Vous pouvez utiliser ctypes pour appeler directement l'ioctl.