summaryrefslogtreecommitdiff
path: root/lib9p/idl/1992-9P0.9p.wip
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/idl/1992-9P0.9p.wip')
-rw-r--r--lib9p/idl/1992-9P0.9p.wip166
1 files changed, 127 insertions, 39 deletions
diff --git a/lib9p/idl/1992-9P0.9p.wip b/lib9p/idl/1992-9P0.9p.wip
index 4278fa3..c9432c9 100644
--- a/lib9p/idl/1992-9P0.9p.wip
+++ b/lib9p/idl/1992-9P0.9p.wip
@@ -1,9 +1,22 @@
-# 1992-9P0.9p - Definitions of 9P0 (Plan 9 1st ed) messages
+# lib9p/idl/1992-9P0.9p - Definitions of 9P0 (Plan 9 1st ed) messages
#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
-# https://man.cat-v.org/plan_9_1st_ed/5/
+# The original 9P protocol ("9P0"), from Plan 9 1st edition.
+#
+# Documentation:
+# - https://github.com/plan9foundation/plan9/tree/1e-1993-01-03/sys/man/5
+# - https://github.com/plan9foundation/plan9/tree/1e-1993-01-03/sys/man/6/auth
+# - https://man.cat-v.org/plan_9_1st_ed/5/
+# - https://man.cat-v.org/plan_9_1st_ed/6/auth
+#
+# Implementation references:
+# - https://github.com/plan9foundation/plan9/blob/1e-1993-01-03/sys/include/fcall.h (MAXFDATA)
+# - https://github.com/plan9foundation/plan9/blob/1e-1993-01-03/sys/include/libc.h (`ch` bits)
+# - https://github.com/plan9foundation/plan9/blob/1e-1993-01-03/sys/src/fs/port/fcall.c (`stat`)
+# - https://github.com/plan9foundation/plan9/blob/1e-1993-01-03/sys/src/fs/port/fs.c (`offset:max`)
+# - https://github.com/plan9foundation/plan9/blob/1e-1993-01-03/sys/src/fs/port/portdata.h (MAXDAT)
version "9P0"
# tag - identify a request/response pair
@@ -15,39 +28,114 @@ num fid = 2
# uni"Q"ue "ID"entification
struct qid = "path[4] version[4]"
-# a nul-padded string
-struct name = 28*(txt[1])
-
-msg Tnop = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
-msg Rnop = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
-msg Tsession = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
-msg Rsession = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
-msg Rerror = "typ[1,val=TODO] tag[tag] ename[64]"
-msg Tflush = "typ[1,val=TODO] tag[tag] oldtag[tag]"
-msg Rflush = "typ[1,val=TODO] tag[tag]"
-msg Tauth = "typ[1,val=TODO] tag[tag] fid[fid] uid[28] chal[36]"
-msg Rauth = "typ[1,val=TODO] tag[tag] fid[fid] chal[30]"
-msg Tattach = "typ[1,val=TODO] tag[tag] fid[fid] uid[28] aname[28] auth[28]"
-msg Rattach = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
-msg Tclone = "typ[1,val=TODO] tag[tag] fid[fid] newfid[fid]"
-msg Rclone = "typ[1,val=TODO] tag[tag] fid[fid]"
-msg Tclwalk = "typ[1,val=TODO] tag[tag] fid[fid] newfid[fid] name[28]"
-msg Rclwalk = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
-msg Twalk = "typ[1,val=TODO] tag[tag] fid[fid] name[28]"
-msg Rwalk = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
-msg Topen = "typ[1,val=TODO] tag[tag] fid[fid] mode[1]"
-msg Ropen = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
-msg Tcreate = "typ[1,val=TODO] tag[tag] fid[fid] name[28] perm[4] mode[1]"
-msg Rcreate = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
-msg Tread = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192]"
-msg Rread = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192] pad[1] count*(data[1])"
-msg Twrite = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192] pad[1] count*(data[1])"
-msg Rwrite = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192]"
-msg Tclunk = "typ[1,val=TODO] tag[tag] fid[fid]"
-msg Rclunk = "typ[1,val=TODO] tag[tag] fid[fid]"
-msg Tremove = "typ[1,val=TODO] tag[tag] fid[fid]"
-msg Rremove = "typ[1,val=TODO] tag[tag] fid[fid]"
-msg Tstat = "typ[1,val=TODO] tag[tag] fid[fid]"
-msg Rstat = "typ[1,val=TODO] tag[tag] fid[fid] stat[116]"
-msg Twstat = "typ[1,val=TODO] tag[tag] fid[fid] stat[116]"
-msg Rwstat = "typ[1,val=TODO] tag[tag] fid[fid]"
+# a nul-terminated+padded string
+struct name = "28*(txt[1])"
+
+# a nul-terminated+padded string
+struct errstr = "64*(txt[1])"
+
+# "O"pen flags (flags to pass to Topen and Tcreate)
+# Unused bits are *ignored*.
+bitfield o = 1
+ "bit 0=num(MODE)" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ "bit 1=num(MODE)" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ #"bit 2=unused"
+ #"bit 3=unused"
+ "bit 4=TRUNC"
+ "bit 5=reserved(CEXEC)" # close-on-exec
+ "bit 6=RCLOSE" # remove-on-close
+ #"bit 7=unused"
+
+ "num(MODE) READ = 0" # make available for this FID: Tread()
+ "num(MODE) WRITE = 1" # make available for this FID: Twrite()
+ "num(MODE) RDWR = 2" # make available for this FID: Tread() and Twrite()
+ "num(MODE) EXEC = 3" # make available for this FID: Tread()
+
+ "mask FLAG = 0b11111100"
+
+# "CH"annel flags - file permissions and attributes (a "channel" is
+# what a file handle is called inside of the Plan 9 kernel).
+bitfield ch = 4
+ "bit 31=DIR"
+ "bit 30=APPEND"
+ "bit 29=EXCL"
+ #...
+ "bit 8=OWNER_R"
+ "bit 7=OWNER_W"
+ "bit 6=OWNER_X"
+ "bit 5=GROUP_R"
+ "bit 4=GROUP_W"
+ "bit 3=GROUP_X"
+ "bit 2=OTHER_R"
+ "bit 1=OTHER_W"
+ "bit 0=OTHER_X"
+
+ "mask PERM=0777" # {OWNER,GROUP,OTHER}_{R,W,X}
+
+struct stat = "file_name[name]"
+ "file_owner[name]"
+ "file_group[name]"
+ "file_qid[qid]"
+ "file_mode[ch]"
+ "file_atime[4]"
+ "file_mtime[4]"
+ "file_size[8]"
+ "kern_type[2]"
+ "kern_dev[2]"
+
+# Authentication uses symetric-key encryption, using a per-client
+# secret-key. The encryption scheme is beyond the scope of this
+# document.
+struct auth_ticket = "15*(dat[1])"
+struct encrypted_auth_challenge = "36*(ciphertext[1])"
+struct cleartext_auth_challenge = "magic[1,val=1] 7*(client_challenge[1]) server[name]"
+struct encrypted_auth_response = "30*(ciphertext[1])"
+struct cleartext_auth_response = "magic[1,val=4] 7*(client_challenge[1]) ticket[auth_ticket]"
+
+# A 9P0 session goes:
+#
+# [nop()]
+# session()
+# [auth_tok=auth()]
+# attach([auth_tok])
+# ...
+
+msg Tmux = "typ[1,val=48] mux[2]" # Undocumented, but implemented by mux(3) / libmux.a
+#msg Rmux = "typ[1,val=49] illegal"
+msg Tnop = "typ[1,val=50] tag[tag,val=0xFFFF]"
+msg Rnop = "typ[1,val=51] tag[tag,val=0xFFFF]"
+msg Tsession = "typ[1,val=52] tag[tag,val=0xFFFF]"
+msg Rsession = "typ[1,val=53] tag[tag,val=0xFFFF]"
+#msg Terror = "typ[1,val=54] illegal"
+msg Rerror = "typ[1,val=55] tag[tag] errstr[errstr]"
+msg Tflush = "typ[1,val=56] tag[tag] oldtag[tag]"
+msg Rflush = "typ[1,val=57] tag[tag]"
+msg Tattach = "typ[1,val=58] tag[tag] fid[fid] uid[name] aname[name] auth[auth_ticket] 13*(pad[1])" # Pad to allow auth_tickets up to 28 bytes.
+msg Rattach = "typ[1,val=59] tag[tag] fid[fid] qid[qid]"
+msg Tclone = "typ[1,val=60] tag[tag] fid[fid] newfid[fid]"
+msg Rclone = "typ[1,val=61] tag[tag] fid[fid]"
+msg Twalk = "typ[1,val=62] tag[tag] fid[fid] name[name]"
+msg Rwalk = "typ[1,val=63] tag[tag] fid[fid] qid[qid]"
+msg Topen = "typ[1,val=64] tag[tag] fid[fid] mode[o]"
+msg Ropen = "typ[1,val=65] tag[tag] fid[fid] qid[qid]"
+msg Tcreate = "typ[1,val=66] tag[tag] fid[fid] name[name] perm[ch] mode[o]"
+msg Rcreate = "typ[1,val=67] tag[tag] fid[fid] qid[qid]"
+# For `count:max`, see 1e/2e/3e `sys/include/fcall.h:MAXFDATA` or 1e/2e `sys/src/fs/port/portdata.h:MAXDAT`.
+# For read `offset:max`, see 1e/2e/3e `sys/src/fs/port/fs.c:f_read()` or 3e `sys/src/lib9p/srv.c:srv():case Tread`.
+# For write `offset:max`, see 1e/2e/3e `sys/src/fs/port/fs.c:f_write()`.
+msg Tread = "typ[1,val=68] tag[tag] fid[fid] offset[8,max=s64_max] count[2,max=8192]"
+msg Rread = "typ[1,val=69] tag[tag] fid[fid] count[2,max=8192] pad[1] count*(data[1])"
+msg Twrite = "typ[1,val=70] tag[tag] fid[fid] offset[8,max=s64_max] count[2,max=8192] pad[1] count*(data[1])"
+msg Rwrite = "typ[1,val=71] tag[tag] fid[fid] count[2,max=8192]"
+msg Tclunk = "typ[1,val=72] tag[tag] fid[fid]"
+msg Rclunk = "typ[1,val=73] tag[tag] fid[fid]"
+msg Tremove = "typ[1,val=74] tag[tag] fid[fid]"
+msg Rremove = "typ[1,val=75] tag[tag] fid[fid]"
+msg Tstat = "typ[1,val=76] tag[tag] fid[fid]"
+msg Rstat = "typ[1,val=77] tag[tag] fid[fid] stat[stat]"
+msg Twstat = "typ[1,val=78] tag[tag] fid[fid] stat[stat]"
+msg Rwstat = "typ[1,val=79] tag[tag] fid[fid]"
+msg Tclwalk = "typ[1,val=80] tag[tag] fid[fid] newfid[fid] name[name]"
+msg Rclwalk = "typ[1,val=81] tag[tag] fid[fid] qid[qid]"
+msg Tauth = "typ[1,val=82] tag[tag] fid[fid] uid[name] chal[encrypted_auth_challenge]" # chal is an encrypted
+msg Rauth = "typ[1,val=83] tag[tag] fid[fid] chal[encrypted_auth_response]"