2016-02-11 165 views
1

我试图在python上发出ARP请求。我的代码:在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

+0

出于好奇,有什么理由不使用scapy吗? – Goodies

+0

第二层帧是一个带有广播目的地MAC地址(FFFF.FFFF.FFFF)和ARP ethertype(0x0806)的标准以太网帧。三层报文是一个ARP请求。有关ARP数据包格式,请参阅http://www.tcpipguide.com/free/t_ARPMessageFormat.htm。 –

+0

@Goodies这是“计算机网络”课程的家庭作业。 – 0x1337

回答

2

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客户机。