Example #1
0
class UDS_RDBI(Packet):
    dataIdentifiers = ObservableDict()
    name = 'ReadDataByIdentifier'
    fields_desc = [
        FieldListField("identifiers", [],
                       XShortEnumField('dataIdentifier', 0, dataIdentifiers))
    ]
Example #2
0
class GENEVE(Packet):
    name = "GENEVE"
    fields_desc = [
        BitField("version", 0, 2),
        BitField("optionlen", None, 6),
        BitField("oam", 0, 1),
        BitField("critical", 0, 1),
        BitField("reserved", 0, 6),
        XShortEnumField("proto", 0x0000, ETHER_TYPES),
        X3BytesField("vni", 0),
        XByteField("reserved2", 0x00),
        PacketListField("options", [],
                        GeneveOptions,
                        length_from=lambda pkt: pkt.optionlen * 4)
    ]

    def post_build(self, p, pay):
        if self.optionlen is None:
            tmp_len = (len(p) - 8) // 4
            p = chb(tmp_len & 0x2f | orb(p[0]) & 0xc0) + p[1:]
        return p + pay

    def answers(self, other):
        if isinstance(other, GENEVE):
            if ((self.proto == other.proto) and (self.vni == other.vni)):
                return self.payload.answers(other.payload)
        else:
            return self.payload.answers(other)
        return 0

    def mysummary(self):
        return self.sprintf("GENEVE (vni=%GENEVE.vni%,"
                            "optionlen=%GENEVE.optionlen%,"
                            "proto=%GENEVE.proto%)")
Example #3
0
class CDPMsgCapabilities(CDPMsgGeneric):
    name = "Capabilities"
    fields_desc = [
        XShortEnumField("type", 0x0004, _cdp_tlv_types),
        ShortField("len", 8),
        FlagsField("cap", 0, 32, _cdp_capabilities)
    ]
Example #4
0
class DoIPRawPacket(Packet):
    """
    This class models the a raw/generic Diagnositics over IP (DoIP) packet.
    The protocol version (inverse protocol version) are fixed to 0x02.
    The fields 'payload_type', 'payload_length' and 'payload_content'
    should be set according to the actual payload.

    Example of a generic acknowledge:
    >>> from scapy.contrib.doip import *
    >>> DoIP(payload_type=0x0000, payload_length=1, payload_content=b'\x02')
    <DoIP  payload_type=generic DoIP header negative acknowledge payload_length=1 payload_content='\x02' |>
    """
    name = "DoIPRaw"
    # field names are abbreviated to facilitate pretty printing etc.
    fields_desc = [
        XByteField("protocol_version", 0x02),
        XByteField("inverse_version", 0xFD),
        XShortEnumField("payload_type", 0, payload_types),
        IntField("payload_length", 0),
        StrLenField("payload_content",
                    "",
                    length_from=lambda pkt: pkt.payload_length)
    ]

    def dissect(self, b):
        """
        Dissect an incoming DoIP packet.

        :param b: bytes to dissect
        :type b: bytes
        :raises: ValueError
        """
        if len(b) < 8:
            raise ValueError("given packet too short")
        return super(DoIPRawPacket, self).dissect(b)
class Dot1Q(Packet):
    name = "802.1Q"
    aliastypes = [Ether]
    fields_desc = [BitField("prio", 0, 3),
                   BitField("id", 0, 1),
                   BitField("vlan", 1, 12),
                   XShortEnumField("type", 0x0000, ETHER_TYPES)]

    def answers(self, other):
        if isinstance(other, Dot1Q):
            if ((self.type == other.type) and
                    (self.vlan == other.vlan)):
                return self.payload.answers(other.payload)
        else:
            return self.payload.answers(other)
        return 0

    def default_payload_class(self, pay):
        if self.type <= 1500:
            return LLC
        return conf.raw_layer

    def extract_padding(self, s):
        if self.type <= 1500:
            return s[:self.type], s[self.type:]
        return s, None

    def mysummary(self):
        if isinstance(self.underlayer, Ether):
            return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%")  # noqa: E501
        else:
            return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%")
