Ejemplo n.º 1
0
class PortIngressRuleClauseMatchLength06(Packet):
    """ Variable Descriptor: Port Ingress Rule Clause """
    name = "Variable Descriptor: Port Ingress Rule Clause"
    fields_desc = [
        XByteField("branch", 0xD7),
        XShortField("leaf", 0x0501),
        ByteField("length", 13),
        XByteField("clause", 2),
        XByteField("fieldcode", 0),
        XByteField("fieldinstance", 0),
        XByteField("msbmask", 0),
        XByteField("lsbmask", 0),
        XByteField("operator", 0),
        XByteField("matchlength", 6),
        XByteField("match0", 0x01),
        XByteField("match1", 0x80),
        XByteField("match2", 0xc2),
        XByteField("match3", 0x00),
        XByteField("match4", 0x00),
        XByteField("match5", 0x00),
    ]
Ejemplo n.º 2
0
class GMLAN_RMBAPR(Packet):
    name = 'ReadMemoryByAddressPositiveResponse'
    fields_desc = [
        MultipleTypeField([
            (XShortField('memoryAddress',
                         0), lambda pkt: GMLAN.determine_len(2)),
            (X3BytesField('memoryAddress',
                          0), lambda pkt: GMLAN.determine_len(3)),
            (XIntField('memoryAddress', 0), lambda pkt: GMLAN.determine_len(4))
        ], XIntField('memoryAddress', 0)),
        StrField('dataRecord', None, fmt="B")
    ]

    def answers(self, other):
        return other.__class__ == GMLAN_RMBA and \
            other.memoryAddress == self.memoryAddress

    @staticmethod
    def get_log(pkt):
        return pkt.sprintf("%GMLAN.service%"), \
            (pkt.sprintf("%GMLAN_RMBAPR.memoryAddress%"), pkt.dataRecord)
Ejemplo n.º 3
0
class OFPPacketQueue(Packet):
    name = "OFP_PACKET_QUEUE"
    fields_desc = [
        IntField("queue_id", 0),
        ShortField("len", None),
        XShortField("pad", 0),
        PacketListField("properties", [],
                        OFPQT,
                        length_from=lambda pkt: pkt.len - 8)
    ]

    def extract_padding(self, s):
        return b"", s

    def post_build(self, p, pay):
        if self.properties == []:
            p += raw(OFPQTNone())
        if self.len is None:
            tmp_len = len(p) + len(pay)
            p = p[:4] + struct.pack("!H", tmp_len) + p[6:]
        return p + pay
Ejemplo n.º 4
0
class EIGRPSeq(EIGRPGeneric):
    name = "EIGRP Sequence"
    fields_desc = [
        XShortField("type", 0x0003),
        ShortField("len", None),
        ByteField("addrlen", 4),
        ConditionalField(IPField("ipaddr", "192.168.0.1"),
                         lambda pkt: pkt.addrlen == 4),
        ConditionalField(IP6Field("ip6addr", "2001::"),
                         lambda pkt: pkt.addrlen == 16)
    ]

    def post_build(self, p, pay):
        p += pay

        if self.len is None:
            tmp_len = len(p)
            tmp_p = p[:2] + chb((tmp_len >> 8) & 0xff)
            p = tmp_p + chb(tmp_len & 0xff) + p[4:]

        return p
Ejemplo n.º 5
0
class PPTPStartControlConnectionReply(PPTP):
    name = "PPTP Start Control Connection Reply"
    fields_desc = [LenField("len", 156),
                   ShortEnumField("type", 1, _PPTP_msg_type),
                   XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
                   ShortEnumField("ctrl_msg_type", 2, _PPTP_ctrl_msg_type),
                   XShortField("reserved_0", 0x0000),
                   ShortField("protocol_version", 0x0100),
                   ByteEnumField("result_code", 1,
                                 _PPTP_start_control_connection_result),
                   ByteEnumField("error_code", 0, _PPTP_general_error_code),
                   FlagsField("framing_capabilities", 0, 32,
                              _PPTP_FRAMING_CAPABILITIES_FLAGS),
                   FlagsField("bearer_capabilities", 0, 32,
                              _PPTP_BEARER_CAPABILITIES_FLAGS),
                   ShortField("maximum_channels", 65535),
                   ShortField("firmware_revision", 256),
                   StrFixedLenField("host_name", "linux", 64),
                   StrFixedLenField("vendor_string", "", 64)]

    def answers(self, other):
        return isinstance(other, PPTPStartControlConnectionRequest)
Ejemplo n.º 6
0
class PPTP(Packet):
    name = "PPTP"
    fields_desc = [FieldLenField("len", None, fmt="H", length_of="data",
                                 adjust=lambda p, x: x + 12),
                   ShortEnumField("type", 1, _PPTP_msg_type),
                   XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
                   ShortEnumField("ctrl_msg_type", 1, _PPTP_ctrl_msg_type),
                   XShortField("reserved_0", 0x0000),
                   StrLenField("data", "", length_from=lambda p: p.len - 12)]

    registered_options = {}

    @classmethod
    def register_variant(cls):
        cls.registered_options[cls.ctrl_msg_type.default] = cls

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt:
            o = orb(_pkt[9])
            return cls.registered_options.get(o, cls)
        return cls
Ejemplo n.º 7
0
class GMLAN_SA(Packet):
    subfunctions = {
        0: 'ReservedByDocument',
        1: 'SPSrequestSeed',
        2: 'SPSsendKey',
        3: 'DevCtrlrequestSeed',
        4: 'DevCtrlsendKey',
        255: 'ReservedByDocument'}
    for i in range(0x05, 0x0a + 1):
        subfunctions[i] = 'ReservedByDocument'
    for i in range(0x0b, 0xfa + 1):
        subfunctions[i] = 'Reserved for vehicle manufacturer specific needs'
    for i in range(0xfb, 0xfe + 1):
        subfunctions[i] = 'Reserved for ECU or ' \
                          'system supplier manufacturing needs'

    name = 'SecurityAccess'
    fields_desc = [
        ByteEnumField('subfunction', 0, subfunctions),
        ConditionalField(XShortField('securityKey', B""),
                         lambda pkt: pkt.subfunction % 2 == 0)
    ]
