web-dev-qa-db-fra.com

Obtenir une adresse MAC

J'ai besoin d'une méthode multiplateforme 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 que j'ai pu trouver sous Linux consistait à exécuter ifconfig et à exécuter une expression régulière sur sa sortie. Je n'aime pas utiliser un paquet qui ne fonctionne que sur un système d'exploitation, et analyser la sortie d'un autre programme ne semble pas très élégant, sans parler des erreurs. 

Est-ce que quelqu'un connaît une méthode multi-plateforme (Windows et Linux) pour obtenir l'adresse MAC? Si non, quelqu'un connaît-il des méthodes plus élégantes que celles que j'ai énumérées ci-dessus?

95
Mark Roddy

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

from uuid import getnode as get_mac
mac = get_mac()

La valeur de retour est l'adresse MAC sous la forme d'un entier de 48 bits.

138
Armin Ronacher

La solution pure en python de ce problème sous Linux pour obtenir le MAC pour une interface locale spécifique, initialement publiée sous la forme d'un commentaire par vishnubob et améliorée 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')
76
synthesizerpatel

netifaces est un bon module à utiliser pour obtenir l’adresse MAC (et d’autres adresses). C'est une plateforme croisée et c'est un peu plus logique 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'}]

25
camflan

Une autre chose à noter est que uuid.getnode() peut simuler l'adresse MAC en renvoyant un nombre aléatoire de 48 bits, ce qui peut ne pas correspondre à vos attentes. De plus, rien n'indique explicitement que l'adresse MAC a été falsifiée, mais vous pouvez le détecter en appelant deux fois getnode() et en vérifiant 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.
20
mhawke

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

Une méthode simple pour trouver l'adresse MAC d'une interface spécifique est la suivante:

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")
15
Julio Schurt

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

Il serait important de savoir pour quel type de réseau vous voulez le MAC, car de nombreux ordinateurs peuvent exister (bluetooth, plusieurs cartes, etc.).

Cela fonctionne lorsque vous connaissez l'adresse IP de l'iface pour laquelle vous avez besoin du 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'
8
kursancew

Notez que vous pouvez créer votre propre bibliothèque multiplate-forme en python à l'aide d'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.

3
John Fouhy

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)
2
Python Novice

Pour Linux, permettez-moi de vous présenter un script Shell qui indiquera l'adresse MAC et vous permettra de la modifier (détection de code MAC).

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

Couper les arguments peut dffer (je ne suis pas un expert) essayez:

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

Pour changer de MAC, nous pouvons faire:

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

changera l'adresse mac en 00: 80: 48: BA: d1: 30 (temporairement, restaure l'adresse réelle au redémarrage).

1

Le paquetage getmac multiplateforme fonctionnera pour cela, si cela ne vous dérange pas de prendre une dépendance. Cela fonctionne avec Python 2.7+ et 3.4+. Il essaiera différentes méthodes jusqu'à ce que soit obtenir une adresse ou renvoyer Aucune.

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. 

Mise à jour (14 janvier 2019): le package ne prend désormais en charge que Python 2.7+ et 3.4+. Vous pouvez toujours utiliser une ancienne version du paquet si vous devez travailler avec un ancien Python (2.5, 2.6, 3.2, 3.3).

1
Ghost of Goes

Alternativement

import uuid
mac_id=(':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff)
0
Ajay Kumar K K

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

http://www.codeguru.com/Cpp/I-N/network/networkinformation/article.php/c5451

Ce que je ferais dans ce cas serait de les intégrer dans une fonction et, en fonction du système d’exploitation, exécuterait la commande appropriée, analyserait selon les besoins et renverrait uniquement l’adresse MAC formatée à votre guise. Bien sûr, cela reste identique, sauf que vous n’avez qu’à le faire une fois, et que cela semble plus propre du code principal.

0
Mostlyharmless