Пример #1
0
class LLDPDUGenericOrganisationSpecific(LLDPDU):

    ORG_UNIQUE_CODE_PNO = 0x000ecf
    ORG_UNIQUE_CODE_IEEE_802_1 = 0x0080c2
    ORG_UNIQUE_CODE_IEEE_802_3 = 0x00120f
    ORG_UNIQUE_CODE_TIA_TR_41_MED = 0x0012bb
    ORG_UNIQUE_CODE_HYTEC = 0x30b216

    ORG_UNIQUE_CODES = {
        ORG_UNIQUE_CODE_PNO: "PROFIBUS International (PNO)",
        ORG_UNIQUE_CODE_IEEE_802_1: "IEEE 802.1",
        ORG_UNIQUE_CODE_IEEE_802_3: "IEEE 802.3",
        ORG_UNIQUE_CODE_TIA_TR_41_MED:
        "TIA TR-41 Committee . Media Endpoint Discovery",
        ORG_UNIQUE_CODE_HYTEC: "Hytec Geraetebau GmbH"
    }

    fields_desc = [
        BitEnumField('_type', 127, 7, LLDPDU.TYPES),
        BitFieldLenField('_length',
                         None,
                         9,
                         length_of='data',
                         adjust=lambda pkt, x: len(pkt.data) + 4),
        ThreeBytesEnumField('org_code', 0, ORG_UNIQUE_CODES),
        ByteField('subtype', 0x00),
        XStrLenField('data', '', length_from=lambda pkt: pkt._length - 4)
    ]