Ejemplo n.º 8
0
class PPPoED(PPPoE):
    name = "PPP over Ethernet Discovery"

    code_list = {
        0x00: "PPP Session Stage",
        0x09: "PPPoE Active Discovery Initiation (PADI)",
        0x07: "PPPoE Active Discovery Offer (PADO)",
        0x0a: "PPPoE Active Discovery Session-Grant (PADG)",
        0x0b: "PPPoE Active Discovery Session-Credit Response (PADC)",
        0x0c: "PPPoE Active Discovery Quality (PADQ)",
        0x19: "PPPoE Active Discovery Request (PADR)",
        0x65: "PPPoE Active Discovery Session-confirmation (PADS)",
        0xa7: "PPPoE Active Discovery Terminate (PADT)"
    }

    fields_desc = [
        BitField("version", 1, 4),
        BitField("type", 1, 4),
        ByteEnumField("code", 0x09, code_list),
        XShortField("sessionid", 0x0),
        ShortField("len", None)
    ]
Ejemplo n.º 9
0
class RSVP(Packet):
    name = "RSVP"
    fields_desc = [
        BitField("Version", 1, 4),
        BitField("Flags", 1, 4),
        ByteEnumField("Class", 0x01, rsvpmsgtypes),
        XShortField("chksum", None),
        ByteField("TTL", 1),
        XByteField("dataofs", 0),
        ShortField("Length", None)
    ]

    def post_build(self, p, pay):
        p += pay
        if self.Length is None:
            tmp_len = len(p)
            tmp_p = p[:6] + chb((tmp_len >> 8) & 0xff) + chb(tmp_len & 0xff)
            p = tmp_p + p[8:]
        if self.chksum is None:
            ck = checksum(p)
            p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
        return p
Ejemplo n.º 10
0
class AOE(Packet):
    name = "ATA over Ethernet"
    fields_desc = [
        BitField("version", 1, 4),
        FlagsField("flags", 0, 4, ["Response", "Error", "r1", "r2"]),
        ByteEnumField(
            "error", 0, {
                1: "Unrecognized command code",
                2: "Bad argument parameter",
                3: "Device unavailable",
                4: "Config string present",
                5: "Unsupported exception",
                6: "Target is reserved"
            }),
        XShortField("major", 0xFFFF),
        XByteField("minor", 0xFF),
        ByteEnumField(
            "cmd", 1, {
                0: "Issue ATA Command",
                1: "Query Config Information",
                2: "Mac Mask List",
                3: "Reserve / Release"
            }),
        XIntField("tag", 0),
        ConditionalField(
            PacketField("i_ata_cmd", IssueATACommand(), IssueATACommand),
            lambda x: x.cmd == 0),
        ConditionalField(
            PacketField("q_conf_info", QueryConfigInformation(),
                        QueryConfigInformation), lambda x: x.cmd == 1),
        ConditionalField(PacketField("mac_m_list", MacMaskList(), MacMaskList),
                         lambda x: x.cmd == 2),
        ConditionalField(
            PacketField("res_rel", ReserveRelease(), ReserveRelease),
            lambda x: x.cmd == 3)
    ]

    def extract_padding(self, s):
        return "", s
Ejemplo n.º 11
0
class ExpectedSubmodule(Packet):
    """Description of a submodule in an API of an expected submodule"""
    name = "Submodule"
    fields_desc = [
        XShortField("SubslotNumber", 0),
        XIntField("SubmoduleIdentNumber", 0),
        # Submodule Properties
        XByteField("SubmoduleProperties_reserved_2", 0),
        BitField("SubmoduleProperties_reserved_1", 0, 2),
        BitField("SubmoduleProperties_DiscardIOXS", 0, 1),
        BitField("SubmoduleProperties_ReduceOutputSubmoduleDataLength", 0, 1),
        BitField("SubmoduleProperties_ReduceInputSubmoduleDataLength", 0, 1),
        BitField("SubmoduleProperties_SharedInput", 0, 1),
        BitEnumField("SubmoduleProperties_Type", 0, 2,
                     ["NO_IO", "INPUT", "OUTPUT", "INPUT_OUTPUT"]),
        PacketListField(
            "DataDescription", [], ExpectedSubmoduleDataDescription,
            count_from=lambda p: 2 if p.SubmoduleProperties_Type == 3 else 1
        ),
    ]

    def extract_padding(self, s):
        return None, s  # No extra payload
Ejemplo n.º 12
0
class OFPTFlowRemoved(_ofp_header):
    name = "OFPT_FLOW_REMOVED"
    fields_desc = [
        ByteEnumField("version", 0x01, ofp_version),
        ByteEnumField("type", 11, ofp_type),
        ShortField("len", None),
        IntField("xid", 0),
        PacketField("match", OFPMatch(), OFPMatch),
        LongField("cookie", 0),
        ShortField("priority", 0),
        ByteEnumField("reason", 0, {
            0: "OFPRR_IDLE_TIMEOUT",
            1: "OFPRR_HARD_TIMEOUT",
            2: "OFPRR_DELETE"
        }),
        XByteField("pad1", 0),
        IntField("duration_sec", 0),
        IntField("duration_nsec", 0),
        ShortField("idle_timeout", 0),
        XShortField("pad2", 0),
        LongField("packet_count", 0),
        LongField("byte_count", 0)
    ]
Ejemplo n.º 13
0
class PPTPOutgoingCallReply(PPTP):
    name = "PPTP Outgoing Call Reply"
    fields_desc = [
        LenField("len", 32),
        ShortEnumField("type", 1, _PPTP_msg_type),
        XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
        ShortEnumField("ctrl_msg_type", 8, _PPTP_ctrl_msg_type),
        XShortField("reserved_0", 0x0000),
        ShortField("call_id", 1),
        ShortField("peer_call_id", 1),
        ByteEnumField("result_code", 1, _PPTP_result_code),
        ByteEnumField("error_code", 0, _PPTP_general_error_code),
        ShortField("cause_code", 0),
        IntField("connect_speed", 100000000),
        ShortField("pkt_window_size", 16),
        ShortField("pkt_proc_delay", 0),
        IntField("channel_id", 0)
    ]

    def answers(self, other):
        return isinstance(
            other,
            PPTPOutgoingCallRequest) and other.call_id == self.peer_call_id