Example #6
0
class CDPMsgDuplex(CDPMsgGeneric):
    name = "Duplex"
    fields_desc = [
        XShortEnumField("type", 0x000b, _cdp_tlv_types),
        ShortField("len", 5),
        ByteEnumField("duplex", 0x00, _cdp_duplex)
    ]
Example #7
0
class CDPMsgPortID(CDPMsgGeneric):
    name = "Port ID"
    fields_desc = [
        XShortEnumField("type", 0x0003, _cdp_tlv_types),
        FieldLenField("len", None, "iface", "!H", adjust=lambda pkt, x: x + 4),
        StrLenField("iface", "Port 1", length_from=lambda x: x.len - 4)
    ]  # noqa: E501
Example #8
0
class ModbusPDU08DiagnosticsResponse(_ModbusPDUNoPayload):
    name = "Diagnostics Response"
    fields_desc = [
        XByteField("funcCode", 0x08),
        XShortEnumField("subFunc", 0x0000, _diagnostics_sub_function),
        FieldListField("data", [0x0000], XShortField("", 0x0000))
    ]
Example #9
0
class CDPMsgNativeVLAN(CDPMsgGeneric):
    name = "Native VLAN"
    fields_desc = [
        XShortEnumField("type", 0x000a, _cdp_tlv_types),
        ShortField("len", 6),
        ShortField("vlan", 1)
    ]
Example #10
0
class GENEVE(Packet):
    name = "GENEVE"
    fields_desc = [
        BitField("version", 0, 2),
        BitField("optionlen", None, 6),
        BitField("oam", 0, 1),
        BitField("critical", 0, 1),
        BitField("reserved", 0, 6),
        XShortEnumField("proto", 0x0000, ETHER_TYPES),
        X3BytesField("vni", 0),
        XByteField("reserved2", 0x00),
        GENEVEOptionsField("options", "")
    ]

    def post_build(self, p, pay):
        p += pay
        optionlen = self.optionlen
        if optionlen is None:
            optionlen = (len(self.options) + 3) // 4
            p = chb(optionlen & 0x2f | orb(p[0]) & 0xc0) + p[1:]
        return p

    def answers(self, other):
        if isinstance(other, GENEVE):
            if ((self.proto == other.proto) and (self.vni == other.vni)):
                return self.payload.answers(other.payload)
        else:
            return self.payload.answers(other)
        return 0

    def mysummary(self):
        return self.sprintf("GENEVE (vni=%GENEVE.vni%,"
                            "optionlen=%GENEVE.optionlen%,"
                            "proto=%GENEVE.proto%)")
Example #11
0
class CDPMsg(CDPMsgGeneric):
    name = "CDP "
    fields_desc = [XShortEnumField("type", None, _cdp_tlv_types),
                   FieldLenField("len", None, "val", fmt="!H",
                                 adjust=lambda pkt, x: x + 4),
                   StrLenField("val", "", length_from=lambda x:x.len - 4,
                               max_length=65531)]
Example #12
0
class UDS_WDBI(Packet):
    name = 'WriteDataByIdentifier'
    fields_desc = [
        XShortEnumField('dataIdentifier', 0,
                        UDS_RDBI.dataIdentifiers),
        StrField('dataRecord', 0, fmt="B")
    ]
class GRE_PPTP(GRE):

    """
    Enhanced GRE header used with PPTP
    RFC 2637
    """

    name = "GRE PPTP"
    deprecated_fields = {
        "seqence_number": ("sequence_number", "2.4.4"),
    }
    fields_desc = [BitField("chksum_present", 0, 1),
                   BitField("routing_present", 0, 1),
                   BitField("key_present", 1, 1),
                   BitField("seqnum_present", 0, 1),
                   BitField("strict_route_source", 0, 1),
                   BitField("recursion_control", 0, 3),
                   BitField("acknum_present", 0, 1),
                   BitField("flags", 0, 4),
                   BitField("version", 1, 3),
                   XShortEnumField("proto", 0x880b, ETHER_TYPES),
                   ShortField("payload_len", None),
                   ShortField("call_id", None),
                   ConditionalField(XIntField("sequence_number", None), lambda pkt: pkt.seqnum_present == 1),  # noqa: E501
                   ConditionalField(XIntField("ack_number", None), lambda pkt: pkt.acknum_present == 1)]  # noqa: E501

    def post_build(self, p, pay):
        p += pay
        if self.payload_len is None:
            pay_len = len(pay)
            p = p[:4] + chb((pay_len >> 8) & 0xff) + chb(pay_len & 0xff) + p[6:]  # noqa: E501
        return p
