Python ARP 嗅探原始套接字无回复数据包。

15

为了更好地理解网络概念并提高我的Python技能,我正在尝试使用Python实现数据包嗅探器。我刚开始学习Python,所以代码当然还可以优化;)

我已经实现了一个数据包嗅探器,可以解包以太网帧和ARP头。我想使用原始套接字来实现它,因为我想了解这些头中的每个字节,所以请不要使用Scapy帮助:)

问题是,我无法获得任何ARP回复包。它总是操作码1,而我...

以下是我的源代码:

import socket
import struct
import binascii

rawSocket = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(0x0806))

while True:

    packet = rawSocket.recvfrom(2048)

    ethernet_header = packet[0][0:14]
    ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header)

    arp_header = packet[0][14:42]
    arp_detailed = struct.unpack("2s2s1s1s2s6s4s6s4s", arp_header)

    print "****************_ETHERNET_FRAME_****************"
    print "Dest MAC:        ", binascii.hexlify(ethernet_detailed[0])
    print "Source MAC:      ", binascii.hexlify(ethernet_detailed[1])
    print "Type:            ", binascii.hexlify(ethernet_detailed[2])
    print "************************************************"
    print "******************_ARP_HEADER_******************"
    print "Hardware type:   ", binascii.hexlify(arp_detailed[0])
    print "Protocol type:   ", binascii.hexlify(arp_detailed[1])
    print "Hardware size:   ", binascii.hexlify(arp_detailed[2])
    print "Protocol size:   ", binascii.hexlify(arp_detailed[3])
    print "Opcode:          ", binascii.hexlify(arp_detailed[4])
    print "Source MAC:      ", binascii.hexlify(arp_detailed[5])
    print "Source IP:       ", socket.inet_ntoa(arp_detailed[6])
    print "Dest MAC:        ", binascii.hexlify(arp_detailed[7])
    print "Dest IP:         ", socket.inet_ntoa(arp_detailed[8])
    print "*************************************************\n"

请问为什么我只收到这些响应包而没有其他响应?

输出:

****************_ETHERNET_FRAME_****************
Dest MAC:         ffffffffffff
Source MAC:       0012bfc87243
Type:             0806
************************************************
******************_ARP_HEADER_******************
Hardware type:    0001
Protocol type:    0800
Hardware size:    06
Protocol size:    04
Opcode:           0001
Source MAC:       0012bfc87243
Source IP:        192.168.2.1
Dest MAC:         000000000000
Dest IP:          192.168.2.226
*************************************************

到目前为止,谢谢! :)


我认为问题不在于ARP操作码本身。你的recvfrom()似乎只能捕获入站数据包,而不能捕获出站数据包。在这种情况下,操作码2(ARP回复)是出站的,因此无法被捕获。 - Santa
如果你运行脚本并让你的机器发送ARP ping,那么你只会看到操作码2(ARP回复),而看不到原始的出站ping。 - Santa
1个回答

16

我认为您需要指定套接字协议号0x0003以便嗅探所有内容,之后再过滤掉非ARP数据包。这对我有效:

import socket
import struct
import binascii

rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))

while True:

    packet = rawSocket.recvfrom(2048)

    ethernet_header = packet[0][0:14]
    ethernet_detailed = struct.unpack("!6s6s2s", ethernet_header)

    arp_header = packet[0][14:42]
    arp_detailed = struct.unpack("2s2s1s1s2s6s4s6s4s", arp_header)

    # skip non-ARP packets
    ethertype = ethernet_detailed[2]
    if ethertype != '\x08\x06':
        continue

    print "****************_ETHERNET_FRAME_****************"
    print "Dest MAC:        ", binascii.hexlify(ethernet_detailed[0])
    print "Source MAC:      ", binascii.hexlify(ethernet_detailed[1])
    print "Type:            ", binascii.hexlify(ethertype)
    print "************************************************"
    print "******************_ARP_HEADER_******************"
    print "Hardware type:   ", binascii.hexlify(arp_detailed[0])
    print "Protocol type:   ", binascii.hexlify(arp_detailed[1])
    print "Hardware size:   ", binascii.hexlify(arp_detailed[2])
    print "Protocol size:   ", binascii.hexlify(arp_detailed[3])
    print "Opcode:          ", binascii.hexlify(arp_detailed[4])
    print "Source MAC:      ", binascii.hexlify(arp_detailed[5])
    print "Source IP:       ", socket.inet_ntoa(arp_detailed[6])
    print "Dest MAC:        ", binascii.hexlify(arp_detailed[7])
    print "Dest IP:         ", socket.inet_ntoa(arp_detailed[8])
    print "*************************************************\n"

使用arpping从同一主机广播并回复的示例输出:

****************_ETHERNET_FRAME_****************
Dest MAC:         ffffffffffff
Source MAC:       000c29eb37bf
Type:             0806
************************************************
******************_ARP_HEADER_******************
Hardware type:    0001
Protocol type:    0800
Hardware size:    06
Protocol size:    04
Opcode:           0001
Source MAC:       000c29eb37bf
Source IP:        192.168.16.133
Dest MAC:         ffffffffffff
Dest IP:          192.168.16.2
*************************************************

****************_ETHERNET_FRAME_****************
Dest MAC:         000c29eb37bf
Source MAC:       005056f37861
Type:             0806
************************************************
******************_ARP_HEADER_******************
Hardware type:    0001
Protocol type:    0800
Hardware size:    06
Protocol size:    04
Opcode:           0002
Source MAC:       005056f37861
Source IP:        192.168.16.2
Dest MAC:         000c29eb37bf
Dest IP:          192.168.16.133
*************************************************

好的,谢谢!这绝对有效!现在我必须分析这种行为!谢谢! - user3325230
谢谢!你是怎么知道协议0x0003会嗅探所有内容的?我正在阅读《分配的互联网协议号码》文档,它说数字3是GGP - 网关到网关。 - Matt - Give Up Github
3
第三个参数(proto)的语义实际上取决于第一个参数中的AF_*系列。对于AF_PACKET,协议号0x3表示“所有以太网帧”,在Linux头文件中通常表示为ETH_P_ALL - Santa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接