Source code for pcapkit.protocols.link.vlan

# -*- coding: utf-8 -*-
"""VLAN - 802.1Q Customer VLAN Tag Type
==========================================

:mod:`pcapkit.protocols.link.vlan` contains
:class:`~pcapkit.protocols.link.vlan.VLAN`
only, which implements extractor for 802.1Q
Customer VLAN Tag Type [*]_, whose structure is
described as below:

======= ========= ====================== =============================
Octets      Bits        Name                    Description
======= ========= ====================== =============================
  1           0   ``vlan.tci``              Tag Control Information
  1           0   ``vlan.tci.pcp``          Priority Code Point
  1           3   ``vlan.tci.dei``          Drop Eligible Indicator
  1           4   ``vlan.tci.vid``          VLAN Identifier
  3          24   ``vlan.type``             Protocol (Internet Layer)
======= ========= ====================== =============================

.. [*] https://en.wikipedia.org/wiki/IEEE_802.1Q

"""
from typing import TYPE_CHECKING

from pcapkit.const.vlan.priority_level import PriorityLevel as RegType_PriorityLevel
from pcapkit.protocols.data.link.vlan import TCI as DataType_TCI
from pcapkit.protocols.data.link.vlan import VLAN as DataType_VLAN
from pcapkit.protocols.link.link import Link
from pcapkit.utilities.exceptions import UnsupportedCall

if TYPE_CHECKING:
    from typing import Any, NoReturn, Optional

    from typing_extensions import Literal

    from pcapkit.const.reg.ethertype import EtherType as RegType_EtherType

__all__ = ['VLAN']


[docs]class VLAN(Link[DataType_VLAN]): """This class implements 802.1Q Customer VLAN Tag Type.""" ########################################################################## # Properties. ########################################################################## @property def name(self) -> 'Literal["802.1Q Customer VLAN Tag Type"]': """Name of current protocol.""" return '802.1Q Customer VLAN Tag Type' @property def alias(self) -> 'Literal["802.1Q"]': """Acronym of corresponding protocol.""" return '802.1Q' @property def info_name(self) -> 'Literal["c_tag"]': """Key name of the :attr:`info` dict.""" return 'c_tag' @property def length(self) -> 'Literal[4]': """Header length of current protocol.""" return 4 @property def protocol(self) -> 'RegType_EtherType': """Name of next layer protocol.""" return self._info.type ########################################################################## # Methods. ##########################################################################
[docs] def read(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'DataType_VLAN': # pylint: disable=unused-argument """Read 802.1Q Customer VLAN Tag Type. Structure of 802.1Q Customer VLAN Tag Type [`IEEE 802.1Q <https://standards.ieee.org/ieee/802.1Q/6844/>`__]: .. code-block:: text 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | TCI | | |-------------------------------| | | P |D| | Type | | C |E| VID | | | P |I| | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: length: Length of packet data. **kwargs: Arbitrary keyword arguments. Returns: Parsed packet data. """ if length is None: length = len(self) _tcif = self._read_binary(2) _type = self._read_protos(2) vlan = DataType_VLAN( tci=DataType_TCI( pcp=RegType_PriorityLevel.get(int(_tcif[:3], base=2)), dei=bool(_tcif[3]), vid=int(_tcif[4:], base=2), ), type=_type, ) return self._decode_next_layer(vlan, _type, length - self.length)
[docs] def make(self, **kwargs: 'Any') -> 'NoReturn': """Make (construct) packet data. Args: **kwargs: Arbitrary keyword arguments. Returns: Constructed packet data. """ raise NotImplementedError
########################################################################## # Data models. ########################################################################## def __length_hint__(self) -> 'Literal[4]': """Return an estimated length for the object.""" return 4
[docs] @classmethod def __index__(cls) -> 'NoReturn': # pylint: disable=invalid-index-returned """Numeral registry index of the protocol. Raises: UnsupportedCall: This protocol has no registry entry. """ raise UnsupportedCall(f'{cls.__name__!r} object cannot be interpreted as an integer')