Example #14
0
class CDPMsgIPPrefix(CDPMsgGeneric):
    name = "IP Prefix"
    type = 0x0007
    fields_desc = [XShortEnumField("type", 0x0007, _cdp_tlv_types),
                   ShortField("len", 9),
                   IPField("prefix", "192.168.0.1"),
                   ByteField("plen", 24)]
Example #15
0
class IODWriteMultipleReq(Block):
    """IODWriteMultiple request"""
    fields_desc = [
        BlockHeader,
        ShortField("seqNum", 0),
        UUIDField("ARUUID", None),
        XIntField("API", 0xffffffff),
        XShortField("slotNumber", 0xffff),
        XShortField("subslotNumber", 0xffff),
        StrFixedLenField("padding", "", length=2),
        XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX),
        FieldLenField("recordDataLength", None, fmt="I", length_of="blocks"),
        StrFixedLenField("RWPadding", "", length=24),
        FieldListField("blocks", [],
                       PadFieldWithLen(PacketField("", None, IODWriteReq), 4),
                       length_from=lambda pkt: pkt.recordDataLength)
    ]
    # default values
    block_type = 0x0008
    index = 0xe040
    API = 0xffffffff
    slotNumber = 0xffff
    subslotNumber = 0xffff

    def post_build(self, p, pay):
        # patch the update of block_length, as requests field must not be
        # included. block_length is always 60
        if self.block_length is None:
            p = p[:2] + struct.pack("!H", 60) + p[4:]

        # Remove the final padding added in requests
        fld, val = self.getfield_and_val("blocks")
        if fld.i2count(self, val) > 0:
            length = len(val[-1])
            pad = fld.field.padlen(length)
            if pad > 0:
                p = p[:-pad]
                # also reduce the recordDataLength accordingly
                if self.recordDataLength is None:
                    val = struct.unpack("!I", p[36:40])[0]
                    val -= pad
                    p = p[:36] + struct.pack("!I", val) + p[40:]

        return Packet.post_build(self, p, pay)

    def get_response(self):
        """Generate the response block of this request.
        Careful: it only sets the fields which can be set from the request
        """
        res = IODWriteMultipleRes()
        for field in ["seqNum", "ARUUID", "API", "slotNumber",
                      "subslotNumber", "index"]:
            res.setfieldval(field, self.getfieldval(field))

        # append all block response
        res_blocks = []
        for block in self.getfieldval("blocks"):
            res_blocks.append(block.get_response())
        res.setfieldval("blocks", res_blocks)
        return res
Example #16
0
class IODWriteMultipleRes(Block):
    """IODWriteMultiple response"""
    fields_desc = [
        BlockHeader,
        ShortField("seqNum", 0),
        UUIDField("ARUUID", None),
        XIntField("API", 0xffffffff),
        XShortField("slotNumber", 0xffff),
        XShortField("subslotNumber", 0xffff),
        StrFixedLenField("padding", "", length=2),
        XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX),
        FieldLenField("recordDataLength", None, fmt="I", length_of="blocks"),
        XShortField("additionalValue1", 0),
        XShortField("additionalValue2", 0),
        IntEnumField("status", 0, ["OK"]),
        StrFixedLenField("RWPadding", "", length=16),
        FieldListField("blocks", [], PacketField("", None, IODWriteRes),
                       length_from=lambda pkt: pkt.recordDataLength)
    ]
    # default values
    block_type = 0x8008
    index = 0xe040

    def post_build(self, p, pay):
        # patch the update of block_length, as requests field must not be
        # included. block_length is always 60
        if self.block_length is None:
            p = p[:2] + struct.pack("!H", 60) + p[4:]

        return Packet.post_build(self, p, pay)
