コード例 #1
0
ファイル: hopopt.py プロジェクト: lorenzatoandrea/PyPCAPKit
    def _read_opt_smf_dpd(self, code, *, desc):
        """Read HOPOPT SMF_DPD option.

        Structure of HOPOPT SMF_DPD option [RFC 5570]:
            * IPv6 SMF_DPD Option Header in I-DPD mode
                 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
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                               ...              |0|0|0|  01000  | Opt. Data Len |
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |0|TidTy| TidLen|             TaggerID (optional) ...           |
                +-+-+-+-+-+-+-+-+               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |                               |            Identifier  ...
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                Octets      Bits        Name                        Description
                  0           0     hopopt.smf_dpd.type         Option Type
                  0           0     hopopt.smf_dpd.type.value   Option Number
                  0           0     hopopt.smf_dpd.type.action  Action (00)
                  0           2     hopopt.smf_dpd.type.change  Change Flag (0)
                  1           8     hopopt.smf_dpd.length       Length of Option Data
                  2          16     hopopt.smf_dpd.dpd_type     DPD Type (0)
                  2          17     hopopt.smf_dpd.tid_type     TaggerID Type
                  2          20     hopopt.smf_dpd.tid_len      TaggerID Length
                  3          24     hopopt.smf_dpd.tid          TaggerID
                  ?           ?     hopopt.smf_dpd.id           Identifier

            * IPv6 SMF_DPD Option Header in H-DPD Mode
                 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
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                               ...              |0|0|0| OptType | Opt. Data Len |
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |1|    Hash Assist Value (HAV) ...
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                Octets      Bits        Name                        Description
                  0           0     hopopt.smf_dpd.type         Option Type
                  0           0     hopopt.smf_dpd.type.value   Option Number
                  0           0     hopopt.smf_dpd.type.action  Action (00)
                  0           2     hopopt.smf_dpd.type.change  Change Flag (0)
                  1           8     hopopt.smf_dpd.length       Length of Option Data
                  2          16     hopopt.smf_dpd.dpd_type     DPD Type (1)
                  2          17     hopopt.smf_dpd.hav          Hash Assist Value

        """
        _type = self._read_opt_type(code)
        _size = self._read_unpack(1)
        _tidd = self._read_binary(1)

        if _tidd[0] == '0':
            _mode = 'I-DPD'
            _tidt = _TID_TYPE.get(_tidd[1:4], 'Unassigned')
            _tidl = int(_tidd[4:], base=2)
            if _tidt == 'NULL':
                if _tidl != 0:
                    raise ProtocolError(f'{self.alias}: [Optno {code}] invalid format')
                _iden = self._read_fileng(_size-1)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    id=_iden,
                )
            elif _tidt == 'IPv4':
                if _tidl != 3:
                    raise ProtocolError(f'{self.alias}: [Optno {code}] invalid format')
                _tidf = self._read_fileng(4)
                _iden = self._read_fileng(_size-4)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    tid=ipaddress.ip_address(_tidf),
                    id=_iden,
                )
            elif _tidt == 'IPv6':
                if _tidl != 15:
                    raise ProtocolError(f'{self.alias}: [Optno {code}] invalid format')
                _tidf = self._read_fileng(15)
                _iden = self._read_fileng(_size-15)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    tid=ipaddress.ip_address(_tidf),
                    id=_iden,
                )
            else:
                _tidf = self._read_unpack(_tidl+1)
                _iden = self._read_fileng(_size-_tidl-2)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    tid=_tidf,
                    id=_iden,
                )
        elif _tidd[0] == '1':
            _data = self._read_binary(_size-1)

            opt = dict(
                desc=desc,
                type=_type,
                length=_size + 2,
                dpd_type=_mode,
                tid_type=_tidt,
                hav=_tidd[1:] + _data,
            )
        else:
            raise ProtocolError(f'{self.alias}: [Optno {code}] invalid format')

        return opt
コード例 #2
0
    def _read_opt_smf_dpd(self, code, *, desc):
        """Read HOPOPT ``SMF_DPD`` option.

        Structure of HOPOPT ``SMF_DPD`` option [:rfc:`5570`]:

        * IPv6 ``SMF_DPD`` option header in **I-DPD** mode

          .. code:: 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
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                            ...              |0|0|0|  01000  | Opt. Data Len |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |0|TidTy| TidLen|             TaggerID (optional) ...           |
             +-+-+-+-+-+-+-+-+               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                               |            Identifier  ...
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        * IPv6 ``SMF_DPD`` option header in **H-DPD** mode

          .. code:: 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
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                            ...              |0|0|0| OptType | Opt. Data Len |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |1|    Hash Assist Value (HAV) ...
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        Args:
            code (int): option type value

        Keyword Args:
            desc (str): option description

        Returns:
            Union[DataType_Opt_SMF_I_PDP, DataType_Opt_SMF_H_PDP]: parsed option data

        Raises:
            ProtocolError: If the option is malformed.

        """
        _type = self._read_opt_type(code)
        _size = self._read_unpack(1)
        _tidd = self._read_binary(1)

        if _tidd[0] == '0':
            _mode = 'I-DPD'
            _tidt = _TID_TYPE.get(_tidd[1:4])
            _tidl = int(_tidd[4:], base=2)

            if _tidt == _TID_TYPE.NULL:
                if _tidl != 0:
                    raise ProtocolError(
                        f'{self.alias}: [OptNo {code}] invalid format')
                _iden = self._read_fileng(_size - 1)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    id=_iden,
                )
            elif _tidt == _TID_TYPE.IPv4:
                if _tidl != 3:
                    raise ProtocolError(
                        f'{self.alias}: [OptNo {code}] invalid format')
                _tidf = self._read_fileng(4)
                _iden = self._read_fileng(_size - 4)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    tid=ipaddress.ip_address(_tidf),
                    id=_iden,
                )
            elif _tidt == _TID_TYPE.IPv6:
                if _tidl != 15:
                    raise ProtocolError(
                        f'{self.alias}: [OptNo {code}] invalid format')
                _tidf = self._read_fileng(15)
                _iden = self._read_fileng(_size - 15)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    tid=ipaddress.ip_address(_tidf),
                    id=_iden,
                )
            else:
                _tidf = self._read_unpack(_tidl + 1)
                _iden = self._read_fileng(_size - _tidl - 2)

                opt = dict(
                    desc=desc,
                    type=_type,
                    length=_size + 2,
                    dpd_type=_mode,
                    tid_type=_tidt,
                    tid_len=_tidl,
                    tid=_tidf,
                    id=_iden,
                )
        elif _tidd[0] == '1':
            _mode = 'H-DPD'
            _tidt = _TID_TYPE.get(_tidd[1:4])
            _data = self._read_binary(_size - 1)

            opt = dict(
                desc=desc,
                type=_type,
                length=_size + 2,
                dpd_type=_mode,
                tid_type=_tidt,
                hav=_tidd[1:] + _data,
            )
        else:
            raise ProtocolError(f'{self.alias}: [OptNo {code}] invalid format')

        return opt