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?

89
demandé sur Greg Mattes 2008-10-01 22:51:36

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.

130
répondu Armin Ronacher 2008-10-01 19:06:30

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')
72
répondu synthesizerpatel 2014-11-24 15:46:57

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'}]

23
répondu camflan 2016-02-05 19:22:39

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.
19
répondu mhawke 2008-10-02 08:11:03

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")
12
répondu Julio Schurt 2015-08-18 19:22:28

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'
8
répondu kursancew 2017-05-23 12:10:31

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.

3
répondu John Fouhy 2008-10-01 22:09:58

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).

2
répondu Sarath Sadasivan Pillai 2013-07-29 03:04:57

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.

1
répondu Mostlyharmless 2008-10-01 19:02:33

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)
1
répondu Python Novice 2016-12-10 14:53:26

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.

0
répondu Ghost of Goes 2018-08-02 06:28:03

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.

-7
répondu DGentry 2008-10-01 19:12:56