MAC Adresi Almak


111

Çalışma zamanında bir bilgisayarın MAC adresini belirlemek için çapraz platform yöntemine ihtiyacım var. Windows için 'wmi' modülü kullanılabilir ve Linux altında bulabildiğim tek yöntem ifconfig'i çalıştırmak ve çıktısında bir regex çalıştırmaktı. Yalnızca bir işletim sisteminde çalışan bir paket kullanmaktan hoşlanmıyorum ve başka bir programın çıktısını ayrıştırmak, hataya eğilimli olduğundan bahsetmeye gerek yok.

MAC adresini almak için çapraz platform yöntemi (Windows ve Linux) yöntemi bilen var mı? Değilse, yukarıda listelediklerimden daha zarif yöntemler bilen var mı?


Burada potansiyel olarak yararlı olabilecek birçok cevap var! Python'da eth0'ın IP adresini nasıl alabilirim?
uhoh

Yanıtlar:


160

Python 2.5, (en az bir sürümde) mac adresine ihtiyaç duyan bir uuid uygulaması içerir. Mac bulma işlevini kendi kodunuza kolayca aktarabilirsiniz:

from uuid import getnode as get_mac
mac = get_mac()

Dönüş değeri, mac adresinin 48 bitlik tamsayıdır.


25
Bunu bir Windows kutusunda denedim ve harika çalışıyor ... üzerinde denediğim dizüstü bilgisayarda 2 NIC (bir kablosuz) olması ve hangi MAC'nin döndüğünü belirlemenin bir yolu olmaması dışında. Bu kodu kullanmak istiyorsanız, sadece bir uyarı.
technomalogical

24
Sadece bir uyarı: getnodeDokümantasyona bakarsanız, Mac'i algılayamazsa rastgele bir süre döneceğini söyler: "Tüm donanım adresi alma girişimleri başarısız olursa, sekizinci biti ile rastgele 48 bitlik bir sayı seçeriz RFC 4122'de önerildiği gibi 1'e ayarlayın. " Bu yüzden sekizinci kısmı kontrol edin!
deinonychusaur

27
hex(mac)Mac'in tanıdık onaltılık biçimini elde etmek için
ekran görüntüsü345

43
Veya ':'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2))her baytın iki nokta üst üste ile ayrılmış olduğu büyük harfli bir MAC için.
tomlogic

5
getnode (), Windows 7 dizüstü bilgisayarımı her yeniden başlattığımda farklı bir şey döndürüyor.
nu everest

81

Linux altında bu problem için saf python çözümü, belirli bir yerel arayüz için MAC'i almak için, başlangıçta vishnubob tarafından bir yorum olarak yayınlanmıştır ve bu aktif durum tarifinde Ben Mackey tarafından geliştirilmiştir.

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

Bu Python 3 uyumlu koddur:

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

36

netifaces, mac adresini (ve diğer adresleri) almak için kullanmak için iyi bir modüldür. Çapraz platformdur ve soket veya uuid kullanmaktan biraz daha mantıklıdır.

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


Kişisel olarak kullanıldı, her sistemde belirli bir kurulum / derleme gerektirir, ancak iyi çalışır.
Aatch

22

Dikkat etmeniz gereken bir diğer şey de uuid.getnode(), beklediğiniz gibi olmayabilecek rastgele 48 bitlik bir sayı döndürerek MAC adresinin sahte olabileceğidir. Ayrıca, MAC adresinin sahte olduğuna dair açık bir gösterge yoktur, ancak getnode()iki kez arayarak ve sonucun değişip değişmediğini görerek bunu tespit edebilirsiniz . Her iki aramada da aynı değer döndürülürse, MAC adresiniz vardır, aksi takdirde sahte bir adres alırsınız.

>>> 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'inci değerin 1 olduğundan değil, çünkü bir ağ kartı tarafından kullanılamıyor. Adresin sahte olup olmadığını tespit etmek için sadece bu biti kontrol etmek yeterlidir.
Frédéric Grosshans

