rea-reverse

Analyze a .pcap / .pcapng Capture Offline with REA

Written for REA 6.7.0Published by rea-reverseUpdated 9 min read
On this page

You have a .pcap or .pcapng file: a tcpdump capture from a server, a Wireshark recording of a device handshake, or an export someone attached to a bug. You want to know what is in it, which hosts talked to which, what names were resolved, and the exact value of one field in the frames that match a filter, without ever re-sending any of the recorded traffic.

REA, the open-source project by morluto, has two commands for this. Both read a capture file that already exists on disk and send nothing on the network. They do not capture traffic and they do not open an interface. inspect-pcap-capture gives you a portable overview of one capture: endpoints, DNS, TLS SNI and a protocol breakdown. inspect-packet-capture runs TShark against the same file to return the exact fields you ask for from the frames that match a display filter, recorded as Evidence an agent can cite.

Who this is for: developers, network and QA engineers, and anyone who has a saved capture and needs an AI agent to read it against code or a ticket rather than open Wireshark by hand.

Before anything else, the hard requirement: both commands are backed by Wireshark’s command-line tools, which REA never installs and which run this analysis only on Linux. The next section says exactly what you need. If you are on macOS or Windows, read it first.

Only analyze captures you are allowed to read: your own traffic, a test device, or a system you are authorized to inspect. A packet capture can contain other people’s data and credentials in clear text. See REA’s DISCLAIMER.md. There is no affiliation between this site and the REA project.

Analyze a .pcap / .pcapng Capture Offline with REASilent walkthrough with English captions.

Requirements and platform limits

These two commands are different from REA’s other capture reader. inspect-web-network-capture, which reads HAR and Fiddler SAZ files, is pure REA and runs anywhere. The two commands here shell out to the Wireshark suite, so they carry its constraints:

  • You supply the Wireshark 4.x tools. REA never installs them. inspect-pcap-capture needs both tshark and capinfos; inspect-packet-capture needs tshark. Install Wireshark (or its CLI tools) yourself.
  • Select the binaries by putting them on PATH, or by setting the absolute paths REA_TSHARK_COMMAND and REA_CAPINFOS_COMMAND. If you set one of those variables it must be an absolute path, or REA refuses with tshark_not_absolute / capinfos_not_absolute.
  • inspect-packet-capture requires Linux plus util-linux prlimit, which REA uses to bound the TShark process. inspect-pcap-capture also relies on Linux prlimit; on Windows it uses owned Job Objects instead. In practice, run both on Linux.
  • Only Wireshark 4.x is accepted. An older or newer major version is rejected with a *_version_unsupported refusal. This workflow was verified on Linux with Wireshark 4.6.6.
  • TShark runs under a private, empty personal profile (configuration: "private-empty-personal-profile"), so your local Wireshark preferences and coloring rules do not change the output.

Because of the Linux requirement, the examples below show the commands and the shape of what REA returns, taken from the REA 6.7.0 package contract. They are not captured runs from this page.

Check your tools first

Before you point REA at a capture, confirm it can see your Wireshark tools. inspect-pcap-client reads no capture file at all. It reports the selected tshark and capinfos commands, whether each came from the environment or PATH, and their versions:

rea inspect-pcap-client --json

If a tool is missing or the wrong major version, this is where you find out, rather than part-way through reading a file. To see which field names TShark knows for a protocol, so you can pass the right ones to --fields, use inspect-packet-fields:

# list protocol registrations matching "usb"
rea inspect-packet-fields --query usb --json
# list the field definitions registered under the tls protocol
rea inspect-packet-fields --kind fields --protocol tls --query sni --json

This rereads the installed TShark glossary each call and describes the tool’s capabilities, not any traffic. Install REA as described in Install REA and connect it to Claude Code, Cursor or Codex.

Command 1: an overview with inspect-pcap-capture

Start with the overview. It takes one argument, the capture path, and no other flags beyond REA’s global output options:

