Source code for pcapkit.protocols.internet.mh

# -*- coding: utf-8 -*-
# pylint: disable=fixme
"""mobility header

:mod:`pcapkit.protocols.internet.mh` contains
:class:`~pcapkit.protocols.internet.mh.MH` only,
which implements extractor for Mobility Header
(MH) [*]_, whose structure is described as below:

======= ========= ================== ===============================
Octets      Bits        Name                    Description
======= ========= ================== ===============================
  0           0   ``mh.next``                 Next Header
  1           8   ``mh.length``               Header Length
  2          16   ``mh.type``                 Mobility Header Type
  3          24                               Reserved
  4          32   ``mh.chksum``               Checksum
  6          48   ``mh.data``                 Message Data
======= ========= ================== ===============================

.. [*] https://en.wikipedia.org/wiki/Mobile_IP#Changes_in_IPv6_for_Mobile_IPv6

"""
# TODO: Implements extractor for message data of all MH types.

from pcapkit.const.mh.packet import Packet as _MOBILITY_TYPE
from pcapkit.const.reg.transtype import TransType
from pcapkit.protocols.internet.internet import Internet
from pcapkit.utilities.exceptions import UnsupportedCall

__all__ = ['MH']


[docs]class MH(Internet): """This class implements Mobility Header.""" ########################################################################## # Properties. ########################################################################## @property def name(self): """Name of current protocol. :rtype: Literal['Mobility Header'] """ return 'Mobility Header' @property def length(self): """Header length of current protocol. :rtype: int """ return self._info.length # pylint: disable=E1101 @property def payload(self): """Payload of current instance. Raises: UnsupportedCall: if the protocol is used as an IPv6 extension header :rtype: pcapkit.protocols.protocol.Protocol """ if self.extension: # pylint: disable=E1101 raise UnsupportedCall(f"'{self.__class__.__name__}' object has no attribute 'payload'") return self._next @property def protocol(self): """Name of next layer protocol. :rtype: pcapkit.const.reg.transtype.TransType """ return self._info.next # pylint: disable=E1101 ########################################################################## # Methods. ##########################################################################
[docs] def read(self, length=None, *, extension=False, **kwargs): # pylint: disable=arguments-differ,unused-argument """Read Mobility Header. Structure of MH header [:rfc:`6275`]:: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Payload Proto | Header Len | MH Type | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | . . . Message Data . . . | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: length (Optional[int]): Length of packet data. Keyword Args: extension (bool): If the packet is used as an IPv6 extension header. **kwargs: Arbitrary keyword arguments. Returns: DataType_MH: Parsed packet data. """ if length is None: length = len(self) _next = self._read_protos(1) _hlen = self._read_unpack(1) _type = self._read_unpack(1) _temp = self._read_fileng(1) _csum = self._read_fileng(2) _data = self._read_fileng((_hlen+1)*8) mh = dict( next=_next, length=(_hlen + 1) * 8, type=_MOBILITY_TYPE.get(_type), chksum=_csum, data=_data, ) length -= mh['length'] mh['packet'] = self._read_packet(header=mh['length'], payload=length) if extension: self._protos = None return mh return self._decode_next_layer(mh, _next, 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 __post_init__(self, file, length=None, *, extension=False, **kwargs): # pylint: disable=arguments-differ """Post initialisation hook. Args: file (io.BytesIO): Source packet stream. length (Optional[int]): Length of packet data. Keyword Args: extension (bool): If the protocol is used as an IPv6 extension header. **kwargs: Arbitrary keyword arguments. See Also: For construction argument, please refer to :meth:`make`. """ #: bool: If the protocol is used as an IPv6 extension header. self._extf = extension # call super __post_init__ super().__post_init__(file, length, extension=extension, **kwargs)
[docs] def __length_hint__(self): """Return an estimated length for the object. :rtype: Literal[6] """ return 6
[docs] @classmethod def __index__(cls): # pylint: disable=invalid-index-returned """Numeral registry index of the protocol. Returns: pcapkit.const.reg.transtype.TransType: Numeral registry index of the protocol in `IANA`_. .. _IANA: https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml """ return TransType(135)