Flow Tracing

Note

This approximates the Follow TCP Stream feature of Wireshark.

pcapkit.foundation.traceflow implements flow tracing.

See also

Customisation & Extensions, on customisation and extension.

Every flow tracing class subclasses TraceFlowBase, following the flows of extracted packets:

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

    B --> TCP

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

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

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

Auxiliary Data

class pcapkit.foundation.traceflow.TraceFlowManager(tcp)[source]

Bases: Info

TraceFlow Manager.

tcp: TCP

TCP flow tracing.

class pcapkit.foundation.traceflow.data.data.TraceFlowData(tcp)[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, as reassembled datagrams – one per direction and acknowledgement number, see TCP. 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 reassembly and flow tracing subpackages are siblings, and the flow tracer reaches the reassembler only lazily, when analyse asks for one, so the few lines are written in each rather than one importing the other – the same reason their 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:

The conversation’s reassembled datagrams, one per direction and acknowledgement number. 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.FrameRecord(mapping, *, packet, frame_info, time_epoch)[source]

Bases: Info

A frame as a third-party engine’s flow tracing adapter reports it.

The mapping is the engine’s own dissection of the frame, which every trace format that takes a mapping writes unchanged. Beside it, as attributes the mapping does not show, it carries what the PCAP trace dumper reads of a frame – PCAPIO._append_value takes packet, frame_info and time_epoch – so trace_format='pcap' writes the frame’s record too (#1507). A key of the mapping and an attribute of the same name stay apart: record['packet'] is the engine’s, and record.packet the frame’s captured octets.

Parameters:
  • mapping (Mapping[str, Any]) – The engine’s dissection of the frame.

  • packet (bytes) – The frame’s captured octets.

  • frame_info (FrameInfo) – The frame’s PCAP record header.

  • time_epoch (Decimal) – The frame’s exact UNIX timestamp.

Changed in version 1.6.0: An Info rather than a dict subclass, so it is immutable and no dict. to_dict() exports the mapping alone, as any Info exports its keys, and drops the packet, frame_info and time_epoch attributes (#2726).

packet: bytes

The frame’s captured octets.

frame_info: FrameInfo

The frame’s PCAP record header, with the fraction in the capture’s own resolution.

time_epoch: Decimal

The frame’s exact UNIX timestamp, from which PCAPIO._make_timestamp tells which resolution frame_info.ts_usec is in. A Decimal, since only that settles it exactly.

__getattribute__(name)[source]

Read an attribute, taking packet, frame_info and time_epoch from the keys holding them.

So a mapping key of the same name never stands in for one of them.

Parameters:

name (str) – Attribute name.

Raises:

AttributeError – If name is one of them and the record carries none, as one from_dict() builds from a mapping.

Return type:

Any

__reduce_ex__(protocol)[source]

Reduce to a call of _frame_record(), under every protocol.

A release before 1.6.0 reduces a record to it as well, so a pickle loads on either side of 1.6.0.

Parameters:

protocol (SupportsIndex) – Pickle protocol in use, which does not change the reduction.

Return type:

tuple[Any, ...]

Returns:

(_frame_record, (mapping, packet, frame_info, time_epoch)).