Example #17
0
class MACsec(Packet):
    """representation of one MACsec frame"""
    name = '802.1AE'
    fields_desc = [
        BitField('Ver', 0, 1),
        BitField('ES', 0, 1),
        BitField('SC', 0, 1),
        BitField('SCB', 0, 1),
        BitField('E', 0, 1),
        BitField('C', 0, 1),
        BitField('an', 0, 2),
        BitField('reserved', 0, 2),
        BitField('shortlen', 0, 6),
        IntField("pn", 1),
        ConditionalField(PacketField("sci", None, MACsecSCI),
                         lambda pkt: pkt.SC),  # noqa: E501
        ConditionalField(XShortEnumField("type", None, ETHER_TYPES),
                         lambda pkt: pkt.type is not None)
    ]

    def mysummary(self):
        summary = self.sprintf("an=%MACsec.an%, pn=%MACsec.pn%")
        if self.SC:
            summary += self.sprintf(", sci=%MACsec.sci%")
        if self.type is not None:
            summary += self.sprintf(", %MACsec.type%")
        return summary
Example #18
0
class IODWriteReq(Block):
    """IODWrite request block"""
    fields_desc = [
        BlockHeader,
        ShortField("seqNum", 0),
        UUIDField("ARUUID", None),
        XIntField("API", 0),
        XShortField("slotNumber", 0),
        XShortField("subslotNumber", 0),
        StrFixedLenField("padding", "", length=2),
        XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX),
        LenField("recordDataLength", None, fmt="I"),
        StrFixedLenField("RWPadding", "", length=24),
    ]
    # default block_type value
    block_type = 0x0008

    def payload_length(self):
        return self.recordDataLength

    def get_response(self):
        """Generate the response block of this request.
        Careful: it only sets the fields which can be set from the request
        """
        res = IODWriteRes()
        for field in ["seqNum", "ARUUID", "API", "slotNumber",
                      "subslotNumber", "index"]:
            res.setfieldval(field, self.getfieldval(field))
        return res
class Ether(Packet):
    name = "Ethernet"
    fields_desc = [DestMACField("dst"),
                   SourceMACField("src"),
                   XShortEnumField("type", 0x9000, ETHER_TYPES)]
    __slots__ = ["_defrag_pos"]

    def hashret(self):
        return struct.pack("H", self.type) + self.payload.hashret()

    def answers(self, other):
        if isinstance(other, Ether):
            if self.type == other.type:
                return self.payload.answers(other.payload)
        return 0

    def mysummary(self):
        return self.sprintf("%src% > %dst% (%type%)")

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and len(_pkt) >= 14:
            if struct.unpack("!H", _pkt[12:14])[0] <= 1500:
                return Dot3
        return cls
class GRE(Packet):
    name = "GRE"
    deprecated_fields = {
        "seqence_number": ("sequence_number", "2.4.4"),
    }
    fields_desc = [BitField("chksum_present", 0, 1),
                   BitField("routing_present", 0, 1),
                   BitField("key_present", 0, 1),
                   BitField("seqnum_present", 0, 1),
                   BitField("strict_route_source", 0, 1),
                   BitField("recursion_control", 0, 3),
                   BitField("flags", 0, 5),
                   BitField("version", 0, 3),
                   XShortEnumField("proto", 0x0000, ETHER_TYPES),
                   ConditionalField(XShortField("chksum", None), lambda pkt:pkt.chksum_present == 1 or pkt.routing_present == 1),  # noqa: E501
                   ConditionalField(XShortField("offset", None), lambda pkt:pkt.chksum_present == 1 or pkt.routing_present == 1),  # noqa: E501
                   ConditionalField(XIntField("key", None), lambda pkt:pkt.key_present == 1),  # noqa: E501
                   ConditionalField(XIntField("sequence_number", None), lambda pkt:pkt.seqnum_present == 1),  # noqa: E501
                   ]

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and struct.unpack("!H", _pkt[2:4])[0] == 0x880b:
            return GRE_PPTP
        return cls

    def post_build(self, p, pay):
        p += pay
        if self.chksum_present and self.chksum is None:
            c = checksum(p)
            p = p[:4] + chb((c >> 8) & 0xff) + chb(c & 0xff) + p[6:]
        return p
