首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用dispatch_hook()

使用dispatch_hook()
EN

Stack Overflow用户
提问于 2015-01-19 04:38:18
回答 1查看 783关注 0票数 3

如何使用dispatch_hook()链接不同的层。我有这样的包裹。我只是想知道是否有更好的方法使用dispatch_hook()来完成这个任务。

我就是这样制作包的:

代码语言:javascript
复制
>>>> 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
>>>  

代码片段:

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-19 13:21:55

.dispatch_hook()背后的思想是有一个主类,让我们称它为Protocol,它继承(直接或不直接)从Packet,并有派生类(直接或不继承,从ProtocolPacket);假设我们有Protocol1Protocol2

当您(或Scapy)通过调用.dispatch_hook()实例化类时,将调用Protocol()方法。它使用传递给Protocol()的完全相同的参数调用,并返回将要(真正)使用的类。

让我们举一个实际的例子,从Scapy代码。Ether() (以太网v2)和Dot3() ()是非常相似的第二层协议:它们都从六个字节的目标地址开始,然后是六个字节的源地址。Ether()接下来的两个字节是有效负载的类型,而Dot3()后面的两个字节是数据包大小。因为数据包不能超过1500个字节,而且以太网类型不能小于1500 (准确地说,1536是最小的)。

来自Scapy代码(文件scapy/layers/l2.py):

代码语言:javascript
复制
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协议的一个实现。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28018040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档