web-dev-qa-db-ja.com

Pythonを使用してデバイスからMACアドレスを取得します

ローカルネットワーク上のデバイスからlayer IIアドレスを取得する方法(Pythonを使用)を探しています。 Layer IIIアドレスは既知です。

目標は、IPアドレスのデータベースを定期的にポーリングするスクリプトを作成して、MACアドレスが変更されていないことを確認し、変更されている場合は自分に電子メールでアラートを送信することです。

19
nfarrar

Python=で質問に答えるには、プラットフォームによって異なります。Windowsは手元にないので、次の解決策は、私が書いたLinuxボックスで動作します。正規表現を少し変更すると、 OS Xで動作させる。

まず、ターゲットにpingする必要があります。これにより、システムのARPキャッシュにターゲットが配置されます(ネットマスク内にある限り、この状況のように聞こえます)。観察する:

13:40 jsmith@undertow% ping 97.107.138.15
PING 97.107.138.15 (97.107.138.15) 56(84) bytes of data.
64 bytes from 97.107.138.15: icmp_seq=1 ttl=64 time=1.25 ms
^C

13:40 jsmith@undertow% arp -n 97.107.138.15
Address                  HWtype  HWaddress           Flags Mask            Iface
97.107.138.15            ether   fe:fd:61:6b:8a:0f   C                     eth0

それを知って、あなたは少しサブプロセスの魔法をします-そうでなければあなたは自分でARPキャッシュチェックコードを書いていて、あなたはそれをしたくありません:

>>> from subprocess import Popen, PIPE
>>> import re
>>> IP = "1.2.3.4"

>>> # do_ping(IP)
>>> # The time between ping and arp check must be small, as ARP may not cache long

>>> pid = Popen(["arp", "-n", IP], stdout=PIPE)
>>> s = pid.communicate()[0]
>>> mac = re.search(r"(([a-f\d]{1,2}\:){5}[a-f\d]{1,2})", s).groups()[0]
>>> mac
"fe:fd:61:6b:8a:0f"
19
Jed Smith

このサイトで 同様の質問 がそれほど前に回答されていませんでした。その質問の質問者が選んだ回答で述べたように、Pythonには組み込みの方法がありません。ARP情報を取得するには、arpなどのシステムコマンドを呼び出す必要があります、または Scapy を使用して独自のパケットを生成します。

編集:Scapyを使用した例 ウェブサイトから

モニターモードのWi-Fiカードからの802.11フレームでも、マシンのすべてのインターフェイスを常に監視し、それが検出するすべてのARP要求を印刷する別のツールを次に示します。 sniff()のstore = 0パラメータに注意して、すべてのパケットをメモリに何も保存しないようにします。

_#! /usr/bin/env python
from scapy import *

def arp_monitor_callback(pkt):
    if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
        return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")

sniff(prn=arp_monitor_callback, filter="arp", store=0)
_

まさにあなたが探しているものではありませんが、間違いなく正しい方向に進んでいます。楽しい!

5
jathanism

ARPスプーファーを監視したいように聞こえますか?この場合、必要なのは arpwatch だけであり、近くにあるすべてのLinuxディストリビューションで利用できます。ここからソースをダウンロード: http://ee.lbl.gov/

2
intgr

unixベースのシステムの場合:

#!/usr/bin/env python2.7

import re
import subprocess
arp_out =subprocess.check_output(['arp','-lan'])

re.findall(r"((\w{2,2}\:{0,1}){6})",arp_out)

macのタプルのリストを返します。 scapyは素晴らしいツールですが、この場合はやり過ぎのようです

2

Linuxの場合、コマンドラインutil "arp"を見逃します。たとえば、ベースのヨクトLinux組み込み環境イメージ。

「arp」ツールを使用しない別の方法は、ファイル/ proc/net/arpを読み取って解析することです。

root@raspberrypi:~# cat /proc/net/arp
IP address       HW type     Flags       HW address            Mask     Device
192.168.1.1      0x1         0x2         xx:xx:xx:xx:xx:xx     *        wlan0
192.168.1.33     0x1         0x2         yy:yy:yy:yy:yy:yy     *        wlan0
2
urnenfeld

Scapyを使用して192.168.0.0/24サブネットをスキャンする簡単なソリューションは次のとおりです。

from scapy.all import *

ans,unans = arping("192.168.0.0/24", verbose=0)
for s,r in ans:
    print("{} {}".format(r[Ether].src,s[ARP].pdst))
1
AliA

linuxの場合、より簡単な方法:

print os.system('arp -n ' + str(remoteIP))

あなたは得るでしょう:

    Address        HWtype  HWaddress           Flags Mask            Iface
    192.168.....   ether   9B:39:15:f2:45:51   C                     wlan0
1
thais dbraz

ここにあるnetifacesを使ってみてください。 netifaces

0
Olu Smith

Python 3.7。の一般的な更新。備考:arpのオプション-nは、Linuxベースのシステムの特定の回答で提供されているように、Windowsシステムではarpリストを提供しません。こちらの回答に記載されているオプション-aを使用してください。

from subprocess import Popen, PIPE

pid = Popen(['arp', '-a', ip], stdout=PIPE, stderr=PIPE)

IP, MAC, var = ((pid.communicate()[0].decode('utf-8').split('Type\r\n'))[1]).split('     ')
IP  =  IP.strip(' ')
MAC =  MAC.strip(' ')

if ip == IP:
    print ('Remote Host : %s\n        MAC : %s' % (IP, MAC))
0
ZF007