Example #21
0
class ProfinetIO(Packet):
    """ Basic PROFINET IO dispatcher """
    fields_desc = [
        XShortEnumField("frameID", 0, (i2s_frameid, s2i_frameid))
    ]

    def guess_payload_class(self, payload):
        # For frameID in the RT_CLASS_* range, use the RTC packet as payload
        if self.frameID in [0xfefe, 0xfeff, 0xfefd]:
            from scapy.contrib.pnio_dcp import ProfinetDCP
            return ProfinetDCP
        elif self.frameID == 0xFE01:
            from scapy.contrib.pnio_rpc import Alarm_Low
            return Alarm_Low
        elif self.frameID == 0xFC01:
            from scapy.contrib.pnio_rpc import Alarm_High
            return Alarm_High
        elif (
                (0x0100 <= self.frameID < 0x1000) or
                (0x8000 <= self.frameID < 0xFC00)


        ):
            return PNIORealTimeCyclicPDU
        return super(ProfinetIO, self).guess_payload_class(payload)
Example #22
0
class CDPMsgUntrustedPortCoS(CDPMsgGeneric):
    name = "Untrusted Port CoS"
    fields_desc = [
        XShortEnumField("type", 0x0013, _cdp_tlv_types),
        ShortField("len", 5),
        XByteField("untrusted_port_cos", 0x0)
    ]
Example #23
0
class CDPMsgTrustBitmap(CDPMsgGeneric):
    name = "Trust Bitmap"
    fields_desc = [
        XShortEnumField("type", 0x0012, _cdp_tlv_types),
        ShortField("len", 5),
        XByteField("trust_bitmap", 0x0)
    ]
Example #24
0
class CDPMsgPower(CDPMsgGeneric):
    name = "Power"
    # Check if field length is fixed (2 bytes)
    fields_desc = [
        XShortEnumField("type", 0x0010, _cdp_tlv_types),
        ShortField("len", 6),
        _CDPPowerField("power", 1337)
    ]
Example #25
0
class CDPMsgMTU(CDPMsgGeneric):
    name = "MTU"
    # Check if field length is fixed (2 bytes)
    fields_desc = [
        XShortEnumField("type", 0x0011, _cdp_tlv_types),
        ShortField("len", 6),
        ShortField("mtu", 1500)
    ]
Example #26
0
class CDPMsgIPGateway(CDPMsgGeneric):
    name = "IP Gateway"
    type = 0x0007
    fields_desc = [
        XShortEnumField("type", 0x0007, _cdp_tlv_types),
        ShortField("len", 8),
        IPField("defaultgw", "192.168.0.1")
    ]
Example #27
0
class CDPMsgVoIPVLANReply(CDPMsgGeneric):
    name = "VoIP VLAN Reply"
    fields_desc = [
        XShortEnumField("type", 0x000e, _cdp_tlv_types),
        ShortField("len", 7),
        ByteField("status?", 1),
        ShortField("vlan", 1)
    ]
Example #28
0
class UDS_IOCBI(Packet):
    name = 'InputOutputControlByIdentifier'
    dataIdentifiers = ObservableDict()
    fields_desc = [
        XShortEnumField('dataIdentifier', 0, dataIdentifiers),
        ByteField('controlOptionRecord', 0),
        StrField('controlEnableMaskRecord', b"", fmt="B")
    ]
Example #29
0
class KWP_CDIPR(Packet):
    name = 'ClearDiagnosticInformationPositiveResponse'

    fields_desc = [XShortEnumField('groupOfDTC', 0, KWP_CDI.DTCGroups)]

    def answers(self, other):
        # type: (Packet) -> int
        return isinstance(other, KWP_CDI) and \
            self.groupOfDTC == other.groupOfDTC
Example #30
0
class AlarmCRBlockRes(Block):
    fields_desc = [
        BlockHeader,
        XShortEnumField("AlarmCRType", 1, ALARM_CR_TYPE),
        ShortField("LocalAlarmReference", 0),
        ShortField("MaxAlarmDataLength", 0)
    ]
    # default block_type value
    block_type = 0x8103