我为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'
答案 0 :(得分:2)
此代码没有按照您的想法执行。 _PCEP_ERR_values
应该将数值与字符串值相关联(就像_PCEP_ERR_types
),并将文本值与字典相关联。
您必须使用MultiEnumField
,并且在Scapy source code的ICMP
图层中有一个很好的使用该类型字段的示例。
_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
)