125 votes

Obtenir l'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 sous Linux que j'ai pu trouver était de lancer ifconfig et d'exécuter une expression rationnelle sur sa sortie. Je n'aime pas utiliser un paquet qui ne fonctionne que sur un seul système d'exploitation, et l'analyse de la sortie d'un autre programme ne semble pas très élégante, sans parler du risque d'erreur.

Quelqu'un connaît-il une méthode multiplateforme (Windows et linux) pour obtenir l'adresse MAC ? Sinon, quelqu'un connaît-il des méthodes plus élégantes que celles que j'ai énumérées ci-dessus ?

0 votes

Il y a beaucoup de réponses potentiellement utiles ici ! Comment puis-je obtenir l'adresse IP de eth0 en Python ?

178voto

Armin Ronacher Points 16894

Python 2.5 inclut une implémentation de l'uuid qui (dans au moins une version) a besoin de 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 en tant qu'entier de 48 bits.

27 votes

Je viens d'essayer ceci sur une boîte Windows et ça marche très bien... sauf que l'ordinateur portable sur lequel je l'ai essayé a 2 NICs (un sans fil) et il n'y a aucun moyen de déterminer quel MAC il a retourné. Juste un mot d'avertissement si vous voulez utiliser ce code.

1 votes

C'est une fonctionnalité de l'énumérateur de périphériques de Windows. Quelle que soit la méthode utilisée pour obtenir l'adresse, vous devez être prudent si vous l'utilisez comme un identifiant unique.

26 votes

Juste un avertissement : Si vous regardez le getnode Dans la documentation, il est dit qu'il renverra une longueur aléatoire s'il ne parvient pas à détecter le mac : "Si toutes les tentatives pour obtenir l'adresse matérielle échouent, nous choisissons un nombre aléatoire de 48 bits avec son huitième bit mis à 1 comme recommandé dans la RFC 4122." Donc vérifiez ce huitième bit !

92voto

synthesizerpatel Points 9762

La solution purement python pour ce problème sous Linux pour obtenir le MAC d'une interface locale spécifique, initialement postée comme commentaire par vishnubob et améliorée par Ben Mackey dans cette recette d'activite

#!/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')

Il s'agit du code compatible avec Python 3 :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import fcntl
import socket
import struct

def getHwAddr(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', bytes(ifname, 'utf-8')[:15]))
    return ':'.join('%02x' % b for b in info[18:24])

def main():
    print(getHwAddr('enp0s8'))

if __name__ == "__main__":
    main()

40voto

camflan Points 4010

Netifaces est un bon module à utiliser pour obtenir l'adresse mac (et d'autres adresses). Il est multiplateforme et a un peu plus de sens que l'utilisation de 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'}]

0 votes

Je l'ai utilisé personnellement, il nécessite une installation/compilation spécifique sur chaque système mais fonctionne bien.

22voto

mhawke Points 10385

Une autre chose que vous devriez noter est que uuid.getnode() peut falsifier l'adresse MAC en renvoyant un nombre aléatoire de 48 bits qui peut ne pas correspondre à ce que vous attendez. De plus, il n'y a pas d'indication explicite que l'adresse MAC a été falsifiée, mais vous pouvez le détecter en appelant getnode() deux fois et voir 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 truqué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.

8 votes

Non pas que la valeur du 8 soit 1 précisément parce qu'il ne peut pas être utilisé par une carte réseau. La simple vérification de ce bit suffit à détecter si l'adresse est truquée ou non.

17 votes

La vérification se fait simplement avec : if (mac >> 40)%2 : raise OSError, "Le système ne semble pas avoir de MAC valide".

9voto

kursancew Points 41

J'utilise ma réponse d'ici : https://stackoverflow.com/a/18031868/2362361

Il serait important de savoir à quel iface vous voulez le MAC car il peut en exister plusieurs (bluetooth, plusieurs nics, etc.).

Cela fonctionne si vous connaissez l'IP de l'interface pour laquelle vous avez besoin du MAC, en utilisant la fonction 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

Test :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X