diff options
Diffstat (limited to 'lib9p/idl/1992-9P0.9p.wip')
-rw-r--r-- | lib9p/idl/1992-9P0.9p.wip | 125 |
1 files changed, 105 insertions, 20 deletions
diff --git a/lib9p/idl/1992-9P0.9p.wip b/lib9p/idl/1992-9P0.9p.wip index 15997d9..086e8e4 100644 --- a/lib9p/idl/1992-9P0.9p.wip +++ b/lib9p/idl/1992-9P0.9p.wip @@ -3,7 +3,20 @@ # 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,8 +28,77 @@ num fid = 2 # uni"Q"ue "ID"entification struct qid = "path[4] version[4]" -# a nul-padded string -struct name = 28*(txt[1]) +# 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 + "0=mode_0" # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum + "1=mode_1" # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum + #"2=unused" + #"3=unused" + "4=TRUNC" + #"5=_reserved_CEXEC" # close-on-exec + "6=RCLOSE" # remove-on-close + #"7=unused" + + "READ = 0" # make available for this FID: Tread() + "WRITE = 1" # make available for this FID: Twrite() + "RDWR = 2" # make available for this FID: Tread() and Twrite() + "EXEC = 3" # make available for this FID: Tread() + + "MODE_MASK = 0b00000011" + "FLAG_MASK = 0b11111100" + +# "C"??? "H"??? - file permissions and attributes +bitfield ch = 4 + "31=DIR" + "30=APPEND" + "29=EXCL" + #... + "8=OWNER_R" + "7=OWNER_W" + "6=OWNER_X" + "5=GROUP_R" + "4=GROUP_W" + "3=GROUP_X" + "2=OTHER_R" + "1=OTHER_W" + "0=OTHER_X" + + "PERM_MASK=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" @@ -25,32 +107,35 @@ 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] ename[64]" +msg Rerror = "typ[1,val=55] tag[tag] ename[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[28] aname[28] auth[28]" -msg Rattach = "typ[1,val=59] tag[tag] fid[fid] qid[8]" +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[28]" -msg Rwalk = "typ[1,val=63] tag[tag] fid[fid] qid[8]" -msg Topen = "typ[1,val=64] tag[tag] fid[fid] mode[1]" -msg Ropen = "typ[1,val=65] tag[tag] fid[fid] qid[8]" -msg Tcreate = "typ[1,val=66] tag[tag] fid[fid] name[28] perm[4] mode[1]" -msg Rcreate = "typ[1,val=67] tag[tag] fid[fid] qid[8]" -msg Tread = "typ[1,val=68] tag[tag] fid[fid] offset[8] count[2,max=8192]" +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] 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[116]" -msg Twstat = "typ[1,val=78] tag[tag] fid[fid] stat[116]" +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[28]" -msg Rclwalk = "typ[1,val=81] tag[tag] fid[fid] qid[8]" -msg Tauth = "typ[1,val=82] tag[tag] fid[fid] uid[28] chal[36]" -msg Rauth = "typ[1,val=83] tag[tag] fid[fid] chal[30]" +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]" |