Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
7d5e24d
Add IPX, NetBEUI, NetBIOS, SMB 1.0, and shortname stub subsystems
pgodwin May 4, 2026
0445baa
Move local_fs backend into pkg/vfs and have AFP consume it via interface
pgodwin May 4, 2026
a145edb
Switch IPX and NetBEUI ports to per-protocol pcap handles
pgodwin May 5, 2026
0ff06cd
IPX Phase 1: node identity, source fill, addressed-to-us filter
pgodwin May 5, 2026
de2a7d7
IPX Phase 2: RIP responder and periodic broadcast on socket 0x0453
pgodwin May 5, 2026
9f488d5
IPX Phase 3: SAP responder, registry, and periodic broadcast on socke…
pgodwin May 5, 2026
3d44033
NB-IPX Phase 5A: NetBIOS-over-IPX wire codec
pgodwin May 5, 2026
455c33f
NB-IPX Phase 5B: name claim with retry, advertise via SAP on success
pgodwin May 5, 2026
9c558ed
IPX/NetBEUI: fall back to EtherTalk interface; accept SMB.Shares.* alias
pgodwin May 5, 2026
d690828
icons: rename omnitalk.{icns,ico} to classicstack.{icns,ico}
pgodwin May 6, 2026
a92c8fa
afp: integrate shortname mapper and VFS event bus
pgodwin May 6, 2026
689d932
ipx: add per-link pcap capture and router tx/rx debug tracing
pgodwin May 6, 2026
39a96e5
netbios: expand NetBEUI/NB-IPX transports with name table and sessions
pgodwin May 6, 2026
0fd54c7
smb: build out SMB1 server, direct-IPX transport, and identity config
pgodwin May 6, 2026
bb2b5c3
config: enable SMB+IPX+NetBIOS in server.toml and add SMB MVP prompt
pgodwin May 6, 2026
05bcda6
spec: add SMB/CIFS/BRWS and IEEE 802 reference material
pgodwin May 6, 2026
ff392d0
gitattributes: pin text files to LF and renormalize tree
pgodwin May 6, 2026
c38edc5
Implement QUERY_INFORMATION_DISK (0x80)
pgodwin May 6, 2026
c43cf38
Implement CHECK_DIRECTORY (0x10)
pgodwin May 6, 2026
269c6fc
Implement SEARCH (0x81)
pgodwin May 6, 2026
0679d3f
Implement OPEN_ANDX (0x2D)
pgodwin May 6, 2026
6af120e
Implement READ_ANDX (0x2E)
pgodwin May 6, 2026
7385ebb
Implement WRITE_ANDX (0x2F)
pgodwin May 6, 2026
a3a2670
Implement CLOSE (0x04)
pgodwin May 6, 2026
6130942
Implement FLUSH (0x05)
pgodwin May 6, 2026
4394a01
Refactor SMB service into grouped command files
pgodwin May 6, 2026
ca8daf0
Implement LOCKING_ANDX (0x24)
pgodwin May 6, 2026
4ff8791
Implement DELETE (0x06)
pgodwin May 6, 2026
1ae258a
Implement RENAME (0x07)
pgodwin May 6, 2026
e088091
Implement DELETE_DIRECTORY (0x01)
pgodwin May 6, 2026
aa8707b
smb/ipx: ignore inbound SMB response packets to prevent duplicate rep…
pgodwin May 6, 2026
c526eb8
port: add loopback filtering to prevent pcap echoes
pgodwin May 7, 2026
0c47440
smb: clarify Echo response behavior
pgodwin May 7, 2026
91724ad
ipx: dedupe immediate duplicate inbound frames
pgodwin May 7, 2026
7ae4846
smb/ipx: implement SMB_COM_ECHO EchoCount responses
pgodwin May 7, 2026
31023f2
gofmt: tidy alignment and trailing blank lines
pgodwin May 7, 2026
8d398c3
smb: advertise NT capabilities and SystemTime in NEGOTIATE response
pgodwin May 7, 2026
03cf196
smb: IPC$ is a virtual share; return STATUS_BAD_NETWORK_NAME for unkn…
pgodwin May 7, 2026
e9cf3ae
smb: implement RAP NetShareEnum (function code 0x0000) for share enum…
pgodwin May 7, 2026
ca16224
netbeui: add pcap capture sink and enable transport in server.toml
pgodwin May 7, 2026
c367633
ipx/port: pre-register outbound frames in the dedupe ring
pgodwin May 7, 2026
f1ef3f6
smb/over_ipx_direct: stamp CID and SequenceNumber in responses
pgodwin May 7, 2026
8188881
smb: enumerate, read, seek, lock — share enumeration to file I/O
pgodwin May 7, 2026
9454990
rawlink: implement L2 Wi-Fi bridge adapter for non-EtherTalk protocols
pgodwin May 11, 2026
9501f73
shortname: decouple mapper from AFP and integrate as a VFS service
pgodwin May 11, 2026
375240b
netbeui: implement LLC Type-2 connection-oriented transport
pgodwin May 11, 2026
89e2c99
netbios/over_netbeui: implement session state, status queries, and ad…
pgodwin May 11, 2026
e2cd36f
smb: implement legacy core commands, DOS matching, and find-next resp…
pgodwin May 11, 2026
3d20d61
cmd/classicstack: unify bridge settings, add BPF filtering, and wire …
pgodwin May 11, 2026
930e017
docs: update architecture, readme, and config schemas
pgodwin May 11, 2026
6537772
fixup: adjust default interface for ipx and netbeui
pgodwin May 11, 2026
a7fa7ee
smb: honor SMB_COM_READ_MPX per spec instead of rejecting with ERRuseSTD
pgodwin May 11, 2026
e57276d
Fix CI Runners
pgodwin May 12, 2026
01b7a68
Remove duplicate macgarden_fs.go
pgodwin May 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Normalize line endings on commit. Files in the repo are stored with LF;
# Windows checkouts get CRLF for shell scripts marked otherwise, but Go
# tooling expects LF so we pin text files to LF on checkout too.
* text=auto eol=lf

