MAC 주소 얻기


111

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

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


여기에 잠재적으로 유용한 답변이 많이 있습니다! 파이썬에서 eth0의 IP 주소를 어떻게 얻을 수 있습니까?
— uhoh

답변:


160

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

from uuid import getnode as get_mac
mac = get_mac()

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


25
방금 Windows 상자에서 시도해 보았고 훌륭하게 작동합니다. 시도한 랩톱에는 2 개의 NIC (하나의 무선)가 있고 반환 된 MAC을 확인할 방법이 없다는 점만 제외하면됩니다. 이 코드를 사용하려면 경고 한 마디 만하십시오.
— technomalogical

24
경고 : getnode문서 를 보면 Mac을 감지하지 못하면 임의의 long을 반환한다고 말합니다. "하드웨어 주소를 얻으려는 모든 시도가 실패하면 8 번째 비트가있는 임의의 48 비트 숫자를 선택합니다. RFC 4122에서 권장하는대로 1로 설정합니다. " 8 번째 비트를 확인하십시오!
— deinonychusaur 2013

27
hex(mac)맥의 친숙한 진수 형식 얻을
— screenshot345

43
또는 ':'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2))각 바이트가 콜론으로 구분 된 대문자 MAC의 경우.
— tomlogic

5
getnode ()는 Windows 7 노트북을 다시 시작할 때마다 다른 것을 반환합니다.
— nu everest 2014

80

특정 로컬 인터페이스에 대한 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()

35

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


개인적으로 사용하고 각 시스템에 특정 설치 / 컴파일이 필요하지만 잘 작동합니다.
— Aatch

22

주의해야 할 또 다른 사항은 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.

8
8 번째의 값은 네트워크 카드에서 사용할 수 없기 때문에 정확히 1이 아닙니다. 이 비트를 확인하는 것만으로도 주소가 위조되었는지 여부를 감지 할 수 있습니다.
— Frédéric Grosshans 2012

15
체크 단지로 수행됩니다 (맥은 >> 40) % 2 경우 : 인상 OSError는 "이 시스템이 유효한 MAC이 보이지 않는다"
— 프레데릭 Grosshans

17

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

특정 인터페이스의 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")

2
OS X 또는 Windows에는 그다지 유용하지 않습니다. : |
— RandomInsano

1
Pis에게 딱!
— MikeT

8

여기에서 내 대답 사용 : 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'

6

교차 플랫폼 인 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]

import socket그런 다음 [addr.address for n in nics for addr in nics[n] if n == 'enp4s0' and addr.family == socket.AF_PACKET]결과['ab:cd:ef:01:02:03']
— Donn Lee

3

조건부 가져 오기를 사용하여 Python에서 고유 한 크로스 플랫폼 라이브러리를 빌드 할 수 있습니다. 예 :

import platform
if platform.system() == 'Linux':
  import LinuxMac
  mac_address = LinuxMac.get_mac_address()
elif platform.system() == 'Windows':
  # etc

이렇게하면 os.system 호출 또는 플랫폼 별 라이브러리를 사용할 수 있습니다.


2
그건 정말 답이 아니다 - 단지 코멘트
— 스테파노

1

종속성을 고려하지 않는다면 크로스 플랫폼 getmac 패키지가이를 위해 작동합니다. Python 2.7+ 및 3.4+에서 작동합니다. 주소를 얻거나 None을 반환 할 때까지 다양한 방법을 시도합니다.

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)

면책 조항 : 나는 패키지의 작성자입니다.

업데이트 (2019 년 1 월 14 일) : 패키지는 이제 Python 2.7+ 및 3.4+ 만 지원합니다. 이전 Python (2.5, 2.6, 3.2, 3.3)으로 작업해야하는 경우 이전 버전의 패키지를 계속 사용할 수 있습니다.


1

eth0인터페이스 MAC 주소 를 얻으려면

import psutil

nics = psutil.net_if_addrs()['eth0']

for interface in nics:
   if interface.family == 17:
      print(interface.address)

0

통일 된 방법은 모르지만 여기에 유용하다고 생각되는 것이 있습니다.

http://www.codeguru.com/Cpp/IN/network/networkinformation/article.php/c5451

이 경우 내가 할 일은 이들을 함수로 래핑하고 OS에 따라 적절한 명령을 실행하고 필요에 따라 구문 분석하고 원하는 형식의 MAC 주소 만 반환하는 것입니다. 물론 한 번만하면되고 메인 코드에서 더 깔끔해 보인다는 점을 제외하면 모두 동일합니다.


0

Linux의 경우 mac 주소를 표시하고 변경할 수있는 (MAC 스니핑) 쉘 스크립트를 소개하겠습니다.

 ifconfig eth0 | grep HWaddr |cut -dH -f2|cut -d\  -f2
 00:26:6c:df:c3:95

컷 논쟁은 다를 수 있습니다 (나는 전문가가 아닙니다)

ifconfig etho | grep HWaddr
eth0      Link encap:Ethernet  HWaddr 00:26:6c:df:c3:95  

MAC을 변경하려면 다음을 수행 할 수 있습니다.

ifconfig eth0 down
ifconfig eth0 hw ether 00:80:48:BA:d1:30
ifconfig eth0 up

Mac 주소를 00 : 80 : 48 : BA : d1 : 30으로 변경합니다 (일시적으로 재부팅시 실제 주소로 복원 됨).


6
이것이 질문과 관련이 있습니까?
— bot47

-1

또는

import uuid
mac_id=(':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff)

-8

Linux의 경우 SIOCGIFHWADDR ioctl을 사용하여 MAC 주소를 검색 할 수 있습니다.

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

"python"질문에 태그를 지정했습니다. 이 정보를 얻기위한 기존 Python 모듈을 모릅니다. ctypes 를 사용 하여 ioctl을 직접 호출 할 수 있습니다.


8
-1 그는 파이썬 솔루션을 원합니다. 그래서 당신은 가서 그에게 웹 전체에 칠해진 동일한 역류 된 C 솔루션을 제공합니다.
— Aatch June 07
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.