Base Class

pcapkit.foundation.reassembly.reassembly contains Reassembly only, which is an abstract base class for all reassembly classes, bases on algorithms described in RFC 791 and RFC 815, implements datagram reassembly of IP and TCP packets.

class pcapkit.foundation.reassembly.reassembly.Reassembly(*, strict=True, store=True, timeout=None)[source]

Bases: ReassemblyBase[_PT, _DT, _IT, _BT], Generic[_PT, _DT, _IT, _BT]

Base reassembly class.

Example

Registration is opt-in. Pass keyword argument protocol at class definition to register the reassembly under that protocol name:

class MyProtocol(Reassembly, protocol='my_protocol'):
    ...

Omit it and the subclass is not registered, which is how a class that is not meant to be selectable by name declines:

class MyMixin(Reassembly):  # not registered
    ...

Such a class can still be registered later, on demand:

Extractor.register_reassembly('my_mixin', MyMixin)
Parameters:
  • strict (bool) – if return all datagrams (including those not implemented) when submit

  • store (bool) – if store reassembled datagram in memory, i.e., self._dtgram (if not, datagram will be discarded after callback)

  • timeout (float | None) – reassembly timeout in seconds, on the capture’s own clock; None selects the protocol’s __timeout__ default

See also

For more information on customisation and extension, please refer to Customisation & Extensions.

property name: str

Protocol name of current reassembly class.

Note

This property is also available as a class variable. Its value can be set by __protocol_name__ class attribute.

property protocol: Type[Protocol]

Protocol of current reassembly class.

Note

This property is also available as a class variable. Its value can be set by __protocol_type__ class attribute.

property registry: python:dict[str, ModuleDescriptor[ReassemblyBase] | typing.Type[ReassemblyBase]]

Mapping of protocol names to reassembly classes.

Note

This property is only available as a class variable, since it is defined on ReassemblyMeta. It reads __reassembly__, the single table every reassembly registration lands in, so it is not a per-class mapping.

property count: int

Total number of reassembled packets.

property datagram: tuple[_DT, ...]

Reassembled datagram.

Raises:

UnsupportedCall – If self._flag_d is set to False.

property timeout: float

Reassembly timeout, in seconds, of the current reassembly object.

A buffer whose first-arriving fragment is older than this many seconds on the capture’s own clock is abandoned rather than held for the life of the object – see expire(). math.inf disables expiry.

abstractmethod reassembly(info)

Reassembly procedure.

Parameters:

info (TypeVar(_PT, bound= Info)) – info dict of packets to be reassembled

abstractmethod submit(buf, **kwargs)

Submit reassembled payload.

Parameters:
  • buf (TypeVar(_BT, bound= Info)) – buffer dict of reassembled packets

  • **kwargs (Any) – arbitrary keyword arguments; implementations accept timeout, set when the buffer is being submitted because expire() abandoned it rather than because it completed or the capture ended

Return type:

list[TypeVar(_DT, bound= Info)]

expire(timestamp)

Abandon every buffer whose reassembly timeout has elapsed.

Parameters:

timestamp (float) – Current time on the capture’s clock, in seconds since the Unix epoch – i.e. the capture timestamp of the packet just handed to reassembly().

Return type:

list[TypeVar(_DT, bound= Info)]

Returns:

Datagrams of the buffers abandoned, reported with Completion.TIMEOUT. Empty when nothing expired, which is the overwhelmingly common case.

A buffer expires when more than timeout seconds separate timestamp from the capture timestamp of its first-arriving fragment, which is the deadline RFC 8200 Section 4.5 states (“within 60 seconds of the reception of the first-arriving fragment”) and which RFC 815 suggests implementing by reading “the clock when each first fragment arrives”. A later fragment therefore does not extend the deadline.

Note

The clock only advances when this reassembly object is fed, since a packet handed to it is the only evidence an offline parser has that capture time has moved on. For IPv4 and TCP that is nearly every frame of the relevant protocol; for IPv6 it is only the fragments, so an IPv6 buffer that stalls and is followed by no further IPv6 fragment is reported as Completion.PARTIAL at the end of the capture. That is the honest answer: the capture never shows that the deadline passed. A caller with an outside source of time may call this method itself to advance the clock.

fetch()

Fetch datagram.

Return type:

tuple[TypeVar(_DT, bound= Info), ...]

Returns:

Tuple of reassembled datagrams.

Fetch reassembled datagrams from self._dtgram and returns a tuple of such datagrams.

If no cache found, the method will call self.submit to forcedly obtain newly reassembled payload. Otherwise, the already calculated self._dtgram will be returned.

index(pkt_num)

Return datagram index.