Ejemplo n.º 14
0
class VRRPv3(Packet):
    fields_desc = [
        BitField("version", 3, 4),
        BitField("type", 1, 4),
        ByteField("vrid", 1),
        ByteField("priority", 100),
        FieldLenField("ipcount", None, count_of="addrlist", fmt="B"),
        BitField("res", 0, 4),
        BitField("adv", 100, 12),
        XShortField("chksum", None),
        # FIXME: addrlist should also allow IPv6 addresses :/
        FieldListField("addrlist", [],
                       IPField("", "0.0.0.0"),
                       count_from=lambda pkt: pkt.ipcount)
    ]

    def post_build(self, p, pay):
        if self.chksum is None:
            if isinstance(self.underlayer, IP):
                ck = in4_chksum(112, self.underlayer, p)
            elif isinstance(self.underlayer, IPv6):
                ck = in6_chksum(112, self.underlayer, p)
            else:
                warning(
                    "No IP(v6) layer to compute checksum on VRRP. Leaving null"
                )  # noqa: E501
                ck = 0
            p = p[:6] + chb(ck >> 8) + chb(ck & 0xff) + p[8:]
        return p

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and len(_pkt) >= 16:
            ver_n_type = orb(_pkt[0])
            if ver_n_type < 48 or ver_n_type > 57:  # Version != 3
                return VRRP
        return VRRPv3
Ejemplo n.º 15
0
class APHECaps(IEEE1905_TLV):
    name = "AP VHT Capabilities TLV"
    fields_desc = [
        XByteField("type", 0x88),
        XShortField("len", None),
        MACField("radio_id", None),
        FieldLenField("he_mcs_len", None, fmt='B', count_of="he_mcs"),
        FieldListField("he_mcs",
                       None,
                       XByteField("byte", None),
                       count_from=lambda p: p.he_mcs_len),
        BitField("max_tx_streams", 0, 3),
        BitField("max_rx_streams", 0, 3),
        BitField("he_80mhz_plus_flag", 0, 1),
        BitField("he_160mhz_flag", 0, 1),
        BitField("su_beamformer_cap_flag", 0, 1),
        BitField("mu_beamformer_cap_flag", 0, 1),
        BitField("ul_mu_mmio_cap_flag", 0, 1),
        BitField("ul_mu_mmio_ofdma_cap_flag", 0, 1),
        BitField("dl_mu_mmio_ofdma_cap_flag", 0, 1),
        BitField("ul_ofdma_cap_flag", 0, 1),
        BitField("dl_ofdma_cap_flag", 0, 1),
        BitField("reserved", 0, 1)
    ]
Ejemplo n.º 16
0
class YOARP(Packet):
    name = "YOARP"
    fields_desc = [
        XShortField("hwtype", 0x0001),
        XShortEnumField("ptype", 0x9999, ETHER_TYPES),
        ByteField("hwlen", 6),
        ByteField("plen", 2),
        ShortEnumField("op", 1,
                       {"who-has": 1, "is-at": 2, "RARP-req": 3,
                        "RARP-rep": 4, "Dyn-RARP-req": 5,
                        "Dyn-RAR-rep": 6, "Dyn-RARP-err": 7,
                        "InARP-req": 8, "InARP-rep": 9}),
        ARPSourceMACField("hwsrc"),
        YOIPField("psrc", "0.0"),
        MACField("hwdst", ETHER_ANY),
        YOIPField("pdst", "0.0")
    ]
    who_has = 1
    is_at = 2

    def extract_padding(self, s):
        return "", s

    def answers(self, other):
        if isinstance(other, YOARP):
            if ((self.op == self.is_at) and
                    (other.op == self.who_has) and
                    (self.psrc == other.pdst)):
                return 1
        return 0

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and len(_pkt) >= 4 and _pkt[2:4] == "\x08\x00":
            return ARP
        return cls
Ejemplo n.º 17
0
class OSPFv3_Hdr(Packet):
    name = "OSPFv3 Header"
    fields_desc = [ByteField("version", 3),
                   ByteEnumField("type", 1, _OSPF_types),
                   ShortField("len", None),
                   IPField("src", "1.1.1.1"),
                   IPField("area", "0.0.0.0"),
                   XShortField("chksum", None),
                   ByteField("instance", 0),
                   ByteField("reserved", 0)]

    def post_build(self, p, pay):
        p += pay
        tmp_len = self.len

        if tmp_len is None:
            tmp_len = len(p)
            p = p[:2] + struct.pack("!H", tmp_len) + p[4:]

        if self.chksum is None:
            chksum = in6_chksum(89, self.underlayer, p)
            p = p[:12] + struct.pack("!H", chksum) + p[14:]

        return p
Ejemplo n.º 18
0
class PIMv2Hdr(Packet):
    name = "Protocol Independent Multicast Version 2 Header"
    fields_desc = [
        BitField("version", 2, 4),
        BitEnumField("type", 0, 4, PIM_TYPE),
        ByteField("reserved", 0),
        XShortField("chksum", None)
    ]

    def post_build(self, p, pay):
        """
        Called implicitly before a packet is sent to compute and
         place PIM checksum.

        Parameters:
          self    The instantiation of an PIMv2Hdr class
          p       The PIMv2Hdr message in hex in network byte order
          pay     Additional payload for the PIMv2Hdr message
        """
        p += pay
        if self.chksum is None:
            ck = checksum(p)
            p = p[:2] + struct.pack("!H", ck) + p[4:]
        return p
Ejemplo n.º 19
0
class CARP(Packet):
    name = "CARP"
    fields_desc = [BitField("version", 4, 4),
                   BitField("type", 4, 4),
                   ByteField("vhid", 1),
                   ByteField("advskew", 0),
                   ByteField("authlen", 0),
                   ByteField("demotion", 0),
                   ByteField("advbase", 0),
                   XShortField("chksum", 0),
                   XIntField("counter1", 0),
                   XIntField("counter2", 0),
                   XIntField("hmac1", 0),
                   XIntField("hmac2", 0),
                   XIntField("hmac3", 0),
                   XIntField("hmac4", 0),
                   XIntField("hmac5", 0)
                   ]

    def post_build(self, pkt, pay):
        if self.chksum == None:
            pkt = pkt[:6] + struct.pack("!H", checksum(pkt)) + pkt[8:]

        return pkt
Ejemplo n.º 20
0
class UDS_IOCBIPR(Packet):
    name = 'InputOutputControlByIdentifierPositiveResponse'
    fields_desc = [
        XShortField('dataIdentifier', 0),
        StrField('controlStatusRecord', 0, fmt="B")
    ]
Ejemplo n.º 21
0
class IrLMP(Packet):
    name = "IrDA Link Management Protocol"
    fields_desc = [XShortField("Service hints", 0),
                   XByteField("Character set", 0),
                   StrField("Device name", "")]
Ejemplo n.º 22
0
class UDS_RSDBI(Packet):
    name = 'ReadScalingDataByIdentifier'
    fields_desc = [XShortField('dataIdentifier', 0)]
