在 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
在每种情况下访问原始层,这使其跨平台。
我正在尝试在 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
在每种情况下访问原始层,这使其跨平台。