Skip to content

Latest commit

 

History

History
156 lines (124 loc) · 11.6 KB

File metadata and controls

156 lines (124 loc) · 11.6 KB

Configuration Reference

Every unit can have its own config file, read once, the first time it's opened (open count transitions 0→1 — see below). An unconfigured unit works with sensible compiled-in defaults; you only need a config file to change something.

File location

ENV:sana2loop/unit<N>.config

falling back to

S:sana2loop/unit<N>.config

if ENV: doesn't have one — useful on a minimal system with no ENV: assign at all. <N> is the unit number with no leading zero (unit0.config, unit10.config, ...).

A missing file is not an error — the unit just uses its compiled-in defaults. A file that exists but has a problem (an unrecognized key, or a malformed line) fails the entire OpenDevice() call with S2ERR_BAD_ARGUMENT — this device treats a config typo as something that should be loud, not silently ignored or silently reinterpreted.

File format

Plain text, one key=value per line:

mode=crossover
peer=3
mtu=1400
# a comment
  • Lines starting with # are comments.
  • Blank lines are ignored.
  • No surrounding whitespace tolerance — key = value (with spaces) is malformed, not forgiving.
  • Every value below is validated (range-checked for numeric keys); an out-of-range or malformed value fails the whole file exactly like an unrecognized key does.

Keys

General

Key Values Default Meaning
mtu 1–1500 1500 (1006 for a non-Ethernet wire=) Maximum Transmit Unit reported by S2_DEVICEQUERY and enforced on CMD_WRITE/S2_BROADCAST/S2_MULTICAST. SANA2IOF_RAW writes get 14 extra bytes of headroom (Ethernet header size) — see the SANA-II spec's raw-frame convention. This same number (MTU+14) is also reported as RawMTU (SANA-II Rev 4) via S2_DEVICEQUERY — except on a mode=replay unit or a non-Ethernet wire= unit, which always report RawMTU=0 (no raw writes supported there).
mintu 0–1500 0 (no minimum) Minimum accepted write size. A CMD_WRITE/S2_BROADCAST/S2_MULTICAST shorter than this fails with S2ERR_BAD_ARGUMENT — rejected, never silently padded (padding would change the bytes a reader sees, against this device's byte-exact delivery contract). Useful for catching a stack that forgets real Ethernet's 60-byte minimum-frame padding, which works fine on a loopback but fails on real hardware. A mintu above the unit's (resolved) mtu fails the whole config. 0 (the default) disables the check entirely.
bps any nonzero number 10000000 (see wire= for its per-wire defaults) The link speed S2_DEVICEQUERY reports in its BPS field. Reported only — nothing in this device throttles or delays traffic based on it.
wire ethernet, slip, cslip, ppp ethernet What kind of wire this unit pretends to be — see Wire types below.
addr colon-separated hex bytes (derived per unit) Pins the unit's factory station address (and, with it, the current address a fresh open starts from) — e.g. addr=02:11:22:33:44:55, or addr=C0:A8:4C:02 on a non-Ethernet wire=. The byte count must match the wire's address width exactly (6 for Ethernet, 4 otherwise), and an Ethernet address with the group (multicast) bit set is rejected. S2_CONFIGINTERFACE still works on top exactly as always: it changes the current address; the pinned factory value stays. Useful for reproducible recorded fixtures and for mimicking a specific topology a stack config expects.
rxqueue 0–64 0 Bounded convenience receive queue. 0 means strict drop: a packet with no queued CMD_READ/S2_READORPHAN waiting for it is dropped immediately (and counted in Sana2DeviceStats.UnknownTypesReceived) — real SANA-II drivers hold no internal buffers, and this default matches that. A nonzero value lets up to that many undelivered packets sit in a per-unit queue instead.
buffhooks 8, 16, 32 8 Which SANA-II Rev 2/3 buffer-management hook width this unit actually invokes, for whichever opener negotiated it (offered the matching S2_CopyToBuff16/32/S2_CopyFromBuff16/32 tag at OpenDevice()). An opener that didn't negotiate the configured width falls back to its own base hook transparently — this is never a hard requirement, only a preference. 8 (the default) always uses the base hook, matching every version of this device before this knob existed.

Wire types

wire= selects the hardware type S2_DEVICEQUERY reports and, with it, how addressing works on the unit:

ethernet (default) slip / cslip / ppp
HardwareType S2WireType_Ethernet S2WireType_SLIP / _CSLIP / _PPP
Address size 6 bytes (48 bits) 4 bytes (32 bits) — an IP address stands in for a hardware address, the established convention for serial-wire SANA-II drivers
Factory address 02:53:32:4C:00:<unit> 0A:53:32:<unit> (i.e. 10.83.50.<unit>)
Default mtu / bps 1500 / 10000000 1006 / 19200 (ppp: 1006 / 115200) — an explicit mtu=/bps= always wins, wherever it sits in the file
Broadcast / multicast supported S2_BROADCAST, S2_MULTICAST, and S2_ADD/DELMULTICASTADDRESS all fail S2ERR_NOT_SUPPORTED — a point-to-point wire has no such addressing
SANA2IOF_RAW writes allowed (MTU+14) fail S2ERR_NOT_SUPPORTED; RawMTU reports 0
mode=replay / record= supported fails the config — the pcap side of this device is built around LINKTYPE_ETHERNET framing

A crossover pair should configure the same wire= on both ends — a write while the two ends' wire types differ fails with S2ERR_BAD_STATE (loudly, rather than silently never matching the peer's differently-sized address). Since config is only read at a unit's own first open, that also means opening both ends of a non-Ethernet pair before writing.