Пример #2
0
class LLDPDUEndOfLLDPDU(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.1 / p. 26
    """
    fields_desc = [
        BitEnumField('_type', 0x00, 7, LLDPDU.TYPES),
        BitField('_length', 0x00, 9),
    ]

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

    def _check(self):
        """
        run layer specific checks
        """
        if conf.contribs['LLDP'].strict_mode() and self._length != 0:
            raise LLDPInvalidLengthField('length must be 0 - got '
                                         '{}'.format(self._length))

    def post_dissect(self, s):
        self._check()
        return super(LLDPDUEndOfLLDPDU, self).post_dissect(s)

    def do_build(self):
        self._check()
        return super(LLDPDUEndOfLLDPDU, self).do_build()
Пример #3
0
class LLDPDUTimeToLive(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.4 / p. 29
    """
    fields_desc = [
        BitEnumField('_type', 0x03, 7, LLDPDU.TYPES),
        BitField('_length', 0x02, 9),
        ShortField('ttl', 20)
    ]

    def _check(self):
        """
        run layer specific checks
        """
        if conf.contribs['LLDP'].strict_mode() and self._length != 2:
            raise LLDPInvalidLengthField('length must be 2 - got '
                                         '{}'.format(self._length))

    def post_dissect(self, s):
        self._check()
        return super(LLDPDUTimeToLive, self).post_dissect(s)

    def do_build(self):
        self._check()
        return super(LLDPDUTimeToLive, self).do_build()
Пример #4
0
class LLDPDUSystemDescription(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.7 / p. 31
    """
    fields_desc = [
        BitEnumField('_type', 0x06, 7, LLDPDU.TYPES),
        BitFieldLenField('_length', None, 9, length_of='description'),
        StrLenField('description', '', length_from=lambda pkt: pkt._length)
    ]
Пример #5
0
class LLDPDUSystemName(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.6 / p. 30
    """
    fields_desc = [
        BitEnumField('_type', 0x05, 7, LLDPDU.TYPES),
        BitFieldLenField('_length', None, 9, length_of='system_name'),
        StrLenField('system_name', '', length_from=lambda pkt: pkt._length)
    ]
Пример #6
0
class LLDPDUSystemCapabilities(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.8 / p. 31
    """
    fields_desc = [
        BitEnumField('_type', 0x07, 7, LLDPDU.TYPES),
        BitFieldLenField('_length', 4, 9),
        BitField('reserved_5_available', 0, 1),
        BitField('reserved_4_available', 0, 1),
        BitField('reserved_3_available', 0, 1),
        BitField('reserved_2_available', 0, 1),
        BitField('reserved_1_available', 0, 1),
        BitField('two_port_mac_relay_available', 0, 1),
        BitField('s_vlan_component_available', 0, 1),
        BitField('c_vlan_component_available', 0, 1),
        BitField('station_only_available', 0, 1),
        BitField('docsis_cable_device_available', 0, 1),
        BitField('telephone_available', 0, 1),
        BitField('router_available', 0, 1),
        BitField('wlan_access_point_available', 0, 1),
        BitField('mac_bridge_available', 0, 1),
        BitField('repeater_available', 0, 1),
        BitField('other_available', 0, 1),
        BitField('reserved_5_enabled', 0, 1),
        BitField('reserved_4_enabled', 0, 1),
        BitField('reserved_3_enabled', 0, 1),
        BitField('reserved_2_enabled', 0, 1),
        BitField('reserved_1_enabled', 0, 1),
        BitField('two_port_mac_relay_enabled', 0, 1),
        BitField('s_vlan_component_enabled', 0, 1),
        BitField('c_vlan_component_enabled', 0, 1),
        BitField('station_only_enabled', 0, 1),
        BitField('docsis_cable_device_enabled', 0, 1),
        BitField('telephone_enabled', 0, 1),
        BitField('router_enabled', 0, 1),
        BitField('wlan_access_point_enabled', 0, 1),
        BitField('mac_bridge_enabled', 0, 1),
        BitField('repeater_enabled', 0, 1),
        BitField('other_enabled', 0, 1),
    ]

    def _check(self):
        """
        run layer specific checks
        """
        if conf.contribs['LLDP'].strict_mode() and self._length != 4:
            raise LLDPInvalidLengthField('length must be 4 - got '
                                         '{}'.format(self._length))

    def post_dissect(self, s):
        self._check()
        return super(LLDPDUSystemCapabilities, self).post_dissect(s)

    def do_build(self):
        self._check()
        return super(LLDPDUSystemCapabilities, self).do_build()
Пример #7
0
class LLDPDUPortID(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.3 / p. 26
    """
    LLDP_PORT_ID_TLV_SUBTYPES = {
        0x00: 'reserved',
        0x01: 'interface alias',
        0x02: 'port component',
        0x03: 'MAC address',
        0x04: 'network address',
        0x05: 'interface name',
        0x06: 'agent circuit ID',
        0x07: 'locally assigned',
        range(0x08, 0xff): 'reserved'
    }

    SUBTYPE_RESERVED = 0x00
    SUBTYPE_INTERFACE_ALIAS = 0x01
    SUBTYPE_PORT_COMPONENT = 0x02
    SUBTYPE_MAC_ADDRESS = 0x03
    SUBTYPE_NETWORK_ADDRESS = 0x04
    SUBTYPE_INTERFACE_NAME = 0x05
    SUBTYPE_AGENT_CIRCUIT_ID = 0x06
    SUBTYPE_LOCALLY_ASSIGNED = 0x07

    fields_desc = [
        BitEnumField('_type', 0x02, 7, LLDPDU.TYPES),
        BitFieldLenField('_length',
                         None,
                         9,
                         length_of='id',
                         adjust=lambda pkt, x: len(pkt.id) + 1),
        ByteEnumField('subtype', 0x00, LLDP_PORT_ID_TLV_SUBTYPES),
        StrLenField('id', '', length_from=lambda pkt: pkt._length - 1)
    ]

    def _check(self):
        """
        run layer specific checks
        """
        if conf.contribs['LLDP'].strict_mode() and not self.id:
            raise LLDPInvalidLengthField('id must be >= 1 characters long')

    def post_dissect(self, s):
        self._check()
        return super(LLDPDUPortID, self).post_dissect(s)

    def do_build(self):
        self._check()
        return super(LLDPDUPortID, self).do_build()
Пример #8
0
class LLDPDUManagementAddress(LLDPDU):
    """
        ieee 802.1ab-2016 - sec. 8.5.9 / p. 32

        currently only 0x00..0x1e are used by standards, no way to
        use anything > 0xff as management address subtype is only
        one octet wide

        see https://www.iana.org/assignments/
        address-family-numbers/address-family-numbers.xhtml
    """
    IANA_ADDRESS_FAMILY_NUMBERS = {
        0x00: 'other',
        0x01: 'IPv4',
        0x02: 'IPv6',
        0x03: 'NSAP',
        0x04: 'HDLC',
        0x05: 'BBN',
        0x06: '802',
        0x07: 'E.163',
        0x08: 'E.164',
        0x09: 'F.69',
        0x0a: 'X.121',
        0x0b: 'IPX',
        0x0c: 'Appletalk',
        0x0d: 'Decnet IV',
        0x0e: 'Banyan Vines',
        0x0f: 'E.164 with NSAP',
        0x10: 'DNS',
        0x11: 'Distinguished Name',
        0x12: 'AS Number',
        0x13: 'XTP over IPv4',
        0x14: 'XTP over IPv6',
        0x15: 'XTP native mode XTP',
        0x16: 'Fiber Channel World-Wide Port Name',
        0x17: 'Fiber Channel World-Wide Node Name',
        0x18: 'GWID',
        0x19: 'AFI for L2VPN',
        0x1a: 'MPLS-TP Section Endpoint ID',
        0x1b: 'MPLS-TP LSP Endpoint ID',
        0x1c: 'MPLS-TP Pseudowire Endpoint ID',
        0x1d: 'MT IP Multi-Topology IPv4',
        0x1e: 'MT IP Multi-Topology IPv6'
    }

    SUBTYPE_MANAGEMENT_ADDRESS_OTHER = 0x00
    SUBTYPE_MANAGEMENT_ADDRESS_IPV4 = 0x01
    SUBTYPE_MANAGEMENT_ADDRESS_IPV6 = 0x02
    SUBTYPE_MANAGEMENT_ADDRESS_NSAP = 0x03
    SUBTYPE_MANAGEMENT_ADDRESS_HDLC = 0x04
    SUBTYPE_MANAGEMENT_ADDRESS_BBN = 0x05
    SUBTYPE_MANAGEMENT_ADDRESS_802 = 0x06
    SUBTYPE_MANAGEMENT_ADDRESS_E_163 = 0x07
    SUBTYPE_MANAGEMENT_ADDRESS_E_164 = 0x08
    SUBTYPE_MANAGEMENT_ADDRESS_F_69 = 0x09
    SUBTYPE_MANAGEMENT_ADDRESS_X_121 = 0x0A
    SUBTYPE_MANAGEMENT_ADDRESS_IPX = 0x0B
    SUBTYPE_MANAGEMENT_ADDRESS_APPLETALK = 0x0C
    SUBTYPE_MANAGEMENT_ADDRESS_DECNET_IV = 0x0D
    SUBTYPE_MANAGEMENT_ADDRESS_BANYAN_VINES = 0x0E
    SUBTYPE_MANAGEMENT_ADDRESS_E_164_WITH_NSAP = 0x0F
    SUBTYPE_MANAGEMENT_ADDRESS_DNS = 0x10
    SUBTYPE_MANAGEMENT_ADDRESS_DISTINGUISHED_NAME = 0x11
    SUBTYPE_MANAGEMENT_ADDRESS_AS_NUMBER = 0x12
    SUBTYPE_MANAGEMENT_ADDRESS_XTP_OVER_IPV4 = 0x13
    SUBTYPE_MANAGEMENT_ADDRESS_XTP_OVER_IPV6 = 0x14
    SUBTYPE_MANAGEMENT_ADDRESS_XTP_NATIVE_MODE_XTP = 0x15
    SUBTYPE_MANAGEMENT_ADDRESS_FIBER_CHANNEL_WORLD_WIDE_PORT_NAME = 0x16
    SUBTYPE_MANAGEMENT_ADDRESS_FIBER_CHANNEL_WORLD_WIDE_NODE_NAME = 0x17
    SUBTYPE_MANAGEMENT_ADDRESS_GWID = 0x18
    SUBTYPE_MANAGEMENT_ADDRESS_AFI_FOR_L2VPN = 0x19
    SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_SECTION_ENDPOINT_ID = 0x1A
    SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_LSP_ENDPOINT_ID = 0x1B
    SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_PSEUDOWIRE_ENDPOINT_ID = 0x1C
    SUBTYPE_MANAGEMENT_ADDRESS_MT_IP_MULTI_TOPOLOGY_IPV4 = 0x1D
    SUBTYPE_MANAGEMENT_ADDRESS_MT_IP_MULTI_TOPOLOGY_IPV6 = 0x1E

    INTERFACE_NUMBERING_SUBTYPES = {
        0x01: 'unknown',
        0x02: 'ifIndex',
        0x03: 'system port number'
    }

    SUBTYPE_INTERFACE_NUMBER_UNKNOWN = 0x01
    SUBTYPE_INTERFACE_NUMBER_IF_INDEX = 0x02
    SUBTYPE_INTERFACE_NUMBER_SYSTEM_PORT_NUMBER = 0x03
    '''
        Note - calculation of _length field:
        _length = 1@_management_address_string_length +
                  1@management_address_subtype +
                  management_address.len +
                  1@interface_numbering_subtype +
                  4@interface_number +
                  1@_oid_string_length +
                  object_id.len
    '''

    fields_desc = [
        BitEnumField('_type', 0x08, 7, LLDPDU.TYPES),
        BitFieldLenField('_length',
                         None,
                         9,
                         length_of='management_address',
                         adjust=lambda pkt, x: 8 + len(pkt.management_address)
                         + len(pkt.object_id)),
        BitFieldLenField(
            '_management_address_string_length',
            None,
            8,
            length_of='management_address',
            adjust=lambda pkt, x: len(pkt.management_address) + 1),
        ByteEnumField('management_address_subtype', 0x00,
                      IANA_ADDRESS_FAMILY_NUMBERS),
        XStrLenField(
            'management_address',
            '',
            length_from=lambda pkt: pkt._management_address_string_length - 1),
        ByteEnumField('interface_numbering_subtype',
                      SUBTYPE_INTERFACE_NUMBER_UNKNOWN,
                      INTERFACE_NUMBERING_SUBTYPES),
        BitField('interface_number', 0, 32),
        BitFieldLenField('_oid_string_length', None, 8, length_of='object_id'),
        XStrLenField('object_id',
                     '',
                     length_from=lambda pkt: pkt._oid_string_length),
    ]

    def _check(self):
        """
        run layer specific checks
        """
        if conf.contribs['LLDP'].strict_mode():
            management_address_len = len(self.management_address)
            if management_address_len == 0 or management_address_len > 31:
                raise LLDPInvalidLengthField(
                    'management address must be  1..31 characters long - '
                    'got string of size {}'.format(management_address_len))

    def post_dissect(self, s):
        self._check()
        return super(LLDPDUManagementAddress, self).post_dissect(s)

    def do_build(self):
        self._check()
        return super(LLDPDUManagementAddress, self).do_build()