Files
TeslaRel410/emulator/NET-NOTES.md
T
CydandClaude Fable 5 5b44ede702 Networking: console SW extracted, TCP port 1501 found, pod = Puck
Console 4.10 (PowerPC PEF/CodeWarrior) + Console.ini extracted from the
.sit. Console.ini answers the open protocol question: the console<->pod
TCP port is 1501. Full cockpit endpoint roster recorded; our emulated pod
200.0.0.113 is the cockpit Puck. The real 6100 does not boot but is no
longer needed -- run Console 4.10 under SheepShaver. Only remaining
protocol unknown is the on-stream message framing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 22:12:49 -05:00

11 KiB
Raw Blame History

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).

Milestone 1 — DONE (2026-07-04): pod boots on the network path

Verified end to end under DOSBox-X (slirp backend), no -egg bypass:

  • [ne2000] ne2000=true, nicbase=300, nicirq=3, backend=slirp → NE2000 emulated at Base=0x300 irq=3; slirp 4.9.1 initialized.
  • The Novell ODI chain works against the emulated NE2000, no external packet driver needed: lslne2000 (Novell/Eagle NE2000 MLID v1.53, from NWCLIENT) → odipkt (FTP Software ODI packet driver). ODIPKT installed at SINT 0x60, MLID NE2000, MAC CE:3D:72:67:38:69, frames Ethernet_II (board 1) + 802.2 (board 2).
  • GOTCHA: the ODI tools read NET.CFG from the directory the .COM loads from, and the stock NWCLIENT\NET.CFG says Link Driver LNEPCI — with no NE2000 section the MLID defaults to 802.2-only and odipkt fails ("An MLID could not be found"). Fix without touching ALPHA_1: keep an emulator NET.CFG (Link Driver NE2000 + FRAME Ethernet_II) beside copies of lsl/ne2000/odipkt on a scratch drive and load from there.
  • netnub -f btl4opt (no egg) launches the game as btl4opt -net 250224, sets up the game↔netnub channel at INT 0x61 (separate from odipkt's 0x60), initializes the network manager ("Changing blocking from 0 to 1"), and the game boots through the VPX handshake to an open (blank) render window — waiting for a console to deliver a mission egg.

Working scratch files: scratchpad/net_stageB.conf, scratchpad/net/{NET.CFG,LSL.COM,NE2000.COM,ODIPKT.COM}. Launch env: VPXLOG + VPX_RESPOND=1 + VPX_RENDER=1 (VPX board must answer or the game exits before networking).

Console side: a Mac emulator stands in for the ops console (user, 2026-07-04)

The user is building a Mac emulator running the real 410console as the console peer (instead of a from-scratch Python stand-in). This merges the networking and console-port workstreams: the real console software will connect to the pod and push eggs. Implication for topology — two separate emulators (DOSBox pod + Mac console) must share an L2 segment, which slirp (NAT, per-process isolation) cannot bridge. Plan: move the pod's NE2000 to backend=pcap on a host-only/loopback adapter; bridge the Mac emulator to the same adapter; pod=200.0.0.113, console=200.0.0.1 on 200.0.0.0/24. Then milestone 3 (protocol) can be captured live from the real console traffic rather than reverse-engineered blind.

Console emulator = SheepShaver (2026-07-04)

The real ops console is a Power Macintosh 6100/66 (PowerPC 601) → emulate with SheepShaver (PPC Mac, Mac OS 7.5.29.0.4). Basilisk II (68k) is out. GOTCHA: the 6100's OWN ROM does NOT work in SheepShaver ("Unsupported ROM type" — SheepShaver emulates a PCI 9500; the 6100 is NuBus). Use a compatible old-world PPC ROM instead (7100/66, 7500, 7600, or 8500) — PPC apps are Toolbox/OS-based, not ROM-specific, so the 410console app runs regardless. Target Mac OS 7.5.57.6.1 (console era). Networking: SheepShaver TAP ↔ DOSBox-X NE2000 pcap, both bridged to a host adapter on 200.0.0.0/24 (console .1, pod .113).

Leverage the real 6100 (user has it): (1) image its hard drive → get the exact console software + OS + MacTCP/OpenTransport config → drop into SheepShaver for a faithful reproducible console; (2) fastest path to a first egg + LIVE protocol capture = put the real 6100 on a physical Ethernet with the pcap-bridged pod (needs an AAUI→RJ45 transceiver) and capture the console→pod egg exchange off the wire (hands us milestone 3). Sequence: real 6100 first (seeds image + capture) → SheepShaver as the archival console built from that image.

Console software EXTRACTED + protocol port FOUND (2026-07-04)

The user unstuffed 410consoleArchive.sit (via infinitemac.org) to 4_10extractedConsole/. Contents: Console 4.10 (the app), per-site config, fonts, logs. This means the dead 6100 is NOT a blocker — we have the console software directly; run it in SheepShaver (no disk image needed; fresh Mac OS 7.6.1/8.1 + MacTCP set to 200.0.0.1).

  • App is PowerPC — data fork magic Joy!peffpwpc (PEF/PowerPC), Metrowerks CodeWarrior 1993-95; 3.4MB resource fork. Confirms SheepShaver (needs standard shared libs: InterfaceLib/MathLib, present in any 7.5+ install).
  • Console.ini is the master config: [NetworkEndpoint::Cockpit::*] sections define every pod. THE TCP PORT IS 1501 (defaultPort / localHostPort) — this answers the milestone-3 "listen port unknown" question. Console connects to each pod IP:1501; pod LISTENS on 1501.

Cockpit endpoint roster (base Console.ini) — our emulated pod = "Puck" 200.0.0.113:

cockpit IP hostType
Frequent Flyer 200.0.0.11 (sic) 0
Privateer 200.0.0.112 0
Puck 200.0.0.113 0
Carpe Diem 200.0.0.114 0
Man O' War 200.0.0.115 0
Divine Wind 200.0.0.116 0
Icarus 200.0.0.117 0
Gypsy 200.0.0.118 0
Alpha Mission Review 200.0.0.119 2
Alpha Camera 200.0.0.120 2

hostType 0 = playable cockpit, 2 = special (mission-review / camera ship). ini Folder/ holds real per-venue configs (DBAtlanta/Chicago/Houston/ Toronto/LaZerPark/... — the actual VWE centers), same .11x/1501 scheme.

Revised topology: SheepShaver console @200.0.0.1 → TCP 200.0.0.113:1501 → pod "Puck". Remaining protocol unknown is just the on-stream message framing (NetworkPacketHeader + ReceiveEggFileMessage) — capture it once the console connects, or read it from network.hpp.

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.