Ejemplo n.º 23
0
class UDS_DDDIPR(Packet):
    name = 'DynamicallyDefineDataIdentifierPositiveResponse'
    fields_desc = [
        ByteField('definitionMode', 0),
        XShortField('dynamicallyDefinedDataIdentifier', 0)
    ]
Ejemplo n.º 24
0
class DoIP(Packet):
    payload_types = {
        0x0000: "Generic DoIP header NACK",
        0x0001: "Vehicle identification request",
        0x0002: "Vehicle identification request with EID",
        0x0003: "Vehicle identification request with VIN",
        0x0004:
        "Vehicle announcement message/vehicle identification response message",  # noqa: E501
        0x0005: "Routing activation request",
        0x0006: "Routing activation response",
        0x0007: "Alive check request",
        0x0008: "Alive check response",
        0x4001: "DoIP entity status request",
        0x4002: "DoIP entity status response",
        0x4003: "Diagnostic power mode information request",
        0x4004: "Diagnostic power mode information response",
        0x8001: "Diagnostic message",
        0x8002: "Diagnostic message ACK",
        0x8003: "Diagnostic message NACK"
    }
    name = 'DoIP'
    fields_desc = [
        XByteField("protocol_version", 0x02),
        XByteField("inverse_version", 0xFD),
        XShortEnumField("payload_type", 0, payload_types),
        IntField("payload_length", None),
        ConditionalField(
            ByteEnumField(
                "nack", 0, {
                    0: "Incorrect pattern format",
                    1: "Unknown payload type",
                    2: "Message too large",
                    3: "Out of memory",
                    4: "Invalid payload length"
                }), lambda p: p.payload_type in [0x0]),
        ConditionalField(StrFixedLenField("vin", b"", 17),
                         lambda p: p.payload_type in [3, 4]),
        ConditionalField(XShortField("logical_address", 0),
                         lambda p: p.payload_type in [4]),
        ConditionalField(StrFixedLenField("eid", b"", 6),
                         lambda p: p.payload_type in [2, 4]),
        ConditionalField(StrFixedLenField("gid", b"", 6),
                         lambda p: p.payload_type in [4]),
        ConditionalField(
            XByteEnumField(
                "further_action", 0, {
                    0x00:
                    "No further action required",
                    0x01:
                    "Reserved by ISO 13400",
                    0x02:
                    "Reserved by ISO 13400",
                    0x03:
                    "Reserved by ISO 13400",
                    0x04:
                    "Reserved by ISO 13400",
                    0x05:
                    "Reserved by ISO 13400",
                    0x06:
                    "Reserved by ISO 13400",
                    0x07:
                    "Reserved by ISO 13400",
                    0x08:
                    "Reserved by ISO 13400",
                    0x09:
                    "Reserved by ISO 13400",
                    0x0a:
                    "Reserved by ISO 13400",
                    0x0b:
                    "Reserved by ISO 13400",
                    0x0c:
                    "Reserved by ISO 13400",
                    0x0d:
                    "Reserved by ISO 13400",
                    0x0e:
                    "Reserved by ISO 13400",
                    0x0f:
                    "Reserved by ISO 13400",
                    0x10:
                    "Routing activation required to initiate central security",
                }), lambda p: p.payload_type in [4]),
        ConditionalField(
            XByteEnumField(
                "vin_gid_status", 0, {
                    0x00: "VIN and/or GID are synchronized",
                    0x01: "Reserved by ISO 13400",
                    0x02: "Reserved by ISO 13400",
                    0x03: "Reserved by ISO 13400",
                    0x04: "Reserved by ISO 13400",
                    0x05: "Reserved by ISO 13400",
                    0x06: "Reserved by ISO 13400",
                    0x07: "Reserved by ISO 13400",
                    0x08: "Reserved by ISO 13400",
                    0x09: "Reserved by ISO 13400",
                    0x0a: "Reserved by ISO 13400",
                    0x0b: "Reserved by ISO 13400",
                    0x0c: "Reserved by ISO 13400",
                    0x0d: "Reserved by ISO 13400",
                    0x0e: "Reserved by ISO 13400",
                    0x0f: "Reserved by ISO 13400",
                    0x10: "Incomplete: VIN and GID are NOT synchronized"
                }), lambda p: p.payload_type in [4]),
        ConditionalField(
            XShortField("source_address", 0), lambda p: p.payload_type in
            [5, 8, 0x8001, 0x8002, 0x8003]),  # noqa: E501
        ConditionalField(
            XByteEnumField("activation_type", 0, {
                0: "Default",
                1: "WWH-OBD",
                0xe0: "Central security"
            }), lambda p: p.payload_type in [5]),
        ConditionalField(XShortField("logical_address_tester", 0),
                         lambda p: p.payload_type in [6]),
        ConditionalField(XShortField("logical_address_doip_entity", 0),
                         lambda p: p.payload_type in [6]),
        ConditionalField(
            XByteEnumField(
                "routing_activation_response",
                0,
                {
                    0x00:
                    "Routing activation denied due to unknown source address.",
                    0x01:
                    "Routing activation denied because all concurrently supported TCP_DATA sockets are registered and active.",  # noqa: E501
                    0x02:
                    "Routing activation denied because an SA different from the table connection entry was received on the already activated TCP_DATA socket.",  # noqa: E501
                    0x03:
                    "Routing activation denied because the SA is already registered and active on a different TCP_DATA socket.",  # noqa: E501
                    0x04:
                    "Routing activation denied due to missing authentication.",
                    0x05:
                    "Routing activation denied due to rejected confirmation.",
                    0x06:
                    "Routing activation denied due to unsupported routing activation type.",  # noqa: E501
                    0x07: "Reserved by ISO 13400.",
                    0x08: "Reserved by ISO 13400.",
                    0x09: "Reserved by ISO 13400.",
                    0x0a: "Reserved by ISO 13400.",
                    0x0b: "Reserved by ISO 13400.",
                    0x0c: "Reserved by ISO 13400.",
                    0x0d: "Reserved by ISO 13400.",
                    0x0e: "Reserved by ISO 13400.",
                    0x0f: "Reserved by ISO 13400.",
                    0x10: "Routing successfully activated.",
                    0x11: "Routing will be activated; confirmation required."
                }),
            lambda p: p.payload_type in [6]),
        ConditionalField(XIntField("reserved_iso", 0),
                         lambda p: p.payload_type in [5, 6]),
        ConditionalField(XIntField("reserved_oem", 0),
                         lambda p: p.payload_type in [5, 6]),
        ConditionalField(
            XByteEnumField("diagnostic_power_mode", 0, {
                0: "not ready",
                1: "ready",
                2: "not supported"
            }), lambda p: p.payload_type in [0x4004]),
        ConditionalField(
            ByteEnumField("node_type", 0, {
                0: "DoIP gateway",
                1: "DoIP node"
            }), lambda p: p.payload_type in [0x4002]),
        ConditionalField(XByteField("max_open_sockets", 0),
                         lambda p: p.payload_type in [0x4002]),
        ConditionalField(XByteField("cur_open_sockets", 0),
                         lambda p: p.payload_type in [0x4002]),
        ConditionalField(IntField("max_data_size", 0),
                         lambda p: p.payload_type in [0x4002]),
        ConditionalField(XShortField("target_address", 0),
                         lambda p: p.payload_type in [0x8001, 0x8002, 0x8003
                                                      ]),  # noqa: E501
        ConditionalField(XByteEnumField("ack_code", 0, {0: "ACK"}),
                         lambda p: p.payload_type in [0x8002]),
        ConditionalField(
            ByteEnumField(
                "nack_code", 0, {
                    0x00: "Reserved by ISO 13400",
                    0x01: "Reserved by ISO 13400",
                    0x02: "Invalid source address",
                    0x03: "Unknown target address",
                    0x04: "Diagnostic message too large",
                    0x05: "Out of memory",
                    0x06: "Target unreachable",
                    0x07: "Unknown network",
                    0x08: "Transport protocol error"
                }), lambda p: p.payload_type in [0x8003]),
    ]

    def answers(self, other):
        # type: (Packet) -> int
        """DEV: true if self is an answer from other"""
        if other.__class__ == self.__class__:
            if self.payload_type == 0:
                return 1

            matches = [(4, 1), (4, 2), (4, 3), (6, 5), (8, 7),
                       (0x4002, 0x4001), (0x4004, 0x4003), (0x8001, 0x8001),
                       (0x8003, 0x8001)]
            if (self.payload_type, other.payload_type) in matches:
                if self.payload_type == 0x8001:
                    return self.payload.answers(other.payload)
                return 1
        return 0

    def hashret(self):
        # type: () -> bytes
        if self.payload_type in [0x8001, 0x8002, 0x8003]:
            return bytes(self)[:2] + struct.pack(
                "H", self.target_address ^ self.source_address)
        return bytes(self)[:2]

    def post_build(self, pkt, pay):
        # type: (bytes, bytes) -> bytes
        """
        This will set the Field 'payload_length' to the correct value.
        """
        if self.payload_length is None:
            pkt = pkt[:4] + struct.pack("!I", len(pay) + len(pkt) - 8) + \
                pkt[8:]
        return pkt + pay

    def extract_padding(self, s):
        # type: (bytes) -> Tuple[bytes, Optional[bytes]]
        if self.payload_type == 0x8001:
            return s[:self.payload_length - 4], None
        else:
            return b"", None
