Scope: RVI-Sentinel is a defensive, cross-platform toolkit for authorized iPhone/iPad packet capture and persistent network-baseline analysis. It combines Apple's native Remote Virtual Interface workflow on macOS with the upstream
gh2o/rvi_capturebackend on Linux and Windows, while keeping capture and analysis independent.
- Overview
- Executive Summary
- Overall Architecture
- Verified Analyzer Screenshot
- Installation
- Desktop Analysis GUI
- Analyze an Existing Capture
- macOS Capture with Apple RVI
- Linux and Windows Capture
- Persistent Baselining
- Current Analysis Fields
- Encryption Limitations
- Testing Without Live Capture
- Repository Structure
- Privacy and Responsible Use
- Evidence and Provenance
- Conclusions
- Upstream Source
- Community Standards
- License
RVI-Sentinel is a defensive network-analysis toolkit for inspecting packet captures over time. It supports Apple's native Remote Virtual Interface (rvictl) workflow on macOS and integrates the upstream gh2o/rvi_capture project for iPhone/iPad packet capture on Linux and Windows.
The project deliberately separates capture from analysis:
A packet capture shows what happened during one session. A persistent baseline shows what changed.
The analyzer works with ordinary .pcap and .pcapng files from any authorized source. An iPhone, rvictl, or rvi0 is not required to use the analysis engine.
- macOS iPhone/iPad capture with Apple
rvictl+rvi0+tcpdump. - Linux and Windows iPhone/iPad capture through
gh2o/rvi_capture. - PCAP and PCAPNG analysis through
tshark. - IPv4 and IPv6 endpoint inventory.
- TCP and UDP port-frequency analysis.
- DNS query extraction.
- TLS Server Name Indication (SNI) extraction when visible.
- QUIC/HTTP/3-style traffic heuristics, including UDP/443 activity.
- DNS-label Shannon entropy heuristic for generated or encoded-looking names.
- Persistent first-seen / last-seen observations across captures.
- New-vs-known endpoint, DNS, and TLS-hostname detection.
- JSON investigation reports and CSV exports.
- Deterministic integration test that validates analysis without live capture.
| Type | Finding |
|---|---|
| Direct capability | capture_rvi.sh drives Apple's rvictl / rvi0 / tcpdump workflow on macOS. |
| Direct capability | capture_mobile.py integrates the separately fetched gh2o/rvi_capture backend for Linux and Windows. |
| Direct capability | analyze.py accepts authorized PCAP or PCAPNG input and produces persistent JSON plus CSV findings. |
| Direct verification | The deterministic analyzer integration test passes without an iPhone, rvictl, or rvi0. |
| Interpretation boundary | A newly observed endpoint or hostname is a baseline change, not proof of malicious activity. |
| Visibility boundary | Packet metadata does not defeat TLS, QUIC, VPNs, Private Relay, encrypted DNS, ECH, or application-layer encryption. |
flowchart TB
Device[iPhone / iPad]
subgraph Hosts[Authorized capture host]
Mac[macOS<br/>rvictl + rvi0 + tcpdump]
Cross[Linux / Windows<br/>gh2o/rvi_capture]
end
Capture[PCAP / PCAPNG evidence]
Tshark[tshark field extraction]
GUI[Optional PySide6 desktop GUI]
Analyzer[analyze.py CLI engine]
Metadata[IP / ports / DNS / TLS SNI / QUIC heuristics]
Report[Current JSON + CSV reports]
Baseline[Persistent findings_master.json baseline]
Device -->|USB| Mac
Device -->|USB| Cross
Mac --> Capture
Cross --> Capture
Capture --> GUI --> Analyzer
Capture --> Analyzer
Analyzer --> Tshark --> Metadata
Metadata --> Report
Metadata --> Baseline
The two capture paths converge on the same host-independent analysis pipeline.
Text-only architecture
iPhone / iPad
|
| USB
+--------------+--------------+
| |
macOS Linux / Windows
| |
rvictl gh2o/rvi_capture
| |
rvi0 |
| |
tcpdump |
+--------------+--------------+
|
v
PCAP / PCAPNG
|
v
tshark
|
+------------+------------+
| | |
v v v
IP / ports DNS TLS / QUIC
| | |
+------------+------------+
|
v
analyze.py
|
+------------+------------+
| |
v v
Current report Persistent state
JSON + CSV findings_master.json
The key design rule is:
CAPTURE LAYER != ANALYSIS LAYER
The screenshot records the repository's deterministic analyzer integration test. It verifies packet-field parsing, IPv4 endpoint tracking, DNS and TLS SNI extraction, QUIC-like classification, DNS entropy handling, JSON/CSV exports, persistent baselining, and known/new differentiation without requiring live device capture.
Clone RVI-Sentinel:
git clone https://github.com/hideouts-io/RVI-Sentinel.git
cd RVI-SentinelCheck the analyzer:
python3 analyze.py --helpThe CLI analyzer uses Python's standard library. Packet decoding requires tshark, the command-line component of Wireshark. The optional desktop GUI uses PySide6.
The desktop GUI wraps the existing analyzer without replacing it. It supports:
- selecting or dropping an authorized PCAP, PCAPNG, or CAP file;
- choosing a persistent baseline and export directory;
- configuring the DNS entropy threshold and console result count;
- displaying the exact
analyze.pycommand before execution; - live analyzer output and actionable process errors;
- summary, endpoint, DNS, TLS SNI, protocol, port, and entropy-heuristic views;
- PTR reverse-DNS names and address-scope labels for every endpoint;
- optional local MaxMind-compatible GeoIP city/country lookup without a web API;
- TCP/UDP-aware service labels and plain-language port explanations;
- a report-specific Interpretation view that explains scope, caveats, and next steps;
- explicit new-versus-known baseline labels;
- opening the generated export directory.
Live device capture remains in the existing platform-specific CLI workflows while the GUI capture boundary is developed and validated.
Create a project-local environment and install the optional GUI dependency:
python3 -m venv venv
venv/bin/python -m pip install -r requirements-gui.txtUse the non-hidden venv/ directory shown above. In macOS File Provider-managed folders, a dot-prefixed environment such as .venv/ can propagate the hidden file flag to Qt plugins and prevent the Cocoa platform plugin from being discovered.
Launch the GUI:
./scripts/run_gui.shOn macOS, the launcher builds a lightweight local dist/RVI-Sentinel.app wrapper and starts its native entry point with the project icon so RVI-Sentinel has its own Dock identity. The generated application bundle stays outside version control. Launch through scripts/run_gui.sh so the app inherits the terminal's authorized access to a project stored in Documents without requesting broader disk access.
Optionally open a capture immediately:
./scripts/run_gui.sh captures/authorized-capture.pcapngThe GUI requires the same tshark runtime dependency as the CLI analyzer. It does not elevate privileges, capture live traffic, or bypass encryption.
Geolocation is deliberately local-only: RVI-Sentinel never sends captured endpoint IP addresses to a geolocation web API. To add approximate locations, download a current MaxMind-compatible City or Country .mmdb database, keep it outside version control (the repository's data/ contents are ignored), and choose it in Local GeoIP database before analysis. MaxMind provides GeoLite downloadable databases after account and license-key setup.
IP geolocation is approximate. It often represents a network or nearby population center and must not be interpreted as the exact location of a device, person, or household. PTR hostnames are also attribution hints rather than proof: they may be absent, generic, stale, shared, or controlled by a hosting provider. Reverse-DNS resolution sends PTR queries for the observed addresses to the Mac's configured DNS resolver.
These screenshots use a deterministic synthetic report and documentation-only sample values. No private capture, endpoint list, baseline, or generated report is included.
The Endpoints view keeps packet counts and baseline status alongside PTR hostname hints, address scope, and optional local-only GeoIP results.
TCP and UDP observations remain distinct so the GUI can explain common uses such as TCP/443 HTTPS, UDP/443 QUIC/HTTP/3, UDP/53 DNS, TCP/5223 Apple Push Service, and TCP/62078 iOS lockdown. A conventional port label is context, not proof that a particular process or server was present.
The Interpretation view explains the report-specific counts, new-versus-known baseline changes, endpoint-attribution limits, port observations, encrypted traffic, and entropy findings without turning a heuristic or newly observed value into a malicious verdict.
Given:
capture.pcapng
run:
python3 analyze.py capture.pcapngOutputs are written to:
data/findings_master.json
exports/
├── capture_report.json
├── capture_endpoints.csv
├── capture_dns.csv
└── capture_tls_sni.csv
Use a dedicated baseline for one device or investigation:
python3 analyze.py capture.pcapng \
--baseline data/iphone_baseline.json \
--export-dir exports/iphoneConnect and trust the iPhone/iPad over USB.
Find its UDID:
xcrun xctrace list devicesStart RVI:
./capture_rvi.sh start <UDID>or directly:
rvictl -s <UDID>A virtual interface such as rvi0 should appear:
ifconfig rvi0Capture:
./capture_rvi.sh capture captures/ios_capture.pcapngEquivalent manual command:
sudo tcpdump -i rvi0 -n -s 0 -U \
-w captures/ios_capture.pcapngAnalyze:
python3 analyze.py captures/ios_capture.pcapngStop RVI:
./capture_rvi.sh stop <UDID>RVI-Sentinel integrates the open-source project:
https://github.com/gh2o/rvi_capture
The upstream project describes itself as rvictl for Linux and Windows and creates packet-capture dumps from connected iOS devices. It supports both PCAP and PCAPNG, optional UDID selection, file/FIFO output, stdout streaming, and direct Wireshark streaming.
RVI-Sentinel does not copy the upstream Python implementation into this repository. Instead, the setup helper clones the canonical source directly so provenance remains clear.
Install the upstream capture backend locally:
python3 scripts/setup_rvi_capture.pyIt is placed at:
tools/rvi_capture/
That directory is intentionally ignored by Git.
Update the upstream checkout later with:
python3 scripts/setup_rvi_capture.py --updateThe setup helper prints the exact upstream commit SHA so you can record which capture implementation produced a packet trace.
See SOURCES.md for attribution and provenance details.
Upstream documents the following requirements:
- Python 3
libimobiledeviceusbmuxdrunning
On Debian/Ubuntu-derived systems, a typical starting point is:
sudo apt update
sudo apt install python3 libimobiledevice-utils usbmuxdConfirm that the connected device is visible:
idevice_id -lInstall the upstream backend:
python3 scripts/setup_rvi_capture.pyCapture an iPhone/iPad to PCAPNG:
python3 capture_mobile.py \
captures/iphone_linux.pcapngSelect a particular device:
python3 capture_mobile.py \
--udid <IPHONE_UDID> \
captures/iphone_linux.pcapngCapture and immediately analyze:
python3 capture_mobile.py \
--analyze \
captures/iphone_linux.pcapngUpstream documents the following requirements:
- Python 3
- iTunes / Apple mobile-device components
AppleMobileDeviceService.exerunning
The upstream project states that its required libimobiledevice components are downloaded as needed on Windows.
From PowerShell:
python scripts\setup_rvi_capture.pyCapture:
python capture_mobile.py `
captures\iphone_windows.pcapngSpecify the UDID:
python capture_mobile.py `
--udid <IPHONE_UDID> `
captures\iphone_windows.pcapngCapture and analyze in one workflow:
python capture_mobile.py `
--analyze `
captures\iphone_windows.pcapngAfter running the setup helper, you can invoke upstream rvi_capture.py directly.
Linux:
python3 tools/rvi_capture/rvi_capture.py \
--format pcapng \
--udid <IPHONE_UDID> \
captures/iphone.pcapngWindows PowerShell:
python tools\rvi_capture\rvi_capture.py `
--format pcapng `
--udid <IPHONE_UDID> `
captures\iphone.pcapngIf --udid is omitted, upstream selects the first device it finds.
Then analyze normally:
python3 analyze.py captures/iphone.pcapngThe upstream project can write capture data to stdout:
./tools/rvi_capture/rvi_capture.py - | wireshark -k -i -For RVI-Sentinel investigations, saving a PCAPNG first is often preferable because it creates a repeatable evidence artifact that can be re-analyzed later.
PCAPNG can retain interface metadata. The upstream rvi_capture documentation discusses iOS interfaces such as:
en0 Wi-Fi
pdp_ip0 cellular
ipsec1 IPSec outer transport observed for VoLTE
ipsec3 IPSec inner transport observed for VoLTE
In Wireshark, inspect:
frame.interface_name
This can help distinguish traffic paths when the capture includes the relevant metadata.
| Host OS | iPhone/iPad capture backend | Output | RVI-Sentinel analysis |
|---|---|---|---|
| macOS | Apple rvictl + tcpdump |
PCAP/PCAPNG | Yes |
| Linux | gh2o/rvi_capture + libimobiledevice/usbmuxd |
PCAP/PCAPNG | Yes |
| Windows | gh2o/rvi_capture + Apple mobile-device services |
PCAP/PCAPNG | Yes |
| Any analysis host | Existing authorized PCAP/PCAPNG | PCAP/PCAPNG | Yes |
The default state database is:
data/findings_master.json
For observed endpoints, DNS names, and visible TLS SNI values, RVI-Sentinel records historical context including first seen, last seen, observation counts, capture membership, and recent capture counts.
This allows a later capture to distinguish previously observed infrastructure from newly observed infrastructure.
A new endpoint or hostname is not automatically suspicious. It is simply a change worth contextualizing.
RVI-Sentinel asks tshark for fields including:
frame.time_epoch
ip.src
ip.dst
ipv6.src
ipv6.dst
tcp.srcport
tcp.dstport
udp.srcport
udp.dstport
dns.qry.name
tls.handshake.extensions_server_name
_ws.col.Protocol
RVI packet visibility does not defeat TLS, QUIC, VPN encryption, iCloud Private Relay, encrypted DNS, ECH, or application-layer encryption.
You may still observe useful metadata such as source/destination addresses, ports, timing, traffic volume, unencrypted DNS, visible TLS SNI, and protocol classifications.
RVI-Sentinel does not attempt to bypass device security controls or decrypt protected application content.
Run:
python3 tests/test_analyzer.py
python3 -m tests.test_gui_models
python3 -m tests.test_finding_enrichment
QT_QPA_PLATFORM=offscreen venv/bin/python -m tests.test_gui_integrationThe test does not connect to an iPhone, invoke rvictl, create rvi0, or capture live traffic. It supplies deterministic fake tshark field output and validates the analysis layer independently.
The GUI integration test uses the same deterministic field stream to exercise Qt process execution, report loading, and results presentation without displaying a window or requiring live capture.
Expected completion includes:
PASS: analyzer works without rvictl/rvi0
RVI-Sentinel/
├── analyze.py
├── enrich_endpoints.py # bounded PTR and local GeoIP enrichment process
├── finding_enrichment.py # address, location, and port explanations
├── gui.py # optional PySide6 analysis desktop UI
├── gui_models.py # typed request/report validation
├── capture_rvi.sh # macOS rvictl/rvi0 capture
├── capture_mobile.py # Linux/Windows frontend
├── scripts/
│ ├── run_gui.sh # launch GUI from project environment
│ └── setup_rvi_capture.py # fetch canonical gh2o/rvi_capture source
├── evidence/
│ └── rvi-sentinel-analyzer-test.png
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── feature_request.yml
│ │ └── config.yml
│ └── pull_request_template.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── SECURITY.md
├── SOURCES.md # upstream provenance/attribution
├── README.md
├── requirements.txt
├── requirements-gui.txt
├── LICENSE
├── .gitignore
├── tests/
│ ├── test_analyzer.py
│ ├── test_finding_enrichment.py
│ ├── test_gui_integration.py
│ └── test_gui_models.py
├── captures/
├── data/
├── exports/
└── tools/
└── rvi_capture/ # local upstream clone; intentionally ignored
Packet captures can reveal sensitive metadata even when payloads are encrypted. The repository ignores PCAP files, generated reports, local baselines, and the local upstream checkout by default.
Endpoint geolocation uses only the local .mmdb file selected by the user. RVI-Sentinel does not send captures, reports, DNS names, SNI values, or endpoint lists to a geolocation web API. PTR hostname resolution does query the Mac's configured DNS resolver for each observed endpoint.
Use RVI-Sentinel only with devices, networks, and packet captures you own or are explicitly authorized to inspect.
This repository keeps capture provenance, analysis output, and interpretation separate:
| Layer | Evidence or record |
|---|---|
| Capture implementation | macOS uses Apple rvictl and tcpdump; Linux and Windows use a separately cloned canonical gh2o/rvi_capture checkout. |
| Backend provenance | scripts/setup_rvi_capture.py prints the exact upstream commit SHA after installation. |
| Packet evidence | PCAP or PCAPNG files remain independent inputs that can be retained and re-analyzed. |
| Current findings | JSON and CSV exports describe the supplied capture. |
| Historical context | The persistent baseline records first seen, last seen, counts, and capture membership. |
| Verification evidence | tests/test_analyzer.py validates the analysis layer deterministically; the screenshot above records a passing run. |
Live device capture depends on the host OS, USB trust state, and the platform-specific prerequisites documented above. The deterministic test verifies the analysis pipeline, not a live macOS, Linux, or Windows device session.
For third-party attribution and redistribution boundaries, see SOURCES.md.
RVI-Sentinel provides three host capture paths with one common analysis model:
- macOS capture through Apple's native RVI tooling.
- Linux capture through
gh2o/rvi_capture,libimobiledevice, andusbmuxd. - Windows capture through
gh2o/rvi_captureand Apple mobile-device services. - Host-independent analysis of existing authorized PCAP and PCAPNG evidence.
- Persistent comparison of endpoints, DNS names, and visible TLS SNI across captures.
- Explicit limits: baseline changes require context, and encrypted content remains protected.
The central design principle is that capture produces evidence, while analysis and persistent baselining explain how that evidence differs from earlier observations.
Linux/Windows iOS capture functionality is provided by the separately maintained upstream project:
https://github.com/gh2o/rvi_capture
RVI-Sentinel's integration code does not claim authorship of that implementation. See SOURCES.md.
- Read the Code of Conduct before participating.
- Follow the Contributing Guidelines for setup, validation, privacy, and pull-request expectations.
- Report vulnerabilities privately through the Security Policy.
- Use the structured GitHub issue forms for bugs and feature requests.
Never publish private captures, generated reports, baseline data, endpoint inventories, device identifiers, credentials, or unsanitized investigation logs in an issue or pull request.
RVI-Sentinel's own project code is MIT licensed. See LICENSE. Upstream dependencies retain their own copyright and licensing status.




