예제 #1
0
class DCPControlBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 5, DCP_OPTIONS),
        MultiEnumField("sub_option",
                       4,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        LenField("dcp_block_length", 3),
        ByteEnumField("response", 2, DCP_OPTIONS),
        MultiEnumField("response_sub_option",
                       2,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        ByteEnumField("block_error", 0, BLOCK_ERRORS),
        PadField(StrLenField("padding",
                             b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2),
                 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #2
0
class DCPFullIPBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 1, DCP_OPTIONS),
        MultiEnumField("sub_option",
                       3,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        LenField("dcp_block_length", None),
        ShortEnumField("block_info", 1, IP_BLOCK_INFOS),
        IPField("ip", "192.168.0.2"),
        IPField("netmask", "255.255.255.0"),
        IPField("gateway", "192.168.0.1"),
        FieldListField("dnsaddr", [],
                       IPField("", "0.0.0.0"),
                       count_from=lambda x: 4),
        PadField(StrLenField("padding",
                             b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2),
                 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #3
0
class DCPNameOfStationBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option",
                       2,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        FieldLenField("dcp_block_length",
                      None,
                      length_of="name_of_station",
                      adjust=lambda p, x: x + 2),
        # FieldLenField("dcp_block_length", None, length_of= "name_of_station", adjust=lambda p,x: x +2),

        # TODO it should take the len from name_of_station, but it takes the len of the rest of the packet
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        StrLenField(
            "name_of_station",
            "et200sp",
            length_from=lambda x: x.dcp_block_length - 2),  # this works
        PadField(StrLenField("padding",
                             b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2),
                 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #4
0
class DCPAliasNameBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option",
                       6,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        FieldLenField("dcp_block_length",
                      None,
                      length_of="alias_name",
                      adjust=lambda p, x: x + 2),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        StrLenField("alias_name",
                    "et200sp",
                    length_from=lambda x: x.dcp_block_length - 2),
        PadField(StrLenField("padding",
                             b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2),
                 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #5
0
class SAPHDBOptionPartRow(PacketNoPadded):
    """SAP HANA SQL Command Network Protocol Option Part Row

    This packet represents a row in an Option Part.

    Each row is comprised of a key, type and value.
    """
    part_kind = None
    option_keys = None
    name = "SAP HANA SQL Command Network Protocol Option Part Row"
    fields_desc = [
        MultiEnumField("key", 0, hdb_option_part_key_vals, depends_on=lambda x: x.part_kind, fmt="<b"),
        EnumField("type", 0, hdb_data_type_vals, fmt="<b"),
        ConditionalField(FieldLenField("length", None, length_of="value", fmt="<h"), lambda x: x.type in [29, 30, 33]),
        MultipleTypeField(
            [
                (LESignedByteField("value", 0), lambda x: x.type == 1),
                (LESignedShortField("value", 0), lambda x: x.type == 2),
                (LESignedIntField("value", 0), lambda x: x.type == 3),
                (LESignedLongField("value", 0), lambda x: x.type == 4),
                (Field("value", 0, fmt="<d"), lambda x: x.type == 7),
                (YesNoByteField("value", 0), lambda x: x.type == 28),
                (StrFixedLenField("value", None, length_from=lambda x: x.length), lambda x: x.type in [29, 30, 33]),
            ],
            StrField("value", ""),
        ),
    ]
예제 #6
0
class DeviceOption(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option", 5, DCP_SUBOPTIONS, fmt='B',
                       depends_on=lambda p: p.option),
    ]

    def extract_padding(self, s):
        return '', s
예제 #7
0
class IKEv2_payload_Transform(IKEv2_class):
    name = "IKE Transform"
    fields_desc = [
        ByteEnumField("next_payload", None, {0: "last", 3: "Transform"}),
        ByteField("res", 0),
        ShortField("length", 8),
        ByteEnumField("transform_type", None, IKEv2Transforms),
        ByteField("res2", 0),
        MultiEnumField("transform_id", None, IKEv2TransformNum, depends_on=lambda pkt: pkt.transform_type, fmt="H"),  # noqa: E501
        ConditionalField(IKEv2_Key_Length_Attribute("key_length"), lambda pkt: pkt.length > 8),  # noqa: E501
    ]
예제 #8
0
class DCPBaseBlock(Packet):
    """
        base class for all DCP Blocks
    """
    fields_desc = [
        ByteEnumField("option", 1, DCP_OPTIONS),
        MultiEnumField("sub_option", 2, DCP_SUBOPTIONS, fmt='B',
                       depends_on=lambda p: p.option),
        FieldLenField("dcp_block_length", None, length_of="data"),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        StrLenField("data", "", length_from=lambda x: x.dcp_block_length),
    ]

    def extract_padding(self, s):
        return '', s
예제 #9
0
class DCPMACBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 1, DCP_OPTIONS),
        MultiEnumField("sub_option", 1, DCP_SUBOPTIONS, fmt='B',
                       depends_on=lambda p: p.option),
        FieldLenField("dcp_block_length", None),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        MACField("mac", "00:00:00:00:00:00"),
        PadField(StrLenField("padding", b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2), 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #10
0
파일: radius.py 프로젝트: yvyshneva/scapy
class _RadiusAttrIntEnumVal(_SpecificRadiusAttr):
    """
    Implements a RADIUS attribute which value field is 4 bytes long integer.
    """

    __slots__ = ["val"]

    fields_desc = [
        ByteEnumField("type", 6, _radius_attribute_types),
        ByteField("len", 6),
        MultiEnumField("value",
                       0,
                       _radius_attrs_values,
                       depends_on=lambda p: p.type,
                       fmt="I")
    ]
예제 #11
0
class DCPDeviceInstanceBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option", 7, DCP_SUBOPTIONS, fmt='B',
                       depends_on=lambda p: p.option),
        LenField("dcp_block_length", 4),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        XByteField("device_instance_high", 0x00),
        XByteField("device_instance_low", 0x01),
        PadField(StrLenField("padding", b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2), 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #12
0
class DCPDeviceRoleBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option", 4, DCP_SUBOPTIONS, fmt='B',
                       depends_on=lambda p: p.option),
        LenField("dcp_block_length", 4),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        ByteEnumField("device_role_details", 1, DCP_DEVICE_ROLES),
        XByteField("reserved", 0x00),
        PadField(StrLenField("padding", b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2), 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #13
0
class DCPDeviceIDBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option", 3, DCP_SUBOPTIONS, fmt='B',
                       depends_on=lambda p: p.option),
        LenField("dcp_block_length", None),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        XShortField("vendor_id", 0x002a),
        XShortField("device_id", 0x0313),
        PadField(StrLenField("padding", b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2), 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #14
0
class DCPManufacturerSpecificBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option", 1, DCP_SUBOPTIONS, fmt='B',
                       depends_on=lambda p: p.option),
        FieldLenField("dcp_block_length", None),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        StrLenField("device_vendor_value", "et200sp",
                    length_from=lambda x: x.dcp_block_length - 2),
        PadField(StrLenField("padding", b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2), 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #15
0
class DCPDeviceInitiativeBlock(Packet):
    """
        device initiative DCP block
    """
    fields_desc = [
        ByteEnumField("option", 6, DCP_OPTIONS),
        MultiEnumField("sub_option",
                       1,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        FieldLenField("dcp_block_length", None, length_of="device_initiative"),
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        ShortField("device_initiative", 1),
    ]

    def extract_padding(self, s):
        return '', s
예제 #16
0
class DCPBaseBlock(Packet):
    """
        base class for all DCP Blocks
    """
    fields_desc = [
        ByteEnumField("option", 1, DCP_OPTIONS),
        MultiEnumField("sub_option",
                       2,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        FieldLenField("dcp_block_length", None, length_of="data"),  # TODO
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        StrLenField("data", "", length_from=lambda x: x.dcp_block_length),
    ]

    # needed for dissecting multiple blocks
    # https://stackoverflow.com/questions/8073508/scapy-adding-new-protocol-with-complex-field-groupings
    def extract_padding(self, s):
        return '', s
예제 #17
0
class DCPDeviceOptionsBlock(Packet):
    fields_desc = [
        ByteEnumField("option", 2, DCP_OPTIONS),
        MultiEnumField("sub_option",
                       5,
                       DCP_SUBOPTIONS,
                       fmt='B',
                       depends_on=lambda p: p.option),
        LenField("dcp_block_length", None),  # TODO
        ShortEnumField("block_info", 0, BLOCK_INFOS),
        PacketListField("device_options", [],
                        DeviceOption,
                        length_from=lambda p: p.dcp_block_length - 2),
        PadField(StrLenField("padding",
                             b"\x00",
                             length_from=lambda p: p.dcp_block_length % 2),
                 1,
                 padwith=b"\x00")
    ]

    def extract_padding(self, s):
        return '', s
예제 #18
0
class LLTD(Packet):
    name = "LLTD"
    answer_hashret = {
        # (tos, function) tuple mapping (answer -> query), used by
        # .hashret()
        (1, 1): (0, 0),
        (0, 12): (0, 11),
    }
    fields_desc = [
        ByteField("version", 1),
        ByteEnumField("tos", 0, {
            0: "Topology discovery",
            1: "Quick discovery",
            2: "QoS diagnostics",
        }),
        ByteField("reserved", 0),
        MultiEnumField("function",
                       0, {
                           0: {
                               0: "Discover",
                               1: "Hello",
                               2: "Emit",
                               3: "Train",
                               4: "Probe",
                               5: "Ack",
                               6: "Query",
                               7: "QueryResp",
                               8: "Reset",
                               9: "Charge",
                               10: "Flat",
                               11: "QueryLargeTlv",
                               12: "QueryLargeTlvResp",
                           },
                           1: {
                               0: "Discover",
                               1: "Hello",
                               8: "Reset",
                           },
                           2: {
                               0: "QosInitializeSink",
                               1: "QosReady",
                               2: "QosProbe",
                               3: "QosQuery",
                               4: "QosQueryResp",
                               5: "QosReset",
                               6: "QosError",
                               7: "QosAck",
                               8: "QosCounterSnapshot",
                               9: "QosCounterResult",
                               10: "QosCounterLease",
                           },
                       },
                       depends_on=lambda pkt: pkt.tos,
                       fmt="B"),
        MACField("real_dst", None),
        MACField("real_src", None),
        ConditionalField(ShortField("xid", 0),
                         lambda pkt: pkt.function in [0, 8]),
        ConditionalField(ShortField("seq", 0),
                         lambda pkt: pkt.function not in [0, 8]),
    ]

    def post_build(self, pkt, pay):
        if (self.real_dst is None or self.real_src is None) and \
           isinstance(self.underlayer, Ether):
            eth = self.underlayer
            if self.real_dst is None:
                pkt = (pkt[:4] + eth.fields_desc[0].i2m(eth, eth.dst) +
                       pkt[10:])
            if self.real_src is None:
                pkt = (pkt[:10] + eth.fields_desc[1].i2m(eth, eth.src) +
                       pkt[16:])
        return pkt + pay

    def mysummary(self):
        if isinstance(self.underlayer, Ether):
            return self.underlayer.sprintf(
                'LLTD %src% > %dst% %LLTD.tos% - %LLTD.function%')
        else:
            return self.sprintf('LLTD %tos% - %function%')

    def hashret(self):
        tos, function = self.tos, self.function
        return "%c%c" % self.answer_hashret.get((tos, function),
                                                (tos, function))

    def answers(self, other):
        if not isinstance(other, LLTD):
            return False
        if self.tos == 0:
            if self.function == 0 and isinstance(self.payload, LLTDDiscover) \
               and len(self[LLTDDiscover].stations_list) == 1:
                # "Topology discovery - Discover" with one MAC address
                # discovered answers a "Quick discovery - Hello"
                return other.tos == 1 and \
                    other.function == 1 and \
                    LLTDAttributeHostID in other and \
                    other[LLTDAttributeHostID].mac == \
                    self[LLTDDiscover].stations_list[0]
            elif self.function == 12:
                # "Topology discovery - QueryLargeTlvResp" answers
                # "Topology discovery - QueryLargeTlv" with same .seq
                # value
                return other.tos == 0 and other.function == 11 \
                    and other.seq == self.seq
        elif self.tos == 1:
            if self.function == 1 and isinstance(self.payload, LLTDHello):
                # "Quick discovery - Hello" answers a "Topology
                # discovery - Discover"
                return other.tos == 0 and other.function == 0 and \
                    other.real_src == self.current_mapper_address
        return False
예제 #19
0
class ProfinetDCP(Packet):
    """
    Profinet DCP Packet

    Requests are handled via ConditionalField because here only 1 Block is used
    every time.

    Response can contain 1..n Blocks, for that you have to use one ProfinetDCP
    Layer with one or multiple DCP*Block Layers::

        ProfinetDCP / DCPNameOfStationBlock / DCPDeviceIDBlock ...

    Example for a DCP Identify All Request::

        Ether(dst="01:0e:cf:00:00:00") /
        ProfinetIO(frameID=DCP_IDENTIFY_REQUEST_FRAME_ID) /
        ProfinetDCP(service_id=DCP_SERVICE_ID_IDENTIFY,
            service_type=DCP_REQUEST, option=255, sub_option=255,
            dcp_data_length=4)

    Example for a DCP Identify Response::

        Ether(dst=dst_mac) /
        ProfinetIO(frameID=DCP_IDENTIFY_RESPONSE_FRAME_ID) /
        ProfinetDCP(
            service_id=DCP_SERVICE_ID_IDENTIFY,
            service_type=DCP_RESPONSE) /
        DCPNameOfStationBlock(name_of_station="device1")

    Example for a DCP Set Request::

        Ether(dst=mac) /
        ProfinetIO(frameID=DCP_GET_SET_FRAME_ID) /
        ProfinetDCP(service_id=DCP_SERVICE_ID_SET, service_type=DCP_REQUEST,
            option=2, sub_option=2, dcp_data_length=14, dcp_block_length=10,
            name_of_station=name, reserved=0)

    """

    name = "Profinet DCP"
    # a DCP PDU consists of some fields and 1..n DCP Blocks
    fields_desc = [
        ByteEnumField("service_id", 5, DCP_SERVICE_ID),
        ByteEnumField("service_type", 0, DCP_SERVICE_TYPE),
        XIntField("xid", 0x01000001),
        # XShortField('reserved', 0),

        ShortField('reserved', 0),
        LenField("dcp_data_length", None),

        # DCP REQUEST specific
        ConditionalField(ByteEnumField("option", 2, DCP_OPTIONS),
                         lambda pkt: pkt.service_type == 0),
        ConditionalField(
            MultiEnumField("sub_option", 3, DCP_SUBOPTIONS, fmt='B',
                           depends_on=lambda p: p.option),
            lambda pkt: pkt.service_type == 0),

        # calculate the len fields - workaround
        ConditionalField(LenField("dcp_block_length", 0),
                         lambda pkt: pkt.service_type == 0),

        # DCP SET REQUEST #
        ConditionalField(ShortEnumField("block_qualifier", 1,
                                        BLOCK_QUALIFIERS),
                         lambda pkt: pkt.service_id == 4 and
                         pkt.service_type == 0),
        # Name Of Station
        ConditionalField(StrLenField("name_of_station_set_req", "et200sp",
                         length_from=lambda x: x.dcp_block_length - 2),
                         lambda pkt: pkt.service_id == 4 and
                         pkt.service_type == 0 and pkt.option == 2 and
                         pkt.sub_option == 2),

        # MAC
        ConditionalField(MACField("mac", "00:00:00:00:00:00"),
                         lambda pkt: pkt.service_id == 4 and
                         pkt.service_type == 0 and pkt.option == 1 and
                         pkt.sub_option == 1),
        # IP
        ConditionalField(IPField("ip", "192.168.0.2"),
                         lambda pkt: pkt.service_id == 4 and
                         pkt.service_type == 0 and pkt.option == 1 and
                         pkt.sub_option == 2),
        ConditionalField(IPField("netmask", "255.255.255.0"),
                         lambda pkt: pkt.service_id == 4 and
                         pkt.service_type == 0 and pkt.option == 1 and
                         pkt.sub_option == 2),
        ConditionalField(IPField("gateway", "192.168.0.1"),
                         lambda pkt: pkt.service_id == 4 and
                         pkt.service_type == 0 and pkt.option == 1 and
                         pkt.sub_option == 2),

        # DCP IDENTIFY REQUEST #
        # Name of station
        ConditionalField(StrLenField("name_of_station_identify_req", "et200sp",
                                     length_from=lambda x: x.dcp_block_length),
                         lambda pkt: pkt.service_id == 5 and
                         pkt.service_type == 0 and pkt.option == 2 and
                         pkt.sub_option == 2),

        # Alias name
        ConditionalField(StrLenField("alias_name", "et200sp",
                                     length_from=lambda x: x.dcp_block_length),
                         lambda pkt: pkt.service_id == 5 and
                         pkt.service_type == 0 and pkt.option == 2 and
                         pkt.sub_option == 6),

        # implement further REQUEST fields if needed ....

        # DCP RESPONSE BLOCKS #
        ConditionalField(
            PacketListField("dcp_blocks", [], guess_dcp_block_class,
                            length_from=lambda p: p.dcp_data_length),
            lambda pkt: pkt.service_type == 1),
    ]

    def post_build(self, pkt, pay):
        # add padding to ensure min packet length

        padding = MIN_PACKET_LENGTH - (len(pkt + pay))
        pay += b"\0" * padding

        return Packet.post_build(self, pkt, pay)