PcapFileEx.Flows.AnalysisResult (pcap_file_ex v0.5.5)

View Source

Result of analyzing a PCAP file for traffic flows.

Contains protocol-specific flow lists, a unified timeline for playback, and a lookup map for O(1) flow access by key.

Fields

  • flows - Map of FlowKey.t() => flow_ref() for O(1) lookups
  • http1 - List of HTTP/1 flows (sorted by first exchange timestamp)
  • http2 - List of HTTP/2 flows (sorted by first stream timestamp)
  • udp - List of UDP flows (sorted by first datagram timestamp)
  • timeline - Unified timeline of all events (sorted by timestamp, then deterministically by flow and event)
  • stats - Aggregate statistics across all flows

Flow Lookup

Use get_flow/2 for O(1) access to flows by key:

key = FlowKey.new(:http2, client_endpoint, server_endpoint)
flow = AnalysisResult.get_flow(result, key)

Or extract a key from an existing flow:

key = Flow.key(some_flow)
flow = AnalysisResult.get_flow(result, key)

Timeline Access

Use get_event/2 to retrieve actual event data from a timeline event:

Enum.each(result.timeline, fn event ->
  case AnalysisResult.get_event(result, event) do
    %HTTP1.Exchange{} = ex -> handle_http1(ex)
    %HTTP2.Stream{} = stream -> handle_http2(stream)
    %UDP.Datagram{} = dg -> handle_udp(dg)
  end
end)

Examples

{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng")

# Access by protocol
IO.puts("HTTP/1 flows: #{length(result.http1)}")
IO.puts("HTTP/2 flows: #{length(result.http2)}")
IO.puts("UDP flows: #{length(result.udp)}")

# Query specific flows
result.http2
|> Enum.filter(fn f -> f.flow.from == "web-client" end)

# Playback in timeline order
Enum.each(result.timeline, fn event ->
  data = AnalysisResult.get_event(result, event)
  playback(data)
end)

Summary

Functions

Builds an AnalysisResult from protocol-specific flow lists.

Retrieves the actual event data from a TimelineEvent.

Looks up a flow by its FlowKey.

Creates a new empty AnalysisResult.

Types

flow_ref()

@type flow_ref() :: %{protocol: :http1 | :http2 | :udp, index: non_neg_integer()}

t()

@type t() :: %PcapFileEx.Flows.AnalysisResult{
  flows: %{required(PcapFileEx.FlowKey.t()) => flow_ref()},
  http1: [PcapFileEx.Flows.HTTP1.Flow.t()],
  http2: [PcapFileEx.Flows.HTTP2.Flow.t()],
  stats: PcapFileEx.Flows.Stats.t(),
  timeline: [PcapFileEx.Flows.TimelineEvent.t()],
  udp: [PcapFileEx.Flows.UDP.Flow.t()]
}

Functions

build(http1_flows, http2_flows, udp_flows)

Builds an AnalysisResult from protocol-specific flow lists.

Constructs the flows map, timeline, and aggregate stats.

Parameters

  • http1_flows - List of HTTP/1 flows
  • http2_flows - List of HTTP/2 flows
  • udp_flows - List of UDP flows

get_event(result, event)

Retrieves the actual event data from a TimelineEvent.

Returns the event struct (Exchange, Stream, or Datagram) or nil if not found.

Parameters

  • result - The AnalysisResult
  • event - The TimelineEvent

Examples

event = Enum.at(result.timeline, 5)
case AnalysisResult.get_event(result, event) do
  %HTTP1.Exchange{} = ex ->
    IO.puts("#{ex.request.method} #{ex.request.path}")

  %HTTP2.Stream{exchange: ex} ->
    IO.puts("#{ex.request.method} #{ex.request.path}")

  %UDP.Datagram{} = dg ->
    IO.puts("UDP: #{dg.size} bytes")
end

get_flow(result, key)

Looks up a flow by its FlowKey.

Returns the flow struct or nil if not found.

Parameters

  • result - The AnalysisResult
  • key - The FlowKey to look up

Examples

key = FlowKey.new(:http2, client_endpoint, server_endpoint)
case AnalysisResult.get_flow(result, key) do
  %HTTP2.Flow{} = flow -> handle_flow(flow)
  nil -> :not_found
end

new()

@spec new() :: t()

Creates a new empty AnalysisResult.