backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / lib / packet / lldp.py
diff --git a/ryu/build/lib.linux-armv7l-2.7/ryu/lib/packet/lldp.py b/ryu/build/lib.linux-armv7l-2.7/ryu/lib/packet/lldp.py
new file mode 100644 (file)
index 0000000..a48884d
--- /dev/null
@@ -0,0 +1,613 @@
+# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2012 Isaku Yamahata <yamahata at private email ne jp>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Link Layer Discovery Protocol(LLDP, IEEE 802.1AB)
+http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf
+
+
+basic TLV format::
+
+    octets | 1          | 2             | 3 ...             n + 2 |
+           --------------------------------------------------------
+           | TLV type | TLV information | TLV information string  |
+           | (7bits)  | string length   | (0-507 octets)          |
+           |          | (9bits)         |                         |
+           --------------------------------------------------------
+    bits   |8        2|1|8             1|
+
+
+Organizationally specific TLV format::
+
+    octets | 1          | 2        | 3 ...  5 | 6       | 7 ...    n + 6 |
+           ---------------------------------------------------------------
+           | TLV type | Length     | OUI      | Subtype | Infomation     |
+           | (7bits)  | (9bits)    | (24bits) | (8bits) | (0-507 octets) |
+           ---------------------------------------------------------------
+    bits   |8        2|1|8        1|
+
+
+LLDPDU format::
+
+    ------------------------------------------------------------------------
+    | Chassis ID | Port ID | TTL | optional TLV | ... | optional TLV | End |
+    ------------------------------------------------------------------------
+
+Chasis ID, Port ID, TTL, End are mandatory
+optional TLV may be inserted in any order
+"""
+
+import struct
+from ryu.lib import stringify
+from ryu.lib.packet import packet_base
+
+
+# LLDP destination MAC address
+LLDP_MAC_NEAREST_BRIDGE = '01:80:c2:00:00:0e'
+LLDP_MAC_NEAREST_NON_TPMR_BRIDGE = '01:80:c2:00:00:03'
+LLDP_MAC_NEAREST_CUSTOMER_BRIDGE = '01:80:c2:00:00:00'
+
+
+LLDP_TLV_TYPELEN_STR = '!H'
+LLDP_TLV_SIZE = 2
+LLDP_TLV_TYPE_MASK = 0xfe00
+LLDP_TLV_TYPE_SHIFT = 9
+LLDP_TLV_LENGTH_MASK = 0x01ff
+
+
+# LLDP TLV type
+LLDP_TLV_END = 0                        # End of LLDPDU
+LLDP_TLV_CHASSIS_ID = 1                 # Chassis ID
+LLDP_TLV_PORT_ID = 2                    # Port ID
+LLDP_TLV_TTL = 3                        # Time To Live
+LLDP_TLV_PORT_DESCRIPTION = 4           # Port Description
+LLDP_TLV_SYSTEM_NAME = 5                # System Name
+LLDP_TLV_SYSTEM_DESCRIPTION = 6         # System Description
+LLDP_TLV_SYSTEM_CAPABILITIES = 7        # System Capabilities
+LLDP_TLV_MANAGEMENT_ADDRESS = 8         # Management Address
+LLDP_TLV_ORGANIZATIONALLY_SPECIFIC = 127  # organizationally Specific TLVs
+
+
+class LLDPBasicTLV(stringify.StringifyMixin):
+    _LEN_MIN = 0
+    _LEN_MAX = 511
+    tlv_type = None
+
+    def __init__(self, buf=None, *_args, **_kwargs):
+        super(LLDPBasicTLV, self).__init__()
+        if buf:
+            (self.typelen, ) = struct.unpack(
+                LLDP_TLV_TYPELEN_STR, buf[:LLDP_TLV_SIZE])
+            tlv_type = \
+                (self.typelen & LLDP_TLV_TYPE_MASK) >> LLDP_TLV_TYPE_SHIFT
+            assert self.tlv_type == tlv_type
+
+            self.len = self.typelen & LLDP_TLV_LENGTH_MASK
+            assert len(buf) >= self.len + LLDP_TLV_SIZE
+
+            self.tlv_info = buf[LLDP_TLV_SIZE:]
+            self.tlv_info = self.tlv_info[:self.len]
+
+    @staticmethod
+    def get_type(buf):
+        (typelen, ) = struct.unpack(LLDP_TLV_TYPELEN_STR, buf[:LLDP_TLV_SIZE])
+        return (typelen & LLDP_TLV_TYPE_MASK) >> LLDP_TLV_TYPE_SHIFT
+
+    @staticmethod
+    def set_tlv_type(subcls, tlv_type):
+        assert issubclass(subcls, LLDPBasicTLV)
+        subcls.tlv_type = tlv_type
+
+    def _len_valid(self):
+        return self._LEN_MIN <= self.len and self.len <= self._LEN_MAX
+
+
+class lldp(packet_base.PacketBase):
+    """LLDPDU encoder/decoder class.
+
+    An instance has the following attributes at least.
+
+    ============== =====================================
+    Attribute      Description
+    ============== =====================================
+    tlvs           List of TLV instance.
+    ============== =====================================
+    """
+    _tlv_parsers = {}
+
+    def __init__(self, tlvs):
+        super(lldp, self).__init__()
+        self.tlvs = tlvs
+
+    # at least it must have chassis id, port id, ttl and end
+    def _tlvs_len_valid(self):
+        return len(self.tlvs) >= 4
+
+    # chassis id, port id, ttl and end
+    def _tlvs_valid(self):
+        return (self.tlvs[0].tlv_type == LLDP_TLV_CHASSIS_ID and
+                self.tlvs[1].tlv_type == LLDP_TLV_PORT_ID and
+                self.tlvs[2].tlv_type == LLDP_TLV_TTL and
+                self.tlvs[-1].tlv_type == LLDP_TLV_END)
+
+    @classmethod
+    def _parser(cls, buf):
+        tlvs = []
+
+        while buf:
+            tlv_type = LLDPBasicTLV.get_type(buf)
+            tlv = cls._tlv_parsers[tlv_type](buf)
+            tlvs.append(tlv)
+            offset = LLDP_TLV_SIZE + tlv.len
+            buf = buf[offset:]
+            if tlv.tlv_type == LLDP_TLV_END:
+                break
+            assert len(buf) > 0
+
+        lldp_pkt = cls(tlvs)
+
+        assert lldp_pkt._tlvs_len_valid()
+        assert lldp_pkt._tlvs_valid()
+
+        return lldp_pkt, None, buf
+
+    @classmethod
+    def parser(cls, buf):
+        try:
+            return cls._parser(buf)
+        except:
+            return None, None, buf
+
+    def serialize(self, payload, prev):
+        data = bytearray()
+        for tlv in self.tlvs:
+            data += tlv.serialize()
+
+        return data
+
+    @classmethod
+    def set_type(cls, tlv_cls):
+        cls._tlv_parsers[tlv_cls.tlv_type] = tlv_cls
+
+    @classmethod
+    def get_type(cls, tlv_type):
+        return cls._tlv_parsers[tlv_type]
+
+    @classmethod
+    def set_tlv_type(cls, tlv_type):
+        def _set_type(tlv_cls):
+            tlv_cls.set_tlv_type(tlv_cls, tlv_type)
+            cls.set_type(tlv_cls)
+            return tlv_cls
+        return _set_type
+
+    def __len__(self):
+        return sum(LLDP_TLV_SIZE + tlv.len for tlv in self.tlvs)
+
+
+@lldp.set_tlv_type(LLDP_TLV_END)
+class End(LLDPBasicTLV):
+    """End TLV encoder/decoder class
+
+    ============== =====================================
+    Attribute      Description
+    ============== =====================================
+    buf            Binary data to parse.
+    ============== =====================================
+    """
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(End, self).__init__(buf, *args, **kwargs)
+        if buf:
+            pass
+        else:
+            self.len = 0
+            self.typelen = 0
+
+    def serialize(self):
+        return struct.pack('!H', self.typelen)
+
+
+@lldp.set_tlv_type(LLDP_TLV_CHASSIS_ID)
+class ChassisID(LLDPBasicTLV):
+    """Chassis ID TLV encoder/decoder class
+
+    ============== =====================================
+    Attribute      Description
+    ============== =====================================
+    buf            Binary data to parse.
+    subtype        Subtype.
+    chassis_id     Chassis id corresponding to subtype.
+    ============== =====================================
+    """
+
+    _PACK_STR = '!B'
+    _PACK_SIZE = struct.calcsize(_PACK_STR)
+    # subtype id(1 octet) + chassis id length(1 - 255 octet)
+    _LEN_MIN = 2
+    _LEN_MAX = 256
+
+    # Chassis ID subtype
+    SUB_CHASSIS_COMPONENT = 1   # EntPhysicalAlias (IETF RFC 4133)
+    SUB_INTERFACE_ALIAS = 2     # IfAlias (IETF RFC 2863)
+    SUB_PORT_COMPONENT = 3      # EntPhysicalAlias (IETF RFC 4133)
+    SUB_MAC_ADDRESS = 4         # MAC address (IEEE std 802)
+    SUB_NETWORK_ADDRESS = 5     # networkAddress
+    SUB_INTERFACE_NAME = 6      # IfName (IETF RFC 2863)
+    SUB_LOCALLY_ASSIGNED = 7    # local
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(ChassisID, self).__init__(buf, *args, **kwargs)
+        if buf:
+            (self.subtype, ) = struct.unpack(
+                self._PACK_STR, self.tlv_info[:self._PACK_SIZE])
+            self.chassis_id = self.tlv_info[self._PACK_SIZE:]
+        else:
+            self.subtype = kwargs['subtype']
+            self.chassis_id = kwargs['chassis_id']
+            self.len = self._PACK_SIZE + len(self.chassis_id)
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!HB', self.typelen, self.subtype) + self.chassis_id
+
+
+@lldp.set_tlv_type(LLDP_TLV_PORT_ID)
+class PortID(LLDPBasicTLV):
+    """Port ID TLV encoder/decoder class
+
+    ============== =====================================
+    Attribute      Description
+    ============== =====================================
+    buf            Binary data to parse.
+    subtype        Subtype.
+    port_id        Port ID corresponding to subtype.
+    ============== =====================================
+    """
+    _PACK_STR = '!B'
+    _PACK_SIZE = struct.calcsize(_PACK_STR)
+
+    # subtype id(1 octet) + port id length(1 - 255 octet)
+    _LEN_MIN = 2
+    _LEN_MAX = 256
+
+    # Port ID subtype
+    SUB_INTERFACE_ALIAS = 1     # ifAlias (IETF RFC 2863)
+    SUB_PORT_COMPONENT = 2      # entPhysicalAlias (IETF RFC 4133)
+    SUB_MAC_ADDRESS = 3         # MAC address (IEEE Std 802)
+    SUB_NETWORK_ADDRESS = 4     # networkAddress
+    SUB_INTERFACE_NAME = 5      # ifName (IETF RFC 2863)
+    SUB_AGENT_CIRCUIT_ID = 6    # agent circuit ID(IETF RFC 3046)
+    SUB_LOCALLY_ASSIGNED = 7    # local
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(PortID, self).__init__(buf, *args, **kwargs)
+        if buf:
+            (self.subtype, ) = struct.unpack(
+                self._PACK_STR, self.tlv_info[:self._PACK_SIZE])
+            self.port_id = self.tlv_info[self._PACK_SIZE:]
+        else:
+            self.subtype = kwargs['subtype']
+            self.port_id = kwargs['port_id']
+            self.len = self._PACK_SIZE + len(self.port_id)
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!HB', self.typelen, self.subtype) + self.port_id
+
+
+@lldp.set_tlv_type(LLDP_TLV_TTL)
+class TTL(LLDPBasicTLV):
+    """Time To Live TLV encoder/decoder class
+
+    ============== =====================================
+    Attribute      Description
+    ============== =====================================
+    buf            Binary data to parse.
+    ttl            Time To Live.
+    ============== =====================================
+    """
+    _PACK_STR = '!H'
+    _PACK_SIZE = struct.calcsize(_PACK_STR)
+    _LEN_MIN = _PACK_SIZE
+    _LEN_MAX = _PACK_SIZE
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(TTL, self).__init__(buf, *args, **kwargs)
+        if buf:
+            (self.ttl, ) = struct.unpack(
+                self._PACK_STR, self.tlv_info[:self._PACK_SIZE])
+        else:
+            self.ttl = kwargs['ttl']
+            self.len = self._PACK_SIZE
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!HH', self.typelen, self.ttl)
+
+
+@lldp.set_tlv_type(LLDP_TLV_PORT_DESCRIPTION)
+class PortDescription(LLDPBasicTLV):
+    """Port description TLV encoder/decoder class
+
+    ================= =====================================
+    Attribute         Description
+    ================= =====================================
+    buf               Binary data to parse.
+    port_description  Port description.
+    ================= =====================================
+    """
+    _LEN_MAX = 255
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(PortDescription, self).__init__(buf, *args, **kwargs)
+        if buf:
+            pass
+        else:
+            self.port_description = kwargs['port_description']
+            self.len = len(self.port_description)
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!H', self.typelen) + self.port_description
+
+    @property
+    def port_description(self):
+        return self.tlv_info
+
+    @port_description.setter
+    def port_description(self, value):
+        self.tlv_info = value
+
+
+@lldp.set_tlv_type(LLDP_TLV_SYSTEM_NAME)
+class SystemName(LLDPBasicTLV):
+    """System name TLV encoder/decoder class
+
+    ================= =====================================
+    Attribute         Description
+    ================= =====================================
+    buf               Binary data to parse.
+    system_name       System name.
+    ================= =====================================
+    """
+    _LEN_MAX = 255
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(SystemName, self).__init__(buf, *args, **kwargs)
+        if buf:
+            pass
+        else:
+            self.system_name = kwargs['system_name']
+            self.len = len(self.system_name)
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!H', self.typelen) + self.tlv_info
+
+    @property
+    def system_name(self):
+        return self.tlv_info
+
+    @system_name.setter
+    def system_name(self, value):
+        self.tlv_info = value
+
+
+@lldp.set_tlv_type(LLDP_TLV_SYSTEM_DESCRIPTION)
+class SystemDescription(LLDPBasicTLV):
+    """System description TLV encoder/decoder class
+
+    =================== =====================================
+    Attribute           Description
+    =================== =====================================
+    buf                 Binary data to parse.
+    system_description  System description.
+    =================== =====================================
+    """
+    _LEN_MAX = 255
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(SystemDescription, self).__init__(buf, *args, **kwargs)
+        if buf:
+            pass
+        else:
+            self.system_description = kwargs['system_description']
+            self.len = len(self.system_description)
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!H', self.typelen) + self.tlv_info
+
+    @property
+    def system_description(self):
+        return self.tlv_info
+
+    @system_description.setter
+    def system_description(self, value):
+        self.tlv_info = value
+
+
+@lldp.set_tlv_type(LLDP_TLV_SYSTEM_CAPABILITIES)
+class SystemCapabilities(LLDPBasicTLV):
+    """System Capabilities TLV encoder/decoder class
+
+    ================= =====================================
+    Attribute         Description
+    ================= =====================================
+    buf               Binary data to parse.
+    system_cap        System Capabilities.
+    enabled_cap       Enabled Capabilities.
+    ================= =====================================
+    """
+    # system cap(2) + enabled cap(2)
+    _PACK_STR = '!HH'
+    _PACK_SIZE = struct.calcsize(_PACK_STR)
+    _LEN_MIN = _PACK_SIZE
+    _LEN_MAX = _PACK_SIZE
+
+    # System Capabilities
+    CAP_REPEATER = (1 << 1)             # IETF RFC 2108
+    CAP_MAC_BRIDGE = (1 << 2)           # IEEE Std 802.1D
+    CAP_WLAN_ACCESS_POINT = (1 << 3)    # IEEE Std 802.11 MIB
+    CAP_ROUTER = (1 << 4)               # IETF RFC 1812
+    CAP_TELEPHONE = (1 << 5)            # IETF RFC 4293
+    CAP_DOCSIS = (1 << 6)               # IETF RFC 4639 and IETF RFC 4546
+    CAP_STATION_ONLY = (1 << 7)         # IETF RFC 4293
+    CAP_CVLAN = (1 << 8)                # IEEE Std 802.1Q
+    CAP_SVLAN = (1 << 9)                # IEEE Std 802.1Q
+    CAP_TPMR = (1 << 10)                # IEEE Std 802.1Q
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(SystemCapabilities, self).__init__(buf, *args, **kwargs)
+        if buf:
+            (self.system_cap, self.enabled_cap) = struct.unpack(
+                self._PACK_STR, self.tlv_info[:self._PACK_SIZE])
+        else:
+            self.system_cap = kwargs['system_cap']
+            self.enabled_cap = kwargs['enabled_cap']
+            self.len = self._PACK_SIZE
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!HHH',
+                           self.typelen, self.system_cap, self.enabled_cap)
+
+
+@lldp.set_tlv_type(LLDP_TLV_MANAGEMENT_ADDRESS)
+class ManagementAddress(LLDPBasicTLV):
+    """Management Address TLV encoder/decoder class
+
+    ================= =====================================
+    Attribute         Description
+    ================= =====================================
+    buf               Binary data to parse.
+    addr_subtype      Address type.
+    addr              Device address.
+    intf_subtype      Interface type.
+    intf_num          Interface number.
+    oid               Object ID.
+    ================= =====================================
+    """
+    _LEN_MIN = 9
+    _LEN_MAX = 167
+
+    _ADDR_PACK_STR = '!BB'    # address string length, address subtype
+    _ADDR_PACK_SIZE = struct.calcsize(_ADDR_PACK_STR)
+    _ADDR_LEN_MIN = 1
+    _ADDR_LEN_MAX = 31
+
+    _INTF_PACK_STR = '!BIB'   # interface subtype, interface number, oid length
+    _INTF_PACK_SIZE = struct.calcsize(_INTF_PACK_STR)
+    _OID_LEN_MIN = 0
+    _OID_LEN_MAX = 128
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(ManagementAddress, self).__init__(buf, *args, **kwargs)
+        if buf:
+            (self.addr_len, self.addr_subtype) = struct.unpack(
+                self._ADDR_PACK_STR, self.tlv_info[:self._ADDR_PACK_SIZE])
+            assert self._addr_len_valid()
+            offset = self._ADDR_PACK_SIZE + self.addr_len - 1
+            self.addr = self.tlv_info[self._ADDR_PACK_SIZE:offset]
+
+            (self.intf_subtype, self.intf_num, self.oid_len) = struct.unpack(
+                self._INTF_PACK_STR,
+                self.tlv_info[offset:offset + self._INTF_PACK_SIZE])
+            assert self._oid_len_valid()
+
+            offset = offset + self._INTF_PACK_SIZE
+            self.oid = self.tlv_info[offset:]
+        else:
+            self.addr_subtype = kwargs['addr_subtype']
+            self.addr = kwargs['addr']
+            self.addr_len = len(self.addr) + 1  # 1 octet subtype
+            assert self._addr_len_valid()
+
+            self.intf_subtype = kwargs['intf_subtype']
+            self.intf_num = kwargs['intf_num']
+
+            self.oid = kwargs['oid']
+            self.oid_len = len(self.oid)
+            assert self._oid_len_valid()
+
+            self.len = self._ADDR_PACK_SIZE + self.addr_len - 1 \
+                + self._INTF_PACK_SIZE + self.oid_len
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        tlv_info = struct.pack(self._ADDR_PACK_STR,
+                               self.addr_len, self.addr_subtype)
+        tlv_info += self.addr
+        tlv_info += struct.pack(self._INTF_PACK_STR,
+                                self.intf_subtype, self.intf_num, self.oid_len)
+        tlv_info += self.oid
+        return struct.pack('!H', self.typelen) + tlv_info
+
+    def _addr_len_valid(self):
+        return (self._ADDR_LEN_MIN <= self.addr_len or
+                self.addr_len <= self._ADDR_LEN_MAX)
+
+    def _oid_len_valid(self):
+        return self._OID_LEN_MIN <= self.oid_len <= self._OID_LEN_MAX
+
+
+@lldp.set_tlv_type(LLDP_TLV_ORGANIZATIONALLY_SPECIFIC)
+class OrganizationallySpecific(LLDPBasicTLV):
+    """Organizationally Specific TLV encoder/decoder class
+
+    ================= =============================================
+    Attribute         Description
+    ================= =============================================
+    buf               Binary data to parse.
+    oui               Organizationally unique ID.
+    subtype           Organizationally defined subtype.
+    info              Organizationally defined information string.
+    ================= =============================================
+    """
+    _PACK_STR = '!3sB'
+    _PACK_SIZE = struct.calcsize(_PACK_STR)
+    _LEN_MIN = _PACK_SIZE
+    _LEN_MAX = 511
+
+    def __init__(self, buf=None, *args, **kwargs):
+        super(OrganizationallySpecific, self).__init__(buf, *args, **kwargs)
+        if buf:
+            (self.oui, self.subtype) = struct.unpack(
+                self._PACK_STR, self.tlv_info[:self._PACK_SIZE])
+            self.info = self.tlv_info[self._PACK_SIZE:]
+        else:
+            self.oui = kwargs['oui']
+            self.subtype = kwargs['subtype']
+            self.info = kwargs['info']
+            self.len = self._PACK_SIZE + len(self.info)
+            assert self._len_valid()
+            self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len
+
+    def serialize(self):
+        return struct.pack('!H3sB', self.typelen, self.oui,
+                           self.subtype) + self.info
+
+
+lldp.set_classes(lldp._tlv_parsers)