Key Values Default Meaning
mode echo, crossover, replay echo (crossover for units 2 and 3) What the unit does with traffic.
peer a unit number itself Required for mode=crossover — the other unit this one is paired with. A crossover unit with no distinct peer fails to open.
replay a dos.library-openable path — Required for mode=replay — the .pcap capture to load.
replaycap 1–256 4 Maximum records a mode=replay unit will load — a capture with more fails the whole open (S2ERR_BAD_ARGUMENT). The default (4) is deliberately small (see Replay and Record for why); raise it per-unit if your capture is bigger and your target has the memory to spare — a value that doesn't actually fit fails with S2ERR_NO_RESOURCES instead, since the device can't know your target's free memory in advance.
replaymode consume, scheduled consume How a replay unit delivers its loaded records — see Replay and Record.
record a dos.library-openable path — If set, every packet this unit actually receives (in any mode) is captured to this path as .pcap, flushed at last close.
recordmax 1–262144 65536 RAM buffer size (bytes) for record=. Once full, further packets are silently not appended (counted, not fatal) — see S2_GETSPECIALSTATS in Replay and Record.

replay=/record= buffers are held in RAM for as long as the device stays loaded, even after every opener of the unit has closed it — see Replay and Record: Memory usage, and freeing it manually if that matters for your setup.

Fault injection (see Fault Injection for the full pipeline and examples)

Key Values Default Meaning
seed any number — PRNG seed for this unit's fault injection (xorshift32). 0 is accepted but coerced to 1 when actually used (an all-zero xorshift32 state never changes). Leave unset for a fixed default seed.
errors 0–65535 0 (disabled) 1-in-N chance a write fails visibly: S2ERR_TX_FAILURE with S2WERR_TOO_MANY_RETRIES, plus S2EVENT_TX|S2EVENT_ERROR fired to any queued S2_ONEVENT. The loud counterpart to droppct/loss's silent vanishing — exercises error-handling/retry paths instead of timeouts. 1 = every write fails (deterministic, no PRNG).
droppct 0–100 0 Percent chance a written packet is silently lost (accepted by the writer, never delivered).
loss 0–65535 0 (disabled) 1-in-N chance a written packet is silently lost — same observable behavior as droppct, at rates a whole percent can't express (loss=1000 ≈ 0.1%). Composes with droppct; each draws independently. 1 = every write lost (deterministic, no PRNG).
duppct 0–100 0 Percent chance a written packet is delivered twice (a genuine second copy, independently subject to reordering).
truncate 0–1500 0 (disabled) Caps delivered packet length to this many bytes. 0 disables truncation.
reorder 0–8 0 (disabled) Reorder window size. 0 disables reordering; delivery order matches write order.
delay 0–3000 0 (disabled, synchronous delivery) Fixed delivery latency in VBlank ticks (50/sec). Runs last in the pipeline, after reorder.
deviation 0–3000 0 (no jitter) Symmetric jitter around delay, in ticks — actual latency per write is drawn from [delay-deviation, delay+deviation], clamped at 0. Legal with delay=0 (pure scatter, no floor). Can reorder delivery on its own, independent of reorder=.
oversilent 0 or 1 0 Crossover only. When a written packet exceeds the peer's MTU (not the writer's own, which is checked unconditionally), 1 accepts the write and silently vanishes the packet — simulating a PMTUD black hole — instead of failing the write with S2ERR_MTU_EXCEEDED.
offlineafter any count 0 (disabled) Auto-forces the unit offline after this many successful writes, as if S2_OFFLINE had been issued.
onlineafter any count 0 (disabled) Auto-forces the unit back online after this many failed write attempts while offline, as if S2_ONLINE had been issued — simulates a flaky link recovering on its own.

When configuration is read

A unit resets to a fully clean state (offline, factory station address, zeroed stats, rxqueue back to 0, mode/peer/fault-injection knobs back to their compiled-in defaults) every time its open count transitions from 0 to 1 — i.e. the first OpenDevice() after the last close. Its config file is read at that same moment. A busy unit's live configuration is never disturbed by a config file changing on disk; you have to let every opener close first (dropping the count to 0) before a config edit takes effect on the next open.

The config file is only read when the opener is a real Process (FindTask(NULL)->tc_Node.ln_Type == NT_PROCESS) — a bare Exec Task opening the device gets compiled-in defaults with no dos.library call at all, preserving the device's Kickstart 1.3 guarantee that its core open/read/write path never depends on DOS being available.

Example: a crossover pair with a lossy link

ENV:sana2loop/unit4.config:

mode=crossover
peer=5
droppct=5
seed=42

ENV:sana2loop/unit5.config:

mode=crossover
peer=4

Opening units 4 and 5 now gives you a virtual null-modem link where ~5% of what unit 4 writes never arrives at unit 5 — useful for testing retry logic without touching real hardware.