在 python 上发出 ARP 请求

Make ARP request on python

我正在尝试在 python 上发出 ARP 请求。我的代码:

import socket
from struct import pack
from uuid import getnode as get_mac

def main():
    dest_ip = [10, 7, 31, 99]
    local_mac = [int(("%x" % get_mac())[i:i+2], 16) for i in range(0, 12, 2)]
    local_ip = [int(x) for x in socket.gethostbyname(socket.gethostname()).split('.')]

    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.SOCK_RAW)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.bind(('', 0))

    ARP_FRAME = [
        pack('!H', 0x0001), # HRD
        pack('!H', 0x0800), # PRO
        pack('!B', 0x06), # HLN
        pack('!B', 0x04), # PLN 
        pack('!H', 0x0001), # OP
        pack('!6B', *local_mac), # SHA
        pack('!4B', *local_ip), # SPA
        pack('!6B', *(0x00,)*6), # THA
        pack('!4B', *dest_ip), # TPA
    ]
    print(ARP_FRAME)
    sock.sendto(b''.join(ARP_FRAME), ('255.255.255.255', 0))
    sock.close()

if __name__ == "__main__":
    main()

当我执行这段代码时,Wireshark 没有捕获任何数据包。 我认为套接字有问题。当我执行 socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.SOCK_RAW) 时,我得到 AttributeError: module 'socket' has no attribute 'AF_PACKET'。我做错了什么以及如何解决?

OS X 10.11.3

socket.AF_INET是IP数据包的套接字。由于ARP是以太网,所以不会这样工作,你需要访问以太网层。

在 Linux 上,您可以使用:

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))

其中 s 是您用来将套接字分配给的任何变量。

要发送数据包,你应该绑定接口

s.bind(("eth0", 0))

其中 "eth0" 是网络接口名称。

之后,您可以发送数据包

s.send(packet)

将数据包作为字节串作为您的有效负载。

AttributeError: module 'socket' has no attribute 'AF_PACKET'

是说 AF_PACKET 没有在您的平台上实现。 不幸的是,有些平台不提供对低级网络层的访问,windows 是这样,OS X 可能也是这样。 至少,即使在 linux 上,您也需要 root 权限才能访问低级网络,否则您将收到访问被拒绝的错误。

通过 Python 访问低级网络的一个想法是使用虚拟机,例如 Virtualbox,并 运行 linux 来宾。

FTR,要解决此问题,您可以使用 Scapy。 它将使用:

  • AF_PACKET 或 unix 上的 libpcap
  • BSD 上的 BPF
  • Winpcap/Npcap 在 Windows

在每种情况下访问原始层,这使其跨平台。