Source code for pcapkit.protocols.link.vlan
# -*- coding: utf-8 -*-
"""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 pcapkit.const.vlan.priority_level import PriorityLevel as _PCP
from pcapkit.protocols.link.link import Link
from pcapkit.utilities.exceptions import UnsupportedCall
__all__ = ['VLAN']
[docs]class VLAN(Link):
"""This class implements 802.1Q Customer VLAN Tag Type."""
##########################################################################
# Properties.
##########################################################################
@property
def name(self):
"""Name of current protocol.
:rtype: Literal['802.1Q Customer VLAN Tag Type']
"""
return '802.1Q Customer VLAN Tag Type'
@property
def alias(self):
"""Acronym of corresponding protocol.
:rtype: Literal['802.1Q']
"""
return '802.1Q'
@property
def length(self):
"""Header length of current protocol.
:rtype: Literal[4]
"""
return 4
@property
def protocol(self):
"""Name of next layer protocol.
:rtype: pcapkit.const.reg.ethertype.EtherType
"""
return self._info.type # pylint: disable=E1101
##########################################################################
# Methods.
##########################################################################
[docs] def read(self, length=None, **kwargs): # pylint: disable=unused-argument
"""Read 802.1Q Customer VLAN Tag Type.
Args:
length (Optional[int]): Length of packet data.
Keyword Args:
**kwargs: Arbitrary keyword arguments.
Returns:
DataType_VLAN: Parsed packet data.
"""
if length is None:
length = len(self)
_tcif = self._read_binary(2)
_type = self._read_protos(2)
vlan = dict(
tci=dict(
pcp=_PCP.get(int(_tcif[:3], base=2)),
dei=bool(_tcif[3]),
vid=int(_tcif[4:], base=2),
),
type=_type,
)
length -= 4
vlan['packet'] = self._read_packet(header=4, payload=length)
return self._decode_next_layer(vlan, _type, length)
[docs] def make(self, **kwargs):
"""Make (construct) packet data.
Keyword Args:
**kwargs: Arbitrary keyword arguments.
Returns:
bytes: Constructed packet data.
"""
raise NotImplementedError
##########################################################################
# Data models.
##########################################################################
[docs] def __length_hint__(self):
"""Return an estimated length for the object.
:rtype: Literal[4]
"""
return 4
[docs] @classmethod
def __index__(cls): # 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')