Parameters:

pkt_num (int) – index of packet

Return type:

int | None

Returns:

Reassembled datagram index which was from No. pkt_num packet; if not found, returns None.

run(packets)

Run automatically.

Parameters:

packets (list[TypeVar(_PT, bound= Info)]) – list of packet dicts to be reassembled

classmethod register(callback, *, index=None)

Register callback function.

Parameters:
  • callback (Callable[[list[TypeVar(_DT, bound= Info)]], None]) – callback function, which will be called when reassembled datagram is obtained, with the list of reassembled datagrams as its only argument

  • index (int | None) – index to be inserted in the callback list,; by default, the callback will be appended to the end of the list

__callback_fn__: list[Callable[[list[_DT]], None]]

List of callback functions upon reassembled datagram.

_flag_s: bool

Strict mode flag. If set to True, all data will be returned, including those not completely reassembled; otherwise, only completely reassembled data will be returned.

Type:

bool

_flag_d: bool

Store mode flag. If set to True, all reassembled datagram will be stored in memory, i.e., self._dtgram; otherwise, datagram will be discarded after callback.

Type:

bool

_flag_n: bool

New datagram flag. If set to True, the self._dtgram will be repopulated.

Type:

bool

_timeout: float

Reassembly timeout in seconds, on the capture’s clock. math.inf disables expiry.

Type:

float

_buffer: dict[_IT, _BT]

Dict buffer field. This field is used to store reassembled packets in the form of {bufid: buffer}.

Type:

dict[_IT, _BT]

_dtgram: list[_DT]

List reassembled datagram. This list is used to store reassembled datagrams.

Type:

list[_DT]

__call__(packet)

Call packet reassembly.

Parameters:

packet (TypeVar(_PT, bound= Info)) – packet dict to be reassembled (detailed format described in corresponding protocol)

classmethod __init_subclass__(protocol=None, *args, **kwargs)[source]

Initialise subclass.

This method is to be used for registering the reassembly class to Extractor class.

Parameters:
  • protocol (str | None) – Protocol name to register the subclass under, lowercased. None (the default) skips registration entirely.

  • *args (Any) – Arbitrary positional arguments.

  • **kwargs (Any) – Arbitrary keyword arguments.

Raises:

UnsupportedCall – If any unrecognised class keyword is given.

Registration is opt-in: the subclass is registered if and only if protocol is given. This is what lets a subclass decline registration rather than having to inherit ReassemblyBase to avoid it, and it matches EnumSchema.__init_subclass__, which has guarded on its own code keyword all along.

Note

__protocol_name__ is not an opt-in. It supplies the name the reassembly reports, which it does whether or not the class is registered; only the keyword decides registration.

See also

For more details, please refer to pcapkit.foundation.extraction.Extractor.register_reassembly().

__protocol_name__: str

Protocol name of current reassembly object.

__protocol_type__: Type[ProtocolBase]

Protocol of current reassembly object.

__timeout__: float = inf

Default reassembly timeout, in seconds, for this protocol – overridden per protocol, e.g. IPv6.__timeout__. math.inf means “never expire”, which is the base default because nothing here knows what a protocol’s specification asks for.

Type:

float

Internal Definitions

class pcapkit.foundation.reassembly.reassembly.ReassemblyBase(*, strict=True, store=True, timeout=None)[source]

Bases: Generic[_PT, _DT, _IT, _BT]

Base class for reassembly procedure.

Parameters:
  • strict (bool) – if return all datagrams (including those not implemented) when submit

  • store (bool) – if store reassembled datagram in memory, i.e., self._dtgram (if not, datagram will be discarded after callback)

  • timeout (float | None) – reassembly timeout in seconds, measured on the capture’s clock; None selects the protocol’s own __timeout__ default

Note

This class is for internal use only. For customisation, please use Reassembly instead.

class pcapkit.foundation.reassembly.reassembly.ReassemblyMeta(name, bases, namespace, /, **kwargs)[source]

Bases: ABCMeta

Meta class to add dynamic support to Reassembly.

This meta class is used to generate necessary attributes for the Reassembly class. It can be useful to reduce unnecessary registry calls and simplify the customisation process.

Type Variables

pcapkit.foundation.reassembly.reassembly._PT: pcapkit.corekit.infoclass.Info

Packet data structure.

pcapkit.foundation.reassembly.reassembly._DT: pcapkit.corekit.infoclass.Info

Datagram data structure.

pcapkit.foundation.reassembly.reassembly._IT: tuple

Buffer ID data structure.

pcapkit.foundation.reassembly.reassembly._BT: pcapkit.corekit.infoclass.Info

Buffer data structure.