rea inspect-pcap-capture /absolute/path/session.pcapng --json

REA takes an owned snapshot of the file and runs capinfos and tshark against it under resource limits. The result is a single Evidence record whose normalized_result describes the capture. From the 6.7.0 contract, REA returns fields such as:

  • target: the path, bytes and sha256 of the exact file read, so a later run can prove it read the same bytes.
  • file_type and encapsulation as capinfos reports them (this is how you tell pcap from pcapng), plus packet_count, capture_start, capture_end, capture_duration_seconds and snapshot_length.
  • endpoints: distinct endpoints, each an { address, port, packet_count }, with an endpoint_count. The list is bounded, so a huge capture does not produce an unbounded reply.
  • dns_queries: each a { query, response_addresses, response_address_count } taken from the same single-question response, plus dns_query_count. Addresses that could not be attributed to a question are listed separately under unattributed_dns_addresses with their own counts, so the gap is explicit rather than hidden.
  • tls_sni_values and tls_sni_count: the Server Name Indication values seen in TLS handshakes. SNI is sent in clear text, so you learn the hostnames a client reached even when the payload is encrypted.
  • protocol_distribution: the frame.protocols breakdown as { protocol, packet_count } entries, with protocol_count.
  • http_request_uris: request URIs seen on plain-text HTTP ports, bounded, with http_request_uri_count and an http_uri_redaction_count that tells you how many were held back.
  • client: the resolved tshark and capinfos commands, their source (environment or path) and versions, so the overview records which tools produced it.
  • coverage: "complete" or "partial". A partial value means a bound was hit and the inventory above is not exhaustive.

Every Evidence record carries an evidence_id (an ev_-prefixed digest), the subject’s SHA-256, a confidence level (observed, derived or inferred) and an explicit limitations list. That is the part an agent cites: “endpoint X appeared, per evidence ev_... over the file with this SHA-256.”

Keeping the overview small

By default the overview is delivered inline (detail: "complete"). For a large, busy capture that reply can be long. Pass detail: "summary" and REA keeps the complete record in the session and returns a short summary view instead; you then page the retained inventories with inspect-analysis-view using its pcap kind and the parent_evidence_id the summary hands back. This is the same retained-Evidence pattern the HAR analyzer workflow uses with api-surface, and it only works inside one MCP session, because a CLI process exits after each command.

Command 2: extract fields with inspect-packet-capture

The overview tells you what is in the capture. To pull the exact value of specific fields from the frames that match a filter, use inspect-packet-capture. This is the one that requires Linux. You tell it which TShark fields you want and, optionally, a Wireshark display filter:

rea inspect-packet-capture /absolute/path/device.pcapng \
  --fields ip.addr --fields udp.port --fields data.data \
  --display_filter 'udp' \
  --json

The options, from the 6.7.0 contract:

  • --fields (required, repeatable): the TShark field names to return, for example ip.addr, usb.endpoint_address, btatt.opcode. frame.number is always included whether you ask for it or not, so every returned value is tied to a frame.
  • --display_filter: an optional Wireshark display filter (TShark’s -Y), applied within the read limit. Omit it to match every frame read.
  • --decode_as: explicit TShark decode-as selections, for example tcp.port==8888,http, when a protocol runs on a non-standard port.
  • --packet_limit: the maximum number of input packets to read before filtering. Omit it to scan to end-of-file within resource limits. This caps input, not output.
  • --two_pass (default on): two-pass analysis, needed for fields that depend on later packets (reassembly). Pass --two_pass false-style single-pass only when you do not need it.
  • --match_offset / --match_limit: paging over the matching frames. The default page is 50 matches; --match_offset skips matches, and --all_matches returns all remaining matches instead of a bounded page.

The shape of the result

The reply is one Evidence record. Its normalized_result holds, per the contract:

artifact        { path, sha256, bytes }   the exact file read
selection       the fields, filter, decode-as and pass mode you asked for
packets         one object per matching frame
output_window   { matching_packets, returned_packets, has_more }
read_scope      "to-eof" or "up-to-input-packet-limit"
tool            the tshark path, sha256, version banner and exact arguments used
diagnostics     TShark's own notes

Each entry in packets is a frame. frame.number is a single-element tuple holding the frame number as a string; every other field you requested is an ordered array of strings, so a field that occurs more than once in a frame (two ip.addr values, several data.data chunks) keeps all of its occurrences in order. Values are never coerced to numbers; they stay exactly as TShark printed them.

output_window makes paging honest: matching_packets is how many frames matched within the read scope, returned_packets is how many this page holds, and has_more tells you whether to page again with a larger --match_offset. read_scope reminds you whether a --packet_limit was in force, so a “no matches” result is never mistaken for “this traffic is absent from the capture” when you only read the first N packets. The record also states hardware_acquisition: "not-performed" and records the prlimit resource limiter and the limits it enforced (input bytes, output bytes, CPU seconds, timeout). A field you asked for that simply was not present comes back absent for that frame; the contract is explicit that missing fields do not prove the traffic is not there.

A good MCP prompt

Over MCP the commands are the tools inspect_pcap_capture and inspect_packet_capture, with inspect_pcap_client and inspect_packet_fields alongside. A prompt that uses both:

Use REA to inspect /absolute/path/device.pcapng. First give me the capture
overview: endpoints, DNS queries, TLS SNI and the protocol breakdown. Then,
for frames matching the display filter 'tcp.port == 8888', return the fields
frame.time_relative, ip.addr and tcp.payload, and cite the evidence id and the
file's SHA-256. Do not replay or send any of the captured traffic.

The agent calls inspect_pcap_capture for the overview, then inspect_packet_capture with fields, display_filter and optional decode_as, and can read inspect_packet_fields first if it needs to confirm a field name exists in your TShark.

From the capture back to the code

A capture answers “what went over the wire”. It does not answer “which line of code sent it”. Once inspect-packet-capture shows you the request or payload that matters, follow it into the application the same way you would from a browser session:

Troubleshooting

REA refuses with a version or tool error. It could not find a usable tshark (and, for the overview, capinfos), or found the wrong major version. Install Wireshark 4.x and either put the tools on PATH or set absolute REA_TSHARK_COMMAND and REA_CAPINFOS_COMMAND. Confirm with rea inspect-pcap-client.

inspect-packet-capture fails on macOS or Windows. It requires Linux and util-linux prlimit. Run it on a Linux host or container that has your capture file and Wireshark 4.x installed.

A field came back empty, or no frames matched. The field may not exist in your TShark (check with inspect-packet-fields), the display filter may be too narrow, or a --packet_limit stopped the read before the matching frames. Widen the filter, drop the limit, and remember read_scope tells you whether you reached end-of-file.

The overview says coverage: "partial". A capture was large enough to hit a bound, so the endpoint, DNS or protocol lists are not exhaustive. Narrow the file (capture a shorter window) or page the retained Evidence with inspect-analysis-view.

FAQ

Does REA ever replay or send the captured traffic?

No. Both commands read a file on disk through TShark and capinfos. They do not open a network interface, connect to a host, or re-send any recorded packet.

What file formats does it read?

.pcap and .pcapng, the formats tcpdump and Wireshark write. inspect-pcap-capture reports which one it is via file_type. For HAR and Fiddler SAZ captures, use inspect-web-network-capture instead, which is pure REA and needs no Wireshark.

Why not just run TShark myself?

You can. The value REA adds is turning a TShark run into a signed Evidence record, the input file’s SHA-256, the exact arguments used, the tool’s version, resource limits and coverage, so an AI agent can cite a specific field in a specific frame of a specific file, and a later run can prove it read the same bytes.

Do I need Wireshark’s GUI?

No. You need the command-line tools tshark and capinfos (version 4.x), which ship with Wireshark but can be installed without the GUI on most Linux distributions.

Next steps