9.8 KiB
Recorded packet capture inspection
inspect_packet_capture answers which selected protocol fields TShark observes
in an existing capture. Network, USB or Bluetooth recordings can use the same
field/filter interface when the installed TShark supports their encapsulation
and dissectors. This tool does not acquire traffic, open an interface or control
a device. HAR/SAZ/mitmproxy web-capture workflows remain separate.
Supply an existing TShark 4.x installation on Linux, with util-linux
prlimit available at /usr/bin/prlimit. Override its absolute path with
REA_TSHARK_PRLIMIT_COMMAND if required. Unsupported hosts, including macOS
and Windows, are refused before inspection because this integration requires
an enforced address-space limit:
export REA_TSHARK_COMMAND=/absolute/path/to/tshark
rea inspect-packet-capture /artifacts/device.pcapng \
--fields ip.addr --fields udp.port --fields data.data \
--display_filter 'udp' --format json
The corresponding MCP call is:
{
"name": "inspect_packet_capture",
"arguments": {
"path": "/artifacts/device.pcapng",
"fields": ["ip.addr", "udp.port", "data.data"],
"display_filter": "udp"
}
}
frame.number is always included. Repeated values are ordered string arrays,
for example "ip.addr": ["192.0.2.1", "192.0.2.2"]. Missing fields remain
absent; they are not converted to zero or empty arrays. Export-only index/score
metadata is discarded. No payload bytes are automatically added; select a
supported byte field such as data.data or @data when needed.
Selectors are limited before argv expansion: at most 1,024 fields and 1,024
decode_as rules, 8,192 UTF-16 code units per selector, and 32 KiB total encoded
selector arguments (UTF-8 text, terminators, option names and argv pointers).
This leaves headroom below Linux's execve argument/environment limits;
an unusually large inherited environment can still prevent launching.
Output is paged after filtering: match_limit defaults to 50 and match_offset
to 0. The result retains original frame numbers and reports output_window
with the matching count within the input read scope, returned count and
has_more. Request later pages with the offset, or explicit match_limit: null
(CLI --all_matches) for all remaining matches. Paging does not shorten
input reading or change two-pass reassembly. Producer output must still fit its
resource limit; use selected fields, a display filter or an input-packet limit
when dissection output is too large. Each call checks the recording's current
digest, so pages from different source digests must not be combined.
Additional selections:
display_filter: Wireshark display-filter syntax; omitted means no filter.decode_as: explicit dissector overrides, such as["udp.port==5555,dns"]. Repeat--decode_asin the CLI for multiple overrides.packet_limit: optional maximum input packets read before filtering. A limit of 1 can therefore yield zero matching packets even when later frames match. Omitted means read to EOF within resource limits. The report recordsto-eoforup-to-input-packet-limit, never inferring total capture size from the returned packet count.two_pass: defaults to true for fields that need later packets and reassembly dependencies. MCP may set false; CLI uses--no-two_passfor a single pass.
See the TShark manual for field names, display filters, decode-as syntax and pass semantics. Invalid fields or filters return producer diagnostics. An empty result does not prove absence of traffic outside the selected recording, filter or read range. Dissector results are observations, not independently verified device behavior.
Evidence includes source path/digest/size, exact selections, typed packet fields,
configured and resolved executable paths/digests/full version banner, arguments and stderr. Warnings remain
visible even on exit zero. tool.version_diagnostics also retains warnings from
the separate version probe. Post-run identity failures identify the affected
private copy, executable or limiter; resource-signal errors retain the signal
and effective ceilings. Two-pass mode cannot recover missing capture bytes.
Each call uses a private read-only capture copy and an empty personal
configuration directory (WIRESHARK_CONFIG_DIR), with name resolution disabled.
The executable, resource limiter and private input copy are rechecked after execution. Owned
processes, file descriptors and private files are cleaned up; failed cleanup retains ownership and
completed observations for retry. The one-shot CLI awaits a cleanup retry while
preserving the original failure and completed Evidence. Completed observations
remain in the MCP session after cancellation or cleanup failure; bounded
post-run integrity checks finish before honoring a late abort. Source files
are never passed to TShark.
Installed libraries, global configuration and plugins remain trusted, are not
fully fingerprinted, and can influence dissection. This is not an OS sandbox.
Input is limited to 32 MiB before reading, each command to 30 seconds, and
combined stdout/stderr to 4 MiB during collection. Output overflow fails instead
of returning truncated success. Before execution, prlimit enforces 1 GiB
address space per process, 64 MiB per file, 30 CPU seconds and no core
dumps. Stricter inherited soft/hard limits are preserved; Evidence records the effective
ceilings. Both limits are set before execution, so dissector allocations and
compressed-capture expansion cannot exceed the per-process address-space cap.
These are not aggregate process-memory or filesystem quotas. The selected
limiter is trusted; its path, digest and arguments are retained in Evidence.
No arbitrary process flags are accepted.
Verification
npm run build:cached
REA_TSHARK_COMMAND=/absolute/path/to/tshark node scripts/verify-packet-capture.mjs
The verifier generates its own Ethernet/IPv4/UDP/DNS and Bluetooth HCI PCAPs. It exercises real compiled CLI/MCP parity, advertised schemas, repeated/missing fields, filtering, decode-as, both pass modes, a packet limit before matching frames, Evidence persistence, failure diagnostics, source identity and cleanup. An optional positional REA entrypoint verifies an installed package.
The real-tool lane requires Linux and TShark 4.x. A separate kernel-limit regression checks the inherited soft/hard limits and verifies an oversized allocation is refused before it can consume memory. The Ubuntu workflow uses its distribution package; check its outcome before claiming that build verified. The earlier macOS check does not establish the current bounded integration, which deliberately refuses unsupported hosts. Other formats (including PCAPNG), USB, BLE ATT and actual physical capture are not established by these fixtures.
Each provider admits one inspection at a time, including acquisition and cleanup. An occupied provider returns a retryable capacity error before acquiring another file or worker. Closing the provider stops new admission and drains accepted work; failed cleanup remains owned and can be retried.
Discover protocols and field names
inspect_packet_fields / inspect-packet-fields queries the installed TShark
registration glossary before selecting fields for capture inspection:
rea inspect-packet-fields --query usb
rea inspect-packet-fields --kind fields --protocol usb --query idVendor
rea inspect-packet-fields --kind fields --protocol udp --all
kind defaults to protocols; fields selects field definitions. protocol
selects an exact protocol abbreviation (the protocol itself or its child fields).
query is a case-insensitive literal substring in name, abbreviation or field
description. offset skips matching records; limit defaults to 50. MCP
limit: null or CLI --all requests all remaining matches within the resource
budget. --all and --limit conflict. The window reports examined records of
the selected kind before filters, matching records, returned records and
has_more; it never counts capture packets.
Returned records preserve field type, parent protocol, display base, bitmask, description and original glossary line number. Empty producer strings remain empty; protocol records have null field-only properties. Repeated abbreviations remain separate registrations. A listed field is an installation capability, not proof that the field appears in a selected recording.
The adapter uses the documented tshark -G fields grammar under its existing
private empty profile and Linux process limits. TShark 4.6.9's full glossary was
measured at 22,303,197 bytes; discovery admits at most 32 MiB combined command
output (capture inspection remains at 4 MiB). Parsing walks lines once and
constructs objects only for the selected page. Returned strings are copied so
retained pages do not retain the complete glossary string. Before constructing a selected
record it charges six times the source UTF-8 bytes plus 512 bytes against an
8 MiB representation budget, covering JSON escaping and record bookkeeping.
If that budget would be exceeded, narrow the query or page size; results are not
silently truncated. This is a conservative admission budget, not measured heap
usage. Parent pipe buffers and producer per-process limits remain distinct.
Tool/limiter identity, version, stderr and selected arguments are retained in Evidence. No capture, interface or device is opened. Discovery shares capture analysis's admission slot and cleanup owner. Each call rereads the glossary; installed plugins, libraries and global configuration remain trusted and are not fully fingerprinted. There is no cache or snapshot-consistent pagination claim. The real Linux lane checks public CLI/MCP queries against the direct glossary, including USB vendor-ID typing, negative queries and paging.