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

如何使用Scapy定义UDP负载中的自定义协议并通过PcapReader解析

实现方案

完全可以使用Scapy的PcapReader解析包含自定义字段的UDP报文,你只需要先定义自定义协议层,再将其和UDP载荷绑定,就可以直接按字段名读取对应值,具体实现步骤如下:


步骤1:定义自定义协议层

根据你给出的字段结构定义MyProto协议类,字段字节序默认按网络大端序适配,如果你的协议是小端序可以替换为LE开头的字段类:

from scapy.fields import *
from scapy.packet import Packet
from scapy.layers.inet import UDP

class MyProto(Packet):
    name = "my_proto"
    fields_desc = [
        ShortField("VER", 0),      # 2字节版本号
        ShortField("FLAGS", 0),    # 2字节标志位
        LongField("TIMESTAMP", 0), # 8字节时间戳
        IntField("VAL1", 0),       # 4字节数值1
        IntField("VAL2", 0),       # 4字节数值2
        # 剩余字段可按需补充
    ]

步骤2:绑定自定义协议到UDP层

如果你的自定义协议使用固定的UDP源/目标端口,直接做层绑定后,Scapy解析UDP报文时会自动识别载荷为MyProto:

# 示例:绑定UDP目标端口为1234时载荷为MyProto,可根据实际端口调整参数
bind_layers(UDP, MyProto, dport=1234)
# 若为源端口固定,使用sport参数即可:bind_layers(UDP, MyProto, sport=1234)

如果没有固定端口,也可以跳过绑定步骤,后续手动解析UDP载荷即可。


步骤3:使用PcapReader解析抓包数据

from scapy.utils import PcapReader

# 逐包读取pcap文件
for pkt in PcapReader("你的抓包文件路径.pcap"):
    if UDP not in pkt:
        continue
    # 已做层绑定的场景,直接读取MyProto字段
    if MyProto in pkt:
        ver = pkt[MyProto].VER
        flags = pkt[MyProto].FLAGS
        timestamp = pkt[MyProto].TIMESTAMP
        val1 = pkt[MyProto].VAL1
        val2 = pkt[MyProto].VAL2
        # 自行处理字段逻辑
        print(f"版本号:{ver} 标志位:{flags} 时间戳:{timestamp}")
    
    # 未做层绑定的场景,手动解析UDP载荷
    else:
        my_proto = MyProto(raw(pkt[UDP].payload))
        print(f"手动解析版本号:{my_proto.VER}")

注意事项

  • 字节序匹配:如果你的自定义协议是小端序存储,需要把字段类替换为小端版本,比如LEShortField、LELongField、LEIntField,避免解析出的数值异常
  • 可变长度适配:如果自定义头部后还有可变长度的载荷,可以在fields_desc末尾补充对应的可变长度字段类,比如StrLenField等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:45:05