MACアドレスの取得


111

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

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


ここに役立つ可能性のある答えがたくさんあります!Pythonでeth0のIPアドレスを取得するにはどうすればよいですか?
uhoh

回答:


160

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

from uuid import getnode as get_mac
mac = get_mac()

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


25
私はWindowsボックスでこれを試したところ、うまくいきました...試してみたラップトップには2つのNIC(1つのワイヤレス)があり、返されたMACを判別する方法がありません。このコードを使用する場合は、一言だけ注意してください。
テクノロジカル2008年

24
ただ警告:getnodeドキュメントを見ると、macの検出に失敗するとランダムに長い値が返されると書かれています:「ハードウェアアドレスを取得するすべての試みが失敗した場合、ランダムな48ビットの数字とその8番目のビットを選択RFC 4122で推奨されているように1に設定します。」8番目のビットを確認してください。
deinonychusaur 2013

27
hex(mac)Macでおなじみの16進数形式を取得するには
screenshot345

43
または':'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2))、各バイトがコロンで区切られた大文字のMACの場合。
tomlogic 2014年

5
getnode()は、Windows 7ラップトップを再起動するたびに異なるものを返します。
nu everest 2014年

80

Linuxでこの問題を解決して特定のローカルインターフェイスのMACを取得するための純粋なpythonソリューション。元々はvishnubobによってコメントとして投稿され、このactivestateレシピの 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アドレス(およびその他のアドレス)を取得するために使用する優れたモジュールです。これはクロスプラットフォームであり、ソケットや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'}]


個人的に使用し、各システムで特定のインストール/コンパイルが必要ですが、うまく機能します。
2011年

22

もう1つ注意する必要があるのuuid.getnode()は、ランダムな48ビットの数値を返すことでMACアドレスを偽造できるため、期待と異なる可能性があることです。また、MACアドレスが偽造されていることを明示的に示すものはありませんが、getnode()2回呼び出して結果が異なるかどうかを確認することで、MACアドレスを検出できます。両方の呼び出しで同じ値が返された場合は、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であるとは限りません。このビットをチェックするだけで、アドレスが偽造されているかどうかを検出できます。
フレデリック・Grosshans

15
チェックがちょうどで行われます:昇給OSErrorの、「システムが有効なMACを持っていないようだ」(MAC >> 40)%2場合
フレデリック・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 2017

1
Pisに最適!
MikeT 2018年

8

ここから私の答えを使用する:https//stackoverflow.com/a/18031868/2362361

多くのものが存在する可能性があるため(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'

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
それは実際には答えではありません-単なるコメント
Stefano

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アドレスのみを返します。もちろん、1回だけ実行する必要があることを除いて、すべて同じですが、メインコードからは見た目がきれいです。


0

Linuxの場合、Macアドレスを表示し、それを変更できるようにする(MACスニッフィング)シェルスクリプトを紹介しましょう。

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

切り口の議論はdffer(私は専門家ではありません)を試してみてください:

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


-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彼はpythonソリューションを望んでいるので、あなたは彼に行き、ウェブ全体に貼られた同じ逆流したCソリューションを彼に与えます。
2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.