You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Scapy创建带自定义字段的ARP报文无法捕获,求解决方法

问题:Scapy自定义ARP字段无法被嗅探识别

我尝试使用Scapy为ARP报文添加名为is_good_packet的自定义字段,自定义了ARPGood类,但嗅探器无法识别该类型的报文。

自定义ARP报文代码:

class ARPGood(Packet):
    name = "ARPGood"
    fields_desc = [
        ShortEnumField("hwtype", 1, {1: "Ethernet"}),
        ShortEnumField("ptype", 0x0800, {0x0800: "IPv4"}),
        ByteField("hwlen", 6),
        ByteField("plen", 4),
        ShortEnumField("op", 1, {1: "who-has", 2: "is-at"}),
        MACField("hwsrc", "00:00:00:00:00:00"),
        IPField("psrc", "0.0.0.0"),
        MACField("hwdst", "00:00:00:00:00:00"),
        IPField("pdst", "0.0.0.0"),
        BitField("is_good_packet", 0, 1)
    ]

嗅探器代码:

import scapy.all as sp
from ARPSENDER import ARPGood

def sniff(interface):
    sp.sniff(iface=interface, filter="inbound or outbound", store=False, prn=process_packet)

def process_packet(packet):
    print(packet.summary(), packet.show())
    if packet.haslayer(ARPGood):
        print(f"\n\n\n FOUND IT {packet.is_good_packet} \n\n\n")
sniff("eth0")

原本以为嗅探器能捕获到该报文,但没有得到任何结果,想知道是否有其他方法可以为ARP报文添加自定义字段?


解决方案

核心原因

  1. 自定义的ARPGood是独立的Packet类,Scapy默认会用原生ARP类解析以太网类型为0x0806的报文,不会自动映射到你的自定义类。
  2. 标准ARP报文结构中没有is_good_packet字段,直接发送ARPGood报文时,额外字段会被视为ARP的负载而非头部,原生ARP解析会忽略这部分数据。

方法1:扩展Scapy原生ARP类

直接继承Scapy的ARP类添加自定义字段,既保留标准ARP的解析逻辑,又能包含自定义字段:

from scapy.layers.l2 import ARP
from scapy.fields import BitField

# 扩展原生ARP类,追加自定义字段
class ARPGood(ARP):
    fields_desc = ARP.fields_desc + [BitField("is_good_packet", 0, 1)]

发送报文示例:

from scapy.all import sendp, Ether
# 构造带自定义字段的ARP报文
arp_pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARPGood(op=1, psrc="192.168.1.100", pdst="192.168.1.1", is_good_packet=1)
sendp(arp_pkt, iface="eth0")

嗅探逻辑调整:

import scapy.all as sp
from ARPSENDER import ARPGood

def process_packet(packet):
    if packet.haslayer(ARP):
        # 将原生ARP数据重新解析为ARPGood类
        arp_good = ARPGood(packet[ARP].build())
        if hasattr(arp_good, "is_good_packet"):
            print(f"\n\n\n FOUND IT {arp_good.is_good_packet} \n\n\n")

def sniff(interface):
    sp.sniff(iface=interface, filter="arp", store=False, prn=process_packet)

sniff("eth0")

方法2:绑定自定义类到ARP以太网类型

通过bind_layers将自定义ARPGood类绑定到以太网类型0x0806(ARP的类型码),强制Scapy用你的类解析ARP报文:

from scapy.layers.l2 import Ether
from scapy.packet import bind_layers
# 绑定Ethernet(type=0x0806)到ARPGood
bind_layers(Ether, ARPGood, type=0x0806)

注意:此方法会覆盖Scapy默认的ARP绑定,所有ARP报文都会用ARPGood解析,需确保你的类字段与标准ARP完全一致(即字段定义匹配原生ARP后再追加自定义字段)。

方法3:将自定义字段作为ARP负载

如果不需要把字段作为ARP头部的一部分,可以将自定义字段放在ARP报文的负载中:

发送示例:

arp_pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op=1, psrc="192.168.1.100", pdst="192.168.1.1") / b"\x01"  # 用1字节表示is_good_packet
sendp(arp_pkt, iface="eth0")

嗅探逻辑:

def process_packet(packet):
    if packet.haslayer(ARP) and packet[ARP].payload:
        # 读取负载的第一个字节作为is_good_packet值
        is_good = ord(packet[ARP].payload[:1]) & 0x01
        print(f"\n\n\n FOUND IT {is_good} \n\n\n")

内容的提问来源于stack exchange,提问作者namnam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 13:48:23