Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pcapkit/foundation/engines/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,14 @@ class MyMixin(Engine): # not registered
Args:
extractor: :class:`~pcapkit.foundation.extraction.Extractor` instance.

.. versionchanged:: 1.3.0

:attr:`~EngineBase.name` and :attr:`~EngineBase.module` are properties,
read from ``__engine_name__`` and ``__engine_module__`` or else from the
class, where they were abstract class methods each engine implemented.
A subclass registers itself with
:class:`~pcapkit.foundation.extraction.Extractor` at class definition.

.. versionchanged:: 1.5.0

Registration is opt-in, under the ``engine`` class keyword, which
Expand Down
37 changes: 37 additions & 0 deletions pcapkit/foundation/extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ class Extractor(Generic[_P]):
For supported engines, please refer to
:meth:`~pcapkit.foundation.extraction.Extractor.run`.

.. versionchanged:: 1.2.0

``strict`` is renamed ``reasm_strict``, with no alias, and
``reasm_store`` is inserted after it, so a positional argument from
``trace`` onwards moves one place along.

.. versionchanged:: 1.5.0

``layer`` and ``protocol`` stop the dissection where they say, which
Expand Down Expand Up @@ -365,6 +371,11 @@ def reassembly(self) -> 'ReassemblyData':
UnsupportedCall: If :attr:`self._flag_r <pcapkit.foundation.extraction.Extractor._flag_r>`
is :data:`False`, as reassembly is disabled.

.. versionchanged:: 1.1.1

Raises :exc:`~pcapkit.utilities.exceptions.UnsupportedCall` when
reassembly is disabled, where 1.1.0 built the record regardless.

