write paths libpath iterdir is_file files python windows linux networking

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