将自定义 PTPv2 层添加到 scapy
Adding custom PTPv2 layer to scapy
我想在 python (v2.7) 中向 scapy (v2.3.3) 添加一个 PTPv2 层。我将带有 PTP 条目的 ptpv2 class 添加到文件 /scapy/layers/inet.py(因为 PTP 位于第 4 层)。我还将 ptpv2 层绑定到上层,在我的例子中是以太网。
bind_layers(Ethernet,ptpv2)
输入scapy命令"ls()"列出创建的ptpv2层,ok,成功。但是通过我的 python 脚本
访问图层
from scapy.all import *
from scapy.config import conf
conf.debug_dissector = True
for packet in PcapReader('/media/sf_SharedFolder/test.pcap'):
if packet[ptpv2].sequenceId == '0x0566':
# do anything
出现以下错误:
File "/usr/lib/python2.7/dist-packages/scapy/fields.py", line 75, in getfield return s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
struct.error: unpack requires a string argument of length 2
Wireshark 文件有 Frame -> Ethernet -> PTP 层,所以我的绑定命令必须正确。
不知道哪里出错了
这是 Wireshark 文件中的 PTP 层:
这是scapy中创建的ptpv2 class:
class ptpv2(Packet):
name = "Precision Time Protocol"
fields_desc = [
XBitField('transportSpecific', 0x1, 4),
XBitField('messageType', 0x0, 4),
XBitField('versionPTP', 0x2, 4),
XShortField('messageLength', 0x0036),
XBitField('subdomainNumber', 0x0, 8),
XShortField('flags', 0x0208),
XLongField('correction', 0x0),
XLongField('ClockIdentity', 0x08028efffe9b97a5),
XShortField('SourcePortId', 0x0002),
XShortField('sequenceId', 0x0566),
XBitField('control', 0x05, 8),
XBitField('logMessagePeriod', 0x7F, 8),
XLongField('requestreceiptTimestampSec', 0x00000000057b),
XLongField('requestreceiptTimestampNanoSec', 0x0d11715c),
XLongField('requestingSourcePortIdentity', 0x08028efffe9b97a5),
XShortField('requestingSourcePortId', 0x0002) ]
请帮帮我!
谢谢
克里斯
您需要找到导致崩溃的(第一个)数据包:
conf.debug_dissector = True
from pdb import pm
for packet in PcapReader('/media/sf_SharedFolder/test.pcap'):
if packet[ptpv2].sequenceId == '0x0566':
发生错误时:
pm()
pkt
那我们就看看是怎么回事。
发现错误:
Pierre 给了我一个提示,所以我可以解决这个问题。
我在 Bitfields 中使用了错误的长度,而 Longfields 不符合要求的长度。我在 scapy 中制作了工作 PTP 协议的图片:
为了它的价值,我曾经以上面为起点快速获取一堆 1588 条消息的偏移值:
#!/usr/bin/env python
from scapy.utils import rdpcap
from scapy.layers.l2 import Ether
from scapy.packet import Packet, bind_layers
from scapy.fields import *
class ieee1588(Packet):
name = "Precision Time Protocol"
fields_desc = [
BitField('transportSpecific', 1, 4),
BitField('messageType', 0, 4),
ByteField('versionPTP', 2),
LenField('messageLength', 0, fmt="H"),
ByteField('subdomainNumber', 0),
ByteField('dummy1', 0),
XShortField('flags', 0),
LongField('correction', 0),
IntField('dummy2', 0),
XLongField('ClockIdentity', 0),
XShortField('SourcePortId', 0),
XShortField('sequenceId', 0),
ByteField('control', 0),
SignedByteField('logMessagePeriod', 0),
Field('TimestampSec', 0, fmt='6s'),
IntField('TimestampNanoSec', 0)
]
bind_layers(Ether, ieee1588, type=0x88F7)
pcap = rdpcap("./test.pcap")
for pkt in pcap:
ptp = pkt.getlayer(ieee1588)
print(ptp.correction)
可能不是 100% 正确,但它对我的目的有用。
我想在 python (v2.7) 中向 scapy (v2.3.3) 添加一个 PTPv2 层。我将带有 PTP 条目的 ptpv2 class 添加到文件 /scapy/layers/inet.py(因为 PTP 位于第 4 层)。我还将 ptpv2 层绑定到上层,在我的例子中是以太网。
bind_layers(Ethernet,ptpv2)
输入scapy命令"ls()"列出创建的ptpv2层,ok,成功。但是通过我的 python 脚本
访问图层from scapy.all import *
from scapy.config import conf
conf.debug_dissector = True
for packet in PcapReader('/media/sf_SharedFolder/test.pcap'):
if packet[ptpv2].sequenceId == '0x0566':
# do anything
出现以下错误:
File "/usr/lib/python2.7/dist-packages/scapy/fields.py", line 75, in getfield return s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
struct.error: unpack requires a string argument of length 2
Wireshark 文件有 Frame -> Ethernet -> PTP 层,所以我的绑定命令必须正确。
不知道哪里出错了
这是 Wireshark 文件中的 PTP 层:
这是scapy中创建的ptpv2 class:
class ptpv2(Packet):
name = "Precision Time Protocol"
fields_desc = [
XBitField('transportSpecific', 0x1, 4),
XBitField('messageType', 0x0, 4),
XBitField('versionPTP', 0x2, 4),
XShortField('messageLength', 0x0036),
XBitField('subdomainNumber', 0x0, 8),
XShortField('flags', 0x0208),
XLongField('correction', 0x0),
XLongField('ClockIdentity', 0x08028efffe9b97a5),
XShortField('SourcePortId', 0x0002),
XShortField('sequenceId', 0x0566),
XBitField('control', 0x05, 8),
XBitField('logMessagePeriod', 0x7F, 8),
XLongField('requestreceiptTimestampSec', 0x00000000057b),
XLongField('requestreceiptTimestampNanoSec', 0x0d11715c),
XLongField('requestingSourcePortIdentity', 0x08028efffe9b97a5),
XShortField('requestingSourcePortId', 0x0002) ]
请帮帮我!
谢谢
克里斯
您需要找到导致崩溃的(第一个)数据包:
conf.debug_dissector = True
from pdb import pm
for packet in PcapReader('/media/sf_SharedFolder/test.pcap'):
if packet[ptpv2].sequenceId == '0x0566':
发生错误时:
pm()
pkt
那我们就看看是怎么回事。
发现错误:
Pierre 给了我一个提示,所以我可以解决这个问题。 我在 Bitfields 中使用了错误的长度,而 Longfields 不符合要求的长度。我在 scapy 中制作了工作 PTP 协议的图片:
为了它的价值,我曾经以上面为起点快速获取一堆 1588 条消息的偏移值:
#!/usr/bin/env python
from scapy.utils import rdpcap
from scapy.layers.l2 import Ether
from scapy.packet import Packet, bind_layers
from scapy.fields import *
class ieee1588(Packet):
name = "Precision Time Protocol"
fields_desc = [
BitField('transportSpecific', 1, 4),
BitField('messageType', 0, 4),
ByteField('versionPTP', 2),
LenField('messageLength', 0, fmt="H"),
ByteField('subdomainNumber', 0),
ByteField('dummy1', 0),
XShortField('flags', 0),
LongField('correction', 0),
IntField('dummy2', 0),
XLongField('ClockIdentity', 0),
XShortField('SourcePortId', 0),
XShortField('sequenceId', 0),
ByteField('control', 0),
SignedByteField('logMessagePeriod', 0),
Field('TimestampSec', 0, fmt='6s'),
IntField('TimestampNanoSec', 0)
]
bind_layers(Ether, ieee1588, type=0x88F7)
pcap = rdpcap("./test.pcap")
for pkt in pcap:
ptp = pkt.getlayer(ieee1588)
print(ptp.correction)
可能不是 100% 正确,但它对我的目的有用。