# Explicitly mark common text types so detection cannot get it wrong.
*.go text eol=lf
*.md text eol=lf
*.toml text eol=lf
*.json text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf
*.txt text eol=lf
*.conf text eol=lf
*.example text eol=lf

# Windows-only files keep CRLF.
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf

# Binary assets — never touch line endings.
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.icns binary
*.pdf binary
*.doc binary
*.docx binary
*.db binary
*.pcap binary
*.bin binary
93 changes: 93 additions & 0 deletions .github/prompts/plan-smb1VfsMvp.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Plan: SMB1 VFS MVP for DOS and Win9x

Build a dependency-ordered SMB1 server MVP on your existing NetBIOS stack and VFS registry, targeting MS-DOS + Windows 95/98/ME, with guest auth first. The approach is to convert the current browser-focused SMB stub into a stateful file server (UID/TID/FID/search/lock lifecycle), implement enumeration first, then layer read/write/locking/path operations, and implement copy as read+write fallback.

## Steps

### Phase 0: Baseline and guardrails
Confirm build-tag/runtime paths for smb + netbios + netbeui + ipx. Preserve existing browser behavior while adding file-serving commands. Add a short command support matrix (supported vs deferred) for SMB1 scope.

### Phase 1: Session and share state foundation *(blocks all later phases)*
Add per-session state keyed by session context, with UID allocation, TID map per tree connect, FID map per open file, and search-handle map for enumeration continuation.

### Phase 1: Share binding to VFS *(depends on session state)*
Instantiate one VFS backend per share at service start via `vfs.New(share.FSType, vfs.Params{Name, Path, ReadOnly})`, validate share roots, and enforce share read-only behavior at command handlers.

### Phase 2: Command decode/encode scaffold *(depends on session state)*
Keep the existing dispatcher shape, but move command logic into dedicated handlers for incremental implementation and testability. Add a small error-mapping helper early (os/vfs errors → SMB status codes) to keep handlers consistent and testable.

### Phase 3: Share enumeration MVP *(depends on phases 1–2)*
Keep RAP `NetServerEnum2` path working and harden it for stable output and stricter request validation for legacy clients. Ensure it enumerates configured SMB server identity plus observed browser servers.

### Phase 4: Directory and file enumeration MVP *(depends on phases 1–2)*
Implement `SMB_COM_SEARCH` first (DOS/Win9x priority), then add `SMB_COM_TRANSACTION2` support for `TRANS2_FIND_FIRST2` and `TRANS2_FIND_NEXT2`. Use VFS `ReadDir` + `Stat`, wildcard matching, DOS attribute filtering, and optional shortname mapping when configured.

### Phase 4: Search state and paging *(depends on enumeration)*
Add server-side enumeration handles, pagination/cursor continuation, timeout/cleanup, and `FIND_CLOSE2` handling where applicable.

### Phase 5: Open/read/write/close core I/O *(depends on phases 1–2)*
Implement open path plus `READ_ANDX`, `WRITE_ANDX`, and `CLOSE` via VFS `OpenFile`, `ReadAt`, `WriteAt`, `Close`, with I/O size bounded by negotiated buffer size and robust SMB status-code mapping.

### Phase 6: File locking *(depends on phase 5)*
Implement SMB-local byte-range lock table keyed by file identity + range + owner (session/FID), with overlap conflict detection and automatic release on close/session end.

