PcapFileEx.Flows (pcap_file_ex v0.5.5)
View SourceUnified traffic flow analysis API.
Analyzes PCAP files to identify and group traffic by protocol (HTTP/1, HTTP/2, UDP).
Returns a structured AnalysisResult with protocol-specific flow containers,
a unified timeline for playback, and O(1) flow lookups.
Example
{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng")
# Access flows 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)
|> Enum.flat_map(& &1.streams)
# Playback in timeline order
Enum.each(result.timeline, fn event ->
data = PcapFileEx.Flows.AnalysisResult.get_event(result, event)
playback(data)
end)Protocol Detection
TCP flows are classified by content inspection:
- HTTP/2: Connection preface
"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" - HTTP/1: Request methods (
GET,POST, etc.) orHTTP/response
UDP packets are collected separately and grouped by destination server.
Hosts Mapping
Use the :hosts_map option to resolve IP addresses to hostnames:
hosts = %{
"192.168.1.10" => "api-gateway",
"192.168.1.20" => "metrics-collector"
}
{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng", hosts_map: hosts)
# Now flows show friendly names
result.http2
|> Enum.map(fn f -> {f.flow.from, f.flow.server} end)
# => [{"web-client", "api-gateway:8080"}, ...]
Summary
Functions
Analyzes a PCAP file and returns traffic flows grouped by protocol.
Analyzes pre-extracted TCP segments.
Functions
@spec analyze( Path.t(), keyword() ) :: {:ok, PcapFileEx.Flows.AnalysisResult.t()} | {:error, term()}
Analyzes a PCAP file and returns traffic flows grouped by protocol.
Parameters
pcap_path- Path to PCAP/PCAPNG fileopts- Options::hosts_map- Map of IP address strings to hostname strings:decode_content- Whether to decode HTTP bodies (default: true):decoders- List of custom decoder specs (seePcapFileEx.Flows.Decoder):keep_binary- Whentrue, preserve original binary inpayload_binary/body_binarywhen custom decoders are invoked (default:false). Warning: This doubles memory usage for decoded content.:tcp_port- Filter TCP traffic to specific port:udp_port- Filter UDP traffic to specific port
Returns
{:ok, result} where result is an AnalysisResult struct containing:
http1- List of HTTP/1 flowshttp2- List of HTTP/2 flowsudp- List of UDP flowsflows- Map for O(1) flow lookup by FlowKeytimeline- Unified event timeline for playbackstats- Aggregate statistics
Examples
{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng")
# With hosts mapping
hosts = %{"10.0.0.1" => "client", "10.0.0.2" => "server"}
{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng", hosts_map: hosts)
# Filter to specific ports
{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng", tcp_port: 8080)
# With custom decoders
decoder = %{protocol: :udp, match: %{port: 5005}, decoder: &MyDecoder.decode/1}
{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng", decoders: [decoder])
# With binary preservation for playback
{:ok, result} = PcapFileEx.Flows.analyze("capture.pcapng",
decoders: [decoder],
keep_binary: true
)
@spec analyze_segments([PcapFileEx.Flows.TCPExtractor.segment()], [map()], keyword()) :: {:ok, PcapFileEx.Flows.AnalysisResult.t()}
Analyzes pre-extracted TCP segments.
Use this when you already have TCP-reassembled segments, skipping the PCAP parsing step.
Parameters
tcp_segments- List of TCP segments fromTCPExtractorudp_packets- List of UDP packets (optional, default: [])opts- Same options asanalyze/2
Returns
{:ok, result} with AnalysisResult