Networking recon: map WATTCP/NetNub pod stack + emulator bring-up plan
The pods do TCP/IP over Ethernet (WATTCP + NetNub real-mode server; ops console is master, pushes mission eggs to pods over TCP). Pod is a static host on an isolated 200.0.0.0/24 LAN (200.0.0.113, console 200.0.0.1); -egg is the dev bypass of this path. Fork already has NE2000 + pcap/slirp backends; since the emulated card is NE2000 not PCI Lance we skip the Novell ODI chain and load a Crynwr NE2000 packet driver directly. NET-NOTES.md has the full architecture + milestone plan (headline goal: host-side stand-in console pushes an egg over the wire, no -egg bypass). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
# Networking subsystem — recon & bring-up plan
|
||||
|
||||
Goal: bring the pod network up under the emulator so a pod boots the
|
||||
production way (`netnub -f BTL4OPT`, mission egg delivered **over the
|
||||
wire**) instead of the `-egg test.egg` dev bypass. This is also the
|
||||
substrate the ops-console port will plug into.
|
||||
|
||||
## What the pod network actually is (recon 2026-07-04)
|
||||
|
||||
The stack, bottom to top:
|
||||
|
||||
1. **Ethernet NIC + Novell ODI** (AUTOEXEC.BAT): `lsl` (Link Support
|
||||
Layer) → `lnepci` (Lance/PCnet PCI ODI driver) → **`odipkt`** (Dan
|
||||
Lanciani's ODI→Packet-Driver shim). The ODI/Netware login side
|
||||
(IPXODI/VLM/NET LOGIN in STARTNET.BAT) is for file-server access; the
|
||||
game itself only needs the **packet-driver interface** odipkt exposes.
|
||||
`NET.CFG`: LNEPCI, FRAME Ethernet_II + 802.2.
|
||||
2. **WATTCP** — the TCP/IP stack. Confirmed by `WATTCP.CFG` in
|
||||
`REL410/BT`, `REL410/RP`, and per-pod `VGL_LABS/THISPOD`:
|
||||
```
|
||||
my_ip = 200.0.0.113 netmask = 255.255.255.0
|
||||
gateway = 200.0.0.1 nameserver = 200.0.0.1
|
||||
```
|
||||
So each pod is a static host on an isolated **200.0.0.0/24** LAN; the
|
||||
ops console is almost certainly **200.0.0.1**.
|
||||
3. **NetNub** (`netnub.exe`, real-mode) — launches the game as a child
|
||||
(`netnub -f BTL4OPT`) and is the network server for the
|
||||
protected-mode game. Interface (`NetNub/NETNUB.HPP`): a shared `Netcom`
|
||||
struct (version 11, 64KB buffer) + a software interrupt. The game sets
|
||||
a Function code (TCP_OPEN=3, TCP_LISTEN=4, TCP_CLOSE=5,
|
||||
RESOLVE_ADDRESS=6, CHECK_SOCKET=7, UDP_*, plus remote file
|
||||
OPEN/READ/WRITE/SEEK/CLOSE 12-19), copies the marked fields to real
|
||||
mode, INTs, copies back. `tcp_Socket` is ~4300 bytes = classic WATTCP.
|
||||
4. **L4NetworkManager** (`L4NET.HPP/.TCP`) — the game's net brick. The
|
||||
**console is master and connects to the pods**; the pod receives
|
||||
`ReceiveEggFileMessage` (the mission egg), replies
|
||||
`AcknowledgeEggFileMessage` ("connected, ready, send the next host"),
|
||||
and tracks `HostConnected/HostDisconnected`. If the console drops, the
|
||||
pod is built to auto-start anyway.
|
||||
|
||||
Topology to replicate:
|
||||
```
|
||||
[ops console 200.0.0.1] --TCP--> [pod 200.0.0.113] (+ more pods .114..)
|
||||
(master, egg source) (listens, ACKs, runs mission)
|
||||
```
|
||||
|
||||
## Emulator enablers (already in the fork)
|
||||
|
||||
- **NE2000** ISA NIC emulated (`hardware/ne2000.cpp`, Bochs-derived);
|
||||
config `[ne2000] ne2000=true, nicbase=, nicirq=, macaddr=, backend=`.
|
||||
- **Two Ethernet backends** built: `misc/ethernet_pcap.cpp` (bridge to a
|
||||
host NIC via npcap) and `misc/ethernet_slirp.cpp` (user-mode virtual
|
||||
net / NAT). Plus `ethernet_nothing`.
|
||||
|
||||
Key simplification: the emulated card is an **NE2000, not a PCI Lance**, so
|
||||
`lnepci` won't bind. We don't need the Novell ODI chain at all — WATTCP
|
||||
finds a packet driver by scanning INT 0x60-0x80 for the `PKT DRVR`
|
||||
signature, so we load a generic **NE2000 packet driver** (Crynwr
|
||||
`NE2000.COM`) directly against the emulated card's base/IRQ. That drops
|
||||
lsl/lnepci/odipkt/VLM entirely and hands NetNub/WATTCP the packet
|
||||
interface they expect.
|
||||
|
||||
## Bring-up plan
|
||||
|
||||
**Backend choice.** Two viable paths:
|
||||
- *pcap + host-only adapter (recommended, matches real topology):* bridge
|
||||
the NE2000 to a host virtual switch; run the pod at 200.0.0.113 and the
|
||||
stand-in console at 200.0.0.1 on that segment. WATTCP's static IP + LAN
|
||||
assumptions hold exactly; the console connects inbound to the pod with
|
||||
no NAT. Cost: npcap + a host-only/loopback adapter + admin.
|
||||
- *slirp (fallback, self-contained):* no host NIC/admin, but it's NAT and
|
||||
defaults to 10.0.2.0/24 — the pod LISTENS, so inbound needs slirp
|
||||
host-forwarding and a guest-network/IP reconciliation with WATTCP's
|
||||
hard-coded 200.0.0.113. Investigate whether DOSBox-X slirp allows the
|
||||
custom net + static guest IP + inbound forward cleanly.
|
||||
|
||||
**Milestones**
|
||||
1. **NIC up**: `[ne2000]` on, NE2000.COM packet driver loaded, WATTCP/
|
||||
NetNub start clean; pod boots via `netnub -f BTL4OPT` (no `-egg`) and
|
||||
sits waiting for the console. Verify NetNub reports net address
|
||||
200.0.0.113 and a TCP_LISTEN is queued. (New scratch conf, mirror the
|
||||
RIO/sound conf pattern.)
|
||||
2. **L3/L4 reachability**: from the host segment, confirm the pod answers
|
||||
ARP/ping at 200.0.0.113 and a raw TCP connect to its listen port
|
||||
completes (proves NE2000↔backend↔host path end-to-end).
|
||||
3. **Decode the console→pod egg protocol**: `NetworkPacketHeader` +
|
||||
message framing from `network.hpp`/`hostmgr.hpp` + the
|
||||
ReceiveEggFileMessage layout, cross-checked with a live capture of the
|
||||
pod's listen/ACK. (Pin the listen port here — not yet found in source;
|
||||
grep NETNUB.EXE strings / capture.)
|
||||
4. **Eggs over the wire**: a minimal host-side **stand-in console**
|
||||
(Python) connects to the pod, pushes a mission egg, handles the ACK →
|
||||
pod runs the mission with no `-egg` bypass. **This is the headline
|
||||
goal.**
|
||||
5. *(later, joins the console-port workstream):* replace the stand-in
|
||||
with the ported/emulated Mac ops console; multi-pod coordination
|
||||
(HostConnected/Disconnected, mission review, camera ship).
|
||||
|
||||
## Open questions / notes
|
||||
- Exact TCP listen port(s) — not in the source grep; get from NETNUB.EXE
|
||||
or a capture at milestone 3.
|
||||
- Does WATTCP need a real ARP peer for the gateway at boot, or does it
|
||||
proceed with a static IP and only ARP on connect? Affects whether the
|
||||
stand-in console must answer ARP for 200.0.0.1.
|
||||
- `NETCLIENT=PNW` (PARAMETR.bat) selects Personal NetWare — file-server
|
||||
side, not the game's TCP path; likely irrelevant to egg delivery and
|
||||
can stay unloaded under emulation.
|
||||
- RP uses the identical MUNGA net brick + its own WATTCP.CFG — everything
|
||||
here carries over to Red Planet.
|
||||
Reference in New Issue
Block a user