2 * Routines for 9P dissection
3 * Copyright 2005, Nils O. Selaasdal
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * File permission bits decoding taken from packet-nfs.c
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include <epan/packet.h>
36 #include <epan/strutil.h>
37 #include <epan/conversation.h>
39 #include <epan/wmem/wmem.h>
41 #define FIRSTPASS(pinfo) (pinfo->fd->flags.visited == 0)
44 * enum _9p_msg_t - 9P message types
45 * @_9P_TLERROR: not used
46 * @_9P_RLERROR: response for any failed request for 9P2000.L
47 * @_9P_TSTATFS: file system status request
48 * @_9P_RSTATFS: file system status response
49 * @_9P_TSYMLINK: make symlink request
50 * @_9P_RSYMLINK: make symlink response
51 * @_9P_TMKNOD: create a special file object request
52 * @_9P_RMKNOD: create a special file object response
53 * @_9P_TLCREATE: prepare a handle for I/O on an new file for 9P2000.L
54 * @_9P_RLCREATE: response with file access information for 9P2000.L
55 * @_9P_TRENAME: rename request
56 * @_9P_RRENAME: rename response
57 * @_9P_TMKDIR: create a directory request
58 * @_9P_RMKDIR: create a directory response
59 * @_9P_TVERSION: version handshake request
60 * @_9P_RVERSION: version handshake response
61 * @_9P_TAUTH: request to establish authentication channel
62 * @_9P_RAUTH: response with authentication information
63 * @_9P_TATTACH: establish user access to file service
64 * @_9P_RATTACH: response with top level handle to file hierarchy
65 * @_9P_TERROR: not used
66 * @_9P_RERROR: response for any failed request
67 * @_9P_TFLUSH: request to abort a previous request
68 * @_9P_RFLUSH: response when previous request has been cancelled
69 * @_9P_TWALK: descend a directory hierarchy
70 * @_9P_RWALK: response with new handle for position within hierarchy
71 * @_9P_TOPEN: prepare a handle for I/O on an existing file
72 * @_9P_ROPEN: response with file access information
73 * @_9P_TCREATE: prepare a handle for I/O on a new file
74 * @_9P_RCREATE: response with file access information
75 * @_9P_TREAD: request to transfer data from a file or directory
76 * @_9P_RREAD: response with data requested
77 * @_9P_TWRITE: reuqest to transfer data to a file
78 * @_9P_RWRITE: response with out much data was transfered to file
79 * @_9P_TCLUNK: forget about a handle to an entity within the file system
80 * @_9P_RCLUNK: response when server has forgotten about the handle
81 * @_9P_TREMOVE: request to remove an entity from the hierarchy
82 * @_9P_RREMOVE: response when server has removed the entity
83 * @_9P_TSTAT: request file entity attributes
84 * @_9P_RSTAT: response with file entity attributes
85 * @_9P_TWSTAT: request to update file entity attributes
86 * @_9P_RWSTAT: response when file entity attributes are updated
88 * There are 14 basic operations in 9P2000, paired as
89 * requests and responses. The one special case is ERROR
90 * as there is no @_9P_TERROR request for clients to transmit to
91 * the server, but the server may respond to any other request
92 * with an @_9P_RERROR.
94 * See Also: http://plan9.bell-labs.com/sys/man/5/INDEX.html
120 _9P_TXATTRCREATE
= 32,
168 /* 9P Msg types to name mapping */
169 static const value_string ninep_msg_type
[] =
171 {_9P_TLERROR
, "Tlerror"},
172 {_9P_RLERROR
, "Rlerror"},
173 {_9P_TSTATFS
, "Tstatfs"},
174 {_9P_RSTATFS
, "Rstatfs"},
175 {_9P_TLOPEN
, "Tlopen"},
176 {_9P_RLOPEN
, "Rlopen"},
177 {_9P_TLCREATE
, "Tlcreate"},
178 {_9P_RLCREATE
, "Rlcreate"},
179 {_9P_TSYMLINK
, "Tsymlink"},
180 {_9P_RSYMLINK
, "Rsymlink"},
181 {_9P_TMKNOD
, "Tmknod"},
182 {_9P_RMKNOD
, "Rmknod"},
183 {_9P_TRENAME
, "Trename"},
184 {_9P_RRENAME
, "Rrename"},
185 {_9P_TREADLINK
, "Treadlink"},
186 {_9P_RREADLINK
, "Rreadlink"},
187 {_9P_TGETATTR
, "Tgetattr"},
188 {_9P_RGETATTR
, "Rgetattr"},
189 {_9P_TSETATTR
, "Tsetattr"},
190 {_9P_RSETATTR
, "Rsetattr"},
191 {_9P_TXATTRWALK
, "Txattrwalk"},
192 {_9P_RXATTRWALK
, "Rxattrwalk"},
193 {_9P_TXATTRCREATE
, "Txattrcreate"},
194 {_9P_RXATTRCREATE
, "Rxattrcreate"},
195 {_9P_TREADDIR
, "Treaddir"},
196 {_9P_RREADDIR
, "Rreaddir"},
197 {_9P_TFSYNC
, "Tfsync"},
198 {_9P_RFSYNC
, "Rfsync"},
199 {_9P_TLOCK
, "Tlock"},
200 {_9P_RLOCK
, "Rlock"},
201 {_9P_TGETLOCK
, "Tgetlock"},
202 {_9P_RGETLOCK
, "Rgetlock"},
203 {_9P_TLINK
, "Tlink"},
204 {_9P_RLINK
, "Rlink"},
205 {_9P_TMKDIR
, "Tmkdir"},
206 {_9P_RMKDIR
, "Rmkdir"},
207 {_9P_TRENAMEAT
, "Trenameat"},
208 {_9P_RRENAMEAT
, "Rrenameat"},
209 {_9P_TUNLINKAT
, "Tunlinkat"},
210 {_9P_RUNLINKAT
, "Runlinkat"},
211 {_9P_TVERSION
, "Tversion"},
212 {_9P_RVERSION
, "Rversion"},
213 {_9P_TAUTH
, "Tauth"},
214 {_9P_RAUTH
, "Rauth"},
215 {_9P_TATTACH
, "Tattach"},
216 {_9P_RATTACH
, "Rattach"},
217 {_9P_TERROR
, "Terror"},
218 {_9P_RERROR
, "Rerror"},
219 {_9P_TFLUSH
, "Tflush"},
220 {_9P_RFLUSH
, "Rflush"},
221 {_9P_TWALK
, "Twalk"},
222 {_9P_RWALK
, "Rwalk"},
223 {_9P_TOPEN
, "Topen"},
224 {_9P_ROPEN
, "Ropen"},
225 {_9P_TCREATE
, "Tcreate"},
226 {_9P_RCREATE
, "Rcreate"},
227 {_9P_TREAD
, "Tread"},
228 {_9P_RREAD
, "Rread"},
229 {_9P_TWRITE
, "Twrite"},
230 {_9P_RWRITE
, "Rwrite"},
231 {_9P_TCLUNK
, "Tclunk"},
232 {_9P_RCLUNK
, "Rclunk"},
233 {_9P_TREMOVE
, "Tremove"},
234 {_9P_RREMOVE
, "Rremove"},
235 {_9P_TSTAT
, "Tstat"},
236 {_9P_RSTAT
, "Rstat"},
237 {_9P_TWSTAT
, "Twstat"},
238 {_9P_RWSTAT
, "Rwstat"},
241 static value_string_ext ninep_msg_type_ext
= VALUE_STRING_EXT_INIT(ninep_msg_type
);
250 static const value_string ninep_version
[] =
254 {_9P2000_L
, "9P2000.L"},
255 {_9P2000_u
, "9P2000.u"},
258 static value_string_ext ninep_version_ext
= VALUE_STRING_EXT_INIT(ninep_version
);
261 /* File open modes */
262 #define _9P_OREAD 0x0
263 #define _9P_OWRITE 0x1
264 #define _9P_ORDWR 0x2
265 #define _9P_OEXEC 0x3
266 #define _9P_MODEMASK 0x3
267 #define _9P_OTRUNC 0x10
268 #define _9P_ORCLOSE 0x40
270 /* Open/Create modes */
271 static const value_string ninep_mode_vals
[] =
273 {_9P_OREAD
, "Read Access"},
274 {_9P_OWRITE
, "Write Access"},
275 {_9P_ORDWR
, "Read/Write Access "},
276 {_9P_OEXEC
, "Execute Access"},
279 static value_string_ext ninep_mode_vals_ext
= VALUE_STRING_EXT_INIT(ninep_mode_vals
);
282 /* stat mode flags */
283 #define DMDIR 0x80000000 /* Directory */
284 #define DMAPPEND 0x40000000 /* Append only */
285 #define DMEXCL 0x20000000 /* Exclusive use */
286 #define DMMOUNT 0x10000000 /* Mounted channel */
287 #define DMAUTH 0x08000000 /* Authentication */
288 #define DMTMP 0x04000000 /* Temporary */
292 * enum _9p_qid_t - QID types
293 * @_9P_QTDIR: directory
294 * @_9P_QTAPPEND: append-only
295 * @_9P_QTEXCL: excluse use (only one open handle allowed)
296 * @_9P_QTMOUNT: mount points
297 * @_9P_QTAUTH: authentication file
298 * @_9P_QTTMP: non-backed-up files
299 * @_9P_QTSYMLINK: symbolic links (9P2000.u)
300 * @_9P_QTLINK: hard-link (9P2000.u)
301 * @_9P_QTFILE: normal files
303 * QID types are a subset of permissions - they are primarily
304 * used to differentiate semantics for a file system entity via
305 * a jump-table. Their value is also the most signifigant 16 bits
306 * of the permission_t
308 * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
317 _9P_QTSYMLINK
= 0x02,
322 /* 9P Magic Numbers */
323 #define _9P_NOTAG (guint16)(~0)
324 #define _9P_NOFID (guint32)(~0)
325 #define _9P_NONUNAME (guint32)(~0)
326 #define _9P_MAXWELEM 16
329 #define MAXPATHLEN 1024
334 * @brief Length prefixed string type
336 * The protocol uses length prefixed strings for all
337 * string data, so we replicate that for our internal
342 guint16 len
; /* Length of the string */
343 char *str
; /* The string */
347 * @brief file system entity information
349 * qids are /identifiers used by 9P servers to track file system
350 * entities. The type is used to differentiate semantics for operations
351 * on the entity (ie. read means something different on a directory than
352 * on a file). The path provides a server unique index for an entity
353 * (roughly analogous to an inode number), while the version is updated
354 * every time a file is modified and can be used to maintain cache
355 * coherency between clients and serves.
356 * Servers will often differentiate purely synthetic entities by setting
357 * their version to 0, signaling that they should never be cached and
358 * should be accessed synchronously.
360 * See Also://plan9.bell-labs.com/magic/man2html/2/stat
364 guint8 type
; /* Type */
365 guint32 version
; /* Monotonically incrementing version number */
366 guint64 path
; /* Per-server-unique ID for a file system element */
370 /* Bit values for getattr valid field.
372 #define _9P_GETATTR_MODE 0x00000001ULL
373 #define _9P_GETATTR_NLINK 0x00000002ULL
374 #define _9P_GETATTR_UID 0x00000004ULL
375 #define _9P_GETATTR_GID 0x00000008ULL
376 #define _9P_GETATTR_RDEV 0x00000010ULL
377 #define _9P_GETATTR_ATIME 0x00000020ULL
378 #define _9P_GETATTR_MTIME 0x00000040ULL
379 #define _9P_GETATTR_CTIME 0x00000080ULL
380 #define _9P_GETATTR_INO 0x00000100ULL
381 #define _9P_GETATTR_SIZE 0x00000200ULL
382 #define _9P_GETATTR_BLOCKS 0x00000400ULL
384 #define _9P_GETATTR_BTIME 0x00000800ULL
385 #define _9P_GETATTR_GEN 0x00001000ULL
386 #define _9P_GETATTR_DATA_VERSION 0x00002000ULL
388 #define _9P_GETATTR_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */
389 #define _9P_GETATTR_ALL 0x00003fffULL /* Mask for All fields above */
392 /* Bit values for setattr valid field from <linux/fs.h>.
394 #define _9P_SETATTR_MODE 0x00000001UL
395 #define _9P_SETATTR_UID 0x00000002UL
396 #define _9P_SETATTR_GID 0x00000004UL
397 #define _9P_SETATTR_SIZE 0x00000008UL
398 #define _9P_SETATTR_ATIME 0x00000010UL
399 #define _9P_SETATTR_MTIME 0x00000020UL
400 #define _9P_SETATTR_CTIME 0x00000040UL
401 #define _9P_SETATTR_ATIME_SET 0x00000080UL
402 #define _9P_SETATTR_MTIME_SET 0x00000100UL
404 #define _9P_SETATTR_ALL 0x000001FFUL
406 /* 9p2000.L open flags */
407 #define _9P_DOTL_RDONLY 00000000
408 #define _9P_DOTL_WRONLY 00000001
409 #define _9P_DOTL_RDWR 00000002
410 #define _9P_DOTL_NOACCESS 00000003
411 #define _9P_DOTL_CREATE 00000100
412 #define _9P_DOTL_EXCL 00000200
413 #define _9P_DOTL_NOCTTY 00000400
414 #define _9P_DOTL_TRUNC 00001000
415 #define _9P_DOTL_APPEND 00002000
416 #define _9P_DOTL_NONBLOCK 00004000
417 #define _9P_DOTL_DSYNC 00010000
418 #define _9P_DOTL_FASYNC 00020000
419 #define _9P_DOTL_DIRECT 00040000
420 #define _9P_DOTL_LARGEFILE 00100000
421 #define _9P_DOTL_DIRECTORY 00200000
422 #define _9P_DOTL_NOFOLLOW 00400000
423 #define _9P_DOTL_NOATIME 01000000
424 #define _9P_DOTL_CLOEXEC 02000000
425 #define _9P_DOTL_SYNC 04000000
428 /* Bit values for lock type.
430 #define _9P_LOCK_TYPE_RDLCK 0
431 #define _9P_LOCK_TYPE_WRLCK 1
432 #define _9P_LOCK_TYPE_UNLCK 2
434 /* 9P lock type to string table */
435 static const value_string ninep_lock_type
[] =
437 {_9P_LOCK_TYPE_RDLCK
, "Read lock"},
438 {_9P_LOCK_TYPE_WRLCK
, "Write lock"},
439 {_9P_LOCK_TYPE_UNLCK
, "Unlock"},
442 static value_string_ext ninep_lock_type_ext
= VALUE_STRING_EXT_INIT(ninep_lock_type
);
444 /* Bit values for lock status.
446 #define _9P_LOCK_SUCCESS 0
447 #define _9P_LOCK_BLOCKED 1
448 #define _9P_LOCK_ERROR 2
449 #define _9P_LOCK_GRACE 3
451 /* 9P lock status to string table */
452 static const value_string ninep_lock_status
[] =
454 {_9P_LOCK_SUCCESS
, "Success"},
455 {_9P_LOCK_BLOCKED
, "Blocked"},
456 {_9P_LOCK_ERROR
, "Error"},
457 {_9P_LOCK_GRACE
, "Grace"},
460 static value_string_ext ninep_lock_status_ext
= VALUE_STRING_EXT_INIT(ninep_lock_status
);
462 /* Bit values for lock flags.
464 #define _9P_LOCK_FLAGS_NONE 0
465 #define _9P_LOCK_FLAGS_BLOCK 1
466 #define _9P_LOCK_FLAGS_RECLAIM 2
468 /* 9P lock flag to string table */
469 static const value_string ninep_lock_flag
[] =
471 {_9P_LOCK_FLAGS_NONE
, "No flag"},
472 {_9P_LOCK_FLAGS_BLOCK
, "Block"},
473 {_9P_LOCK_BLOCKED
, "Reclaim"},
476 static value_string_ext ninep_lock_flag_ext
= VALUE_STRING_EXT_INIT(ninep_lock_flag
);
478 static const char *invalid_fid_str
= "<invalid fid>";
479 static const char *afid_str
= "<afid>";
481 /* Structures for Protocol Operations */
507 struct _9p_tlcreate
{
514 struct _9p_rlcreate
{
518 struct _9p_tsymlink
{
521 struct _9p_str symtgt
;
524 struct _9p_rsymlink
{
547 struct _9p_treadlink
{
550 struct _9p_rreadlink
{
551 struct _9p_str target
;
553 struct _9p_tgetattr
{
555 guint64 request_mask
;
557 struct _9p_rgetattr
{
577 guint64 data_version
;
579 struct _9p_tsetattr
{
592 struct _9p_rsetattr
{
595 struct _9p_txattrwalk
{
600 struct _9p_rxattrwalk
{
603 struct _9p_txattrcreate
{
610 struct _9p_rxattrcreate
{
613 struct _9p_treaddir
{
618 struct _9p_rreaddir
{
636 struct _9p_str client_id
;
641 struct _9p_tgetlock
{
647 struct _9p_str client_id
;
649 struct _9p_rgetlock
{
654 struct _9p_str client_id
;
674 struct _9p_trenameat
{
676 struct _9p_str oldname
;
678 struct _9p_str newname
;
681 struct _9p_rrenameat
{
684 struct _9p_tunlinkat
{
690 struct _9p_runlinkat
{
705 struct _9p_tversion
{
707 struct _9p_str version
;
709 struct _9p_rversion
{
711 struct _9p_str version
;
715 struct _9p_str uname
;
716 struct _9p_str aname
;
717 guint32 n_uname
; /* 9P2000.u extensions */
723 struct _9p_str error
;
724 guint32 errnum
; /* 9p2000.u extension */
736 struct _9p_str uname
;
737 struct _9p_str aname
;
738 guint32 n_uname
; /* 9P2000.u extensions */
747 struct _9p_str wnames
[_9P_MAXWELEM
];
751 struct _9p_qid wqids
[_9P_MAXWELEM
];
766 struct _9p_str extension
;
809 /* Forward declarations */
810 void proto_register_9P(void);
811 void proto_reg_handoff_9P(void);
813 /* Initialize the protocol and registered fields */
814 static int proto_9P
= -1;
815 static int hf_9P_msgsz
= -1;
816 static int hf_9P_msgtype
= -1;
817 static int hf_9P_tag
= -1;
818 static int hf_9P_oldtag
= -1;
819 static int hf_9P_parmsz
= -1;
820 static int hf_9P_maxsize
= -1;
821 static int hf_9P_fid
= -1;
822 static int hf_9P_nqid
= -1;
823 static int hf_9P_mode
= -1;
824 static int hf_9P_mode_rwx
= -1;
825 static int hf_9P_mode_t
= -1;
826 static int hf_9P_mode_c
= -1;
827 static int hf_9P_iounit
= -1;
828 static int hf_9P_count
= -1;
829 static int hf_9P_offset
= -1;
830 static int hf_9P_perm
= -1;
831 static int hf_9P_qidtype
= -1;
832 static int hf_9P_qidtype_dir
= -1;
833 static int hf_9P_qidtype_append
= -1;
834 static int hf_9P_qidtype_exclusive
= -1;
835 static int hf_9P_qidtype_mount
= -1;
836 static int hf_9P_qidtype_auth_file
= -1;
837 static int hf_9P_qidtype_temp_file
= -1;
838 static int hf_9P_qidvers
= -1;
839 static int hf_9P_qidpath
= -1;
840 static int hf_9P_dm_dir
= -1;
841 static int hf_9P_dm_append
= -1;
842 static int hf_9P_dm_exclusive
= -1;
843 static int hf_9P_dm_mount
= -1;
844 static int hf_9P_dm_auth_file
= -1;
845 static int hf_9P_dm_temp_file
= -1;
846 static int hf_9P_dm_read_owner
= -1;
847 static int hf_9P_dm_write_owner
= -1;
848 static int hf_9P_dm_exec_owner
= -1;
849 static int hf_9P_dm_read_group
= -1;
850 static int hf_9P_dm_write_group
= -1;
851 static int hf_9P_dm_exec_group
= -1;
852 static int hf_9P_dm_read_others
= -1;
853 static int hf_9P_dm_write_others
= -1;
854 static int hf_9P_dm_exec_others
= -1;
855 static int hf_9P_stattype
= -1;
856 static int hf_9P_statmode
= -1;
857 static int hf_9P_atime
= -1;
858 static int hf_9P_mtime
= -1;
859 static int hf_9P_ctime
= -1;
860 static int hf_9P_btime
= -1;
861 static int hf_9P_length
= -1;
862 static int hf_9P_dev
= -1;
863 static int hf_9P_wname
= -1;
864 static int hf_9P_version
= -1;
865 static int hf_9P_afid
= -1;
866 static int hf_9P_uname
= -1;
867 static int hf_9P_aname
= -1;
868 static int hf_9P_ename
= -1;
869 static int hf_9P_enum
= -1;
870 static int hf_9P_name
= -1;
871 static int hf_9P_filename
= -1;
872 static int hf_9P_sdlen
= -1;
873 static int hf_9P_user
= -1;
874 static int hf_9P_group
= -1;
875 static int hf_9P_uid
= -1;
876 static int hf_9P_gid
= -1;
877 static int hf_9P_muid
= -1;
878 static int hf_9P_nwalk
= -1;
879 static int hf_9P_newfid
= -1;
880 static int hf_9P_dfid
= -1;
881 static int hf_9P_getattr_flags
= -1;
882 static int hf_9P_getattr_mode
= -1;
883 static int hf_9P_getattr_nlink
= -1;
884 static int hf_9P_getattr_uid
= -1;
885 static int hf_9P_getattr_gid
= -1;
886 static int hf_9P_getattr_rdev
= -1;
887 static int hf_9P_getattr_atime
= -1;
888 static int hf_9P_getattr_mtime
= -1;
889 static int hf_9P_getattr_ctime
= -1;
890 static int hf_9P_getattr_ino
= -1;
891 static int hf_9P_getattr_size
= -1;
892 static int hf_9P_getattr_blocks
= -1;
893 static int hf_9P_getattr_btime
= -1;
894 static int hf_9P_getattr_gen
= -1;
895 static int hf_9P_getattr_dataversion
= -1;
896 static int hf_9P_setattr_flags
= -1;
897 static int hf_9P_setattr_mode
= -1;
898 static int hf_9P_setattr_uid
= -1;
899 static int hf_9P_setattr_gid
= -1;
900 static int hf_9P_setattr_size
= -1;
901 static int hf_9P_setattr_atime
= -1;
902 static int hf_9P_setattr_mtime
= -1;
903 static int hf_9P_setattr_ctime
= -1;
904 static int hf_9P_setattr_atime_set
= -1;
905 static int hf_9P_setattr_mtime_set
= -1;
906 static int hf_9P_nlink
= -1;
907 static int hf_9P_rdev
= -1;
908 static int hf_9P_size
= -1;
909 static int hf_9P_blksize
= -1;
910 static int hf_9P_blocks
= -1;
911 static int hf_9P_gen
= -1;
912 static int hf_9P_dataversion
= -1;
913 static int hf_9P_fstype
= -1;
914 static int hf_9P_bfree
= -1;
915 static int hf_9P_bavail
= -1;
916 static int hf_9P_files
= -1;
917 static int hf_9P_ffree
= -1;
918 static int hf_9P_fsid
= -1;
919 static int hf_9P_namelen
= -1;
920 static int hf_9P_mknod_major
= -1;
921 static int hf_9P_mknod_minor
= -1;
922 static int hf_9P_lflags
= -1;
923 static int hf_9P_lflags_rdonly
= -1;
924 static int hf_9P_lflags_wronly
= -1;
925 static int hf_9P_lflags_rdwr
= -1;
926 static int hf_9P_lflags_create
= -1;
927 static int hf_9P_lflags_excl
= -1;
928 static int hf_9P_lflags_noctty
= -1;
929 static int hf_9P_lflags_trunc
= -1;
930 static int hf_9P_lflags_append
= -1;
931 static int hf_9P_lflags_nonblock
= -1;
932 static int hf_9P_lflags_dsync
= -1;
933 static int hf_9P_lflags_fasync
= -1;
934 static int hf_9P_lflags_direct
= -1;
935 static int hf_9P_lflags_largefile
= -1;
936 static int hf_9P_lflags_directory
= -1;
937 static int hf_9P_lflags_nofollow
= -1;
938 static int hf_9P_lflags_noatime
= -1;
939 static int hf_9P_lflags_cloexec
= -1;
940 static int hf_9P_lflags_sync
= -1;
941 static int hf_9P_xattr_flag
= -1;
942 static int hf_9P_lock_type
= -1;
943 static int hf_9P_lock_flag
= -1;
944 static int hf_9P_lock_start
= -1;
945 static int hf_9P_lock_length
= -1;
946 static int hf_9P_lock_procid
= -1;
947 static int hf_9P_lock_status
= -1;
949 /*handle for dissecting data in 9P msgs*/
950 static dissector_handle_t data_handle
;
952 /* subtree pointers */
953 static gint ett_9P
= -1;
954 static gint ett_9P_omode
= -1;
955 static gint ett_9P_dm
= -1;
956 static gint ett_9P_wname
= -1;
957 static gint ett_9P_aname
= -1;
958 static gint ett_9P_ename
= -1;
959 static gint ett_9P_uname
= -1;
960 static gint ett_9P_user
= -1;
961 static gint ett_9P_group
= -1;
962 static gint ett_9P_muid
= -1;
963 static gint ett_9P_filename
= -1;
964 static gint ett_9P_version
= -1;
965 static gint ett_9P_qid
= -1;
966 static gint ett_9P_qidtype
= -1;
967 static gint ett_9P_getattr_flags
= -1;
968 static gint ett_9P_setattr_flags
= -1;
969 static gint ett_9P_lflags
= -1;
971 static GHashTable
*_9p_hashtable
= NULL
;
973 static void dissect_9P_mode(tvbuff_t
*tvb
, proto_item
*tree
, int offset
);
974 static void dissect_9P_dm(tvbuff_t
*tvb
, proto_item
*tree
, int offset
, int iscreate
);
975 static void dissect_9P_qid(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
976 static void dissect_9P_lflags(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
977 static void dissect_9P_getattrflags(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
978 static void dissect_9P_setattrflags(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
992 enum _9p_msg_t msgtype
;
994 /* fid path used for create and lcreate */
998 static gint
_9p_hash_equal(gconstpointer k1
, gconstpointer k2
) {
999 const struct _9p_hashkey
*key1
= (struct _9p_hashkey
*)k1
, *key2
= (struct _9p_hashkey
*)k2
;
1001 return ((key1
->conv_index
== key2
->conv_index
) && (key1
->tag
== key2
->tag
) && (key1
->fid
== key2
->fid
));
1004 static guint
_9p_hash_hash(gconstpointer k
)
1006 const struct _9p_hashkey
*key
= (struct _9p_hashkey
*)k
;
1008 return (key
->conv_index
^ key
->tag
^ key
->fid
);
1011 static gboolean
_9p_hash_free_all(gpointer key _U_
, gpointer value _U_
, gpointer user_data _U_
)
1016 static void _9p_hash_free_val(gpointer value
)
1018 struct _9p_hashval
*val
= (struct _9p_hashval
*)value
;
1020 if (val
->data
&& val
->len
) {
1028 static struct _9p_hashval
*_9p_hash_new_val(gsize len
)
1030 struct _9p_hashval
*val
;
1031 val
= (struct _9p_hashval
*)g_malloc(sizeof(struct _9p_hashval
));
1033 val
->data
= g_malloc(len
);
1039 static void _9p_hash_init(void)
1041 if (_9p_hashtable
!= NULL
) {
1042 g_hash_table_foreach_remove(_9p_hashtable
, _9p_hash_free_all
, NULL
);
1044 _9p_hashtable
= g_hash_table_new_full(_9p_hash_hash
, _9p_hash_equal
, g_free
, _9p_hash_free_val
);
1048 static void _9p_hash_set(packet_info
*pinfo
, guint16 tag
, guint32 fid
, struct _9p_hashval
*val
)
1050 struct _9p_hashkey
*key
;
1051 struct _9p_hashval
*oldval
;
1052 conversation_t
*conv
;
1054 conv
= find_or_create_conversation(pinfo
);
1056 key
= (struct _9p_hashkey
*)g_malloc(sizeof(struct _9p_hashkey
));
1058 key
->conv_index
= conv
->index
;
1062 /* remove eventual old entry */
1063 oldval
= (struct _9p_hashval
*)g_hash_table_lookup(_9p_hashtable
, key
);
1065 g_hash_table_remove(_9p_hashtable
, key
);
1067 g_hash_table_insert(_9p_hashtable
, key
, val
);
1070 static struct _9p_hashval
*_9p_hash_get(packet_info
*pinfo
, guint16 tag
, guint32 fid
)
1072 struct _9p_hashkey key
;
1073 conversation_t
*conv
;
1075 conv
= find_or_create_conversation(pinfo
);
1077 key
.conv_index
= conv
->index
;
1081 return (struct _9p_hashval
*)g_hash_table_lookup(_9p_hashtable
, &key
);
1084 static void _9p_hash_free(packet_info
*pinfo
, guint16 tag
, guint32 fid
)
1086 struct _9p_hashkey key
;
1087 conversation_t
*conv
;
1089 conv
= find_or_create_conversation(pinfo
);
1091 key
.conv_index
= conv
->index
;
1095 g_hash_table_remove(_9p_hashtable
, &key
);
1098 static void conv_set_version(packet_info
*pinfo
, enum _9p_version version
)
1100 struct _9p_hashval
*val
;
1102 val
= _9p_hash_new_val(sizeof(enum _9p_version
));
1105 *(enum _9p_version
*)val
->data
= version
;
1107 _9p_hash_set(pinfo
, _9P_NOTAG
, _9P_NOFID
, val
);
1110 static enum _9p_version
conv_get_version(packet_info
*pinfo
)
1112 struct _9p_hashval
*val
;
1114 val
= _9p_hash_get(pinfo
, _9P_NOTAG
, _9P_NOFID
);
1116 return val
? *(enum _9p_version
*)val
->data
: _9P
;
1119 static void conv_set_fid_nocopy(packet_info
*pinfo
, guint32 fid
, const char *path
)
1121 struct _9p_hashval
*val
;
1123 if (!FIRSTPASS(pinfo
) || fid
== _9P_NOFID
)
1126 /* get or create&insert fid tree */
1127 val
= _9p_hash_get(pinfo
, _9P_NOTAG
, fid
);
1129 val
= _9p_hash_new_val(0);
1130 val
->data
= wmem_tree_new(wmem_file_scope());
1131 /* val->len is intentionnaly left to 0 so the tree won't be freed */
1132 _9p_hash_set(pinfo
, _9P_NOTAG
, fid
, val
);
1136 wmem_tree_insert32((wmem_tree_t
*)val
->data
, pinfo
->fd
->num
, (void*)path
);
1139 static void conv_set_fid(packet_info
*pinfo
, guint32 fid
, const gchar
*path
, gsize len
)
1143 if (!FIRSTPASS(pinfo
) || fid
== _9P_NOFID
|| len
== 0)
1146 str
= (char*)wmem_alloc(wmem_file_scope(), len
);
1147 g_strlcpy(str
, path
, len
);
1148 conv_set_fid_nocopy(pinfo
, fid
, str
);
1151 static const char *conv_get_fid(packet_info
*pinfo
, guint32 fid
)
1153 struct _9p_hashval
*val
;
1155 if (fid
== _9P_NOFID
)
1156 return invalid_fid_str
;
1158 val
= _9p_hash_get(pinfo
, _9P_NOTAG
, fid
);
1160 return invalid_fid_str
;
1162 /* -1 because the fid needs to have been set on a previous message.
1163 Let's ignore the possibility of num == 0... */
1164 return (char*)wmem_tree_lookup32_le((wmem_tree_t
*)val
->data
, pinfo
->fd
->num
-1);
1167 static inline void conv_free_fid(packet_info
*pinfo
, guint32 fid
)
1169 conv_set_fid_nocopy(pinfo
, fid
, invalid_fid_str
);
1172 static void conv_set_tag(packet_info
*pinfo
, guint16 tag
, enum _9p_msg_t msgtype
, guint32 fid
, wmem_strbuf_t
*fid_path
)
1174 struct _9p_hashval
*val
;
1175 struct _9p_taginfo
*taginfo
;
1177 if (!FIRSTPASS(pinfo
) || tag
== _9P_NOTAG
)
1180 val
= _9p_hash_new_val(sizeof(struct _9p_taginfo
));
1181 taginfo
= (struct _9p_taginfo
*)val
->data
;
1183 taginfo
->msgtype
= msgtype
;
1186 taginfo
->fid_path
= (char*)wmem_alloc(wmem_file_scope(), wmem_strbuf_get_len(fid_path
)+1);
1187 g_strlcpy(taginfo
->fid_path
, wmem_strbuf_get_str(fid_path
), wmem_strbuf_get_len(fid_path
)+1);
1189 taginfo
->fid_path
= NULL
;
1192 _9p_hash_set(pinfo
, tag
, _9P_NOFID
, val
);
1195 static inline struct _9p_taginfo
*conv_get_tag(packet_info
*pinfo
, guint16 tag
)
1197 struct _9p_hashval
*val
;
1199 /* get tag only makes sense on first pass, as tree isn't built like fid */
1200 if (!FIRSTPASS(pinfo
) || tag
== _9P_NOTAG
)
1203 /* check that length matches? */
1204 val
= _9p_hash_get(pinfo
, tag
, _9P_NOFID
);
1206 return val
? (struct _9p_taginfo
*)val
->data
: NULL
;
1209 static inline void conv_free_tag(packet_info
*pinfo
, guint16 tag
)
1211 if (!FIRSTPASS(pinfo
) || tag
== _9P_NOTAG
)
1214 _9p_hash_free(pinfo
, tag
, _9P_NOFID
);
1217 /* Dissect 9P messages*/
1218 static int dissect_9P(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1220 guint32 u32
, i
, fid
, dfid
, newfid
;
1221 guint16 u16
, tag
, _9p_len
;
1222 enum _9p_msg_t ninemsg
;
1224 const char *mname
, *fid_path
;
1226 wmem_strbuf_t
*tmppath
= NULL
;
1227 gint len
, reportedlen
;
1230 proto_tree
*ninep_tree
, *sub_tree
;
1231 struct _9p_taginfo
* taginfo
;
1234 const int firstpass
= FIRSTPASS(pinfo
);
1236 _9p_version
= conv_get_version(pinfo
);
1237 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, val_to_str_ext_const(_9p_version
, &ninep_version_ext
, "9P"));
1239 col_clear(pinfo
->cinfo
, COL_INFO
);
1241 /*ninesz = tvb_get_letohl(tvb, offset);*/
1242 ninemsg
= (enum _9p_msg_t
)tvb_get_guint8(tvb
, offset
+ 4);
1244 mname
= val_to_str_ext_const(ninemsg
, &ninep_msg_type_ext
, "Unknown");
1246 if(strcmp(mname
, "Unknown") == 0) {
1247 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "9P Data (Message type %u)", (guint
)ninemsg
);
1251 tag
= tvb_get_letohs(tvb
, offset
+5);
1252 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s Tag=%u", mname
, (guint
)tag
);
1254 ti
= proto_tree_add_item(tree
, proto_9P
, tvb
, 0, -1, ENC_NA
);
1255 ninep_tree
= proto_item_add_subtree(ti
, ett_9P
);
1256 proto_tree_add_item(ninep_tree
, hf_9P_msgsz
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1259 proto_tree_add_item(ninep_tree
, hf_9P_msgtype
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1261 proto_tree_add_item(ninep_tree
, hf_9P_tag
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1267 proto_tree_add_item(ninep_tree
, hf_9P_maxsize
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1270 _9p_len
= tvb_get_letohs(tvb
, offset
);
1271 ti
= proto_tree_add_item(ninep_tree
, hf_9P_version
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1272 sub_tree
= proto_item_add_subtree(ti
, ett_9P_version
);
1273 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1276 tvb_s
= tvb_get_string(NULL
, tvb
, offset
+2, _9p_len
);
1278 if (!strncmp(tvb_s
, "9P2000.L", _9p_len
)) {
1280 } else if (!strncmp(tvb_s
, "9P2000", _9p_len
)) {
1282 } else if (!strncmp(tvb_s
, "9P2000.u", _9p_len
)) {
1288 conv_set_version(pinfo
, (enum _9p_version
)u32
);
1292 /* don't set tag for tversion/free it for rversion,
1293 we need that for the actual version number */
1297 proto_tree_add_item(ninep_tree
, hf_9P_afid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1298 fid
= tvb_get_letohl(tvb
, offset
);
1299 conv_set_fid_nocopy(pinfo
, fid
, afid_str
);
1302 _9p_len
= tvb_get_letohs(tvb
, offset
);
1303 ti
= proto_tree_add_item(ninep_tree
, hf_9P_uname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1304 sub_tree
= proto_item_add_subtree(ti
, ett_9P_uname
);
1305 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1306 offset
+= _9p_len
+2;
1308 _9p_len
= tvb_get_letohs(tvb
, offset
);
1309 ti
= proto_tree_add_item(ninep_tree
, hf_9P_aname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1310 sub_tree
= proto_item_add_subtree(ti
, ett_9P_aname
);
1311 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1314 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
1318 if (_9p_version
== _9P2000_L
) {
1319 u32
= tvb_get_letohl(tvb
, offset
);
1320 ti
= proto_tree_add_item(ninep_tree
, hf_9P_enum
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1321 proto_item_append_text(ti
, " (%s)", g_strerror(u32
));
1324 _9p_len
= tvb_get_letohs(tvb
, offset
);
1325 ti
= proto_tree_add_item(ninep_tree
, hf_9P_ename
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1326 sub_tree
= proto_item_add_subtree(ti
, ett_9P_ename
);
1327 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1328 offset
+= 2 + _9p_len
;
1331 /* conv_get_tag checks we're in first pass */
1332 taginfo
= conv_get_tag(pinfo
, tag
);
1333 if (taginfo
&& (taginfo
->msgtype
== _9P_TWALK
|| taginfo
->msgtype
== _9P_TATTACH
))
1334 conv_free_fid(pinfo
, taginfo
->fid
);
1336 conv_free_tag(pinfo
, tag
);
1340 u16
= tvb_get_letohs(tvb
, offset
);
1341 proto_tree_add_item(ninep_tree
, hf_9P_oldtag
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1342 conv_free_tag(pinfo
, u16
);
1344 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1348 fid
= tvb_get_letohl(tvb
, offset
);
1349 proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1352 proto_tree_add_item(ninep_tree
, hf_9P_afid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1355 _9p_len
= tvb_get_letohs(tvb
, offset
);
1356 ti
= proto_tree_add_item(ninep_tree
, hf_9P_uname
, tvb
, offset
+2, _9p_len
, ENC_ASCII
|ENC_NA
);
1357 sub_tree
= proto_item_add_subtree(ti
, ett_9P_uname
);
1358 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1359 offset
+= _9p_len
+ 2;
1361 _9p_len
= tvb_get_letohs(tvb
, offset
);
1362 ti
= proto_tree_add_item(ninep_tree
, hf_9P_aname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1363 sub_tree
= proto_item_add_subtree(ti
, ett_9P_aname
);
1364 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1366 tvb_s
= tvb_get_string(NULL
, tvb
, offset
+2, _9p_len
);
1367 conv_set_fid(pinfo
, fid
, tvb_s
, _9p_len
+1);
1370 offset
+= _9p_len
+2;
1372 proto_tree_add_item(ninep_tree
, hf_9P_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1374 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
1378 fid
= tvb_get_letohl(tvb
, offset
);
1379 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1380 fid_path
= conv_get_fid(pinfo
, fid
);
1381 proto_item_append_text(ti
, " (%s)", fid_path
);
1383 tmppath
= wmem_strbuf_sized_new(wmem_packet_scope(), 0, MAXPATHLEN
);
1384 wmem_strbuf_append(tmppath
, fid_path
);
1388 fid
= tvb_get_letohl(tvb
, offset
);
1389 proto_tree_add_item(ninep_tree
, hf_9P_newfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1392 u16
= tvb_get_letohs(tvb
, offset
);
1393 proto_tree_add_item(ninep_tree
, hf_9P_nwalk
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1395 /* I can't imagine anyone having a directory depth more than 25,
1396 Limit to 10 times that to be sure, 2^16 is too much */
1398 sub_tree
= proto_tree_add_text(ninep_tree
, tvb
, 0, 0, "Only first 250 items shown");
1399 PROTO_ITEM_SET_GENERATED(sub_tree
);
1402 for(i
= 0 ; i
< u16
; i
++) {
1403 _9p_len
= tvb_get_letohs(tvb
, offset
);
1406 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1407 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1408 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1412 tvb_s
= tvb_get_string(NULL
, tvb
, offset
+2, _9p_len
);
1413 wmem_strbuf_append_c(tmppath
, '/');
1414 wmem_strbuf_append(tmppath
, tvb_s
);
1418 offset
+= _9p_len
+ 2;
1422 conv_set_fid(pinfo
, fid
, wmem_strbuf_get_str(tmppath
), wmem_strbuf_get_len(tmppath
)+1);
1425 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
1429 u16
= tvb_get_letohs(tvb
, offset
);
1430 proto_tree_add_item(ninep_tree
, hf_9P_nqid
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1432 /* I can't imagine anyone having a directory depth more than 25,
1433 Limit to 10 times that to be sure, 2^16 is too much */
1436 sub_tree
= proto_tree_add_text(ninep_tree
, tvb
, 0, 0, "Only first 250 items shown");
1437 PROTO_ITEM_SET_GENERATED(sub_tree
);
1440 for(i
= 0; i
< u16
; i
++) {
1441 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1445 conv_free_tag(pinfo
, tag
);
1448 fid
= tvb_get_letohl(tvb
, offset
);
1449 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1450 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1453 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1454 dissect_9P_lflags(tvb
, ti
, offset
);
1456 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1460 fid
= tvb_get_letohl(tvb
, offset
);
1461 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1462 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1465 ti
= proto_tree_add_item(ninep_tree
, hf_9P_mode
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1466 dissect_9P_mode(tvb
, ti
, offset
);
1469 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1473 fid
= tvb_get_letohl(tvb
, offset
);
1474 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1475 fid_path
= conv_get_fid(pinfo
, fid
);
1476 proto_item_append_text(ti
, " (%s)", fid_path
);
1479 _9p_len
= tvb_get_letohs(tvb
, offset
);
1480 ti
= proto_tree_add_item(ninep_tree
, hf_9P_name
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1481 sub_tree
= proto_item_add_subtree(ti
, ett_9P_filename
);
1482 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1484 tmppath
= wmem_strbuf_sized_new(wmem_packet_scope(), 0, MAXPATHLEN
);
1485 wmem_strbuf_append(tmppath
, fid_path
);
1486 wmem_strbuf_append_c(tmppath
, '/');
1487 tvb_s
= tvb_get_string(NULL
, tvb
, offset
+2, _9p_len
);
1488 wmem_strbuf_append(tmppath
, tvb_s
);
1491 offset
+= _9p_len
+ 2;
1493 ti
= proto_tree_add_item(ninep_tree
, hf_9P_perm
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1494 dissect_9P_dm(tvb
, ti
, offset
, 1);
1497 ti
= proto_tree_add_item(ninep_tree
, hf_9P_mode
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1498 dissect_9P_mode(tvb
, ti
, offset
);
1501 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1504 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, tmppath
);
1508 fid
= tvb_get_letohl(tvb
, offset
);
1509 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1510 fid_path
= conv_get_fid(pinfo
, fid
);
1511 proto_item_append_text(ti
, " (%s)", fid_path
);
1514 _9p_len
= tvb_get_letohs(tvb
, offset
);
1515 ti
= proto_tree_add_item(ninep_tree
, hf_9P_name
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1516 sub_tree
= proto_item_add_subtree(ti
, ett_9P_filename
);
1517 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1519 tmppath
= wmem_strbuf_sized_new(wmem_packet_scope(), 0, MAXPATHLEN
);
1520 wmem_strbuf_append(tmppath
, fid_path
);
1521 wmem_strbuf_append_c(tmppath
, '/');
1522 tvb_s
= tvb_get_string(NULL
, tvb
, offset
+2, _9p_len
);
1523 wmem_strbuf_append(tmppath
, tvb_s
);
1526 offset
+= _9p_len
+ 2;
1528 ti
= proto_tree_add_item(ninep_tree
, hf_9P_lflags
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1529 dissect_9P_lflags(tvb
, ti
, offset
);
1532 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1533 dissect_9P_dm(tvb
, ti
, offset
, 0);
1536 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1539 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, tmppath
);
1544 fid
= tvb_get_letohl(tvb
, offset
);
1545 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1546 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1549 proto_tree_add_item(ninep_tree
, hf_9P_offset
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1552 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1555 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1560 u32
= tvb_get_letohl(tvb
, offset
);
1561 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1564 len
= tvb_reported_length_remaining(tvb
, offset
);
1565 reportedlen
= ((gint
)u32
&0xffff) > len
? len
: (gint
)u32
&0xffff;
1566 next_tvb
= tvb_new_subset(tvb
, offset
, len
, reportedlen
);
1567 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1569 conv_free_tag(pinfo
, tag
);
1573 fid
= tvb_get_letohl(tvb
, offset
);
1574 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1575 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1578 proto_tree_add_item(ninep_tree
, hf_9P_offset
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1581 u32
= tvb_get_letohl(tvb
, offset
);
1582 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1584 len
= tvb_reported_length_remaining(tvb
, offset
);
1585 reportedlen
= ((gint
)u32
&0xffff) > len
? len
: (gint
)u32
&0xffff;
1586 next_tvb
= tvb_new_subset(tvb
, offset
, len
, reportedlen
);
1587 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
1589 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1593 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1595 conv_free_tag(pinfo
, tag
);
1599 proto_tree_add_item(ninep_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1602 proto_tree_add_item(ninep_tree
, hf_9P_sdlen
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1605 proto_tree_add_item(ninep_tree
, hf_9P_stattype
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1608 proto_tree_add_item(ninep_tree
, hf_9P_dev
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1611 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1614 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1615 dissect_9P_dm(tvb
, ti
, offset
, 0);
1618 tv
.secs
= tvb_get_letohl(tvb
, offset
);
1620 proto_tree_add_time(ninep_tree
, hf_9P_atime
, tvb
, offset
, 4, &tv
);
1623 tv
.secs
= tvb_get_letohl(tvb
, offset
);
1625 proto_tree_add_time(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 4, &tv
);
1628 proto_tree_add_item(ninep_tree
, hf_9P_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1631 _9p_len
= tvb_get_letohs(tvb
, offset
);
1632 ti
= proto_tree_add_item(ninep_tree
, hf_9P_filename
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1633 sub_tree
= proto_item_add_subtree(ti
, ett_9P_filename
);
1634 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1635 offset
+= _9p_len
+2;
1637 _9p_len
= tvb_get_letohs(tvb
, offset
);
1638 ti
= proto_tree_add_item(ninep_tree
, hf_9P_user
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1639 sub_tree
= proto_item_add_subtree(ti
, ett_9P_user
);
1640 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1641 offset
+= _9p_len
+2;
1643 _9p_len
= tvb_get_letohs(tvb
, offset
);
1644 ti
= proto_tree_add_item(ninep_tree
, hf_9P_group
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1645 sub_tree
= proto_item_add_subtree(ti
, ett_9P_group
);
1646 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1647 offset
+= _9p_len
+2;
1649 _9p_len
= tvb_get_letohs(tvb
, offset
);
1650 ti
= proto_tree_add_item(ninep_tree
, hf_9P_muid
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1651 sub_tree
= proto_item_add_subtree(ti
, ett_9P_muid
);
1652 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1653 offset
+= _9p_len
+2;
1655 conv_free_tag(pinfo
, tag
);
1659 fid
= tvb_get_letohl(tvb
, offset
);
1660 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1661 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1664 proto_tree_add_item(ninep_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1667 proto_tree_add_item(ninep_tree
, hf_9P_sdlen
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1670 proto_tree_add_item(ninep_tree
, hf_9P_stattype
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1673 proto_tree_add_item(ninep_tree
, hf_9P_dev
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1676 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1679 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1680 dissect_9P_dm(tvb
, ti
, offset
, 0);
1683 tv
.secs
= tvb_get_letohl(tvb
, offset
);
1685 proto_tree_add_time(ninep_tree
, hf_9P_atime
, tvb
, offset
, 4, &tv
);
1688 tv
.secs
= tvb_get_letohl(tvb
, offset
);
1690 proto_tree_add_time(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 4, &tv
);
1693 proto_tree_add_item(ninep_tree
, hf_9P_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1696 _9p_len
= tvb_get_letohs(tvb
, offset
);
1697 ti
= proto_tree_add_item(ninep_tree
, hf_9P_filename
, tvb
, offset
+2, _9p_len
, ENC_ASCII
|ENC_NA
);
1698 sub_tree
= proto_item_add_subtree(ti
, ett_9P_filename
);
1699 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1700 offset
+= _9p_len
+2;
1702 _9p_len
= tvb_get_letohs(tvb
, offset
);
1703 ti
= proto_tree_add_item(ninep_tree
, hf_9P_user
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1704 sub_tree
= proto_item_add_subtree(ti
, ett_9P_user
);
1705 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1706 offset
+= _9p_len
+2;
1708 _9p_len
= tvb_get_letohs(tvb
, offset
);
1709 ti
= proto_tree_add_item(ninep_tree
, hf_9P_group
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1710 sub_tree
= proto_item_add_subtree(ti
, ett_9P_group
);
1711 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1712 offset
+= _9p_len
+2;
1714 _9p_len
= tvb_get_letohs(tvb
, offset
);
1715 ti
= proto_tree_add_item(ninep_tree
, hf_9P_muid
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1716 sub_tree
= proto_item_add_subtree(ti
, ett_9P_muid
);
1717 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1718 offset
+= _9p_len
+2;
1720 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1724 fid
= tvb_get_letohl(tvb
, offset
);
1725 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1726 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1729 ti
= proto_tree_add_item(ninep_tree
, hf_9P_getattr_flags
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1730 dissect_9P_getattrflags(tvb
, ti
, offset
);
1733 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1737 ti
= proto_tree_add_item(ninep_tree
, hf_9P_getattr_flags
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1738 dissect_9P_getattrflags(tvb
, ti
, offset
);
1741 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1744 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1745 dissect_9P_dm(tvb
, ti
, offset
, 0);
1748 proto_tree_add_item(ninep_tree
, hf_9P_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1751 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1754 proto_tree_add_item(ninep_tree
, hf_9P_nlink
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1757 proto_tree_add_item(ninep_tree
, hf_9P_rdev
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1760 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1763 proto_tree_add_item(ninep_tree
, hf_9P_blksize
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1766 proto_tree_add_item(ninep_tree
, hf_9P_blocks
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1769 tv
.secs
= (time_t)tvb_get_letoh64(tvb
, offset
);
1770 tv
.nsecs
= (guint32
)tvb_get_letoh64(tvb
, offset
+8);
1771 proto_tree_add_time(ninep_tree
, hf_9P_atime
, tvb
, offset
, 16, &tv
);
1774 tv
.secs
= (time_t)tvb_get_letoh64(tvb
, offset
);
1775 tv
.nsecs
= (guint32
)tvb_get_letoh64(tvb
, offset
+8);
1776 proto_tree_add_time(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 16, &tv
);
1779 tv
.secs
= (time_t)tvb_get_letoh64(tvb
, offset
);
1780 tv
.nsecs
= (guint32
)tvb_get_letoh64(tvb
, offset
+8);
1781 proto_tree_add_time(ninep_tree
, hf_9P_ctime
, tvb
, offset
, 16, &tv
);
1784 tv
.secs
= (time_t)tvb_get_letoh64(tvb
, offset
);
1785 tv
.nsecs
= (guint32
)tvb_get_letoh64(tvb
, offset
+8);
1786 proto_tree_add_time(ninep_tree
, hf_9P_btime
, tvb
, offset
, 16, &tv
);
1789 proto_tree_add_item(ninep_tree
, hf_9P_gen
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1792 proto_tree_add_item(ninep_tree
, hf_9P_dataversion
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1795 conv_free_tag(pinfo
, tag
);
1799 fid
= tvb_get_letohl(tvb
, offset
);
1800 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1801 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1804 ti
= proto_tree_add_item(ninep_tree
, hf_9P_setattr_flags
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1805 dissect_9P_setattrflags(tvb
, ti
, offset
);
1808 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1809 dissect_9P_dm(tvb
, ti
, offset
, 0);
1812 proto_tree_add_item(ninep_tree
, hf_9P_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1815 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1818 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1821 tv
.secs
= (time_t)tvb_get_letoh64(tvb
, offset
);
1822 tv
.nsecs
= (guint32
)tvb_get_letoh64(tvb
, offset
+8);
1823 proto_tree_add_time(ninep_tree
, hf_9P_atime
, tvb
, offset
, 16, &tv
);
1826 tv
.secs
= (time_t)tvb_get_letoh64(tvb
, offset
);
1827 tv
.nsecs
= (guint32
)tvb_get_letoh64(tvb
, offset
+8);
1828 proto_tree_add_time(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 16, &tv
);
1831 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1835 proto_tree_add_item(ninep_tree
, hf_9P_fstype
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1838 proto_tree_add_item(ninep_tree
, hf_9P_blksize
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1841 proto_tree_add_item(ninep_tree
, hf_9P_blocks
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1844 proto_tree_add_item(ninep_tree
, hf_9P_bfree
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1847 proto_tree_add_item(ninep_tree
, hf_9P_bavail
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1850 proto_tree_add_item(ninep_tree
, hf_9P_files
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1853 proto_tree_add_item(ninep_tree
, hf_9P_ffree
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1856 proto_tree_add_item(ninep_tree
, hf_9P_fsid
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1859 proto_tree_add_item(ninep_tree
, hf_9P_namelen
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1862 conv_free_tag(pinfo
, tag
);
1866 fid
= tvb_get_letohl(tvb
, offset
);
1867 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1868 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1871 _9p_len
= tvb_get_letohs(tvb
, offset
);
1872 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1873 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1874 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1875 offset
+= _9p_len
+ 2;
1877 _9p_len
= tvb_get_letohs(tvb
, offset
);
1878 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1879 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1880 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1881 offset
+= _9p_len
+ 2;
1883 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1886 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1890 fid
= tvb_get_letohl(tvb
, offset
);
1891 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1892 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1895 _9p_len
= tvb_get_letohs(tvb
, offset
);
1896 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1897 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1898 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1899 offset
+= _9p_len
+ 2;
1901 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1902 dissect_9P_dm(tvb
, ti
, offset
, 0);
1905 proto_tree_add_item(ninep_tree
, hf_9P_mknod_major
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1908 proto_tree_add_item(ninep_tree
, hf_9P_mknod_minor
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1911 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1914 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1918 fid
= tvb_get_letohl(tvb
, offset
);
1919 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1920 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1923 dfid
= tvb_get_letohl(tvb
, offset
);
1924 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1925 fid_path
= conv_get_fid(pinfo
, dfid
);
1926 proto_item_append_text(ti
, " (%s)", fid_path
);
1929 _9p_len
= tvb_get_letohs(tvb
, offset
);
1930 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1931 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1932 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1934 tmppath
= wmem_strbuf_sized_new(wmem_packet_scope(), 0, MAXPATHLEN
);
1935 wmem_strbuf_append(tmppath
, conv_get_fid(pinfo
, dfid
));
1936 wmem_strbuf_append_c(tmppath
, '/');
1938 tvb_s
= tvb_get_string(NULL
, tvb
, offset
+2, _9p_len
);
1939 wmem_strbuf_append(tmppath
, tvb_s
);
1942 conv_set_fid(pinfo
, fid
, wmem_strbuf_get_str(tmppath
), wmem_strbuf_get_len(tmppath
)+1);
1944 offset
+= _9p_len
+ 2;
1946 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1950 _9p_len
= tvb_get_letohs(tvb
, offset
);
1951 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1952 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1953 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1954 offset
+= _9p_len
+ 2;
1956 conv_free_tag(pinfo
, tag
);
1959 case _9P_TXATTRWALK
:
1960 fid
= tvb_get_letohl(tvb
, offset
);
1961 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1962 fid_path
= conv_get_fid(pinfo
, fid
);
1963 proto_item_append_text(ti
, " (%s)", fid_path
);
1966 newfid
= tvb_get_letohl(tvb
, offset
);
1967 proto_tree_add_item(ninep_tree
, hf_9P_newfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1968 conv_set_fid_nocopy(pinfo
, newfid
, fid_path
);
1971 _9p_len
= tvb_get_letohs(tvb
, offset
);
1972 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1973 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1974 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1975 offset
+= _9p_len
+ 2;
1977 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1980 case _9P_RXATTRWALK
:
1981 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1984 conv_free_tag(pinfo
, tag
);
1987 case _9P_TXATTRCREATE
:
1988 fid
= tvb_get_letohl(tvb
, offset
);
1989 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1990 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1993 _9p_len
= tvb_get_letohs(tvb
, offset
);
1994 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1995 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
1996 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1997 offset
+= _9p_len
+ 2;
1999 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2002 proto_tree_add_item(ninep_tree
, hf_9P_xattr_flag
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2005 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2010 fid
= tvb_get_letohl(tvb
, offset
);
2011 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2012 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2015 proto_tree_add_item(ninep_tree
, hf_9P_lock_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2018 proto_tree_add_item(ninep_tree
, hf_9P_lock_flag
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2021 proto_tree_add_item(ninep_tree
, hf_9P_lock_start
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2024 proto_tree_add_item(ninep_tree
, hf_9P_lock_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2027 proto_tree_add_item(ninep_tree
, hf_9P_lock_procid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2030 _9p_len
= tvb_get_letohs(tvb
, offset
);
2031 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
2032 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
2033 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2034 offset
+= _9p_len
+ 2;
2036 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2040 proto_tree_add_item(ninep_tree
, hf_9P_lock_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2043 conv_free_tag(pinfo
, tag
);
2047 proto_tree_add_item(ninep_tree
, hf_9P_lock_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2050 proto_tree_add_item(ninep_tree
, hf_9P_lock_flag
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2053 proto_tree_add_item(ninep_tree
, hf_9P_lock_start
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2056 proto_tree_add_item(ninep_tree
, hf_9P_lock_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2059 proto_tree_add_item(ninep_tree
, hf_9P_lock_procid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2062 _9p_len
= tvb_get_letohs(tvb
, offset
);
2063 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
2064 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
2065 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2066 offset
+= _9p_len
+ 2;
2068 conv_free_tag(pinfo
, tag
);
2072 fid
= tvb_get_letohl(tvb
, offset
);
2073 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2074 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2077 fid
= tvb_get_letohl(tvb
, offset
);
2078 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2079 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2082 _9p_len
= tvb_get_letohs(tvb
, offset
);
2083 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
2084 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
2085 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2086 offset
+= _9p_len
+ 2;
2088 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2092 fid
= tvb_get_letohl(tvb
, offset
);
2093 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2094 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2097 _9p_len
= tvb_get_letohs(tvb
, offset
);
2098 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
2099 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
2100 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2101 offset
+= _9p_len
+ 2;
2103 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2104 dissect_9P_dm(tvb
, ti
, offset
, 0);
2107 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2110 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2114 fid
= tvb_get_letohl(tvb
, offset
);
2115 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2116 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2119 _9p_len
= tvb_get_letohs(tvb
, offset
);
2120 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
2121 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
2122 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2123 offset
+= _9p_len
+ 2;
2125 fid
= tvb_get_letohl(tvb
, offset
);
2126 ti
= proto_tree_add_item(ninep_tree
, hf_9P_newfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2127 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2130 _9p_len
= tvb_get_letohs(tvb
, offset
);
2131 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
2132 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
2133 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2134 offset
+= _9p_len
+ 2;
2135 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2139 fid
= tvb_get_letohl(tvb
, offset
);
2140 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2141 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2144 _9p_len
= tvb_get_letohs(tvb
, offset
);
2145 ti
= proto_tree_add_item(ninep_tree
, hf_9P_wname
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
2146 sub_tree
= proto_item_add_subtree(ti
, ett_9P_wname
);
2147 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2148 offset
+= _9p_len
+ 2;
2150 /* missing 32bit flag, no clue what meaning it has */
2152 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2157 fid
= tvb_get_letohl(tvb
, offset
);
2158 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2159 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2160 conv_free_fid(pinfo
, fid
);
2162 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
2165 /* Request with only fid */
2170 fid
= tvb_get_letohl(tvb
, offset
);
2171 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2172 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2174 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2177 /* Reply with qid and ionuit */
2180 dissect_9P_qid(tvb
, ninep_tree
, offset
);
2182 proto_tree_add_item(ninep_tree
, hf_9P_iounit
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2185 taginfo
= conv_get_tag(pinfo
, tag
);
2186 if (taginfo
&& taginfo
->fid_path
) {
2187 conv_set_fid_nocopy(pinfo
, taginfo
->fid
, taginfo
->fid_path
);
2190 conv_free_tag(pinfo
, tag
);
2195 dissect_9P_qid(tvb
, ninep_tree
, offset
);
2197 proto_tree_add_item(ninep_tree
, hf_9P_iounit
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2200 conv_free_tag(pinfo
, tag
);
2203 /* Reply with only qid */
2209 dissect_9P_qid(tvb
, ninep_tree
, offset
);
2212 conv_free_tag(pinfo
, tag
);
2218 case _9P_RXATTRCREATE
:
2226 /* Unhandled reply */
2229 conv_free_tag(pinfo
, tag
);
2232 /* Should-not-happen query */
2236 proto_tree_add_text(ninep_tree
, tvb
, 0, 0, "This message type should not happen");
2241 /* dissect 9P open mode flags */
2242 static void dissect_9P_mode(tvbuff_t
*tvb
, proto_item
*item
, int offset
)
2244 proto_item
*mode_tree
;
2247 mode
= tvb_get_guint8(tvb
, offset
);
2248 mode_tree
= proto_item_add_subtree(item
, ett_9P_omode
);
2251 proto_tree_add_boolean(mode_tree
, hf_9P_mode_c
, tvb
, offset
, 1, mode
);
2252 proto_tree_add_boolean(mode_tree
, hf_9P_mode_t
, tvb
, offset
, 1, mode
);
2253 proto_tree_add_uint(mode_tree
, hf_9P_mode_rwx
, tvb
, offset
, 1, mode
);
2256 /* dissect 9P Qid */
2257 static void dissect_9P_qid(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
2259 proto_item
*qid_item
,*qidtype_item
;
2260 proto_tree
*qid_tree
,*qidtype_tree
;
2268 type
= tvb_get_guint8(tvb
, offset
);
2269 vers
= tvb_get_letohs(tvb
, offset
+1);
2270 path
= tvb_get_letoh64(tvb
, offset
+1+4);
2272 qid_item
= proto_tree_add_text(tree
, tvb
, offset
, 13, "Qid type=0x%02x vers=%d path=%" G_GINT64_MODIFIER
"u", type
, vers
, path
);
2273 qid_tree
= proto_item_add_subtree(qid_item
, ett_9P_qid
);
2275 qidtype_item
= proto_tree_add_item(qid_tree
, hf_9P_qidtype
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2276 qidtype_tree
= proto_item_add_subtree(qidtype_item
, ett_9P_qidtype
);
2278 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_dir
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2279 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_append
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2280 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_exclusive
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2281 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_mount
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2282 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_auth_file
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2283 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_temp_file
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2285 proto_tree_add_item(qid_tree
, hf_9P_qidvers
, tvb
, offset
+1, 4, ENC_LITTLE_ENDIAN
);
2286 proto_tree_add_item(qid_tree
, hf_9P_qidpath
, tvb
, offset
+1+4, 8, ENC_LITTLE_ENDIAN
);
2289 /*dissect 9P stat mode and create perm flags */
2290 static void dissect_9P_dm(tvbuff_t
*tvb
, proto_item
*item
, int offset
, int iscreate
)
2292 proto_item
*mode_tree
;
2295 mode_tree
= proto_item_add_subtree(item
, ett_9P_dm
);
2299 proto_tree_add_item(mode_tree
, hf_9P_dm_dir
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2300 if(!iscreate
) { /* Not applicable to Tcreate (?) */
2301 proto_tree_add_item(mode_tree
, hf_9P_dm_append
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2302 proto_tree_add_item(mode_tree
, hf_9P_dm_exclusive
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2303 proto_tree_add_item(mode_tree
, hf_9P_dm_mount
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2304 proto_tree_add_item(mode_tree
, hf_9P_dm_auth_file
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2305 proto_tree_add_item(mode_tree
, hf_9P_dm_temp_file
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2308 proto_tree_add_item(mode_tree
, hf_9P_dm_read_owner
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2309 proto_tree_add_item(mode_tree
, hf_9P_dm_write_owner
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2310 proto_tree_add_item(mode_tree
, hf_9P_dm_exec_owner
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2311 proto_tree_add_item(mode_tree
, hf_9P_dm_read_group
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2312 proto_tree_add_item(mode_tree
, hf_9P_dm_write_group
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2313 proto_tree_add_item(mode_tree
, hf_9P_dm_exec_group
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2314 proto_tree_add_item(mode_tree
, hf_9P_dm_read_others
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2315 proto_tree_add_item(mode_tree
, hf_9P_dm_write_others
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2316 proto_tree_add_item(mode_tree
, hf_9P_dm_exec_others
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2319 /* Dissect 9P getattr_flags */
2320 static void dissect_9P_getattrflags(tvbuff_t
*tvb
, proto_item
*item
, int offset
)
2322 proto_item
*attrmask_tree
;
2324 attrmask_tree
= proto_item_add_subtree(item
, ett_9P_getattr_flags
);
2328 /* fixme: This is actually 8 bytes (64bit) long, but masks have to fit on 32bit. */
2329 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_mode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2330 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_nlink
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2331 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2332 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2333 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_rdev
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2334 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_atime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2335 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_mtime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2336 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_ctime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2337 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_ino
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2338 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2339 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_blocks
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2340 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_btime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2341 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_gen
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2342 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_dataversion
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2345 /* Dissect 9P setattr_flags */
2346 static void dissect_9P_setattrflags(tvbuff_t
*tvb
, proto_item
*item
, int offset
)
2348 proto_item
*attrmask_tree
;
2350 attrmask_tree
= proto_item_add_subtree(item
, ett_9P_setattr_flags
);
2354 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_mode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2355 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2356 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2357 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2358 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_atime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2359 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_mtime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2360 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_ctime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2361 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_atime_set
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2362 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_mtime_set
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2365 /* Dissect 9P lflags */
2366 static void dissect_9P_lflags(tvbuff_t
*tvb
, proto_item
*item
, int offset
)
2368 proto_item
*attrmask_tree
;
2370 attrmask_tree
= proto_item_add_subtree(item
, ett_9P_lflags
);
2374 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_rdonly
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2375 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_wronly
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2376 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_rdwr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2377 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_create
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2378 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_excl
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2379 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_noctty
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2380 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_trunc
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2381 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_append
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2382 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_nonblock
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2383 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_dsync
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2384 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_fasync
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2385 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_direct
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2386 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_largefile
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2387 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_directory
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2388 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_nofollow
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2389 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_noatime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2390 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_cloexec
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2391 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_sync
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2395 /* Register 9P with Wireshark */
2396 void proto_register_9P(void)
2398 static hf_register_info hf
[] = {
2400 {"Msg length", "9p.msglen", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2401 "9P Message Length", HFILL
}},
2403 {"Msg Type", "9p.msgtype", FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &ninep_msg_type_ext
, 0x0,
2404 "Message Type", HFILL
}},
2406 {"Tag", "9p.tag", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2409 {"Old tag", "9p.oldtag", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2412 {"Param length", "9p.paramsz", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2413 "Parameter length", HFILL
}},
2415 {"Max msg size", "9p.maxsize", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2416 "Max message size", HFILL
}},
2418 {"Fid", "9p.fid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2421 {"Nr Qids", "9p.nqid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2422 "Number of Qid results", HFILL
}},
2424 {"Mode", "9p.mode", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2427 {"Open/Create Mode", "9p.mode.rwx", FT_UINT8
, BASE_OCT
| BASE_EXT_STRING
, &ninep_mode_vals_ext
, _9P_MODEMASK
,
2430 {"Trunc", "9p.mode.trunc", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), _9P_OTRUNC
,
2431 "Truncate", HFILL
}},
2433 {"Remove on close", "9p.mode.orclose", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), _9P_ORCLOSE
,
2436 {"I/O Unit", "9p.iounit", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2439 {"Count", "9p.count", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2442 {"Offset", "9p.offset", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2445 {"Permissions", "9p.perm", FT_UINT32
, BASE_OCT
, NULL
, 0x0,
2446 "Permission bits", HFILL
}},
2448 {"Qid path", "9p.qidpath", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2451 {"Directory", "9p.dm.dir", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x80000000,
2454 {"Append only", "9p.dm.append", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x40000000,
2456 {&hf_9P_dm_exclusive
,
2457 {"Exclusive use", "9p.dm.exclusive", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x20000000,
2460 {"Mounted channel", "9p.dm.mount", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x10000000,
2462 {&hf_9P_dm_auth_file
,
2463 {"Authentication file", "9p.dm.auth_file", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x08000000,
2465 {&hf_9P_dm_temp_file
,
2466 {"Temporary file (not backed up)", "9p.dm.temp_file", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x04000000,
2468 {&hf_9P_dm_read_owner
,
2469 {"Read permission for owner", "9p.dm.read_owner", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000400,
2471 {&hf_9P_dm_write_owner
,
2472 {"Write permission for owner", "9p.dm.write_owner", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000200,
2474 {&hf_9P_dm_exec_owner
,
2475 {"Execute permission for owner", "9p.dm.exec_owner", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000100,
2477 {&hf_9P_dm_read_group
,
2478 {"Read permission for group", "9p.dm.read_group", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000040,
2480 {&hf_9P_dm_write_group
,
2481 {"Write permission for group", "9p.dm.write_group", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000020,
2483 {&hf_9P_dm_exec_group
,
2484 {"Execute permission for group", "9p.dm.exec_group", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000010,
2486 {&hf_9P_dm_read_others
,
2487 {"Read permission for others", "9p.dm.read_others", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000004,
2489 {&hf_9P_dm_write_others
,
2490 {"Write permission for others", "9p.dm.write_others", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000002,
2492 {&hf_9P_dm_exec_others
,
2493 {"Execute permission for others", "9p.dm.exec_others", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000001,
2496 {"Qid version", "9p.qidvers", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2499 {"Qid type", "9p.qidtype", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2501 {&hf_9P_qidtype_dir
,
2502 {"Directory", "9p.qidtype.dir", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
2504 {&hf_9P_qidtype_append
,
2505 {"Append only", "9p.qidtype.append", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
2507 {&hf_9P_qidtype_exclusive
,
2508 {"Exclusive use", "9p.qidtype.exclusive", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
2510 {&hf_9P_qidtype_mount
,
2511 {"Mounted channel", "9p.qidtype.mount", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
2513 {&hf_9P_qidtype_auth_file
,
2514 {"Authentication file", "9p.qidtype.auth_file", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
2516 {&hf_9P_qidtype_temp_file
,
2517 {"Temporary file (not backed up)", "9p.qidtype.temp_file", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
2520 {"Mode", "9p.statmode", FT_UINT32
, BASE_OCT
, NULL
, 0x0,
2521 "File mode flags", HFILL
}},
2523 {"Type", "9p.stattype", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2526 {"Atime", "9p.atime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2527 "Access Time", HFILL
}},
2529 {"Mtime", "9p.mtime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2530 "Modified Time", HFILL
}},
2532 {"Ctime", "9p.ctime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2533 "Creation Time", HFILL
}},
2535 {"Btime", "9p.btime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2536 "Btime (Synchronization information)", HFILL
}},
2538 {"Length", "9p.length", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2539 "File Length", HFILL
}},
2541 {"Dev", "9p.dev", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2544 {"Wname", "9p.wname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2545 "Path Name Element", HFILL
}},
2547 {"Version", "9p.version", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2550 {"Afid", "9p.afid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2551 "Authenticating FID", HFILL
}},
2553 {"Uname", "9p.uname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2554 "User Name", HFILL
}},
2556 {"Aname", "9p.aname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2557 "Access Name", HFILL
}},
2559 {"Ename", "9p.ename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2562 {"Enum", "9p.enum", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2565 {"Name", "9p.name", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2566 "Name of file", HFILL
}},
2568 {"Stat data length", "9p.sdlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2571 {"File name", "9p.filename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2574 {"User", "9p.user", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2575 "User name", HFILL
}},
2577 {"Group", "9p.group", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2578 "Group name", HFILL
}},
2580 {"Uid", "9p.uid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2583 {"Gid", "9p.gid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2584 "Group id", HFILL
}},
2586 {"Muid", "9p.muid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2587 "Last modifiers uid", HFILL
}},
2589 {"New fid", "9p.newfid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2590 "New file ID", HFILL
}},
2592 {"Directory fid", "9p.dfid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2593 "Directory ID", HFILL
}},
2595 {"Nr Walks", "9p.nwalk", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2596 "Nr of walk items", HFILL
}},
2598 {"nlink", "9p.nlink", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2599 "Number of links", HFILL
}},
2600 {&hf_9P_getattr_flags
,
2601 {"getattr_flags", "9p.getattr.flags", FT_UINT64
, BASE_HEX
, NULL
, _9P_GETATTR_ALL
,
2602 "Getattr flags", HFILL
}},
2603 {&hf_9P_getattr_mode
,
2604 {"Mode", "9p.getattr.mode", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_MODE
,
2606 {&hf_9P_getattr_nlink
,
2607 {"Nlink", "9p.getattr.nlink", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_NLINK
,
2609 {&hf_9P_getattr_uid
,
2610 {"UID", "9p.getattr.uid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_UID
,
2612 {&hf_9P_getattr_gid
,
2613 {"GID", "9p.getattr.gid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_GID
,
2615 {&hf_9P_getattr_rdev
,
2616 {"Rdev", "9p.getattr.rdev", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_RDEV
,
2618 {&hf_9P_getattr_atime
,
2619 {"Atime", "9p.getattr.atime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_ATIME
,
2621 {&hf_9P_getattr_mtime
,
2622 {"Mtime", "9p.getattr.mtime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_MTIME
,
2624 {&hf_9P_getattr_ctime
,
2625 {"Ctime", "9p.getattr.ctime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_CTIME
,
2627 {&hf_9P_getattr_ino
,
2628 {"Inode", "9p.getattr.inode", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_INO
,
2630 {&hf_9P_getattr_size
,
2631 {"Size", "9p.getattr.size", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_SIZE
,
2633 {&hf_9P_getattr_blocks
,
2634 {"Blocks", "9p.getattr.blocks", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_BLOCKS
,
2636 {&hf_9P_getattr_btime
,
2637 {"Btime", "9p.getattr.btime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_BTIME
,
2639 {&hf_9P_getattr_gen
,
2640 {"Gen", "9p.getattr.gen", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_GEN
,
2642 {&hf_9P_getattr_dataversion
,
2643 {"Data version", "9p.getattr.dataversion", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_DATA_VERSION
,
2645 {&hf_9P_setattr_flags
,
2646 {"setattr_flags", "9p.setattr.flags", FT_UINT32
, BASE_HEX
, NULL
, _9P_SETATTR_ALL
,
2647 "Setattr flags", HFILL
}},
2648 {&hf_9P_setattr_mode
,
2649 {"Mode", "9p.setattr.mode", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_MODE
,
2651 {&hf_9P_setattr_uid
,
2652 {"UID", "9p.setattr.uid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_UID
,
2654 {&hf_9P_setattr_gid
,
2655 {"GID", "9p.setattr.gid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_GID
,
2657 {&hf_9P_setattr_size
,
2658 {"Size", "9p.setattr.size", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_SIZE
,
2660 {&hf_9P_setattr_atime
,
2661 {"Atime", "9p.setattr.atime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_ATIME
,
2663 {&hf_9P_setattr_mtime
,
2664 {"Mtime", "9p.setattr.mtime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_MTIME
,
2666 {&hf_9P_setattr_ctime
,
2667 {"Ctime", "9p.setattr.ctime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_CTIME
,
2669 {&hf_9P_setattr_atime_set
,
2670 {"Atime set", "9p.setattr.atimeset", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_ATIME_SET
,
2672 {&hf_9P_setattr_mtime_set
,
2673 {"Mtime set", "9p.setattr.mtimeset", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_MTIME_SET
,
2676 {"rdev", "9p.rdev", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2677 "Device associated with file", HFILL
}},
2679 {"Size", "9p.size", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2682 {"Blksize", "9p.blksize", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2683 "Block size", HFILL
}},
2685 {"Blocks", "9p.blocks", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2688 {"Gen", "9p.gen", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2689 "inode generation number", HFILL
}},
2690 {&hf_9P_dataversion
,
2691 {"Dataversion", "9p.dataversion", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2692 "Data version", HFILL
}},
2694 {"fstype", "9p.fstype", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2695 "Filesystem type", HFILL
}},
2697 {"bfree", "9p.bfree", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2698 "Free blocks", HFILL
}},
2700 {"bavail", "9p.bavail", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2701 "Available blocks", HFILL
}},
2703 {"files", "9p.files", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2704 "Total files", HFILL
}},
2706 {"ffree", "9p.ffree", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2707 "Free files", HFILL
}},
2709 {"fsid", "9p.fsid", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2710 "Filesystem id", HFILL
}},
2712 {"namelen", "9p.namelen", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2713 "Max name length", HFILL
}},
2714 {&hf_9P_mknod_major
,
2715 {"mknod_major", "9p.mknod.major", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2716 "Major node number", HFILL
}},
2717 {&hf_9P_mknod_minor
,
2718 {"mknod_minor", "9p.mknod.minor", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2719 "Minor node number", HFILL
}},
2721 {"lflags", "9p.lcreate.flags", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2722 "Lcreate flags", HFILL
}},
2723 /* rdonly is 0x00, check instead that we are neither wronly nor rdwrite */
2724 {&hf_9P_lflags_rdonly
,
2725 {"Read only", "9p.lflags.rdonly", FT_BOOLEAN
, 32, TFS(&tfs_no_yes
), _9P_DOTL_WRONLY
|_9P_DOTL_RDWR
,
2727 {&hf_9P_lflags_wronly
,
2728 {"Write only", "9p.lflags.wronly", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_WRONLY
,
2730 {&hf_9P_lflags_rdwr
,
2731 {"Read Write", "9p.lflags.rdwr", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_RDWR
,
2733 {&hf_9P_lflags_create
,
2734 {"Create", "9p.lflags.create", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_CREATE
,
2736 {&hf_9P_lflags_excl
,
2737 {"Exclusive", "9p.lflags.excl", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_EXCL
,
2739 {&hf_9P_lflags_noctty
,
2740 {"noctty", "9p.lflags.noctty", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NOCTTY
,
2742 {&hf_9P_lflags_trunc
,
2743 {"Truncate", "9p.lflags.trunc", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_TRUNC
,
2745 {&hf_9P_lflags_append
,
2746 {"Append", "9p.lflags.append", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_APPEND
,
2748 {&hf_9P_lflags_nonblock
,
2749 {"Nonblock", "9p.lflags.nonblock", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NONBLOCK
,
2751 {&hf_9P_lflags_dsync
,
2752 {"dsync", "9p.lflags.dsync", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_DSYNC
,
2754 {&hf_9P_lflags_fasync
,
2755 {"fasync", "9p.lflags.fasync", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_FASYNC
,
2757 {&hf_9P_lflags_direct
,
2758 {"Direct", "9p.lflags.direct", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_DIRECT
,
2760 {&hf_9P_lflags_largefile
,
2761 {"Large File", "9p.lflags.largefile", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_LARGEFILE
,
2763 {&hf_9P_lflags_directory
,
2764 {"Directory", "9p.lflags.directory", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_DIRECTORY
,
2766 {&hf_9P_lflags_nofollow
,
2767 {"No follow", "9p.lflags.nofollow", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NOFOLLOW
,
2769 {&hf_9P_lflags_noatime
,
2770 {"No atime", "9p.lflags.noatime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NOATIME
,
2772 {&hf_9P_lflags_cloexec
,
2773 {"cloexec", "9p.lflags.cloexec", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_CLOEXEC
,
2775 {&hf_9P_lflags_sync
,
2776 {"Sync", "9p.lflags.sync", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_SYNC
,
2779 {"xattr_flag", "9p.xattr.flag", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2780 "Xattr flag", HFILL
}},
2782 {"lock_type", "9p.lock.type", FT_UINT32
, BASE_HEX
| BASE_EXT_STRING
, &ninep_lock_type_ext
, 0x0,
2783 "Lock type", HFILL
}},
2785 {"lock_flag", "9p.lock.flag", FT_UINT32
, BASE_HEX
| BASE_EXT_STRING
, &ninep_lock_flag_ext
, 0x0,
2786 "Lock flag", HFILL
}},
2788 {"lock_start", "9p.lock.start", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2789 "Lock start", HFILL
}},
2790 {&hf_9P_lock_length
,
2791 {"lock_length", "9p.lock.length", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2792 "Lock length", HFILL
}},
2793 {&hf_9P_lock_procid
,
2794 {"lock_procid", "9p.lock.procid", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2795 "Lock procid", HFILL
}},
2796 {&hf_9P_lock_status
,
2797 {"lock_status", "9p.lock.status", FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &ninep_lock_status_ext
, 0x0,
2798 "Lock status", HFILL
}}
2801 static gint
*ett
[] = {
2816 &ett_9P_getattr_flags
,
2817 &ett_9P_setattr_flags
,
2821 proto_9P
= proto_register_protocol("Plan 9", "9P", "9p");
2823 proto_register_field_array(proto_9P
, hf
, array_length(hf
));
2825 proto_register_subtree_array(ett
, array_length(ett
));
2827 register_init_routine(_9p_hash_init
);
2830 void proto_reg_handoff_9P(void)
2832 dissector_handle_t ninep_handle
;
2834 data_handle
= find_dissector("data");
2836 ninep_handle
= new_create_dissector_handle(dissect_9P
, proto_9P
);
2838 dissector_add_uint("tcp.port", NINEPORT
, ninep_handle
);