Ejemplo n.º 25
0
class LoWPAN_IPHC(Packet):
    """6LoWPAN IPv6 header compressed packets

    It follows the implementation of draft-ietf-6lowpan-hc-15.
    """
    # the LOWPAN_IPHC encoding utilizes 13 bits, 5 dispatch type
    name = "LoWPAN IP Header Compression Packet"
    _address_modes = ["Unspecified", "1", "16-bits inline", "Compressed"]
    _state_mode = ["Stateless", "Stateful"]
    fields_desc = [
        # dispatch
        BitField("_reserved", 0x03, 3),
        BitField("tf", 0x0, 2),
        BitEnumField("nh", 0x0, 1, ["Inline", "Compressed"]),
        BitField("hlim", 0x0, 2),
        BitEnumField("cid", 0x0, 1, [False, True]),
        BitEnumField("sac", 0x0, 1, _state_mode),
        BitEnumField("sam", 0x0, 2, _address_modes),
        BitEnumField("m", 0x0, 1, [False, True]),
        BitEnumField("dac", 0x0, 1, _state_mode),
        BitEnumField("dam", 0x0, 2, _address_modes),
        ConditionalField(ByteField("_contextIdentifierExtension", 0x0),
                         lambda pkt: pkt.cid == 0x1),
        # TODO: THIS IS WRONG!!!!!
        BitVarSizeField("tc_ecn",
                        0,
                        calculate_length=lambda pkt: tf_last_attempt(pkt)[0]
                        ),  # noqa: E501
        BitVarSizeField("tc_dscp",
                        0,
                        calculate_length=lambda pkt: tf_last_attempt(pkt)[1]
                        ),  # noqa: E501
        BitVarSizeField("_padd",
                        0,
                        calculate_length=lambda pkt: tf_last_attempt(pkt)[2]
                        ),  # noqa: E501
        BitVarSizeField("flowlabel",
                        0,
                        calculate_length=lambda pkt: tf_last_attempt(pkt)[3]
                        ),  # noqa: E501

        # NH
        ConditionalField(ByteField("_nhField", 0x0), lambda pkt: not pkt.nh),
        # HLIM: Hop Limit: if it's 0
        ConditionalField(ByteField("_hopLimit", 0x0),
                         lambda pkt: pkt.hlim == 0x0),
        IP6FieldLenField("sourceAddr", "::", 0, length_of=source_addr_mode2),
        IP6FieldLenField(
            "destinyAddr", "::", 0,
            length_of=destiny_addr_mode),  # problem when it's 0  # noqa: E501

        # LoWPAN_UDP Header Compression ########################################  # noqa: E501
        # TODO: IMPROVE!!!!!
        ConditionalField(
            FlagsField(
                "header_compression", 0, 8,
                ["A", "B", "C", "D", "E", "C", "PS", "PD"]),  # noqa: E501
            lambda pkt: pkt.nh),
        ConditionalField(
            BitFieldLenField(
                "udpSourcePort",
                0x0,
                16,
                length_of=lambda pkt: nhc_port(pkt)[0]),  # noqa: E501
            # ShortField("udpSourcePort", 0x0),
            lambda pkt: pkt.nh and pkt.header_compression & 0x2 == 0x0),
        ConditionalField(
            BitFieldLenField(
                "udpDestinyPort",
                0x0,
                16,
                length_of=lambda pkt: nhc_port(pkt)[1]),  # noqa: E501
            lambda pkt: pkt.nh and pkt.header_compression & 0x1 == 0x0),
        ConditionalField(
            XShortField("udpChecksum", 0x0),
            lambda pkt: pkt.nh and pkt.header_compression & 0x4 == 0x0),
    ]

    def post_dissect(self, data):
        """dissect the IPv6 package compressed into this IPHC packet.

        The packet payload needs to be decompressed and depending on the
        arguments, several conversions should be done.
        """

        # uncompress payload
        packet = IPv6()
        packet.version = IPHC_DEFAULT_VERSION
        packet.tc, packet.fl = self._getTrafficClassAndFlowLabel()
        if not self.nh:
            packet.nh = self._nhField
        # HLIM: Hop Limit
        if self.hlim == 0:
            packet.hlim = self._hopLimit
        elif self.hlim == 0x1:
            packet.hlim = 1
        elif self.hlim == 0x2:
            packet.hlim = 64
        else:
            packet.hlim = 255
        # TODO: Payload length can be inferred from lower layers from either the  # noqa: E501
        # 6LoWPAN Fragmentation header or the IEEE802.15.4 header

        packet.src = self.decompressSourceAddr(packet)
        packet.dst = self.decompressDestinyAddr(packet)

        if self.nh == 1:
            # The Next Header field is compressed and the next header is
            # encoded using LOWPAN_NHC

            udp = UDP()
            if self.header_compression and \
               self.header_compression & 0x4 == 0x0:
                udp.chksum = self.udpChecksum

            s, d = nhc_port(self)
            if s == 16:
                udp.sport = self.udpSourcePort
            elif s == 8:
                udp.sport = 0xF000 + s
            elif s == 4:
                udp.sport = 0xF0B0 + s
            if d == 16:
                udp.dport = self.udpDestinyPort
            elif d == 8:
                udp.dport = 0xF000 + d
            elif d == 4:
                udp.dport = 0xF0B0 + d

            packet.payload = udp / data
            data = raw(packet)
        # else self.nh == 0 not necessary
        elif self._nhField & 0xE0 == 0xE0:  # IPv6 Extension Header Decompression  # noqa: E501
            warning('Unimplemented: IPv6 Extension Header decompression'
                    )  # noqa: E501
            packet.payload = conf.raw_layer(data)
            data = raw(packet)
        else:
            packet.payload = conf.raw_layer(data)
            data = raw(packet)

        return Packet.post_dissect(self, data)

    def decompressDestinyAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.destinyAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.m == 0 and self.dac == 0:
            if self.dam == 0:
                pass
            elif self.dam == 1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:]
            elif self.dam == 2:
                tmp_ip = LINK_LOCAL_PREFIX[
                    0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[
                        -2:]  # noqa: E501
            """else: #self.dam == 3
                raise Exception('Unimplemented')"""

        elif self.m == 0 and self.dac == 1:
            if self.dam == 0:
                raise Exception('Reserved')
            elif self.dam == 0x3:
                underlayer = self.underlayer
                while underlayer is not None and not isinstance(
                        underlayer, Dot15d4Data):  # noqa: E501
                    underlayer = underlayer.underlayer
                if type(underlayer) == Dot15d4Data:
                    if underlayer.underlayer.fcf_destaddrmode == 3:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + struct.pack(
                            ">Q", underlayer.dest_addr)  # noqa: E501
                        # Turn off the bit 7.
                        tmp_ip = tmp_ip[0:8] + struct.pack(
                            "B", (orb(tmp_ip[8])
                                  ^ 0x2)) + tmp_ip[9:16]  # noqa: E501
                    elif underlayer.underlayer.fcf_destaddrmode == 2:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + \
                            b"\x00\x00\x00\xff\xfe\x00" + \
                            struct.pack(">Q", underlayer.dest_addr)[6:]
                else:
                    # Most of the times, it's necessary the IEEE 802.15.4 data to extract this address  # noqa: E501
                    raise Exception(
                        'Unimplemented: IP Header is contained into IEEE 802.15.4 frame, in this case it\'s not available.'
                    )  # noqa: E501
            elif self.dam not in [0x1, 0x2]:
                warning("Unknown destiny address compression mode !")
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0:
                raise Exception("unimplemented")
            elif self.dam == 1:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:]
            elif self.dam == 2:
                tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)])
                tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:]
            else:  # self.dam == 3:
                tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:]
        elif self.m == 1 and self.dac == 1:
            if self.dam == 0x0:
                raise Exception(
                    "Unimplemented: I didn't understand the 6lowpan specification"
                )  # noqa: E501
            else:  # all the others values
                raise Exception("Reserved value by specification.")

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.destinyAddr

    def compressSourceAddr(self, ipv6):
        tmp_ip = inet_pton(socket.AF_INET6, ipv6.src)

        if self.sac == 0:
            if self.sam == 0x0:
                tmp_ip = tmp_ip
            elif self.sam == 0x1:
                tmp_ip = tmp_ip[8:16]
            elif self.sam == 0x2:
                tmp_ip = tmp_ip[14:16]
            else:  # self.sam == 0x3:
                pass
        else:  # self.sac == 1
            if self.sam == 0x0:
                tmp_ip = b"\x00" * 16
            elif self.sam == 0x1:
                tmp_ip = tmp_ip[8:16]
            elif self.sam == 0x2:
                tmp_ip = tmp_ip[14:16]

        self.sourceAddr = inet_ntop(socket.AF_INET6, b"\x00" *
                                    (16 - len(tmp_ip)) + tmp_ip)  # noqa: E501
        return self.sourceAddr

    def compressDestinyAddr(self, ipv6):
        tmp_ip = inet_pton(socket.AF_INET6, ipv6.dst)

        if self.m == 0 and self.dac == 0:
            if self.dam == 0x0:
                tmp_ip = tmp_ip
            elif self.dam == 0x1:
                tmp_ip = b"\x00" * 8 + tmp_ip[8:16]
            elif self.dam == 0x2:
                tmp_ip = b"\x00" * 14 + tmp_ip[14:16]
        elif self.m == 0 and self.dac == 1:
            if self.dam == 0x1:
                tmp_ip = b"\x00" * 8 + tmp_ip[8:16]
            elif self.dam == 0x2:
                tmp_ip = b"\x00" * 14 + tmp_ip[14:16]
        elif self.m == 1 and self.dac == 0:
            if self.dam == 0x1:
                tmp_ip = b"\x00" * 10 + tmp_ip[1:2] + tmp_ip[11:16]
            elif self.dam == 0x2:
                tmp_ip = b"\x00" * 12 + tmp_ip[1:2] + tmp_ip[13:16]
            elif self.dam == 0x3:
                tmp_ip = b"\x00" * 15 + tmp_ip[15:16]
        elif self.m == 1 and self.dac == 1:
            raise Exception('Unimplemented')

        self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip)

    def decompressSourceAddr(self, packet):
        try:
            tmp_ip = inet_pton(socket.AF_INET6, self.sourceAddr)
        except socket.error:
            tmp_ip = b"\x00" * 16

        if self.sac == 0:
            if self.sam == 0x0:
                pass
            elif self.sam == 0x1:
                tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[
                    16 - source_addr_mode2(self):16]  # noqa: E501
            elif self.sam == 0x2:
                tmp = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00"
                tmp_ip = tmp + tmp_ip[16 - source_addr_mode2(self):16]
            elif self.sam == 0x3:  # EXTRACT ADDRESS FROM Dot15d4
                underlayer = self.underlayer
                if underlayer is not None:
                    while underlayer is not None and not isinstance(
                            underlayer, Dot15d4Data):  # noqa: E501
                        underlayer = underlayer.underlayer
                    assert type(underlayer) == Dot15d4Data
                    if underlayer.underlayer.fcf_srcaddrmode == 3:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + struct.pack(
                            ">Q", underlayer.src_addr)  # noqa: E501
                        # Turn off the bit 7.
                        tmp_ip = tmp_ip[0:8] + struct.pack(
                            "B", (orb(tmp_ip[8])
                                  ^ 0x2)) + tmp_ip[9:16]  # noqa: E501
                    elif underlayer.underlayer.fcf_srcaddrmode == 2:
                        tmp_ip = LINK_LOCAL_PREFIX[0:8] + \
                            b"\x00\x00\x00\xff\xfe\x00" + \
                            struct.pack(">Q", underlayer.src_addr)[6:]
                else:
                    # Most of the times, it's necessary the IEEE 802.15.4 data to extract this address  # noqa: E501
                    raise Exception(
                        'Unimplemented: IP Header is contained into IEEE 802.15.4 frame, in this case it\'s not available.'
                    )  # noqa: E501
            else:
                warning("Unknown source address compression mode !")
        else:  # self.sac == 1:
            if self.sam == 0x0:
                pass
            elif self.sam == 0x2:
                # TODO: take context IID
                tmp = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00"
                tmp_ip = tmp + tmp_ip[16 - source_addr_mode2(self):16]
            elif self.sam == 0x3:
                tmp_ip = LINK_LOCAL_PREFIX[
                    0:8] + b"\x00" * 8  # TODO: CONTEXT ID  # noqa: E501
            else:
                raise Exception('Unimplemented')
        self.sourceAddr = inet_ntop(socket.AF_INET6, tmp_ip)
        return self.sourceAddr

    def guess_payload_class(self, payload):
        if self.underlayer and isinstance(
                self.underlayer,
            (LoWPANFragmentationFirst,
             LoWPANFragmentationSubsequent)):  # noqa: E501
            return Raw
        return IPv6

    def do_build(self):
        if not isinstance(self.payload, IPv6):
            return Packet.do_build(self)
        ipv6 = self.payload

        self._reserved = 0x03

        # NEW COMPRESSION TECHNIQUE!
        # a ) Compression Techniques

        # 1. Set Traffic Class
        if self.tf == 0x0:
            self.tc_ecn = ipv6.tc >> 6
            self.tc_dscp = ipv6.tc & 0x3F
            self.flowlabel = ipv6.fl
        elif self.tf == 0x1:
            self.tc_ecn = ipv6.tc >> 6
            self.flowlabel = ipv6.fl
        elif self.tf == 0x2:
            self.tc_ecn = ipv6.tc >> 6
            self.tc_dscp = ipv6.tc & 0x3F
        else:  # self.tf == 0x3:
            pass  # no field is set

        # 2. Next Header
        if self.nh == 0x0:
            self.nh = 0  # ipv6.nh
        elif self.nh == 0x1:
            self.nh = 0  # disable compression
            # The Next Header field is compressed and the next header is encoded using LOWPAN_NHC, which is discussed in Section 4.1.  # noqa: E501
            warning(
                'Next header compression is not implemented yet ! Will be ignored'
            )  # noqa: E501

        # 3. HLim
        if self.hlim == 0x0:
            self._hopLimit = ipv6.hlim
        else:  # if hlim is 1, 2 or 3, there are nothing to do!
            pass

        # 4. Context (which context to use...)
        if self.cid == 0x0:
            pass
        else:
            # TODO: Context Unimplemented yet in my class
            self._contextIdentifierExtension = 0

        # 5. Compress Source Addr
        self.compressSourceAddr(ipv6)
        self.compressDestinyAddr(ipv6)

        return Packet.do_build(self)

    def do_build_payload(self):
        if self.header_compression and\
           self.header_compression & 240 == 240:  # TODO: UDP header IMPROVE
            return raw(self.payload)[40 + 16:]
        else:
            return raw(self.payload)[40:]

    def _getTrafficClassAndFlowLabel(self):
        """Page 6, draft feb 2011 """
        if self.tf == 0x0:
            return (self.tc_ecn << 6) + self.tc_dscp, self.flowlabel
        elif self.tf == 0x1:
            return (self.tc_ecn << 6), self.flowlabel
        elif self.tf == 0x2:
            return (self.tc_ecn << 6) + self.tc_dscp, 0
        else:
            return 0, 0
