[python] MAC 주소 얻기

런타임에 컴퓨터의 MAC 주소를 결정하는 교차 플랫폼 방법이 필요합니다. Windows의 경우 ‘wmi’모듈을 사용할 수 있으며 Linux에서 찾을 수있는 유일한 방법은 ifconfig를 실행하고 출력에서 ​​정규식을 실행하는 것입니다. 나는 한 OS에서만 작동하는 패키지를 사용하는 것을 좋아하지 않으며 다른 프로그램의 출력을 파싱하는 것은 오류가 발생하기 쉬운 것은 말할 것도없고 우아하게 보이지 않습니다.

누구든지 MAC 주소를 얻는 크로스 플랫폼 방법 (Windows 및 Linux) 방법을 알고 있습니까? 그렇지 않다면 위에 나열된 것보다 더 우아한 방법을 아는 사람이 있습니까?



답변

Python 2.5에는 (최소 한 버전에서) mac 주소가 필요한 uuid 구현이 포함되어 있습니다. Mac 찾기 기능을 자신의 코드로 쉽게 가져올 수 있습니다.

from uuid import getnode as get_mac
mac = get_mac()

반환 값은 48 비트 정수인 mac 주소입니다.


답변

특정 로컬 인터페이스에 대한 MAC을 얻기 위해 Linux에서이 문제에 대한 순수한 파이썬 솔루션. 원래 vishnubob의 주석으로 게시되었고이 활성 상태 레시피 에서 Ben Mackey에 의해 개선되었습니다.

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

다음은 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()


답변

netifaces는 mac 주소 (및 기타 주소)를 가져 오는 데 사용할 수있는 좋은 모듈입니다. 그것은 크로스 플랫폼이며 socket 또는 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'}]


답변

주의해야 할 또 다른 사항은 uuid.getnode()예상과 다를 수있는 임의의 48 비트 숫자를 반환하여 MAC 주소를 위조 할 수 있다는 것입니다. 또한 MAC 주소가 위조되었다는 명시적인 표시는 없지만 getnode()두 번 호출 하고 결과가 다른지 확인하여 이를 감지 할 수 있습니다. 두 호출에서 동일한 값이 반환되면 MAC 주소가있는 것입니다. 그렇지 않으면 가짜 주소를 얻게됩니다.

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


답변

때때로 우리는 하나 이상의 넷 인터페이스를 가지고 있습니다.

특정 인터페이스의 MAC 주소를 찾는 간단한 방법은 다음과 같습니다.

def getmac(interface):

  try:
    mac = open('/sys/class/net/'+interface+'/address').readline()
  except:
    mac = "00:00:00:00:00:00"

  return mac[0:17]

메서드를 호출하는 것은 간단합니다

myMAC = getmac("wlan0")


답변

여기에서 내 대답 사용 : https://stackoverflow.com/a/18031868/2362361

많은 것이 존재할 수 있기 때문에 (블루투스, 여러 NIC 등) MAC을 원하는 iface를 아는 것이 중요합니다.

MAC이 필요한 iface의 IP를 알 때 다음을 사용하여 작업을 수행합니다 netifaces(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

테스트 :

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


답변

교차 플랫폼 인 psutil을 사용하여이 작업을 수행 할 수 있습니다.

import psutil
nics = psutil.net_if_addrs()
print [j.address for j in nics[i] for i in nics if i!="lo" and j.family==17]