Obtenir L'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 j'ai pu trouver était d'exécuter ifconfig et d'exécuter une expression rationnelle sur sa sortie. Je n'aime pas utiliser un paquet qui ne fonctionne que sur un système d'exploitation, et l'analyse de la sortie d'un autre programme ne semble pas très élégante pour ne pas mentionner les erreurs sujettes.
Est-ce que quelqu'un connaît une méthode multiplateforme (windows et linux) pour obtenir l'adresse MAC? Si non, est-ce que quelqu'un connaît des méthodes plus élégantes que celles que j'ai énumérées ci-dessus?
12 réponses
Python 2.5 inclut une implémentation uuid qui (dans au moins une version) a besoin de l'adresse mac. Vous pouvez importer la fonction de recherche mac dans votre propre code facilement:
from uuid import getnode as get_mac
mac = get_mac()
La valeur de retour est l'adresse mac sous forme d'entier de 48 bits.
La solution Python pure pour ce problème sous Linux pour obtenir le MAC pour une interface locale spécifique, posté à l'origine comme un commentaire par vishnubob et amélioré par sur Ben Mackey dans Cette recette activestate
#!/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). C'est crossplatform 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'}]
Une autre chose que vous devriez noter est que uuid.getnode()
peut simuler L'addr MAC en retournant un nombre aléatoire de 48 bits qui peut ne pas être ce que vous attendez. En outre, il n'y a aucune indication explicite que l'adresse MAC a été truquée, mais vous pouvez la détecter en appelant getnode()
deux fois et en voyant 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 un faux adresse.
>>> 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 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]
Pour 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 le MAC car beaucoup peuvent exister (bluetooth, plusieurs cartes réseau, etc.).
Cela fait le travail 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
Test:
>>> mac_for_ip('169.254.90.191')
'2c:41:38:0a:94:8b'
Notez que vous pouvez créer votre propre bibliothèque multiplateforme en python en utilisant des 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 le système d'exploitation.appels système ou bibliothèques spécifiques à la plate-forme.
Pour Linux, laissez-moi vous présenter un script shell qui affichera l'adresse mac et permet de la changer (Mac sniffing).
ifconfig eth0 | grep HWaddr |cut -dH -f2|cut -d\ -f2
00:26:6c:df:c3:95
Cut arguements peut dffer (Je ne suis pas un expert) essayer:
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/I-N/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, analyserait au besoin et ne retournerait que l'adresse MAC formatée comme vous le souhaitez. Ses bien sûr tout de même, sauf que vous avez seulement à faire une fois, et il semble plus propre de la principale code.
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 paquet multiplateforme getmac 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 va essayer de nombreuses méthodes différentes jusqu'à obtenir une adresse ou en 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)
Avertissement: je suis l'auteur du paquet.
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 l'ioctl directement.