scapy - 如何定义任意长度的枚举字段

时间:2018-03-03 11:26:05

标签: python-3.x scapy

我需要扩展当前scapy(scapy 2.4.0rc5)的IKEv2实现,以支持RFC7296第3.15节中定义的“配置有效负载”。

“配置属性”定义如下:

IKEv2 Configuration Attribute

属性类型是我定义的枚举字段,如下所示:

IKEv2_CP_attribute_types = { 
    1: "INTERNAL_IP4_ADDRESS",
    2: "INTERNAL_IP4_NETMASK",
    3: "INTERNAL_IP4_DNS",
    4: "INTERNAL_IP4_NBNS",
    6: "INTERNAL_IP4_DHCP",
    7: "APPLICATION_VERSION",
    8: "INTERNAL_IP6_ADDRESS",
    10: "INTERNAL_IP6_DNS",
    12: "INTERNAL_IP6_DHCP",
    13: "INTERNAL_IP4_SUBNET",
    14: "SUPPORTED_ATTRIBUTES",
    15: "INTERNAL_IP6_SUBNET",
    16: "MIP6_HOME_PREFIX",
    17: "INTERNAL_IP6_LINK",
    18: "INTERNAL_IP6_PREFIX",
    19: "HOME_AGENT_ADDRESS",
    20: "P_CSCF_IP4_ADDRESS",
    21: "P_CSCF_IP6_ADDRESS",
    22: "FTT_KAT",
    23: "EXTERNAL_SOURCE_IP4_NAT_INFO",
    24: "TIMEOUT_PERIOD_FOR_LIVENESS_CHECK",
    25: "INTERNAL_DNS_DOMAIN",
    26: "INTERNAL_DNSSEC_TA",
    16389: "P_CSCF_IP4_ADDRESS_ALT",    # widely used instead of 20 
    16390: "P_CSCF_IP6_ADDRESS_ALT"     # widely used instead of 21
}

但“属性类型”的适当scapy字段是什么?

应该是这样的:

class CP_Attribute(IKEv2_class):
    name = "IKEv2 CP Attribute"
    fields_desc = [
        ByteEnumField("attr_type",None,IKEv2_CP_attribute_types),
        PacketField("load", "", Raw)
        ]

但“ByteEnumField”是单字节,“属性类型”是15位字段。(我可以使用16位而不是15位,因为R位必须设置为0)

1 个答案:

答案 0 :(得分:1)

我找到了一个深入研究scapy中类似字段的其他协议的答案:

IKEv2_CP_types = {
    1: "CFG_REQUEST",
    2: "CFG_REPLY",
    3: "CFG_SET",
    4: "CFG_ACK"
}

IKEv2_CP_attribute_types = { 
    1: "INTERNAL_IP4_ADDRESS",
    2: "INTERNAL_IP4_NETMASK",
    3: "INTERNAL_IP4_DNS",
    4: "INTERNAL_IP4_NBNS",
    6: "INTERNAL_IP4_DHCP",
    7: "APPLICATION_VERSION",
    8: "INTERNAL_IP6_ADDRESS",
    10: "INTERNAL_IP6_DNS",
    12: "INTERNAL_IP6_DHCP",
    13: "INTERNAL_IP4_SUBNET",
    14: "SUPPORTED_ATTRIBUTES",
    15: "INTERNAL_IP6_SUBNET",
    16: "MIP6_HOME_PREFIX",
    17: "INTERNAL_IP6_LINK",
    18: "INTERNAL_IP6_PREFIX",
    19: "HOME_AGENT_ADDRESS",
    20: "P_CSCF_IP4_ADDRESS",
    21: "P_CSCF_IP6_ADDRESS",
    22: "FTT_KAT",
    23: "EXTERNAL_SOURCE_IP4_NAT_INFO",
    24: "TIMEOUT_PERIOD_FOR_LIVENESS_CHECK",
    25: "INTERNAL_DNS_DOMAIN",
    26: "INTERNAL_DNSSEC_TA",
    16389: "P_CSCF_IP4_ADDRESS_ALT",    # widely used instead of 20 
    16390: "P_CSCF_IP6_ADDRESS_ALT"     # widely used instead of 21
}

class CP_Attribute(IKEv2_class):
    name = "IKEv2 Proposal"
    fields_desc = [
        BitField("R", 0, 1),
        BitEnumField("attr_type",1, 15, IKEv2_CP_attribute_types)
        FieldLenField("length",None,"value","H"),
        PacketField("value", "", Raw)
        ]

class IKEv2_payload_CP(IKEv2_class):
    name = "IKEv2 CP"
    overload_fields = { IKEv2: { "next_payload":47 }}
    fields_desc = [
        ByteEnumField("next_payload",None,IKEv2_payload_type),
        ByteField("res",0),
        FieldLenField("length",None,"attribs","H", adjust=lambda pkt,x:x+8),
        ByteEnumField("cfg_type",None,IKEv2_CP_types),
        X3BytesField("res2",0),
        PacketLenField("attribs",conf.raw_layer(),CP_Attribute,length_from=lambda x:x.length-4),
        ] 

我在IKE_AUTH消息中测试了它,它确实生成了有效的配置负载。 由于scapy非常灵活,我很确定还有其他方法可以更有效地完成同样的工作。所以我欢迎提议,然后在几周内将其提交给scapy。