Scapy: 添加具有复杂字段分组的新协议
我正在尝试使用 scapy
来定义一个新的数据包格式。在这个数据包里,有一系列的项目,而这些项目又由“分组字段”组成。这里的“分组字段”指的是不同类型字段的子序列。我知道在 scapy
中创建“分组字段”的唯一方法是使用 Packet
类,并通过 FieldLenField
或 PacketListField
来引用序列的长度和列表成员的类型。这样做可以吗?看起来像这样:
from scapy.packet import Packet
from scapy.fields import *
class RepeatingGroupedSequence(Packet):
name = "Simple group of two fields"
fields_desc = [IntField('field1', 1),
IntField('field2', 2)]
class TopLayer(Packet):
name = "Storage for Repeating Sequence"
fields_desc = [FieldLenField("length", None, count_of='rep_seq'),
PacketListField('rep_seq', None, RepeatingGroupedSequence,
count_from = lambda pkt: pkt.length),
]
#Now here is the problem that I have with assembling PacketListField:
#craft TopLayer packet
p = TopLayer()
#add two "repeated sequences"
p.rep_seq = [ RepeatingGroupedSequence(), RepeatingGroupedSequence() ]
#both sequences can observed
p.show()
#but the underlying structure of the repeated sequence is #Raw# at this stage
p.show2()
#length is 2
print p.rep_seq, 'length:', len(p.rep_seq)
#but the cloned packet has only one "repeated sequence", the rest is raw
clone = TopLayer(str(p))
clone.show()
#length is 1
print clone.rep_seq, 'length:', len(clone.rep_seq)
不过,这种方法有个问题,就是在重新组装数据包时,分组的结构没有被保留。在组装时,第二个 RepeatedSequence
实例被当作原始数据处理,尽管计数字段显示是2。那怎么才能像这样添加 RepeatingSequences
,以便在重新组装时保留结构呢?有没有办法在不使用 Packet
作为列表存储类型的情况下对字段进行分组?
1 个回答
10
类 RepeatingGroupedSequence
需要重写 extract_padding
方法:
def extract_padding(self, s):
return '', s
默认情况下,每个子包都会把所有内容都当作属于它自己的一层,也就是说:
def extract_padding(self, s):
return s, None
但这并不是用于分组的方式。有人能详细解释一下填充和层分离之间的区别吗?