python - paths - Obtener la dirección MAC
python libpath (12)
A veces tenemos más de una interfaz de red.
Un método simple para averiguar la dirección MAC de una interfaz específica es:
def getmac(interface):
try:
mac = open(''/sys/class/net/''+interface+''/address'').readline()
except:
mac = "00:00:00:00:00:00"
return mac[0:17]
llamar al método es simple
myMAC = getmac("wlan0")
Necesito un método de plataforma cruzada para determinar la dirección MAC de una computadora en tiempo de ejecución. Para Windows se puede usar el módulo ''wmi'' y el único método bajo Linux que pude encontrar fue ejecutar ifconfig y ejecutar una expresión regular a través de su salida. No me gusta usar un paquete que solo funcione en un sistema operativo, y analizar el resultado de otro programa no parece muy elegante, por no mencionar que es propenso a errores.
¿Alguien sabe un método de plataforma cruzada (Windows y Linux) para obtener la dirección MAC? Si no, ¿alguien sabe métodos más elegantes que los que enumeré arriba?
La solución de python puro para este problema bajo Linux para obtener el MAC para una interfaz local específica, originalmente publicada como un comentario por vishnubob y mejorada por Ben Mackey en esta receta de estado activo
#!/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'')
No sé de una manera unificada, pero aquí hay algo que puede serle útil:
http://www.codeguru.com/Cpp/I-N/network/networkinformation/article.php/c5451
Lo que haría en este caso sería incluirlos en una función y, en función del sistema operativo, ejecutaría el comando adecuado, analizar según sea necesario y devolver únicamente la dirección MAC formateada como desee. Por supuesto, es lo mismo, excepto que solo tienes que hacerlo una vez, y se ve más limpio desde el código principal.
Otra cosa que debes tener en cuenta es que uuid.getnode()
puede simular el código MAC devolviendo un número aleatorio de 48 bits que puede no ser lo que estás esperando. Además, no hay una indicación explícita de que la dirección MAC haya sido falsificada, pero usted podría detectarla al llamar a getnode()
dos veces y ver si el resultado varía. Si ambas llamadas devuelven el mismo valor, usted tiene la dirección MAC, de lo contrario recibirá una dirección falsa.
>>> 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.
Para Linux puede recuperar la dirección MAC utilizando 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 ...
Has etiquetado la pregunta "python". No sé de un módulo de Python existente para obtener esta información. Puede usar ctypes para llamar al ioctl directamente.
Para Linux, permítanme presentar un script de shell que muestre la dirección MAC y permita cambiarla (sniffing MAC).
ifconfig eth0 | grep HWaddr |cut -dH -f2|cut -d/ -f2
00:26:6c:df:c3:95
Los argumentos de corte pueden doler (no soy un experto) intente:
ifconfig etho | grep HWaddr
eth0 Link encap:Ethernet HWaddr 00:26:6c:df:c3:95
Para cambiar MAC podemos hacer:
ifconfig eth0 down
ifconfig eth0 hw ether 00:80:48:BA:d1:30
ifconfig eth0 up
cambiará la dirección MAC a 00: 80: 48: BA: d1: 30 (temporalmente, restaurará a la actual al reiniciar).
Puede hacer esto con psutil, que es multiplataforma:
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)
Python 2.5 incluye una implementación de uuid que (en al menos una versión) necesita la dirección MAC. Puede importar la función de búsqueda de mac en su propio código fácilmente:
from uuid import getnode as get_mac
mac = get_mac()
El valor de retorno es la dirección MAC como entero de 48 bits.
Tenga en cuenta que puede crear su propia biblioteca multiplataforma en Python usando importaciones condicionales. p.ej
import platform
if platform.system() == ''Linux'':
import LinuxMac
mac_address = LinuxMac.get_mac_address()
elif platform.system() == ''Windows'':
# etc
Esto le permitirá usar llamadas al sistema os o bibliotecas específicas de la plataforma.
Usando mi respuesta desde aquí: https://.com/a/18031868/2362361
Sería importante saber a qué instancia desea el MAC, ya que pueden existir muchos (bluetooth, varios nics, etc.).
Esto hace el trabajo cuando conoces la IP de la iface para la que necesitas MAC, usando netifaces
(disponible en 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
Pruebas:
>>> mac_for_ip(''169.254.90.191'')
''2c:41:38:0a:94:8b''
netifaces es un buen módulo para usar para obtener la dirección MAC (y otras direcciones). Es una plataforma cruzada y tiene más sentido que usar socket o 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''}]
para la solución de Linux
INTERFACE_NAME = "eth0"
#######################################
def get_mac_id(ifname=INTERFACE_NAME):
import commands
words = commands.getoutput("ifconfig " + ifname).split()
if "HWaddr" in words:
return words[ words.index("HWaddr") + 1 ]
else:
return ''No MAC Address Found!''
Uso:
print get_mac_id(ifname="eth0")