177 lines
9.8 KiB
Markdown
177 lines
9.8 KiB
Markdown
# 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:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```json
|
|
{
|
|
"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](https://man7.org/linux/man-pages/man2/execve.2.html);
|
|
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_as` in 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 records
|
|
`to-eof` or `up-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_pass` for a single pass.
|
|
|
|
See the [TShark manual](https://www.wireshark.org/docs/man-pages/tshark.html)
|
|
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
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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.
|