예제 #1
0
class SAPRFC(Packet):
    """SAP Remote Function Call packet

    This packet is used for the Remote Function Call (RFC) protocol.
    """
    name = "SAP Remote Function Call"
    fields_desc = [
        ByteField("version", 3),  # If the version is 3, the packet has a size > 88h, versions 1 and 2 are 40h
        ByteEnumKeysField("req_type", 0, rfc_req_type_values),

        # Normal client fields (GW_NORMAL_CLIENT)
        ConditionalField(IPField("address", "0.0.0.0"), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(IntField("padd1", 0), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(StrFixedLenPaddedField("service", "", length=10), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(StrFixedLenField("codepage", "1100", length=4), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(StrFixedLenField("padd2", "\x00" * 6, length=6), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(StrFixedLenPaddedField("lu", "", length=8), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(StrFixedLenPaddedField("tp", "", length=8), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(StrFixedLenPaddedField("conversation_id", "", length=8), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(ByteField("appc_header_version", 6), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(ByteField("accept_info", 0xcb), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(SignedShortField("idx", -1), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(IP6Field("address6", "::"), lambda pkt:pkt.req_type == 0x03 and pkt.version == 3),

        ConditionalField(IntField("rc", 0), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(ByteField("echo_data", 0), lambda pkt:pkt.req_type == 0x03),
        ConditionalField(ByteField("filler", 0), lambda pkt:pkt.req_type == 0x03),

        # Monitor Command fields (GW_SEND_CMD)
        ConditionalField(ByteEnumKeysField("cmd", 0, rfc_monitor_cmd_values), lambda pkt:pkt.req_type == 0x09),
    ]
예제 #2
0
파일: SAPMS.py 프로젝트: pyq881120/pysap
class SAPMSAdmRecord(PacketNoPadded):
    """SAP Message Server Administration Record packet

    Packet for Message Server administration records. Each administration
    package has a variable number of records, each one specifies an operation
    to execute.
    """
    name = "SAP Message Server Adm Record"
    fields_desc = [
        ByteEnumKeysField("opcode", 0x00, ms_adm_opcode_values),
        ByteField("serial_number", 0x00),
        ByteField("executed", 0x00),
        ByteField("errorno", 0x00),  # TODO: Look for error names
        ConditionalField(StrFixedLenField("record", None, 100), lambda pkt:pkt.opcode not in [0x01, 0x15, 0x2e]),

        # TODO: Add more opcodes fields

        # AD_PROFILE and AD_SHARED_PARAMETER fields
        ConditionalField(StrNullFixedLenPaddedField("parameter", "", 100), lambda pkt:pkt.opcode in [0x01, 0x2e]),

        # AD_RZL_STRG opcode
        ConditionalField(ByteEnumKeysField("rzl_strg_type", 1, ms_adm_rzl_strg_type_values), lambda pkt:pkt.opcode in [0x15]),
        ConditionalField(ByteField("rzl_strg_name_length", 0), lambda pkt:pkt.opcode in [0x15]),
        ConditionalField(ByteField("rzl_strg_value_offset", 0), lambda pkt:pkt.opcode in [0x15]),
        ConditionalField(ByteField("rzl_strg_value_length", 0), lambda pkt:pkt.opcode in [0x15]),
        ConditionalField(StrFixedLenField("rzl_strg_name", None, 20), lambda pkt:pkt.opcode in [0x15]),
        ConditionalField(IntField("rzl_strg_integer0", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer1", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer2", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer3", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer4", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer5", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer6", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer7", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer8", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(IntField("rzl_strg_integer9", 0), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type in [11, 15, 21, 31, 41, 51]),
        ConditionalField(StrFixedLenField("rzl_strg_value", None, 40), lambda pkt:pkt.opcode in [0x15] and pkt.rzl_strg_type not in [11, 15, 21, 31, 41, 51]),
        ConditionalField(StrFixedLenField("rzl_strg_padd2", None, 36), lambda pkt:pkt.opcode in [0x15]),
    ]
예제 #3
0
파일: SAPDiag.py 프로젝트: deneme056/pysap
class SAPDiagItem(PacketNoPadded):
    """SAP Diag Item packet

    This packet holds the different types of Diag items. The value field is
    interpreted according to the Type/ID/SID specified for the item.
    """
    name = "SAP Diag Item"
    fields_desc = [
        ByteEnumKeysField("item_type", 0, diag_item_types),
        ConditionalField(ByteEnumKeysField("item_id", 0, diag_appl_ids),
                         diag_item_is_appl_appl4),
        ConditionalField(
            ByteMultiEnumKeysField("item_sid",
                                   0,
                                   diag_appl_sids,
                                   depends_on=lambda item: item.item_id,
                                   fmt="B"), diag_item_is_appl_appl4),
        ConditionalField(
            FieldLenField("item_length",
                          None,
                          length_of="item_value",
                          fmt="!H"), diag_item_is_short),
        ConditionalField(
            FieldLenField("item_length4",
                          None,
                          length_of="item_value",
                          fmt="!I"), diag_item_is_long),
        MutablePacketField(
            "item_value",
            None,
            length_from=diag_item_get_length,
            get_class=diag_item_get_class,
            evaluators=[
                lambda item: item.item_type, lambda item: item.item_id,
                lambda item: item.item_sid
            ],
        )
    ]
예제 #4
0
파일: SAPMS.py 프로젝트: pyq881120/pysap
class SAPMSClient3(Packet):
    """SAP Message Server Client packet version 3

    Packet that contains information about a client of the Message Server
    service. This packet is for version 3.
    """
    name = "SAP Message Server Client version 3"
    fields_desc = [
        StrFixedLenField("client", None, 40),
        StrFixedLenField("host", None, 64),
        StrFixedLenField("service", None, 20),
        FlagsField("msgtype", 0, 8, ["ICM", "ATP", "UP2", "SPO", "BTC", "ENQ", "UPD", "DIA"]),
        IP6Field("hostaddrv6", "::1"),
        IPField("hostaddrv4", "0.0.0.0"),
        ShortField("servno", 0x00),
        ByteEnumKeysField("status", 0x00, ms_client_status_values),
        ByteField("nitrace", 0x00),
        ByteField("padd", 0),
    ]
예제 #5
0
파일: SAPMS.py 프로젝트: pyq881120/pysap
class SAPMSClient2(PacketNoPadded):
    """SAP Message Server Client packet version 2

    Packet that contains information about a client of the Message Server
    service. This packet is for version 2, which has been seen only on old
    releases (SAP NW 2004s).
    """
    name = "SAP Message Server Client version 2"
    fields_desc = [
        StrFixedLenField("client", None, 40),
        StrFixedLenField("host", None, 32),
        StrFixedLenField("service", None, 20),
        FlagsField("msgtype", 0, 8, ["ICM", "ATP", "UP2", "SPO", "BTC", "ENQ", "UPD", "DIA"]),
        IPField("hostaddrv4", "0.0.0.0"),
        ShortField("servno", 0x00),
        ByteEnumKeysField("status", 0x00, ms_client_status_values),
        ByteField("nitrace", 0x00),
        StrFixedLenField("padd", None, 14),
    ]
예제 #6
0
class SAPDiagUIEventSource(PacketNoPadded):
    name = "UI Event Source"
    fields_desc = [
        BitField("valid_unused", 0, 4),
        BitField("valid_functionkey_data", 0, 1),
        BitField("valid_navigation_data", 0, 1),
        BitField("valid_control_pos", 0, 1),
        BitField("valid_menu_pos", 0, 1),
        ShortEnumKeysField("event_type", 0, diag_ui_event_type_values),
        ShortEnumKeysField("control_type", 0, diag_ui_event_control_values),
        ConditionalField(
            ByteEnumKeysField("navigation_data", 0,
                              diag_ui_event_navigation_data_values),
            lambda pkt: pkt.valid_navigation_data),
        ConditionalField(ByteField("event_data", 0),
                         lambda pkt: not pkt.valid_navigation_data),
        ShortField("control_row", 0),
        ShortField("control_col", 0),
        FieldLenField("container_nrs", None, count_of="containers"),
        FieldListField("containers",
                       None,
                       ByteField("container", 0),
                       count_from=lambda x: x.container_nrs)
    ]
예제 #7
0
class SAPDiagDyntAtomItem(PacketNoPadded):
    name = "SAP Diag Dynt Atom item"
    fields_desc = [
        ShortField("atom_length", 0),
        ByteField("dlg_flag_1", 0),
        ByteField("dlg_flag_2", 0),
        ByteEnumKeysField("etype", 0, diag_atom_etypes),
        ByteField("area", 0),
        ByteField("block", 0),
        ByteField("group", 0),
        ShortField("row", 0),
        ShortField("col", 0),
        # Attr flags
        BitField("attr_DIAG_BSD_COMBOSTYLE", 0, 1),  # 80
        BitField("attr_DIAG_BSD_YES3D", 0, 1),  # 40
        BitField("attr_DIAG_BSD_PROPFONT", 0, 1),  # 20
        BitField("attr_DIAG_BSD_MATCHCODE", 0, 1),  # 10
        BitField("attr_DIAG_BSD_JUSTRIGHT", 0, 1),  # 08
        BitField("attr_DIAG_BSD_INTENSIFY", 0, 1),  # 04
        BitField("attr_DIAG_BSD_INVISIBLE", 0, 1),  # 02
        BitField("attr_DIAG_BSD_PROTECTED", 0, 1),  # 01

        # DIAG_DGOTYP_FNAME
        ConditionalField(
            StrLenField("name_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype == 114),
        # DIAG_DGOTYP_PUSHBUTTON_2 */
        ConditionalField(ByteField("pushbutton_v_length", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ByteField("pushbutton_v_height", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ShortField("pushbutton_function_code_offset", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ShortField("pushbutton_text_offset", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(StrField("pushbutton_text", ""),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(StrField("pushbutton_function_code", ""),
                         lambda pkt: pkt.etype in [115]),
        # DIAG_DGOTYP_TABSTRIP_BUTTON
        ConditionalField(ByteField("tabstripbutton_v_length", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ByteField("tabstripbutton_v_height", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ByteField("tabstripbutton_page_id", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_function_code_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_text_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_id_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_text", ""),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_function_code", ""),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_id", ""),
                         lambda pkt: pkt.etype in [116]),
        # DIAG_DGOTYP_XMLPROP
        ConditionalField(
            StrLenField("xmlprop_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype == 120),
        # DIAG_DGOTYP_EFIELD_1 or DIAG_DGOTYP_OFIELD_1 or DIAG_DGOTYP_KEYWORD_1
        ConditionalField(ByteField("field1_flag1", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(
            FieldLenField("field1_dlen",
                          None,
                          fmt="B",
                          length_of="field1_text"),
            lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(ByteField("field1_mlen", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(ShortField("field1_maxnrchars", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(
            StrLenField("field1_text",
                        "",
                        length_from=lambda pkt: pkt.field1_dlen),
            lambda pkt: pkt.etype in [121, 122, 123]),
        # DIAG_DGOTYP_FRAME_1
        ConditionalField(ShortField("frame_drows", 0),
                         lambda pkt: pkt.etype in [127]),
        ConditionalField(ShortField("frame_dcols", 0),
                         lambda pkt: pkt.etype in [127]),
        ConditionalField(
            StrLenField("frame_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 17),
            lambda pkt: pkt.etype in [127]),
        # DIAG_DGOTYP_RADIOBUTTON_3
        ConditionalField(ByteField("radiobutton_button", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_visible_label_length", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_event_id_off", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ByteField("radiobutton_event_id_len", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_text_off", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_text_length", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(
            StrLenField("radiobutton_text",
                        "",
                        length_from=lambda pkt: pkt.radiobutton_event_id_len +
                        pkt.radiobutton_text_length),
            lambda pkt: pkt.etype in [129]),
        # DIAG_DGOTYP_EFIELD_2 or DIAG_DGOTYP_OFIELD_2 or DIAG_DGOTYP_KEYWORD_2
        ConditionalField(ShortField("field2_flag1", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(
            FieldLenField("field2_dlen",
                          None,
                          fmt="B",
                          length_of="field2_text"),
            lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(ByteField("field2_mlen", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(ShortField("field2_maxnrchars", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(
            StrLenField("field2_text",
                        "",
                        length_from=lambda pkt: pkt.field2_dlen),
            lambda pkt: pkt.etype in [130, 131, 132]),
        # Remaining types
        ConditionalField(
            StrLenField("value",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype not in
            [114, 115, 116, 120, 121, 122, 123, 127, 129, 130, 131, 132]),
    ]

    def post_build(self, p, pay):
        if pay is None:
            pay = ''
        # Update the atom_length field (first 2 bytes) with the packet length
        p = pack("!H", len(p)) + p[2:]
        return p + pay
예제 #8
0
class SAPRouter(Packet):
    """SAP Router packet

    This packet is used for general SAP Router packets. There are (at least)
    five types of SAP Router packets:

        1. Route packets. For requesting the routing of a connection to a
        remote hosts. The packet contains some general information and a
        connection string with a list of routing hops (:class:`SAPRouterRouteHop`).

        2. Administration packets. This packet is used for the SAP Router to
        send administrative commands. It's suppose to be used only from the
        hosts running the SAP Router or when an specific route is included in
        the routing table. Generally administration packets are not accepted
        from the external binding.

        3. Error Information packets. Packets sent when an error occurred.

        4. Control Message packets. Used to perform some control activities,
        like retrieving the current SAPRouter version or to perform the SNC
        handshake. They have the same structure that error information
        packets.

        5. Route accepted packet. Used to acknowledge a route request
        ("NI_PONG").


    Routed packets and some responses doesn't fill in these five packet
    types. For identifying those cases, you should check the type using the
    function :class:`router_is_known_type`.

    NI Versions found (unconfirmed):
        - 30: Release 40C
        - 36: Release <6.20
        - 38: Release 7.00/7.10
        - 39: Release 7.11
        - 40: Release 7.20/7.21
    """

    # Constants for router types
    SAPROUTER_ROUTE = "NI_ROUTE"
    """ :cvar: Constant for route packets
        :type: C{string} """

    SAPROUTER_ADMIN = "ROUTER_ADM"
    """ :cvar: Constant for administration packets
        :type: C{string} """

    SAPROUTER_ERROR = "NI_RTERR"
    """ :cvar: Constant for error information packets
        :type: C{string} """

    SAPROUTER_CONTROL = "NI_RTERR"
    """ :cvar: Constant for control messages packets
        :type: C{string} """

    SAPROUTER_PONG = "NI_PONG"
    """ :cvar: Constant for route accepted packets
        :type: C{string} """

    router_type_values = [
        SAPROUTER_ADMIN,
        SAPROUTER_ERROR,
        SAPROUTER_CONTROL,
        SAPROUTER_ROUTE,
        SAPROUTER_PONG,
    ]
    """ :cvar: List of known packet types
        :type: ``list`` of C{string} """

    name = "SAP Router"
    fields_desc = [
        # General fields present in all SAP Router packets
        StrNullField("type", SAPROUTER_ROUTE),

        ConditionalField(ByteField("version", 0x02), lambda pkt:router_is_known_type(pkt) and not router_is_pong(pkt)),

        # Route packets
        ConditionalField(ByteField("route_ni_version", 0x28), router_is_route),
        ConditionalField(ByteField("route_entries", 0), router_is_route),
        ConditionalField(ByteEnumKeysField("route_talk_mode", 0, router_ni_talk_mode_values), router_is_route),
        ConditionalField(ShortField("route_padd", 0), router_is_route),
        ConditionalField(ByteField("route_rest_nodes", 0), router_is_route),
        ConditionalField(FieldLenField("route_length", 0, length_of="route_string", fmt="I"), router_is_route),
        ConditionalField(IntField("route_offset", 0), router_is_route),
        ConditionalField(PacketListField("route_string", None, SAPRouterRouteHop,
                                         length_from=lambda pkt:pkt.route_length), router_is_route),

        # Admin packets
        ConditionalField(ByteEnumKeysField("adm_command", 0x02, router_adm_commands), router_is_admin),
        ConditionalField(ShortField("adm_unused", 0x00), lambda pkt:router_is_admin(pkt) and pkt.adm_command not in [10, 11, 12, 13]),

        # Info Request fields
        ConditionalField(StrNullFixedLenField("adm_password", "", 19), lambda pkt:router_is_admin(pkt) and pkt.adm_command in [2]),

        # Cancel Route fields
        ConditionalField(FieldLenField("adm_client_count", None, count_of="adm_client_ids", fmt="H"), lambda pkt:router_is_admin(pkt) and pkt.adm_command in [6]),
        ConditionalField(FieldListField("adm_client_ids", [0x00], IntField("", 0), count_from=lambda pkt:pkt.adm_client_count), lambda pkt:router_is_admin(pkt) and pkt.adm_command in [6]),

        # Trace Connection fields
        ConditionalField(FieldLenField("adm_client_count", None, count_of="adm_client_ids", fmt="I"), lambda pkt:router_is_admin(pkt) and pkt.adm_command in [12, 13]),
        ConditionalField(FieldListField("adm_client_ids", [0x00], IntField("", 0), count_from=lambda pkt:pkt.adm_client_count), lambda pkt:router_is_admin(pkt) and pkt.adm_command in [12, 13]),

        # Set/Clear Peer Trace fields  # TODO: Check whether this field should be a IPv6 address or another proper field
        ConditionalField(StrFixedLenField("adm_address_mask", "", 32), lambda pkt:router_is_admin(pkt) and pkt.adm_command in [10, 11]),

        # Error Information/Control Messages fields
        ConditionalField(ByteEnumKeysField("opcode", 0, router_control_opcodes), lambda pkt: router_is_error(pkt) or router_is_control(pkt)),
        ConditionalField(ByteField("opcode_padd", 0), lambda pkt: router_is_error(pkt) or router_is_control(pkt)),
        ConditionalField(SignedIntEnumField("return_code", 0, router_return_codes), lambda pkt: router_is_error(pkt) or router_is_control(pkt)),

        # Error Information fields
        ConditionalField(FieldLenField("err_text_length", None, length_of="err_text_value", fmt="!I"), lambda pkt: router_is_error(pkt) and pkt.opcode == 0),
        ConditionalField(PacketField("err_text_value", SAPRouterError(), SAPRouterError), lambda pkt: router_is_error(pkt) and pkt.opcode == 0),
        ConditionalField(IntField("err_text_unknown", 0), lambda pkt: router_is_error(pkt) and pkt.opcode == 0),

        # Control Message fields
        ConditionalField(IntField("control_text_length", 0), lambda pkt: router_is_control(pkt) and pkt.opcode != 0),
        ConditionalField(StrField("control_text_value", "*ERR"), lambda pkt: router_is_control(pkt) and pkt.opcode != 0),

        # SNC Frame fields
        ConditionalField(PacketField("snc_frame", None, SAPSNCFrame), lambda pkt: router_is_control(pkt) and pkt.opcode in [70, 71])
    ]
예제 #9
0
파일: SAPDiag.py 프로젝트: deneme056/pysap
class SAPDiag(PacketNoPadded):
    """SAP Diag packet

    This packet holds the Diag Header and serve as a container for
    L{SAPDiagItem} items. It handles compression/decompression, adding the
    appropriate Compression Header when necessary.
    """
    name = "SAP Diag"
    fields_desc = [
        ByteField("mode", 0),

        # Communication flags
        BitField("com_flag_TERM_GRA", 0, 1),
        BitField("com_flag_TERM_NNM", 0, 1),
        BitField("com_flag_TERM_CAS", 0, 1),
        BitField("com_flag_TERM_INI", 0, 1),
        BitField("com_flag_TERM_EOP", 0, 1),
        BitField("com_flag_TERM_NOP", 0, 1),
        BitField("com_flag_TERM_EOC", 0, 1),
        BitField("com_flag_TERM_EOS", 0, 1),
        ByteField("mode_stat", 0),
        ByteField("err_flag", 0),
        ByteField("msg_type", 0),
        ByteField("msg_info", 0),
        ByteField("msg_rc", 0),
        ByteEnumKeysField("compress", 0, diag_compress_values),

        # Compression Header
        ConditionalField(LEIntField("uncompress_length", None),
                         lambda pkt: pkt.compress == 1),
        ConditionalField(
            ByteEnumField("algorithm", 0x12, {
                0x12: "LZH",
                0x10: "LZC"
            }), lambda pkt: pkt.compress == 1),
        ConditionalField(StrFixedLenField("magic_bytes", "\x1f\x9d", 2),
                         lambda pkt: pkt.compress == 1),
        ConditionalField(ByteField("special", 2),
                         lambda pkt: pkt.compress == 1),

        # SNC Frame
        ConditionalField(PacketField("snc_frame", None, SAPSNCFrame),
                         lambda pkt: pkt.compress in [2, 3]),

        # Message info
        ConditionalField(StrEncodedPaddedField("info", None),
                         lambda pkt: pkt.err_flag != 0),

        # Payload
        PacketListField("message", None, SAPDiagItem)
    ]

    def do_compress(self, s):
        """Compress a string using SAP compression C++ extension.

        @param s: string to compress
        @type s: C{string}

        @return: string compression header plus the compressed string
        @rtype: C{string}

        @raise pysapcompress.Error: when a compression error is raised
        """
        if (len(s) > 0):
            # Compress the payload and return the output
            (_, _, outbuffer) = pysapcompress.compress(s,
                                                       pysapcompress.ALG_LZH)
            return outbuffer

    def do_decompress(self, s, length):
        """Decompress a string using SAP compression C++ extension.

        @param s: compression header plus compressed string
        @type s: C{string}

        @param length: reported compressed length
        @type length: C{int}

        @return: decompressed string
        @rtype: C{string}

        @raise pysapcompress.Error: when a decompression error is raised
        """
        if (len(s) > 0):
            # Decompress the payload and return the output
            (_, _, outbuffer) = pysapcompress.decompress(s, length)
            return outbuffer

    def pre_dissect(self, s):
        """Prepares the packet for dissection. If the compression flag is set,
        decompress the payload.
        """
        # If the compression flag is set, decompress everything after the headers
        if s[7] == "\x01":
            # First need to get the reported decompressed length
            (reported_length, ) = unpack("<I", s[8:12])

            # Then return the headers (Diag and Compression) and the payload (message field)
            try:
                return s[:16] + self.do_decompress(s[8:], reported_length)
            except DecompressError:
                return s
        # Uncompressed packet, just return them
        return s

    def post_build(self, p, pay):
        """Compress the payload. If the compression flag is set, compress both
        the message field and the payload.
        """
        if pay is None:
            pay = ''
        if self.compress == 1:
            payload = "".join([str(item) for item in self.message]) + pay
            if (len(payload) > 0):
                try:
                    return p[:8] + self.do_compress(payload)
                except CompressError:
                    return p + pay
        return p + pay

    def get_item(self, item_type=None, item_id=None, item_sid=None):
        """Get an item from the packet's message. Returns None if the message
        is not found, or a list if the item is found multiple times.

        @param item_type: item type byte or string value
        @type item_type: C{int} or C{string} or C{list}

        @param item_id: item ID byte or string value
        @type item_id: C{int} or C{string} or C{list}

        @param item_sid: item SID byte or string value
        @type item_sid: C{int} or C{string} or C{list}

        @return: list of items found on the packet or None
        @rtype: C{list} of L{SAPDiagItem}
        """
        # Expand list lookups
        items = []
        if item_type is not None and type(item_type) == list:
            for itype in item_type:
                items.extend(self.get_item(itype, item_id, item_sid))
            return items
        if item_id is not None and type(item_id) == list:
            for iid in item_id:
                items.extend(self.get_item(item_type, iid, item_sid))
            return items
        if item_sid is not None and type(item_sid) == list:
            for isid in item_sid:
                items.extend(self.get_item(item_type, item_id, isid))
            return items

        # Perform name lookups
        if item_type is not None and isinstance(item_type, str):
            item_type = list(diag_item_types.keys())[list(
                diag_item_types.values()).index(item_type)]
        if item_id is not None and isinstance(item_id, str):
            item_id = list(diag_appl_ids.keys())[list(
                diag_appl_ids.values()).index(item_id)]
        if item_sid is not None and isinstance(item_sid, str):
            item_sid = list(diag_appl_sids[item_id].keys())[list(
                diag_appl_sids[item_id].values()).index(item_sid)]

        # Filter and return items
        if item_sid is None and item_id is None:
            items = [
                item for item in self.message
                if hasattr(item, "item_type") and item.item_type == item_type
            ]
        elif item_sid is None:
            items = [
                item for item in self.message if hasattr(item, "item_type")
                and item.item_type == item_type and item.item_id == item_id
            ]
        else:
            items = [
                item for item in self.message
                if hasattr(item, "item_type") and item.item_type == item_type
                and item.item_id == item_id and item.item_sid == item_sid
            ]

        return items
예제 #10
0
class SAPEnqueue(PacketNoPadded):
    """SAP Enqueue Server packet

    This packet is used for general Enqueue packets.
    """

    name = "SAP Enqueue"
    fields_desc = [
        StrFixedLenField("magic_bytes", "\xab\xcd\xe1\x23", 4),
        IntField("id", 0),
        LenField("len", None, fmt="!I"),
        LenField("len_frag", None, fmt="!I"),
        ByteEnumKeysField("dest", 0x00, enqueue_dest_values),
        ByteEnumKeysField("opcode", 0x00, enqueue_conn_admin_opcode_values),
        ByteField("more_frags", 0),
        ByteEnumKeysField("type", 0x00, enqueue_type_values),

        # Server Admin fields
        ConditionalField(StrNullFixedLenField("adm_eyecatcher1", "ENC", 3),
                         lambda pkt: pkt.dest == 3),
        ConditionalField(ByteField("adm_version", 1),
                         lambda pkt: pkt.dest == 3),
        ConditionalField(ByteField("adm_padd1", 0), lambda pkt: pkt.dest == 3),
        ConditionalField(ByteField("adm_padd2", 0), lambda pkt: pkt.dest == 3),
        ConditionalField(ByteField("adm_padd3", 0), lambda pkt: pkt.dest == 3),
        ConditionalField(StrFixedLenField("adm_eyecatcher2", "#EAA", 4),
                         lambda pkt: pkt.dest == 3),
        ConditionalField(ByteField("adm_1", 1), lambda pkt: pkt.dest == 3),
        ConditionalField(IntField("adm_len", 0), lambda pkt: pkt.dest == 3),
        ConditionalField(
            ByteEnumKeysField("adm_opcode", 0,
                              enqueue_server_admin_opcode_values),
            lambda pkt: pkt.dest == 3),
        ConditionalField(ByteField("adm_flags", 0), lambda pkt: pkt.dest == 3),
        ConditionalField(IntField("adm_rc", 0), lambda pkt: pkt.dest == 3),
        ConditionalField(StrFixedLenField("adm_eyecatcher3", "#EAE", 4),
                         lambda pkt: pkt.dest == 3),

        # Server Admin Trace fields
        ConditionalField(
            ByteField("adm_trace_protocol_version", 1),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            ByteEnumKeysField("adm_trace_action", 3,
                              enqueue_server_admin_trace_action_values),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            ByteEnumKeysField("adm_trace_limit", 0,
                              enqueue_server_admin_trace_limit_values),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            ByteEnumKeysField("adm_trace_thread", 0,
                              enqueue_server_admin_trace_thread_values),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            IntField("adm_trace_unknown1", 0),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            IntField("adm_trace_level", 1),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            IntField("adm_trace_level1", 1),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            ByteField("adm_trace_logging", 0),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            IntField("adm_trace_max_file_size", 20 * 1024 * 1024),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            FieldLenField("adm_trace_nopatterns",
                          0,
                          count_of="adm_trace_patterns",
                          fmt="!I"),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            FieldLenField("adm_trace_nopatterns1",
                          0,
                          count_of="adm_trace_patterns",
                          fmt="!I"),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            IntField("adm_trace_unknown3", 37),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            StrFixedLenField("adm_trace_eyecatcher4", "#EAH", 4),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            PacketListField("adm_trace_patterns",
                            None,
                            SAPEnqueueTracePattern,
                            count_from=lambda pkt: pkt.adm_trace_nopatterns),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),
        ConditionalField(
            StrFixedLenField("adm_trace_eyecatcher5", "#EAD", 4),
            lambda pkt: pkt.dest == 3 and pkt.adm_opcode in [0x06]),

        # Connection Admin fields
        ConditionalField(
            FieldLenField("params_count", None, count_of="params", fmt="!I"),
            lambda pkt: pkt.dest == 6 and pkt.opcode in [1, 2]),
        ConditionalField(
            PacketListField("params",
                            None,
                            SAPEnqueueParam,
                            count_from=lambda pkt: pkt.params_count),
            lambda pkt: pkt.dest == 6 and pkt.opcode in [1, 2]),
    ]

    def post_build(self, pkt, pay):
        """Adjust the len and len_frags fields after the build of the whole
        packet. """
        l = struct.pack("!I", len(pkt) + len(pay))
        pkt = pkt[:8] + l + l + pkt[16:]
        return pkt + pay
예제 #11
0
파일: SAPMS.py 프로젝트: pyq881120/pysap
class SAPMS(Packet):
    """SAP Message Server packet

    This packet is used for the Message Server protocol.
    """
    name = "SAP Message Server"
    fields_desc = [
        StrFixedLenField("eyecatcher", "**MESSAGE**\x00", 12),
        ByteField("version", 0x04),
        ByteEnumKeysField("errorno", 0x00, ms_errorno_values),
        StrFixedLenField("toname", " " * 40, 40),
        FlagsField("msgtype", 0, 8, ["DIA", "UPD", "ENQ", "BTC", "SPO", "UP2", "ATP", "ICM"]),
        StrFixedLenField("reserved", "\x00" * 3, 3),
        StrFixedLenField("key", "\x00" * 8, 8),
        ByteEnumKeysField("flag", 0x01, ms_flag_values),
        ByteEnumKeysField("iflag", 0x01, ms_iflag_values),
        StrFixedLenField("fromname", " " * 40, 40),
        ShortField("padd", 0x0000),

        # OpCode fields
        ConditionalField(ByteEnumKeysField("opcode", 0x00, ms_opcode_values), lambda pkt:pkt.iflag in [0x00, 0x01]),
        ConditionalField(ByteEnumKeysField("opcode_error", 0x00, ms_opcode_error_values), lambda pkt:pkt.iflag in [0x00, 0x01]),
        ConditionalField(ByteField("opcode_version", 0x01), lambda pkt:pkt.iflag in [0x00, 0x01]),
        ConditionalField(ByteField("opcode_charset", 0x03), lambda pkt:pkt.iflag in [0x00, 0x01]),
        ConditionalField(StrField("opcode_value", ""), lambda pkt:pkt.iflag in [0x00, 0x01] and pkt.opcode not in [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x11, 0x1c, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2f, 0x43, 0x44, 0x45, 0x46, 0x47, 0x4a]),

        # Adm OpCode fields
        ConditionalField(StrFixedLenField("adm_eyecatcher", "AD-EYECATCH\x00", 12), lambda pkt:pkt.iflag == 0x05),
        ConditionalField(ByteField("adm_version", 0x01), lambda pkt:pkt.iflag == 0x05),
        ConditionalField(ByteEnumKeysField("adm_type", 0x01, ms_adm_type_values), lambda pkt:pkt.iflag == 0x05),
        ConditionalField(IntToStrField("adm_recsize", 104, 11), lambda pkt:pkt.iflag == 0x05),
        ConditionalField(IntToStrField("adm_recno", 1, 11), lambda pkt:pkt.iflag == 0x05),
        ConditionalField(PacketListField("adm_records", None, SAPMSAdmRecord), lambda pkt:pkt.iflag == 0x05),

        # Server List fields
        ConditionalField(PacketListField("clients", None, SAPMSClient1), lambda pkt:pkt.opcode in [0x02, 0x03, 0x04, 0x05] and pkt.opcode_version == 0x01),
        ConditionalField(PacketListField("clients", None, SAPMSClient2), lambda pkt:pkt.opcode in [0x02, 0x03, 0x04, 0x05] and pkt.opcode_version == 0x02),
        ConditionalField(PacketListField("clients", None, SAPMSClient3), lambda pkt:pkt.opcode in [0x02, 0x03, 0x04, 0x05] and pkt.opcode_version == 0x03),
        ConditionalField(PacketListField("clients", None, SAPMSClient4), lambda pkt:pkt.opcode in [0x02, 0x03, 0x04, 0x05] and pkt.opcode_version == 0x04),

        # Change IP fields
        ConditionalField(IPField("change_ip_addressv4", "0.0.0.0"), lambda pkt:pkt.opcode == 0x06),
        ConditionalField(IP6Field("change_ip_addressv6", "::"), lambda pkt:pkt.opcode == 0x06 and pkt.opcode_version == 0x02),

        # Get/Set Text fields
        ConditionalField(StrFixedLenField("text_name", "", 40), lambda pkt:pkt.opcode in [0x22, 0x23]),
        ConditionalField(FieldLenField("text_length", None, length_of="text_value", fmt="!I"), lambda pkt:pkt.opcode in [0x22, 0x23]),
        ConditionalField(StrFixedLenField("text_value", "", length_from=lambda pkt:pkt.text_length or 80), lambda pkt:pkt.opcode in [0x22, 0x23]),

        # Counter fields
        ConditionalField(PacketField("counter", None, SAPMSCounter), lambda pkt:pkt.opcode in [0x24, 0x25, 0x26, 0x27, 0x28, 0x29]),
        ConditionalField(PacketListField("counters", None, SAPMSCounter), lambda pkt:pkt.opcode in [0x2a]),

        # Security Key 1 fields
        ConditionalField(StrFixedLenField("security_name", None, 40), lambda pkt:pkt.opcode in [0x07, 0x08]),
        ConditionalField(StrFixedLenField("security_key", None, 256), lambda pkt:pkt.opcode in [0x07, 0x08]),

        # Security Key 2 fields
        ConditionalField(IPField("security2_addressv4", "0.0.0.0"), lambda pkt:pkt.opcode == 0x09),
        ConditionalField(ShortField("security2_port", 0), lambda pkt:pkt.opcode == 0x09),
        ConditionalField(StrFixedLenField("security2_key", None, 256), lambda pkt:pkt.opcode == 0x09),
        ConditionalField(IP6Field("security2_addressv6", "::"), lambda pkt:pkt.opcode == 0x09),

        # Hardware ID field
        ConditionalField(StrNullFixedLenField("hwid", "", length=99), lambda pkt:pkt.opcode == 0x0a),

        # Statistics
        ConditionalField(PacketField("stats", None, SAPMSStat3), lambda pkt:pkt.opcode == 0x11 and pkt.flag == 0x03),

        # Codepage
        ConditionalField(IntField("codepage", 0), lambda pkt:pkt.opcode == 0x1c and pkt.flag == 0x03),

        # Dump Info Request fields
        ConditionalField(ByteField("dump_dest", 0x02), lambda pkt:pkt.opcode == 0x1E and pkt.flag == 0x02),
        ConditionalField(StrFixedLenField("dump_filler", "\x00\x00\x00", 3), lambda pkt:pkt.opcode == 0x1E and pkt.flag == 0x02),
        ConditionalField(ShortField("dump_index", 0x00), lambda pkt:pkt.opcode == 0x1E and pkt.flag == 0x02),
        ConditionalField(ShortEnumKeysField("dump_command", 0x01, ms_dump_command_values), lambda pkt:pkt.opcode == 0x1E and pkt.flag == 0x02),
        ConditionalField(StrFixedLenField("dump_name", "\x00" * 40, 40), lambda pkt:pkt.opcode == 0x1E and pkt.flag == 0x02),

        # File Reload fields
        ConditionalField(ByteEnumKeysField("file_reload", 0, ms_file_reload_values), lambda pkt:pkt.opcode == 0x1f),
        ConditionalField(StrFixedLenField("file_filler", "\x00\x00\x00", 3), lambda pkt:pkt.opcode == 0x1f),

        # Get/Set/Del Logon fields
        ConditionalField(PacketField("logon", None, SAPMSLogon), lambda pkt:pkt.opcode in [0x2b, 0x2c, 0x2d]),

        # Server Disconnect/Shutdown fields
        ConditionalField(PacketField("shutdown_client", None, SAPMSClient3), lambda pkt:pkt.opcode in [0x2e, 0x2f, 0x30, 0x4a]),
        ConditionalField(FieldLenField("shutdown_reason_length", None, length_of="shutdown_reason", fmt="!H"), lambda pkt:pkt.opcode in [0x2e, 0x2f, 0x30, 0x4a]),
        ConditionalField(StrLenField("shutdown_reason", "", length_from=lambda pkt:pkt.shutdown_reason_length), lambda pkt:pkt.opcode in [0x2e, 0x2f, 0x30, 0x4a]),

        # Get/Set Property fields
        ConditionalField(PacketField("property", None, SAPMSProperty), lambda pkt:pkt.opcode in [0x43, 0x44, 0x45]),

        # IP/Port to name fields
        ConditionalField(IPField("ip_to_name_address4", "0.0.0.0"), lambda pkt:pkt.opcode == 0x46 and pkt.opcode_version == 0x01),
        ConditionalField(IP6Field("ip_to_name_address6", "::"), lambda pkt:pkt.opcode == 0x46 and pkt.opcode_version == 0x02),
        ConditionalField(ShortField("ip_to_name_port", 0), lambda pkt:pkt.opcode == 0x46),
        ConditionalField(FieldLenField("ip_to_name_length", None, length_of="ip_to_name", fmt="!I"), lambda pkt:pkt.opcode == 0x46),
        ConditionalField(StrLenField("ip_to_name", "", length_from=lambda pkt:pkt.logonname_length), lambda pkt:pkt.opcode == 0x46),

        # Check ACL fields
        ConditionalField(ShortField("error_code", 0), lambda pkt:pkt.opcode == 0x47),
        ConditionalField(StrFixedLenField("acl", "", 46), lambda pkt:pkt.opcode == 0x47),
    ]