Flow Tracing

Note

This was implemented at the demand of my mate @gousaiyang. It is a approximate functionality of Follow TCP Streams in Wireshark.

pcapkit.foundation.traceflow implements flow tracing functions for pcapkit package.

See also

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

All flow tracing classes are implemented as TraceFlowBase subclasses, which are responsible for processing extracted packets and follow the flow and/or stream to provide more insights. Below is a brief diagram of the class hierarchy of pcapkit.foundation.traceflow:

        flowchart LR
    A{{TraceFlowMeta}} -.->|metaclass| B(TraceFlowBase)

    B --> TCP

    B --> C(TraceFlow)
    C --> D([user customisation ...])

    click A "/pcapkit/foundation/traceflow/traceflow.html#pcapkit.foundation.traceflow.traceflow.TraceFlowMeta"
    click B "/pcapkit/foundation/traceflow/traceflow.html#pcapkit.foundation.traceflow.traceflow.TraceFlowBase"
    click C "/pcapkit/foundation/traceflow/traceflow.html#pcapkit.foundation.traceflow.traceflow.TraceFlow"
    click D "/ext.html#reassembly-and-flow-tracing"

    click TCP "/pcapkit/foundation/traceflow/tcp.html#pcapkit.foundation.traceflow.tcp.TCP"
    

Auxiliary Data

class pcapkit.foundation.traceflow.TraceFlowManager(*args: VT, **kwargs: VT)[source]

Bases: Info

TraceFlow Manager.

tcp: TCP

TCP reassembly.

class pcapkit.foundation.traceflow.data.data.TraceFlowData(*args: VT, **kwargs: VT)[source]

Bases: Info

Data storage for flow tracing.

tcp: tuple[Index, ...]

TCP traced flows.

class pcapkit.foundation.traceflow.data.data.Deferred(reassembly)[source]

Bases: object

A postponed reassembly of a traced flow’s application layer.

A traced flow’s packet is the application-layer payload of the conversation, one datagram per direction. Producing it means reassembling the stream, which is neither free nor wanted by most callers of a tracer – so the flow keeps the reassembler it was fed and this holds it until somebody reads Index.packet.

Note

Deliberately not pcapkit.foundation.reassembly.data.data.Deferred, and not shared with it. That one postpones a single analyze() call over bytes already in hand; this postpones a submit over a reassembler’s buffers. The two subpackages are siblings and neither should depend on the other, so the twenty lines are written twice rather than one importing the other – the same reason the two data/data.py modules mirror each other instead of merging.

Parameters:

reassembly (TCP) – The flow’s own TCP reassembler, fed the segments of this conversation as they were traced.

__call__()[source]

Run the postponed reassembly.

Return type:

tuple[Datagram, ...]

Returns:

One reassembled datagram per direction of the conversation. Each carries its own postponed analysis in Datagram.packet, so parsing the payload as an application-layer protocol is still not paid for until that is read in turn.

class pcapkit.foundation.traceflow.data.data.DeferredPacket[source]

Bases: object

Resolves a Deferred packet field on first read.

The reading half of the arrangement above, and the counterpart of pcapkit.foundation.reassembly.data.data.DeferredPacket.

A subclass has to list packet in its __additional__. That is what makes the field lazy at all: Info stores a field named there under a mangled key and maps it back on the way out, so packet never lands in __dict__ itself – which routes reading it through __getattr__(), where the deferred reassembly can run, while dict(index), to_dict() and iteration still report the field under its own name.

__analyse__()[source]

Resolve a deferred reassembly, at most once.

Return type:

tuple[Datagram, ...] | None

Returns:

The flow’s reassembled datagrams, or None when the tracer was not asked to analyse the application layer.

to_dict()[source]

Convert Index into dict.

Return type:

dict[str, Any]

Returns:

The flow’s fields, with packet reassembled if it had not been read yet – a dict holding a Deferred would leak an implementation detail into what is meant to be plain data.