Ejemplo n.º 26
0
class LinkADRReq(Packet):
    name = "LinkADRReq"
    fields_desc = [DataRate_TXPower, XShortField("ChMask", 0), Redundancy]
Ejemplo n.º 27
0
class ARP(Packet):
    name = "ARP"
    fields_desc = [
        XShortField("hwtype", 0x0001),
        XShortEnumField("ptype", 0x0800, ETHER_TYPES),
        FieldLenField("hwlen", None, fmt="B", length_of="hwsrc"),
        FieldLenField("plen", None, fmt="B", length_of="psrc"),
        ShortEnumField("op", 1, {
            "who-has": 1,
            "is-at": 2,
            "RARP-req": 3,
            "RARP-rep": 4,
            "Dyn-RARP-req": 5,
            "Dyn-RAR-rep": 6,
            "Dyn-RARP-err": 7,
            "InARP-req": 8,
            "InARP-rep": 9
        }),
        MultipleTypeField(
            [
                (SourceMACField("hwsrc"),
                 (lambda pkt: pkt.hwtype == 1 and pkt.hwlen == 6,
                  lambda pkt, val: pkt.hwtype == 1 and (
                      pkt.hwlen == 6 or (pkt.hwlen is None and
                                         (val is None or len(val) == 6 or
                                          valid_mac(val)))
                  ))),
            ],
            StrFixedLenField("hwsrc", None, length_from=lambda pkt: pkt.hwlen),
        ),
        MultipleTypeField(
            [
                (SourceIPField("psrc", "pdst"),
                 (lambda pkt: pkt.ptype == 0x0800 and pkt.plen == 4,
                  lambda pkt, val: pkt.ptype == 0x0800 and (
                      pkt.plen == 4 or (pkt.plen is None and
                                        (val is None or valid_net(val)))
                  ))),
                (SourceIP6Field("psrc", "pdst"),
                 (lambda pkt: pkt.ptype == 0x86dd and pkt.plen == 16,
                  lambda pkt, val: pkt.ptype == 0x86dd and (
                      pkt.plen == 16 or (pkt.plen is None and
                                         (val is None or valid_net6(val)))
                  ))),
            ],
            StrFixedLenField("psrc", None, length_from=lambda pkt: pkt.plen),
        ),
        MultipleTypeField(
            [
                (MACField("hwdst", ETHER_ANY),
                 (lambda pkt: pkt.hwtype == 1 and pkt.hwlen == 6,
                  lambda pkt, val: pkt.hwtype == 1 and (
                      pkt.hwlen == 6 or (pkt.hwlen is None and
                                         (val is None or len(val) == 6 or
                                          valid_mac(val)))
                  ))),
            ],
            StrFixedLenField("hwdst", None, length_from=lambda pkt: pkt.hwlen),
        ),
        MultipleTypeField(
            [
                (IPField("pdst", "0.0.0.0"),
                 (lambda pkt: pkt.ptype == 0x0800 and pkt.plen == 4,
                  lambda pkt, val: pkt.ptype == 0x0800 and (
                      pkt.plen == 4 or (pkt.plen is None and
                                        (val is None or valid_net(val)))
                  ))),
                (IP6Field("pdst", "::"),
                 (lambda pkt: pkt.ptype == 0x86dd and pkt.plen == 16,
                  lambda pkt, val: pkt.ptype == 0x86dd and (
                      pkt.plen == 16 or (pkt.plen is None and
                                         (val is None or valid_net6(val)))
                  ))),
            ],
            StrFixedLenField("pdst", None, length_from=lambda pkt: pkt.plen),
        ),
    ]

    def hashret(self):
        return struct.pack(">HHH", self.hwtype, self.ptype,
                           ((self.op + 1) // 2)) + self.payload.hashret()

    def answers(self, other):
        if not isinstance(other, ARP):
            return False
        if self.op != other.op + 1:
            return False
        # We use a loose comparison on psrc vs pdst to catch answers
        # with ARP leaks
        self_psrc = self.get_field('psrc').i2m(self, self.psrc)
        other_pdst = other.get_field('pdst').i2m(other, other.pdst)
        return self_psrc[:len(other_pdst)] == other_pdst[:len(self_psrc)]

    def route(self):
        fld, dst = self.getfield_and_val("pdst")
        fld, dst = fld._find_fld_pkt_val(self, dst)
        if isinstance(dst, Gen):
            dst = next(iter(dst))
        if isinstance(fld, IP6Field):
            return conf.route6.route(dst)
        elif isinstance(fld, IPField):
            return conf.route.route(dst)
        else:
            return None, None, None

    def extract_padding(self, s):
        return "", s

    def mysummary(self):
        if self.op == 1:
            return self.sprintf("ARP who has %pdst% says %psrc%")
        if self.op == 2:
            return self.sprintf("ARP is at %hwsrc% says %psrc%")
        return self.sprintf("ARP %op% %psrc% > %pdst%")
Ejemplo n.º 28
0
class IGMPv3(IGMP):
    """IGMP Message Class for v3.

    This class is derived from class Packet.
    The fields defined below are a
    direct interpretation of the v3 Membership Query Message.
    Fields 'type'  through 'qqic' are directly assignable.
    For 'numsrc', do not assign a value.
    Instead add to the 'srcaddrs' list to auto-set 'numsrc'. To
    assign values to 'srcaddrs', use the following methods::

      c = IGMPv3()
      c.srcaddrs = ['1.2.3.4', '5.6.7.8']
      c.srcaddrs += ['192.168.10.24']

    At this point, 'c.numsrc' is three (3)

    'chksum' is automagically calculated before the packet is sent.

    'mrcode' is also the Advertisement Interval field

    """
    name = "IGMPv3"
    igmpv3types = {
        0x11: "Membership Query",
        0x22: "Version 3 Membership Report",
        0x30: "Multicast Router Advertisement",
        0x31: "Multicast Router Solicitation",
        0x32: "Multicast Router Termination"
    }

    fields_desc = [
        ByteEnumField("type", 0x11, igmpv3types),
        ByteField("mrcode", 20),
        XShortField("chksum", None)
    ]

    def encode_maxrespcode(self):
        """Encode and replace the mrcode value to its IGMPv3 encoded time value if needed,  # noqa: E501
        as specified in rfc3376#section-4.1.1.

        If value < 128, return the value specified. If >= 128, encode as a floating  # noqa: E501
        point value. Value can be 0 - 31744.
        """
        value = self.mrcode
        if value < 128:
            code = value
        elif value > 31743:
            code = 255
        else:
            exp = 0
            value >>= 3
            while (value > 31):
                exp += 1
                value >>= 1
            exp <<= 4
            code = 0x80 | exp | (value & 0x0F)
        self.mrcode = code

    def mysummary(self):
        """Display a summary of the IGMPv3 object."""
        if isinstance(self.underlayer, IP):
            return self.underlayer.sprintf(
                "IGMPv3: %IP.src% > %IP.dst% %IGMPv3.type%")  # noqa: E501
        else:
            return self.sprintf("IGMPv3 %IGMPv3.type%")

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and len(_pkt) >= 4:
            if orb(_pkt[0]) in [0x12, 0x16, 0x17]:
                return IGMP
            elif orb(_pkt[0]) == 0x11 and len(_pkt) < 12:
                return IGMP
        return IGMPv3
Ejemplo n.º 29
0
class CDPv2_HDR(_CDPChecksum, CDPMsgGeneric):
    name = "Cisco Discovery Protocol version 2"
    fields_desc = [ByteField("vers", 2),
                   ByteField("ttl", 180),
                   XShortField("cksum", None),
                   PacketListField("msg", [], _CDPGuessPayloadClass)]
Ejemplo n.º 30
0
class ISIS_ChecksumTlv(ISIS_GenericTlv):
    name = "ISIS Optional Checksum TLV"
    fields_desc = [ByteEnumField("type", 12, _isis_tlv_names),
                   ByteField("len", 2),
                   XShortField("checksum", None)]