"""
if self._flag_r:
data = ReassemblyData(
Expand All @@ -385,6 +396,11 @@ def trace(self) -> 'TraceFlowData':
UnsupportedCall: If :attr:`self._flag_t <pcapkit.foundation.extraction.Extractor._flag_t>`
is :data:`False`, as flow tracing is disabled.

.. versionchanged:: 1.1.1

Raises :exc:`~pcapkit.utilities.exceptions.UnsupportedCall` when
flow tracing is disabled, where 1.1.0 built the record regardless.

"""
if self._flag_t:
data = TraceFlowData(
Expand Down Expand Up @@ -448,6 +464,11 @@ class it names, restores the shipped entry rather than storing
RegistryWarning: If a different dumper is already registered for
``format``; it is overwritten.

.. versionchanged:: 1.3.0

``dumper``, a module descriptor or a class, replaces the ``module``
and ``class_`` name pair, with no alias.

"""
shipped = cls._shipped_output.get(format)
if isinstance(dumper, ModuleDescriptor) and (shipped is None or dumper != shipped[0]):
Expand Down Expand Up @@ -499,6 +520,12 @@ def register_engine(cls, name: 'str', engine: 'ModuleDescriptor[Engine] | Type[E
RegistryWarning: If a different class is already registered under
``name``; it is overwritten.

.. versionchanged:: 1.3.0

``engine``, a module descriptor or a class, replaces the ``module``
and ``class_`` name pair, with no alias, and the engine name it
took as ``engine`` is ``name``.

"""
# The shipped built-in is matched before the descriptor is resolved, so
# restoring an optional engine does not import it (#1363).
Expand Down Expand Up @@ -587,6 +614,11 @@ def register_reassembly(cls, protocol: 'str', reassembly: 'ModuleDescriptor[Reas
RegistryWarning: If a different class is already registered under
``protocol``; it is overwritten.

.. versionchanged:: 1.3.0

``reassembly``, a module descriptor or a class, replaces the
``module`` and ``class_`` name pair, with no alias.

"""
shipped = cls._shipped_reassembly.get(protocol)
if isinstance(reassembly, ModuleDescriptor) and reassembly != shipped:
Expand Down Expand Up @@ -668,6 +700,11 @@ def register_traceflow(cls, protocol: 'str', traceflow: 'ModuleDescriptor[TraceF
RegistryWarning: If a different class is already registered under
``protocol``; it is overwritten.

.. versionchanged:: 1.3.0

``traceflow``, a module descriptor or a class, replaces the
``module`` and ``class_`` name pair, with no alias.

"""
shipped = cls._shipped_traceflow.get(protocol)
if isinstance(traceflow, ModuleDescriptor) and traceflow != shipped:
Expand Down
9 changes: 6 additions & 3 deletions pcapkit/foundation/reassembly/ipv6.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,12 @@ def _rectify_header(self, header: 'bytes', proto: 'TransType') -> 'bytes':
the reassembled packet, and that the Next Header field of the last header
of the unfragmentable part comes from the Fragment header's. Left alone,
the reassembled datagram would advertise a Fragment header on a datagram
that is by definition no longer a fragment. Every toolkit adapter leaves
the Fragment header's *octets* out of ``header``, but none rewrites the
field that points at it, so only that field is left to fix.
that is by definition no longer a fragment. The four toolkit adapters
that build IPv6 reassembly data, :mod:`~pcapkit.toolkit.pcap`,
:mod:`~pcapkit.toolkit.pcapng`, :mod:`~pcapkit.toolkit.dpkt` and
:mod:`~pcapkit.toolkit.scapy`, leave the Fragment header's *octets* out
of ``header``, but none rewrites the field that points at it, so only
that field is left to fix.

Args:
header: Raw header octets of the fragment at fragment offset zero.
Expand Down
9 changes: 9 additions & 0 deletions pcapkit/foundation/reassembly/reassembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,15 @@ class MyMixin(Reassembly): # not registered
timeout: reassembly timeout in seconds, on the capture's own clock;
:data:`None` selects the protocol's :attr:`__timeout__` default

.. versionchanged:: 1.3.0

:attr:`name` and :attr:`protocol` are read from ``__protocol_name__``
and ``__protocol_type__``, where they were abstract properties each
reassembly implemented, and the built-in names are short: ``'IPv4'``
rather than ``'Internet Protocol version 4'``. A subclass registers
itself with :class:`~pcapkit.foundation.extraction.Extractor` at class
definition.

.. versionchanged:: 1.5.0

Registration is opt-in, under the ``protocol`` class keyword; 1.4.x
Expand Down
16 changes: 16 additions & 0 deletions pcapkit/foundation/registry/foundation.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ def register_extractor_engine(name: 'str', module: 'ModuleDescriptor[Engine] | T
the engine ``name`` shipped with, which restores it)
class\_: class name

.. versionchanged:: 1.3.0

The engine name, which was ``engine``, is ``name``, with no alias.

"""
if isinstance(module, str):
module = cast('ModuleDescriptor[Engine]', ModuleDescriptor(module, class_))
Expand Down Expand Up @@ -127,6 +131,10 @@ def register_dumper(format: 'str', module: 'ModuleDescriptor[Dumper] | Type[Dump
* :func:`pcapkit.foundation.registry.foundation.register_extractor_dumper`
* :func:`pcapkit.foundation.registry.foundation.register_traceflow_dumper`

.. versionchanged:: 1.3.0

``ext`` is keyword-only.

"""
if isinstance(module, str):
module = cast('ModuleDescriptor[Dumper]', ModuleDescriptor(module, class_))
Expand Down Expand Up @@ -161,6 +169,10 @@ def register_extractor_dumper(format: 'str', module: 'ModuleDescriptor[Dumper] |
class\_: class name
ext: file extension

.. versionchanged:: 1.3.0

``ext`` is keyword-only.

"""
if isinstance(module, str):
module = cast('ModuleDescriptor[Dumper]', ModuleDescriptor(module, class_))
Expand Down Expand Up @@ -194,6 +206,10 @@ def register_traceflow_dumper(format: 'str', module: 'ModuleDescriptor[Dumper] |
class\_: class name
ext: file extension

.. versionchanged:: 1.3.0

``ext`` is keyword-only.

"""
if isinstance(module, str):
module = cast('ModuleDescriptor[Dumper]', ModuleDescriptor(module, class_))
Expand Down
7 changes: 6 additions & 1 deletion pcapkit/foundation/registry/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ class rather than supplied by a caller, and this function is the funnel
:class:`~pcapkit.foundation.reassembly.reassembly.ReassemblyMeta` and
:class:`~pcapkit.foundation.traceflow.traceflow.TraceFlowMeta` fall back to
:class:`~pcapkit.protocols.misc.raw.Raw`. The registry redesign of
:issue:`514` kept this key, so the collision is reported here rather than
:issue:`514` left this key unchanged and recorded the shared namespace as a
risk it did not fix, so the collision is reported here rather than
resolved.

Args:
Expand Down Expand Up @@ -1036,6 +1037,10 @@ def register_apptype(code: 'int | Enum_AppType', module: 'str | ModuleDescriptor
* :func:`pcapkit.foundation.registry.register_udp`
* :func:`pcapkit.foundation.registry.register_sctp`

.. versionremoved:: 1.3.1

``register_port``, which this replaces with no alias.

.. versionchanged:: 1.5.0

The keyword-only ``proto`` is replaced by ``*transport``, one transport
Expand Down
18 changes: 18 additions & 0 deletions pcapkit/foundation/traceflow/traceflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,15 @@ class it names, restores the shipped entry rather than storing
dumper: module descriptor or a :class:`dictdumper.dumper.Dumper` subclass
ext: file extension

.. versionremoved:: 1.2.0

``register``, which this replaces with no alias.

.. versionchanged:: 1.3.0

``dumper``, a module descriptor or a class, replaces the ``module``
and ``class_`` name pair, with no alias.

"""
from pcapkit.interface.registry import ( # pylint: disable=import-outside-toplevel
restore_shipped_dumper, same_entry)
Expand Down Expand Up @@ -509,6 +518,15 @@ class MyMixin(TraceFlow): # not registered
bidirectional: trace both halves of a conversation as one flow
analyse: reassemble each flow's application layer

.. versionchanged:: 1.3.0

:attr:`name` and :attr:`protocol` are read from ``__protocol_name__``
and ``__protocol_type__``, where they were abstract properties each
flow tracing class implemented, and the built-in name is short:
``'TCP'`` rather than ``'Transmission Control Protocol'``. A subclass
registers itself with :class:`~pcapkit.foundation.extraction.Extractor`
at class definition.

.. versionchanged:: 1.5.0

Registration is opt-in, under the ``protocol`` class keyword; 1.4.x
Expand Down
6 changes: 6 additions & 0 deletions pcapkit/interface/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ def extract(fin: 'Optional[str | IO[bytes]]' = None, fout: 'Optional[str]' = Non
Returns:
An :class:`~pcapkit.foundation.extraction.Extractor` object.

.. versionchanged:: 1.2.0

``strict`` is renamed ``reasm_strict``, with no alias, and
``reasm_store`` is inserted after it, so a positional argument from
``trace`` onwards moves one place along.

.. versionchanged:: 1.5.0

``reasm_timeout``, ``trace_bidirectional`` and ``trace_analyse`` are
Expand Down
18 changes: 9 additions & 9 deletions pcapkit/utilities/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ def read_flag(name: 'str', default: 'bool' = False) -> 'bool':
IPV6_TCP_WARNED_LIMIT = read_limit('IPV6_TCP_WARNED_LIMIT', 32, risk=(
'each capture remembered pins one of its packets in memory'))

#: int: Most objects :meth:`DictDumper._append_fallback
#: <pcapkit.dumpkit.common.DictDumper._append_fallback>` expands for one
#: top-level object, counting an object once per time it is met,
#: int: Most objects
#: :meth:`DictDumper._append_fallback <pcapkit.dumpkit.common.DictDumper._append_fallback>`
#: expands for one top-level object, counting an object once per time it is met,
#: :envvar:`PCAPKIT_FALLBACK_LIMIT`; ``-1`` expands without bound.
#:
#: No fallback object in the ``foundation``, ``dumpkit`` or ``interface`` test
Expand Down Expand Up @@ -261,9 +261,9 @@ def read_flag(name: 'str', default: 'bool' = False) -> 'bool':
READ_CHUNK = read_limit('READ_CHUNK', 1 << 20, minimum=1, risk=(
'a bogus record length allocates up to that many octets in one read'))

#: int: Ceiling on the zero-padding :meth:`FieldBase.unpack
#: <pcapkit.corekit.fields.field.FieldBase.unpack>` will still perform for a
#: field whose declared length outruns its buffer.
#: int: Ceiling on the zero-padding
#: :meth:`FieldBase.unpack <pcapkit.corekit.fields.field.FieldBase.unpack>`
#: will still perform for a field whose declared length outruns its buffer.
#:
#: This is libpcap's own ``MAXIMUM_SNAPLEN`` -- the point past which libpcap
#: itself treats a capture's declared snapshot length as corrupt or
Expand Down Expand Up @@ -299,9 +299,9 @@ def read_flag(name: 'str', default: 'bool' = False) -> 'bool':
MAX_ZERO_PAD_LENGTH = read_limit('MAX_ZERO_PAD_LENGTH', 0x40_000, risk=(
'a hostile capture can declare a field that long and have it zero-filled in memory'))

#: int: Shortfall :meth:`FieldBase.unpack
#: <pcapkit.corekit.fields.field.FieldBase.unpack>` will always zero-pad for,
#: whatever else a parse has already padded.
#: int: Shortfall
#: :meth:`FieldBase.unpack <pcapkit.corekit.fields.field.FieldBase.unpack>`
#: will always zero-pad for, whatever else a parse has already padded.
#:
#: :data:`MAX_ZERO_PAD_LENGTH` bounds each field on its own, and a packet holds
#: many fields, so it leaves the *sum* unbounded: a declared length just under the
Expand Down
Loading