### Phase 7: Rename/move/delete for files and directories *(depends on phases 1–2 and 5)*
Implement rename/move via VFS `Rename` and delete semantics via VFS `Remove` with SMB-compatible precondition checks for both files and directories.

### Phase 8: Copy fallback *(depends on phase 5)*
Implement copy as server-side read+write loop for MVP (same-share first), defer full SMB `COPY` command semantics unless client traces require it.

### Phase 9: Transport hardening *(parallel with late phases)*
Verify parity across NetBIOS over NetBEUI, NetBIOS over IPX, and SMB direct IPX socket 0x0550. Ensure reply routing uses contextual session/datagram endpoints correctly and does not regress browser datagram handling.

### Phase 10: Observability and cleanup *(parallel with phase 9)*
Add targeted debug logging and lifecycle counters for UID/TID/FID/search/lock events and session teardown cleanup.

---

## Relevant files

- `service/smb/server.go` — primary SMB command dispatcher; add state tables, per-command handlers, and lifecycle cleanup
- `service/smb/constants.go` — verify/add command and flag constants used by implemented SMB1 requests
- `service/smb/share.go` — share config contract consumed by VFS instantiation logic
- `service/smb/server_test.go` — extend with SMB session/enum/file-op tests, including transport-context cases
- `pkg/vfs/vfs.go` — leverage `FileSystem` and `File` interfaces directly for SMB backend operations
- `pkg/vfs/local_fs.go` — expected initial backend behavior for local share paths
- `service/netbios/service.go` — contextual session/datagram handling and routing constraints
- `service/smb/over_ipx_direct/transport.go` — SMB direct IPX transport path for socket 0x0550
- `cmd/classicstack/smb_enabled.go` — SMB wiring into NetBIOS and direct IPX transport
- `cmd/classicstack/netbios_enabled.go` — NetBIOS transport selection for tcp, netbeui, ipx
- `spec/ms-smb.md` — normative SMB1 behavior reference for command semantics and status handling

---

## Decisions

| Decision | Choice |
|---|---|
| Client priority | Windows 95/98/ME and MS-DOS |
| Transport priority | SMB direct IPX 0x0550 and NetBIOS over NetBEUI/IPX |
| Auth mode | Guest-only for MVP |
| Operation order | Dependency-driven |
| Path ops scope | Files and directories in MVP |
| Copy mode | Read+write fallback for MVP |

---

## Verification

1. Expand SMB unit tests for each phase: session lifecycle, TID/FID allocation, search pagination, read/write boundaries, lock conflicts, rename/delete/copy outcomes.
2. Add temp-dir-backed tests for `local_fs` share behavior and read-only enforcement.
3. Add transport-level integration checks for netbeui + ipx + direct IPX 0x0550 using the same SMB request sequences.
4. Run manual DOS/Win9x smoke: browse shares, enumerate dirs/files, read/write, lock behavior, rename/move/delete/copy.
5. Re-run existing browser tests to ensure election/announcement/NetServerEnum2 behavior remains intact.

---

## Further Considerations

1. Prefer `SMB_COM_SEARCH` before full TRANS2 to maximise DOS/Win9x compatibility and reduce initial parser complexity.
2. Keep command parsing incremental in `service/smb/server.go` first; split into separate request/response files only after behaviour stabilises to avoid churn.
3. Add the error-mapping helper (`os/vfs error → SMB NTSTATUS`) early so all handlers share consistent status codes from the start.
4. Use `SessionContext.SourceConnID` as the session key when non-zero; fall back to the remote endpoint tuple for transports that don't provide it (e.g. direct IPX 0x0550).
5. Prefer `SMB_COM_SEARCH` first before full TRANS2 to maximize DOS/Win9x compatibility and reduce initial parser complexity.
1 change: 1 addition & 0 deletions .github/workflows/pr-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ jobs:
- "afp macgarden macip"
- "afp sqlite_cnid"
- "all"
- "ipx netbeui smb"
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ go.work.sum
.macgarden/

.captures/
captures/
captures/
classicstack
42 changes: 20 additions & 22 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,24 @@ linters:
- revive
- staticcheck
- unused

linters-settings:
errorlint:
errorf: true
asserts: true
comparison: true
revive:
settings:
errorlint:
errorf: true
asserts: true
comparison: true
revive:
rules:
- name: var-naming
- name: package-comments
- name: exported
disabled: true
gocritic:
disabled-checks:
- ifElseChain
- singleCaseSwitch
exclusions:
rules:
- name: var-naming
- name: package-comments
- name: exported
disabled: true
gocritic:
disabled-checks:
- ifElseChain
- singleCaseSwitch

issues:
exclude-rules:
- path: _test\.go$
linters:
- errcheck
- revive
- path: _test\.go$
linters:
- errcheck
- revive
Loading
Loading