Add PCap support#40
Merged
Merged
Conversation
# Add PCAP bridged networking backend (optional `--features pcap`)
## Summary
Adds an alternative networking backend to the emulated SEEQ 8003 Ethernet controller: instead of the built-in software NAT gateway, the guest's raw Ethernet frames can be **bridged directly onto a real host interface via libpcap**. The guest then appears as a real layer-2 host on the physical LAN — it can DHCP from your real router, be pinged from other machines, mount real NFS shares, etc.
This is **off by default** and gated behind a new `pcap` cargo feature, so default builds are completely unchanged (no new dependencies, same NAT behavior).
```toml
[network]
mode = "pcap"
pcap_interface = "1" # 1-based index, exact name, or omit to auto-pick / prompt
```
## Motivation
The NAT backend is great for zero-config outbound connectivity, but it can't make the guest a first-class citizen on the real LAN (inbound connections from arbitrary hosts, real DHCP, broadcast/discovery protocols, etc.). PCAP bridging covers those cases for users who want the Indy to behave like real hardware on their network.
## What's included
### Core networking
- **`NetBackend` trait** (`src/net.rs`) abstracts the backend the SEEQ chip talks to over its existing rtrb ring buffers. `NatEngine` now implements it; the chip is backend-agnostic.
- **`PcapEngine`** (`src/net_pcap.rs`, new): opens a promiscuous, immediate-mode, non-blocking libpcap capture on the chosen interface; forwards guest TX frames via `sendpacket`, injects matching RX frames back to the guest, and filters out our own echoed TX frames by learned guest MAC.
- **Backend selection** wired in `src/seeq8003.rs` (`seeq-nat` thread) with a clear boot log: `networking backend = PCAP (bridged)` / `NAT (software gateway)`, plus a graceful fallback + warning if `mode = "pcap"` is requested on a build without the feature.
### Configuration (`src/config.rs`)
- New `[network]` section: `NetMode` enum (`nat`/`pcap`) and `pcap_interface`.
- `pcap_interface` accepts a **1-based index** (from `--list-net-interfaces`), an **exact device name**, or can be **omitted** (interactive prompt on a TTY, auto-pick otherwise). Index selection is especially handy on Windows where device names are long `\Device\NPF_{GUID}` strings.
- CLI flags: `--net-mode`, `--pcap-interface`, `--list-net-interfaces`.
- **`deny_unknown_fields`** on `MachineConfig`/`NetworkSection` + **fatal-on-parse-error** for `iris.toml`. Previously a malformed config silently fell back to defaults, which made a misplaced/misquoted `pcap_interface` look like a "random" interface choice. Now it fails loudly with the exact TOML error (and a targeted hint for the Windows backslash footgun).
### Interface enumeration
- `iris --list-net-interfaces` and the monitor `net interfaces` command list candidate interfaces (name, index, flags, addresses, description).
- Interactive interface menu when `mode = "pcap"` and no interface is configured. **Runs once at CLI startup on the main thread** (not in the backend thread), so it reliably gates startup and reads the console on every platform; skipped automatically when there's no TTY (headless/CI).
### GUI integration (`iris-gui`)
- Optional `pcap` feature (`pcap = ["iris/pcap"]`) — forwards to the core feature; off by default to avoid forcing a libpcap/wpcap build dependency on the GUI.
- Network tab gains a **backend dropdown** + a **live interface picker** (dropdown populated from `list_interfaces()`, with auto-pick, manual entry, and a Refresh button).
- Machine summary + running status footer now report the **active backend** (`PCAP bridged — interface: …` vs `NAT gateway — …`) so the chosen backend is verifiable at a glance.
- **App Store safety:** the entire PCAP UI is compiled out when the feature is off — no dangling/non-functional PCAP option appears anywhere (and the runtime forces NAT regardless of an imported `mode = "pcap"`).
### Licensing note (Windows)
The `pcap` crate links the generic `wpcap` import library, so this is **not tied to Npcap** — it should build/link equally against for example Mingw-w64's libpcap or the BSD-licensed WinPcap Developer Pack. IRIS links dynamically and bundles no driver, so the runtime driver's license does not attach to IRIS. Docs and all user-facing messages say "a WinPcap-compatible driver (WinPcap or Npcap)" rather than steering users to one option.
### Incidental fix
- Fixed a first-launch GUI crash (panic in `snap_window_to_fb`): `GuiSettings` used `#[derive(Default)]`, which zeroed `vm_scale`/`ui_scale` (ignoring the serde defaults), causing `clamp(0.05, target)` to panic with `min > max`. Added a manual `Default` impl and hardened the scale math. *(Pre-existing bug surfaced during testing; happy to split into a separate PR if preferred.)*
## Usage
```bash
# Build with PCAP support
cargo build --release --features pcap # CLI
cargo build --release -p iris-gui --features pcap # GUI
# Pick an interface
./target/release/iris --list-net-interfaces
# Run (root / CAP_NET_RAW on Linux, root on macOS, Administrator + WinPcap-compatible driver on Windows)
sudo setcap cap_net_raw,cap_net_admin=eip cargo run --release --features {add-whatever-here},pcap # Linux example
cargo run --release --features {add-whatever-here},pcap
```
Inside IRIX, configure the guest for your real LAN (PCAP mode provides no NAT services — DHCP/DNS/NFS/port-forward come from the real network), and ensure the NVRAM `eaddr` MAC is set.
## Caveats
- Requires elevated privileges to open a raw capture on Linux.
- No NAT services in PCAP mode — the guest uses the real network's services.
- Wired bridges work best; many Wi-Fi APs reject the guest's extra MAC.
## Testing
- Build matrix green: default, `chd,pcap`, `iris-gui` (with/without `pcap`).
- 251 core lib tests pass, including 6 new `net_pcap` unit tests covering index/name/verbatim/auto-pick resolution and out-of-range handling.
- Verified end-to-end: backend selection, interface listing, index selection, fatal-parse + Windows backslash hint, interactive menu gating (TTY) and skip (non-TTY), GUI dropdown enumeration, and the no-feature App-Store path showing zero PCAP UI.
## Files changed
`Cargo.toml`, `src/net.rs`, `src/net_pcap.rs` (new), `src/seeq8003.rs`, `src/hpc3.rs`, `src/config.rs`, `src/main.rs`, `src/lib.rs`, `iris-gui/Cargo.toml`, `iris-gui/src/config_ui.rs`, `iris-gui/src/main.rs`, `iris-gui/src/settings.rs`, plus docs (`README.md`, `rules/irix/networking.md`, `iris.toml`). ~693 insertions across 14 files + the new backend module.
Credit to danifunker for creating a patch that is cleaner than what mine originally was.
Contributor
|
I worked on this PR a bit to make sure we had no merge conflicts or duplicate functions, especially since the pr that was merged on Thursday night touched networking as well. Once this is merged, I'll go ahead and extend iris to handle running as superuser/root/administrator for each platform, and then finally issue a separate build for this feature |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add PCAP bridged networking backend (optional
--features pcap)Summary
Adds an alternative networking backend to the emulated SEEQ 8003 Ethernet controller: instead of the built-in software NAT gateway, the guest's raw Ethernet frames can be bridged directly onto a real host interface via libpcap. The guest then appears as a real layer-2 host on the physical LAN — it can DHCP from your real router, be pinged from other machines, mount real NFS shares, etc.
This is off by default and gated behind a new
pcapcargo feature, so default builds are completely unchanged (no new dependencies, same NAT behavior).Motivation
The NAT backend is great for zero-config outbound connectivity, but it can't make the guest a first-class citizen on the real LAN (inbound connections from arbitrary hosts, real DHCP, broadcast/discovery protocols, etc.). PCAP bridging covers those cases for users who want the Indy to behave like real hardware on their network.
What's included
Core networking
NetBackendtrait (src/net.rs) abstracts the backend the SEEQ chip talks to over its existing rtrb ring buffers.NatEnginenow implements it; the chip is backend-agnostic.PcapEngine(src/net_pcap.rs, new): opens a promiscuous, immediate-mode, non-blocking libpcap capture on the chosen interface; forwards guest TX frames viasendpacket, injects matching RX frames back to the guest, and filters out our own echoed TX frames by learned guest MAC.src/seeq8003.rs(seeq-natthread) with a clear boot log:networking backend = PCAP (bridged)/NAT (software gateway), plus a graceful fallback + warning ifmode = "pcap"is requested on a build without the feature.Configuration (
src/config.rs)[network]section:NetModeenum (nat/pcap) andpcap_interface.pcap_interfaceaccepts a 1-based index (from--list-net-interfaces), an exact device name, or can be omitted (interactive prompt on a TTY, auto-pick otherwise). Index selection is especially handy on Windows where device names are long\Device\NPF_{GUID}strings.--net-mode,--pcap-interface,--list-net-interfaces.deny_unknown_fieldsonMachineConfig/NetworkSection+ fatal-on-parse-error foriris.toml. Previously a malformed config silently fell back to defaults, which made a misplaced/misquotedpcap_interfacelook like a "random" interface choice. Now it fails loudly with the exact TOML error (and a targeted hint for the Windows backslash footgun).Interface enumeration
iris --list-net-interfacesand the monitornet interfacescommand list candidate interfaces (name, index, flags, addresses, description).mode = "pcap"and no interface is configured. Runs once at CLI startup on the main thread (not in the backend thread), so it reliably gates startup and reads the console on every platform; skipped automatically when there's no TTY (headless/CI).GUI integration (
iris-gui)pcapfeature (pcap = ["iris/pcap"]) — forwards to the core feature; off by default to avoid forcing a libpcap/wpcap build dependency on the GUI.list_interfaces(), with auto-pick, manual entry, and a Refresh button).PCAP bridged — interface: …vsNAT gateway — …) so the chosen backend is verifiable at a glance.mode = "pcap").Licensing note (Windows)
The
pcapcrate links the genericwpcapimport library, so this is not tied to Npcap — it should build/link equally against for example Mingw-w64's libpcap or the BSD-licensed WinPcap Developer Pack. IRIS links dynamically and bundles no driver, so the runtime driver's license does not attach to IRIS. Docs and all user-facing messages say "a WinPcap-compatible driver (WinPcap or Npcap)" rather than steering users to one option.Usage
Inside IRIX, configure the guest for your real LAN (PCAP mode provides no NAT services — DHCP/DNS/NFS/port-forward come from the real network), and ensure the NVRAM
eaddrMAC is set.Caveats
Testing
chd,pcap,iris-gui(with/withoutpcap).net_pcapunit tests covering index/name/verbatim/auto-pick resolution and out-of-range handling.Files changed
Cargo.toml,src/net.rs,src/net_pcap.rs(new),src/seeq8003.rs,src/hpc3.rs,src/config.rs,src/main.rs,src/lib.rs,iris-gui/Cargo.toml,iris-gui/src/config_ui.rs,iris-gui/src/main.rs,iris-gui/src/settings.rs, plus docs (README.md,rules/irix/networking.md,iris.toml). ~693 insertions across 14 files + the new backend module.Credit to danifunker for cleaning up my code and creating a patch that is cleaner than what my code originally was.