Networking WORKS: real console <-> real pod over the emulated wire

The emulated SheepShaver console and DOSBox pod now exchange the live
console protocol on TCP 1501. Required chain: rebuild the DOSBox pcap
backend + launch with C:\Windows\System32\Npcap on PATH (npcap DLL
location); a two-TAP Windows bridge (single shared TAP fails); TAP2
MediaStatus=Always-Connected; and binding the pod's pcap to the BRIDGE
MINIPORT (not a member TAP -- member-injected frames aren't re-forwarded),
via realnic=DB5521D (letter-leading GUID fragment; leading-digit is parsed
as an interface index). Captured + decoded the real protocol values
(StateResponse clientID=5/flags=1/host=0/state=1/app=1=BattleTech), which
corrects the earlier synthetic guesses. Full writeup in NET-NOTES.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-05 17:14:48 -05:00
co-authored by Claude Fable 5
parent 929b6bc267
commit bda2f7b8b3
2 changed files with 177 additions and 0 deletions
+48
View File
@@ -292,6 +292,54 @@ same TAP/bridge (200.0.0.113 already via WATTCP). Then the console's
outbound TCP to 200.0.0.113:1501 reaches the pod and we capture the egg
exchange (resolves the framing + endianness caveats above).
## MILESTONE: real console <-> real pod talking over the wire (2026-07-05)
The emulated SheepShaver console and the emulated DOSBox pod now exchange
the live console protocol on TCP 1501. Hard-won setup (all required):
1. **DOSBox-X pcap backend had to be rebuilt + npcap DLL path.** config.h
had `C_PCAP 1` but the stale `ethernet.o` predated it; force-recompile
(`rm src/misc/ethernet.o ethernet_pcap.o; make`). Runtime: npcap installs
its DLLs in `C:\Windows\System32\Npcap\` (npcap-only mode), NOT System32,
so DOSBox couldn't load wpcap.dll -> **launch dosbox-x.exe with
`C:\Windows\System32\Npcap` prepended to PATH.**
2. **Two-TAP Windows bridge** (single shared TAP fails: SheepShaver holds the
user-mode handle, DOSBox rides NDIS, frames don't cross). Console
SheepShaver -> TAP1 (`ether tap` + etherguid); pod -> TAP2; both bridged.
3. **TAP2 media status = Always-Connected** (registry MediaStatus=1 on the
TAP2 class key, needs elevation; the GUI toggle didn't persist). Without
it TAP2 reports "unplugged" and the bridge won't forward to it.
4. **Pod pcap binds to the BRIDGE MINIPORT, not a member TAP.** Injecting on
a bridge *member* (TAP2) isn't re-forwarded by the bridge (the pod TX'd
but the console never saw it). Bind DOSBox `realnic` to the bridge
miniport = "Microsoft Network Adapter Multiplexor Driver". GOTCHA: DOSBox
`realnic` matches a substring of the pcap device NAME (`\Device\NPF_{GUID}`)
and parses a *leading-digit* value as an interface index -- the bridge
GUID `5DB5521D...` starts with 5 -> picked iface #5 (Bluetooth!). Use a
letter-leading fragment: `realnic=DB5521D`.
5. Diagnostics: added `PCAP TX/RX` counters to `ethernet_pcap.cpp`
(SendPacket/GetPackets) -- confirmed the pod WAS transmitting all along;
the bridge forwarding was the only gap. Capture the wire with
`dumpcap -i <bridge#> -f "arp or tcp port 1501" -w cap.pcapng`.
**Verified protocol on the wire (little-endian, matches the source decode):**
- Console->pod **StateQuery** (32B): hdr clientID=4(App) gameID=0 fromHost=1
ts=.. ; msg len=16 id=3 flags=0 ; body requestingHost=1.
- Pod->console **StateResponse** (40B): hdr **clientID=5 (ConsoleClientID)**
gameID=0 fromHost=0 ts=.. ; msg len=24 id=1 **flags=1 (Reliable)** ; body
respondingHostID=0, **applicationState=1**, application=1 (BTL4/BattleTech).
(My earlier synthetic guess had clientID=4/flags=0/host=1/state=0 -- all
wrong, which is why the real console rejected the stand-in. These are the
correct values for pod_responder.py.)
- Console polls StateQuery ~every 2s; pod ACKs + StateResponse each time.
Clean 3-way handshake; zero-length "dup ACKs" are benign keepalives.
OPEN: with this working, the console still hadn't enabled mission-send in
the stripped-down (keyboard-only, no-RIO, no-sound) pod boot -- retrying
with a full RIO+sound boot (`net_full.conf`) so the pod presents its normal
state (applicationState may change when fully booted). Need the console UI
readout to know what state it wants before it will send the mission egg.
## Open questions / notes
- Exact TCP listen port(s) — not in the source grep; get from NETNUB.EXE
or a capture at milestone 3.