web-dev-qa-db-ja.com

MACアドレスの取得

実行時にコンピューターのMACアドレスを決定するクロスプラットフォームの方法が必要です。 Windowsの場合、「wmi」モジュールを使用できます。Linuxで見つけることができる唯一の方法は、ifconfigを実行し、その出力全体で正規表現を実行することでした。 1つのOSでのみ動作するパッケージを使用するのは好きではありません。また、別のプログラムの出力を解析することは、エラーが発生しやすいことは言うまでもありません。

誰もがMACアドレスを取得するためのクロスプラットフォームメソッド(WindowsおよびLinux)メソッドを知っていますか?そうでない場合、上記のリストよりもエレガントな方法を知っている人はいますか?

99
Mark Roddy

Python 2.5には、(少なくとも1つのバージョンで)MACアドレスが必要なuuid実装が含まれています。 Macの検索機能を独自のコードに簡単にインポートできます。

from uuid import getnode as get_mac
mac = get_mac()

戻り値は、48ビット整数としてのMACアドレスです。

142
Armin Ronacher

Linuxでの特定のローカルインターフェイスのMACを取得するこの問題の純粋なpythonソリューション。元はvishnubobによるコメントとして投稿され、Ben Mackeyによる this activestate recipe

#!/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 __== "__main__":
    main()
78

netifacesは、MACアドレス(およびその他のアドレス)を取得するために使用するのに適したモジュールです。これはクロスプラットフォームであり、ソケットまたは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'}]

29
camflan

注意すべきもう1つの点は、uuid.getnode()が、予期しない48ビットの乱数を返すことでMACアドレスを偽造できることです。また、MACアドレスが偽造されていることを示す明示的な表示はありませんが、getnode()を2回呼び出して結果が変化するかどうかを確認することで検出できます。両方の呼び出しで同じ値が返された場合、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.
21
mhawke

時々、複数のネットインターフェースがあります。

特定のインターフェイスの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")
16
Julio Schurt

ここから私の答えを使用してください: https://stackoverflow.com/a/18031868/2362361

多くのMACアドレス(Bluetooth、複数のNICなど)が存在する可能性があるため、MACが必要なifaceを知ることが重要です。

これは、netifaces(PyPIで利用可能)を使用して、MACを必要とするifaceのIPを知っているときに仕事をします:

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'
8
kursancew

これは、クロスプラットフォームのpsutilを使用して実行できます。

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)
4
Python Novice

条件付きインポートを使用して、pythonで独自のクロスプラットフォームライブラリを構築できることに注意してください。例えば.

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

これにより、os.system呼び出しまたはプラットフォーム固有のライブラリを使用できます。

3
John Fouhy

依存関係を気にしないのであれば、クロスプラットフォームの 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
Ghost of Goes

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に変更します(一時的に、再起動時に実際のアドレスに復元します)。

あるいは、

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

私は統一された方法を知りませんが、ここにあなたが役に立つと思うかもしれない何かがあります:

http://www.codeguru.com/Cpp/I-N/network/networkinformation/article.php/c5451

この場合、私はこれらを関数にラップし、OSに基づいて適切なコマンドを実行し、必要に応じて解析し、必要に応じてフォーマットされたMACアドレスのみを返します。もちろん、同じことを1回行うだけでよく、メインコードからはすっきりしています。

0
Mostlyharmless