我是Scapy的新手,所以这可能写在某个地方,但我找不到答案。
我试图创建一个自定义的数据包解析器,但为了将特定的层相互绑定,我需要在更深的层中有一个值的条件下进行。我在RTP层上方至少有三层,但第二层和第三层的数量由第一层中的值决定。
Cust1包含后面的Cust2层的数量。每个Cust2层都将有一个相应的Cust3层,以在Cust2层次链的末端与其匹配。我在下面展示了一个例子,其中我使用了2a/2b/2c和3a/3b/3c来表示这些数字是相同的层类型,但链接在一起。
即
如果Cust1的值为一(1(,则:
UDP/RTP/Cust1/Cust2a/Cust3a
如果Cust1的值为两(2(:
UDP/RTP/Cust1/Cust2a/Cust2b/Cust3a/Cust3b
如果Cust1的值为三(3(:
UDP/RTP/Cust1/Cust2a/Cust2b/Cust2c/Cust3a/Cust3b/Cust3c
等等。。。
那么,对于链中更远的绑定,我如何引用Cust1呢?
bind_layers(RTP, Cust1)
bind_layers(Cust1, Cust2a)
bind_layers(Cust2a, Cust2b, {conditional REF_to_Cust1.value})
bind_layers(Cust2b, Cust2c, {conditional REF_to_Cust1.value})
# etc...
请告诉我,我不必为每个场景创建一个自定义层,并使用它来获得我想要的结果。
如果将数据包分为几层,这是不容易的,使用一些特殊字段可以很容易地实现。(你实际上可以使用guess_payload_class
,但这更痛苦…(
请查看PacketListField或适当的文档。
这是总体思路:
class Cust2(Packet):
...
class Cust3(Packet):
...
class Cust1(Packet):
fields_desc = [
ByteField("number_of_cust2", 0),
...,
PacketFieldList("cust2s", [], Cust2, count_from=lambda pkt: pkt.number_of_cust2),
PacketFieldList("cust3s", [], Cust3, count_from=lambda pkt: pkt.number_of_cust2),
]