scapy:无法将带有子键的dict传递给ByteEnum Field

时间:2015-01-18 04:21:20

标签: python scapy

我为scapy中的ByteEnum字段创建了一个这样的字典。当我将此_PCEP_ERR_values dict传递给ByteEnum字段时,它的错误输出。跟踪说不可用的类型字典。如何将带有子键的字典传递给ByteEnumField?

这是我创建图层的方式:

_PCEP_ERR_types = {1: "PCEP session establishment failure",
                   3: "Unknown Object"}

_PCEP_ERR_values = {_PCEP_ERR_types[1]: {1: "Reception of an invalid Open message or a non Open message",
                                     2: "No Open message received before the expiration of the OpenWait timer",
                                     3: "Unacceptable and non-negotiable session characteristics",
                                     4: "Unacceptable but negotiable session characteristics",
                                     5: "Reception of a second Open message with still unacceptable session characteristics",
                                     6: "Reception of a PCErr message proposing unacceptable session characteristics",
                                     7: "No Keepalive or PCErr message received before the expiration of the KeepWait timer"},
                    _PCEP_ERR_types[3]: {1: "Unrecognized object class",
                                         2: "Unrecognized object Type"}}

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),
                      ByteEnumField("EV", 0, _PCEP_ERR_values)]

执行脚本时剪切回溯:

Traceback (most recent call last):
  File "./pcep-v3.py", line 1624, in <module>
    class PCEPErrorObject(Packet):
  File "./pcep-v3.py", line 1635, in PCEPErrorObject
    ByteEnumField("EV", 0, _PCEP_ERR_values)]
  File "/usr/local/lib64/python2.6/site-packages/scapy/fields.py", line 771,
in __init__
    EnumField.__init__(self, name, default, enum, "B")
  File "/usr/local/lib64/python2.6/site-packages/scapy/fields.py", line 718,
in __init__
    s2i[enum[k]] = k
TypeError: unhashable type: 'dict'

1 个答案:

答案 0 :(得分:2)

此代码没有按照您的想法执行。 _PCEP_ERR_values应该将数值与字符串值相关联(就像_PCEP_ERR_types),并将文本值与字典相关联。

您必须使用MultiEnumField,并且在Scapy source codeICMP图层中有一个很好的使用该类型字段的示例。

_PCEP_ERR_types = {1: "PCEP session establishment failure",
                   3: "Unknown Object"}

_PCEP_ERR_values = {
    1: {1: "Reception of an invalid Open message or a non Open message",
        2: "No Open message received before the expiration of the OpenWait timer",
        3: "Unacceptable and non-negotiable session characteristics",
        4: "Unacceptable but negotiable session characteristics",
        5: "Reception of a second Open message with still unacceptable session characteristics",
        6: "Reception of a PCErr message proposing unacceptable session characteristics",
        7: "No Keepalive or PCErr message received before the expiration of the KeepWait timer"},
    3: {1: "Unrecognized object class",
        2: "Unrecognized object Type"}
}


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")]

顺便说一句(完全不相关),您应该查看dispatch_hook Packet来替换common_object_header;这可能会为您节省不必要的间接访问权限以访问公共字段值(您可以使用pkt.field_name代替pkt.common_object_header.field_name