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.