Scapy发送Wi-Fi数据包时Raw层负载丢失前3字符且重复输出
问题原因与解决方案
核心问题分析
- 前3字符丢失:你发送的是802.11 Data帧(
type=2, subtype=0),这类帧要求必须携带LLC(Logical Link Control)头部(3字节固定值:0xaa, 0xaa, 0x03)。你的驱动将Raw负载的前3字节误判为LLC头并自动剥离,导致接收端只能拿到剩余内容。 - 负载重复15次:802.11帧有最小长度要求(通常为64字节),你的原始数据包长度不足,驱动会自动重复填充负载内容以满足帧长标准,因此出现重复输出。
解决方案一:添加LLC/SNAP层(符合Data帧规范)
在Dot11层和Raw层之间插入标准的LLC和SNAP层,让驱动正确识别协议结构,避免误解析和自动填充:
import scapy.all as scapy from scapy.layers.dot11 import Dot11 from scapy.layers.l2 import LLC, SNAP # 构造合规的Data帧 packet = scapy.RadioTap() / \ Dot11(type=2, subtype=0, addr1="00:c0:ca:b7:2e:7c", addr2="00:11:22:33:44:55", addr3="00:11:22:33:44:55") / \ LLC(dsap=0xaa, ssap=0xaa, ctrl=0x03) / \ SNAP(OUI=0x000000, code=0x0800) / \ scapy.Raw(load="Hello World!")
发送后,接收端的原回调函数即可正确输出完整的Hello World!,无丢失或重复。
解决方案二:改用Management帧(更适合测试场景)
Data帧的协议约束较多,测试自定义数据传输时,推荐使用Management帧的Vendor Specific元素(ID=221)来携带数据,无需处理LLC层:
发送端代码
import scapy.all as scapy from scapy.layers.dot11 import Dot11, Dot11Elt # 构造Vendor Specific类型的Management帧 packet = scapy.RadioTap() / \ Dot11(type=0, subtype=0x0d, addr1="00:c0:ca:b7:2e:7c", addr2="00:11:22:33:44:55", addr3="00:11:22:33:44:55") / \ Dot11Elt(ID=221, info="Hello World!")
接收端回调函数修改
def sniff_callback(packet): if packet.haslayer(Dot11): if packet[Dot11].addr1 == "00:c0:ca:b7:2e:7c": for elt in packet.getlayer(Dot11Elt, nb=0): if elt.ID == 221: print(elt.info.decode("utf-8")) return
这种方式更灵活,不会触发驱动的自动填充逻辑,数据传输更直观。
内容的提问来源于stack exchange,提问作者Aldo
相关产品推荐
相关产品推荐

