我已经为 scapy 中的 ByteEnum 字段创建了一个这样的字典。当我将此 _PCEP_ERR_values 字典传递给 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'
这段代码并没有按照您的想法行事。 _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
;这可能会为您节省访问公共(public)字段值的不必要的间接访问(您可以使用 pkt.field_name
而不是 pkt.common_object_header.field_name
)
我是一名优秀的程序员,十分优秀!