22

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

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

4

8 に答える 8

20

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"
于 2009-11-17T18:44:39.887 に答える
5

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

編集: Web サイトから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)

検証済みの回答と同様のことを行うこともできます。https://scapy.readthedocs.io/en/latest/routing.htmlを参照してください

>>> mac = getmacbyip("10.0.0.1")
>>> mac
'f3:ae:5e:76:31:9b'

これは完全にクロスプラットフォームです。

まさにあなたが探しているものではありませんが、間違いなく正しい軌道に乗っています。楽しみ!

于 2009-11-17T18:41:00.633 に答える
2

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 は素晴らしいツールですが、この場合はやり過ぎのようです

于 2015-07-22T23:47:24.403 に答える
2

Linux では、コマンドライン util "arp" を見落とすことがあります。たとえば、ベースの yocto 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
于 2016-05-15T12:11:03.400 に答える
2

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

于 2009-11-17T18:27:23.360 に答える
0

Python 3.7 の一般的な更新。備考: オプション-nforarpは、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))
于 2019-07-05T09:14:37.127 に答える