15
Kontrol şu şekilde yapılır: if (mac >> 40)% 2: OSError'ı yükseltin, "Sistemin geçerli bir MAC'si yok"
Frédéric Grosshans

17

Bazen birden fazla net arayüzümüz olur.

Belirli bir arayüzün mac adresini bulmanın basit bir yöntemi şudur:

def getmac(interface):

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

  return mac[0:17]

yöntemi aramak basittir

myMAC = getmac("wlan0")

2
OS X veya Windows için pek kullanışlı değil. : |
RandomInsano

1
Pis için mükemmel!
MikeT

8

Cevabımı buradan kullanarak: https://stackoverflow.com/a/18031868/2362361

Birçoğu mevcut olabileceğinden (bluetooth, birkaç nics, vb.) MAC'ı hangi iface için istediğinizi bilmek önemli olacaktır.

Bu, MAC'a ihtiyaç duyduğunuz iface'in IP'sini bildiğinizde netifaces(PyPI'de mevcuttur) şunları kullanarak işi yapar :

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

Test yapmak:

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

6

Bunu çapraz platform olan psutil ile yapabilirsiniz:

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 socketsonra [addr.address for n in nics for addr in nics[n] if n == 'enp4s0' and addr.family == socket.AF_PACKET]sonuçlanır['ab:cd:ef:01:02:03']
Donn Lee

3

Koşullu içe aktarmaları kullanarak python'da kendi çapraz platform kitaplığınızı oluşturabileceğinizi unutmayın. Örneğin

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

Bu, os.system çağrılarını veya platforma özgü kitaplıkları kullanmanıza izin verecektir.


2
bu gerçekten bir cevap değil - sadece bir yorum
Stefano

1

Bir bağımlılık almaktan çekinmiyorsanız , platformlar arası getmac paketi bunun için çalışacaktır. Python 2.7+ ve 3.4+ ile çalışır. Bir adres alana veya Hiçbiri döndürene kadar birçok farklı yöntem deneyecektir.

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)

Feragatname: Paketin yazarıyım.

Güncelleme (14 Ocak 2019): paket artık yalnızca Python 2.7+ ve 3.4+ desteklemektedir. Daha eski bir Python (2.5, 2.6, 3.2, 3.3) ile çalışmanız gerekirse, paketin daha eski bir sürümünü kullanmaya devam edebilirsiniz.


1

eth0Arayüz MAC adresini almak için ,

import psutil

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

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

0

Birleşik bir yol bilmiyorum, ama burada yararlı bulabileceğiniz bir şey var:

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

Bu durumda yapacağım şey, bunları bir işleve dönüştürmek olacak ve işletim sistemine bağlı olarak uygun komutu çalıştıracak, gerektiği gibi ayrıştıracak ve yalnızca istediğiniz gibi biçimlendirilmiş MAC adresini döndürecekti. Tabii ki aynı, sadece bir kez yapmanız gerekmesi dışında ve ana koddan daha temiz görünüyor.


0

Linux için, mac adresini gösterecek ve değiştirilmesine izin verecek bir kabuk betiği sunmama izin verin (MAC koklama).

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

Tartışmaları kesebilir (uzman değilim) şunu deneyin:

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

MAC'i değiştirmek için şunları yapabiliriz:

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

mac adresini 00: 80: 48: BA: d1: 30 olarak değiştirir (geçici olarak, yeniden başlatıldığında gerçek olana geri yüklenir).


6
Bunun soruyla bir ilgisi var mı?
bot47

-1

Alternatif olarak,

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

-8

Linux için, bir SIOCGIFHWADDR ioctl kullanarak MAC adresini alabilirsiniz.

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" sorusunu etiketlediniz. Bu bilgiyi almak için mevcut bir Python modülü bilmiyorum. Sen kullanabilirsiniz ctypes doğrudan ioctl aramak için.


8
-1 O bir python çözümü istiyor, bu yüzden gidin ve ona web boyunca sıvalı aynı yeniden akıtılmış C çözümünü verin.
00'de maç
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.