如何使用dispatch_hook()链接不同的层。我有这样的包裹。我只是想知道是否有更好的方法使用dispatch_hook()来完成这个任务。
我就是这样制作包的:
>>>> pkt=PCEPCommonHeader(Type=6)/PCEPErrorMsg(error_objects=[PCEPErrorObject()])
>>> pkt.show()
###[ PCEP common header ]###
Version= 1
Flags= 0
Type= PCEPErrorMsg
Length= None
###[ PCEPErrorMsg ]###
\error_objects\
|###[ PCEP-ERROR OBJECT ]###
| \common_object_header\
| |###[ PCEP Common Object Header ]###
| | oclass= PCEP-ERROR
| | oType= 1
| | resflags=
| | pflag=
| | iflag=
| | obLength= 4
| Reserved= 0
| flags= 0
| ET= 0
| EV= 0
>>> 代码片段:
connection, pcc_address = pce.accept()
pcc_client=StreamSocket(connection,basecls=PCEPCommonHeader)
_PCEP_types = {6:"PCEPErrorMsg"}
_object_class = {13: "PCEP-ERROR"}
_PCEP_ERR_types = {3: "Unknown Object"}
_PCEP_ERR_values = {3: {1: "Unrecognized object class",
2: "Unrecognized object Type"}}
class PCEPCommonHeader(Packet):
"""This is the common header for all PCEP packets"""
name = "PCEP common header"
#Common Header Length is 4 bytes
fields_desc = [BitField("Version",1,3),
BitField("Flags",0,5),
ByteEnumField("Type", 2, _PCEP_types),
ShortField("Length", None)]
class PCEPCommonObjectHeader(Packet):
"""Common Header for the PCEP Objects"""
#Common ObjectHeader Length is 4 Bytes
name = "PCEP Common Object Header"
fields_desc = [ByteEnumField("oclass",0, _object_class),
BitField("oType",0,4),
FlagsField("resflags", 0x0, 2, "Res"),
FlagsField("pflag", 0x0, 1, "P"),
FlagsField("iflag", 0x0, 1, "I"),
ShortField("obLength", 4)]
class PCEPErrorObject(Packet):
'''PCEP-ERROR Object to notify error conditions in a PCEP session'''
name = 'PCEP-ERROR OBJECT'
common_object = PCEPCommonObjectHeader(oclass=13,oType=1)
fields_desc = [PacketField("common_object_header",common_object,PCEPCommonObjectHeader),
ByteField("Reserved",0),
ByteField("flags",0),
ByteEnumField("ET", 0, _PCEP_ERR_types),
MultiEnumField("EV", 0, _PCEP_ERR_values,depends_on=lambda pkt: pkt.ET,fmt="B")]
class PCEPErrorMsg(Packet):
fields_desc = [PacketListField("error_objects",None,PCEPErrorObject)]
bind_layers( PCEPCommonHeader, PCEPErrorMsg, Type=6)发布于 2015-01-19 13:21:55
.dispatch_hook()背后的思想是有一个主类,让我们称它为Protocol,它继承(直接或不直接)从Packet,并有派生类(直接或不继承,从Protocol或Packet);假设我们有Protocol1和Protocol2。
当您(或Scapy)通过调用.dispatch_hook()实例化类时,将调用Protocol()方法。它使用传递给Protocol()的完全相同的参数调用,并返回将要(真正)使用的类。
让我们举一个实际的例子,从Scapy代码。Ether() (以太网v2)和Dot3() ()是非常相似的第二层协议:它们都从六个字节的目标地址开始,然后是六个字节的源地址。Ether()接下来的两个字节是有效负载的类型,而Dot3()后面的两个字节是数据包大小。因为数据包不能超过1500个字节,而且以太网类型不能小于1500 (准确地说,1536是最小的)。
来自Scapy代码(文件scapy/layers/l2.py):
class Ether(Packet):
[...]
@classmethod
def dispatch_hook(cls, _pkt=None, *args, **kargs):
if _pkt and len(_pkt) >= 14:
if struct.unpack("!H", _pkt[12:14])[0] <= 1500:
return Dot3
return cls
class Dot3(Packet):
[...]
@classmethod
def dispatch_hook(cls, _pkt=None, *args, **kargs):
if _pkt and len(_pkt) >= 14:
if struct.unpack("!H", _pkt[12:14])[0] > 1500:
return Ether
return cls如果需要,可以找到一个更复杂、更完整的示例在TorPylle中,这是Scapy中TOR协议的一个实现。
https://stackoverflow.com/questions/28018040
复制相似问题