2 * Routines for 9P dissection
3 * Copyright 2005, Nils O. Selaasdal
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * File permission bits decoding taken from packet-nfs.c
11 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/packet.h>
18 #include <epan/expert.h>
21 #include "packet-tcp.h"
24 * Protocol specifications:
26 * 9P2000: http://ericvh.github.io/9p-rfc/rfc9p2000.html
27 * 9P2000.L: https://github.com/chaos/diod/blob/master/protocol.md
28 * 9P2000.u: https://ericvh.github.io/9p-rfc/rfc9p2000.u.html
32 * enum _9p_msg_t - 9P message types
33 * @_9P_TLERROR: not used
34 * @_9P_RLERROR: response for any failed request for 9P2000.L
35 * @_9P_TSTATFS: file system status request
36 * @_9P_RSTATFS: file system status response
37 * @_9P_TSYMLINK: make symlink request
38 * @_9P_RSYMLINK: make symlink response
39 * @_9P_TMKNOD: create a special file object request
40 * @_9P_RMKNOD: create a special file object response
41 * @_9P_TLCREATE: prepare a handle for I/O on an new file for 9P2000.L
42 * @_9P_RLCREATE: response with file access information for 9P2000.L
43 * @_9P_TRENAME: rename request
44 * @_9P_RRENAME: rename response
45 * @_9P_TMKDIR: create a directory request
46 * @_9P_RMKDIR: create a directory response
47 * @_9P_TVERSION: version handshake request
48 * @_9P_RVERSION: version handshake response
49 * @_9P_TAUTH: request to establish authentication channel
50 * @_9P_RAUTH: response with authentication information
51 * @_9P_TATTACH: establish user access to file service
52 * @_9P_RATTACH: response with top level handle to file hierarchy
53 * @_9P_TERROR: not used
54 * @_9P_RERROR: response for any failed request
55 * @_9P_TFLUSH: request to abort a previous request
56 * @_9P_RFLUSH: response when previous request has been cancelled
57 * @_9P_TWALK: descend a directory hierarchy
58 * @_9P_RWALK: response with new handle for position within hierarchy
59 * @_9P_TOPEN: prepare a handle for I/O on an existing file
60 * @_9P_ROPEN: response with file access information
61 * @_9P_TCREATE: prepare a handle for I/O on a new file
62 * @_9P_RCREATE: response with file access information
63 * @_9P_TREAD: request to transfer data from a file or directory
64 * @_9P_RREAD: response with data requested
65 * @_9P_TWRITE: request to transfer data to a file
66 * @_9P_RWRITE: response with out much data was transferred to file
67 * @_9P_TCLUNK: forget about a handle to an entity within the file system
68 * @_9P_RCLUNK: response when server has forgotten about the handle
69 * @_9P_TREMOVE: request to remove an entity from the hierarchy
70 * @_9P_RREMOVE: response when server has removed the entity
71 * @_9P_TSTAT: request file entity attributes
72 * @_9P_RSTAT: response with file entity attributes
73 * @_9P_TWSTAT: request to update file entity attributes
74 * @_9P_RWSTAT: response when file entity attributes are updated
76 * There are 14 basic operations in 9P2000, paired as
77 * requests and responses. The one special case is ERROR
78 * as there is no @_9P_TERROR request for clients to transmit to
79 * the server, but the server may respond to any other request
80 * with an @_9P_RERROR.
82 * See Also: http://plan9.bell-labs.com/sys/man/5/INDEX.html
85 static dissector_handle_t ninep_handle
;
110 _9P_TXATTRCREATE
= 32,
158 /* 9P Msg types to name mapping */
159 static const value_string ninep_msg_type
[] =
161 {_9P_TLERROR
, "Tlerror"},
162 {_9P_RLERROR
, "Rlerror"},
163 {_9P_TSTATFS
, "Tstatfs"},
164 {_9P_RSTATFS
, "Rstatfs"},
165 {_9P_TLOPEN
, "Tlopen"},
166 {_9P_RLOPEN
, "Rlopen"},
167 {_9P_TLCREATE
, "Tlcreate"},
168 {_9P_RLCREATE
, "Rlcreate"},
169 {_9P_TSYMLINK
, "Tsymlink"},
170 {_9P_RSYMLINK
, "Rsymlink"},
171 {_9P_TMKNOD
, "Tmknod"},
172 {_9P_RMKNOD
, "Rmknod"},
173 {_9P_TRENAME
, "Trename"},
174 {_9P_RRENAME
, "Rrename"},
175 {_9P_TREADLINK
, "Treadlink"},
176 {_9P_RREADLINK
, "Rreadlink"},
177 {_9P_TGETATTR
, "Tgetattr"},
178 {_9P_RGETATTR
, "Rgetattr"},
179 {_9P_TSETATTR
, "Tsetattr"},
180 {_9P_RSETATTR
, "Rsetattr"},
181 {_9P_TXATTRWALK
, "Txattrwalk"},
182 {_9P_RXATTRWALK
, "Rxattrwalk"},
183 {_9P_TXATTRCREATE
, "Txattrcreate"},
184 {_9P_RXATTRCREATE
, "Rxattrcreate"},
185 {_9P_TREADDIR
, "Treaddir"},
186 {_9P_RREADDIR
, "Rreaddir"},
187 {_9P_TFSYNC
, "Tfsync"},
188 {_9P_RFSYNC
, "Rfsync"},
189 {_9P_TLOCK
, "Tlock"},
190 {_9P_RLOCK
, "Rlock"},
191 {_9P_TGETLOCK
, "Tgetlock"},
192 {_9P_RGETLOCK
, "Rgetlock"},
193 {_9P_TLINK
, "Tlink"},
194 {_9P_RLINK
, "Rlink"},
195 {_9P_TMKDIR
, "Tmkdir"},
196 {_9P_RMKDIR
, "Rmkdir"},
197 {_9P_TRENAMEAT
, "Trenameat"},
198 {_9P_RRENAMEAT
, "Rrenameat"},
199 {_9P_TUNLINKAT
, "Tunlinkat"},
200 {_9P_RUNLINKAT
, "Runlinkat"},
201 {_9P_TVERSION
, "Tversion"},
202 {_9P_RVERSION
, "Rversion"},
203 {_9P_TAUTH
, "Tauth"},
204 {_9P_RAUTH
, "Rauth"},
205 {_9P_TATTACH
, "Tattach"},
206 {_9P_RATTACH
, "Rattach"},
207 {_9P_TERROR
, "Terror"},
208 {_9P_RERROR
, "Rerror"},
209 {_9P_TFLUSH
, "Tflush"},
210 {_9P_RFLUSH
, "Rflush"},
211 {_9P_TWALK
, "Twalk"},
212 {_9P_RWALK
, "Rwalk"},
213 {_9P_TOPEN
, "Topen"},
214 {_9P_ROPEN
, "Ropen"},
215 {_9P_TCREATE
, "Tcreate"},
216 {_9P_RCREATE
, "Rcreate"},
217 {_9P_TREAD
, "Tread"},
218 {_9P_RREAD
, "Rread"},
219 {_9P_TWRITE
, "Twrite"},
220 {_9P_RWRITE
, "Rwrite"},
221 {_9P_TCLUNK
, "Tclunk"},
222 {_9P_RCLUNK
, "Rclunk"},
223 {_9P_TREMOVE
, "Tremove"},
224 {_9P_RREMOVE
, "Rremove"},
225 {_9P_TSTAT
, "Tstat"},
226 {_9P_RSTAT
, "Rstat"},
227 {_9P_TWSTAT
, "Twstat"},
228 {_9P_RWSTAT
, "Rwstat"},
231 static value_string_ext ninep_msg_type_ext
= VALUE_STRING_EXT_INIT(ninep_msg_type
);
240 static const value_string ninep_version
[] =
244 {_9P2000_L
, "9P2000.L"},
245 {_9P2000_u
, "9P2000.u"},
248 static value_string_ext ninep_version_ext
= VALUE_STRING_EXT_INIT(ninep_version
);
251 /* File open modes */
252 #define _9P_OREAD 0x0
253 #define _9P_OWRITE 0x1
254 #define _9P_ORDWR 0x2
255 #define _9P_OEXEC 0x3
256 #define _9P_MODEMASK 0x3
257 #define _9P_OTRUNC 0x10
258 #define _9P_ORCLOSE 0x40
260 /* Open/Create modes */
261 static const value_string ninep_mode_vals
[] =
263 {_9P_OREAD
, "Read Access"},
264 {_9P_OWRITE
, "Write Access"},
265 {_9P_ORDWR
, "Read/Write Access "},
266 {_9P_OEXEC
, "Execute Access"},
269 static value_string_ext ninep_mode_vals_ext
= VALUE_STRING_EXT_INIT(ninep_mode_vals
);
272 /* stat mode flags */
273 #define DMDIR 0x80000000 /* Directory */
274 #define DMAPPEND 0x40000000 /* Append only */
275 #define DMEXCL 0x20000000 /* Exclusive use */
276 #define DMMOUNT 0x10000000 /* Mounted channel */
277 #define DMAUTH 0x08000000 /* Authentication */
278 #define DMTMP 0x04000000 /* Temporary */
282 * enum _9p_qid_t - QID types
283 * @_9P_QTDIR: directory
284 * @_9P_QTAPPEND: append-only
285 * @_9P_QTEXCL: excluse use (only one open handle allowed)
286 * @_9P_QTMOUNT: mount points
287 * @_9P_QTAUTH: authentication file
288 * @_9P_QTTMP: non-backed-up files
289 * @_9P_QTSYMLINK: symbolic links (9P2000.u)
290 * @_9P_QTLINK: hard-link (9P2000.u)
291 * @_9P_QTFILE: normal files
293 * QID types are a subset of permissions - they are primarily
294 * used to differentiate semantics for a file system entity via
295 * a jump-table. Their value is also the most significant 16 bits
296 * of the permission_t
298 * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
307 _9P_QTSYMLINK
= 0x02,
312 /* 9P Magic Numbers */
313 #define _9P_NOTAG (uint16_t)(~0)
314 #define _9P_NOFID (uint32_t)(~0)
315 #define _9P_NONUNAME (uint32_t)(~0)
316 #define _9P_MAXWELEM 16
320 * @brief Length prefixed string type
322 * The protocol uses length prefixed strings for all
323 * string data, so we replicate that for our internal
328 uint16_t len
; /* Length of the string */
329 char *str
; /* The string */
333 * @brief file system entity information
335 * qids are /identifiers used by 9P servers to track file system
336 * entities. The type is used to differentiate semantics for operations
337 * on the entity (ie. read means something different on a directory than
338 * on a file). The path provides a server unique index for an entity
339 * (roughly analogous to an inode number), while the version is updated
340 * every time a file is modified and can be used to maintain cache
341 * coherency between clients and serves.
342 * Servers will often differentiate purely synthetic entities by setting
343 * their version to 0, signaling that they should never be cached and
344 * should be accessed synchronously.
346 * See Also://plan9.bell-labs.com/magic/man2html/2/stat
350 uint8_t type
; /* Type */
351 uint32_t version
; /* Monotonically incrementing version number */
352 uint64_t path
; /* Per-server-unique ID for a file system element */
356 /* Bit values for getattr valid field.
358 #define _9P_GETATTR_MODE 0x00000001U
359 #define _9P_GETATTR_NLINK 0x00000002U
360 #define _9P_GETATTR_UID 0x00000004U
361 #define _9P_GETATTR_GID 0x00000008U
362 #define _9P_GETATTR_RDEV 0x00000010U
363 #define _9P_GETATTR_ATIME 0x00000020U
364 #define _9P_GETATTR_MTIME 0x00000040U
365 #define _9P_GETATTR_CTIME 0x00000080U
366 #define _9P_GETATTR_INO 0x00000100U
367 #define _9P_GETATTR_SIZE 0x00000200U
368 #define _9P_GETATTR_BLOCKS 0x00000400U
370 #define _9P_GETATTR_BTIME 0x00000800U
371 #define _9P_GETATTR_GEN 0x00001000U
372 #define _9P_GETATTR_DATA_VERSION 0x00002000U
375 #define _9P_GETATTR_BASIC 0x000007ffU /* Mask for fields up to BLOCKS */
377 #define _9P_GETATTR_ALL 0x00003fffU /* Mask for All fields above */
380 /* Bit values for setattr valid field from <linux/fs.h>.
382 #define _9P_SETATTR_MODE 0x00000001U
383 #define _9P_SETATTR_UID 0x00000002U
384 #define _9P_SETATTR_GID 0x00000004U
385 #define _9P_SETATTR_SIZE 0x00000008U
386 #define _9P_SETATTR_ATIME 0x00000010U
387 #define _9P_SETATTR_MTIME 0x00000020U
388 #define _9P_SETATTR_CTIME 0x00000040U
389 #define _9P_SETATTR_ATIME_SET 0x00000080U
390 #define _9P_SETATTR_MTIME_SET 0x00000100U
392 #define _9P_SETATTR_ALL 0x000001FFU
394 /* 9p2000.L open flags */
395 #define _9P_DOTL_RDONLY 00000000
396 #define _9P_DOTL_WRONLY 00000001
397 #define _9P_DOTL_RDWR 00000002
398 #define _9P_DOTL_NOACCESS 00000003
399 #define _9P_DOTL_CREATE 00000100
400 #define _9P_DOTL_EXCL 00000200
401 #define _9P_DOTL_NOCTTY 00000400
402 #define _9P_DOTL_TRUNC 00001000
403 #define _9P_DOTL_APPEND 00002000
404 #define _9P_DOTL_NONBLOCK 00004000
405 #define _9P_DOTL_DSYNC 00010000
406 #define _9P_DOTL_FASYNC 00020000
407 #define _9P_DOTL_DIRECT 00040000
408 #define _9P_DOTL_LARGEFILE 00100000
409 #define _9P_DOTL_DIRECTORY 00200000
410 #define _9P_DOTL_NOFOLLOW 00400000
411 #define _9P_DOTL_NOATIME 01000000
412 #define _9P_DOTL_CLOEXEC 02000000
413 #define _9P_DOTL_SYNC 04000000
416 /* Bit values for lock type.
418 #define _9P_LOCK_TYPE_RDLCK 0
419 #define _9P_LOCK_TYPE_WRLCK 1
420 #define _9P_LOCK_TYPE_UNLCK 2
422 /* 9P lock type to string table */
423 static const value_string ninep_lock_type
[] =
425 {_9P_LOCK_TYPE_RDLCK
, "Read lock"},
426 {_9P_LOCK_TYPE_WRLCK
, "Write lock"},
427 {_9P_LOCK_TYPE_UNLCK
, "Unlock"},
430 static value_string_ext ninep_lock_type_ext
= VALUE_STRING_EXT_INIT(ninep_lock_type
);
432 /* Bit values for lock status.
434 #define _9P_LOCK_SUCCESS 0
435 #define _9P_LOCK_BLOCKED 1
436 #define _9P_LOCK_ERROR 2
437 #define _9P_LOCK_GRACE 3
439 /* 9P lock status to string table */
440 static const value_string ninep_lock_status
[] =
442 {_9P_LOCK_SUCCESS
, "Success"},
443 {_9P_LOCK_BLOCKED
, "Blocked"},
444 {_9P_LOCK_ERROR
, "Error"},
445 {_9P_LOCK_GRACE
, "Grace"},
448 static value_string_ext ninep_lock_status_ext
= VALUE_STRING_EXT_INIT(ninep_lock_status
);
450 /* Bit values for lock flags.
452 #define _9P_LOCK_FLAGS_NONE 0
453 #define _9P_LOCK_FLAGS_BLOCK 1
454 #define _9P_LOCK_FLAGS_RECLAIM 2
456 /* 9P lock flag to string table */
457 static const value_string ninep_lock_flag
[] =
459 {_9P_LOCK_FLAGS_NONE
, "No flag"},
460 {_9P_LOCK_FLAGS_BLOCK
, "Block"},
461 {_9P_LOCK_FLAGS_RECLAIM
,"Reclaim"},
464 static value_string_ext ninep_lock_flag_ext
= VALUE_STRING_EXT_INIT(ninep_lock_flag
);
467 * Linux error code values to descriptions table.
468 * Note that the error code values on Linux are platform-dependent;
469 * Linux, on some platforms, tried to match the values of existing UN*Xes
470 * on the platform in question.
472 * The platforms in question appear to be:
474 * 32-bit PowerPC (AIX?)
475 * 32-bit and 64-bit SPARC (SunOS - pre-5, or 5?)
478 * 32-bit MIPS (IRIX?)
479 * 64-bit MIPS (IRIX?)
481 * For now, we don't worry about this, and use the errno values used
482 * on most Linux platforms.
484 static const value_string linux_errno
[] =
486 {1, "Operation not permitted"}, /* EPERM */
487 {2, "No such file or directory"}, /* ENOENT */
488 {3, "No such process"}, /* ESRCH */
489 {4, "Interrupted system call"}, /* EINTR */
490 {5, "I/O error"}, /* EIO */
491 {6, "No such device or address"}, /* ENXIO */
492 {7, "Argument list too long"}, /* E2BIG */
493 {8, "Exec format error"}, /* ENOEXEC */
494 {9, "Bad file number"}, /* EBADF */
495 {10, "No child processes"}, /* ECHILD */
496 {11, "Try again"}, /* EAGAIN */
497 {12, "Out of memory"}, /* ENOMEM */
498 {13, "Permission denied"}, /* EACCES */
499 {14, "Bad address"}, /* EFAULT */
500 {15, "Block device required"}, /* ENOTBLK */
501 {16, "Device or resource busy"}, /* EBUSY */
502 {17, "File exists"}, /* EEXIST */
503 {18, "Cross-device link"}, /* EXDEV */
504 {19, "No such device"}, /* ENODEV */
505 {20, "Not a directory"}, /* ENOTDIR */
506 {21, "Is a directory"}, /* EISDIR */
507 {22, "Invalid argument"}, /* EINVAL */
508 {23, "File table overflow"}, /* ENFILE */
509 {24, "Too many open files"}, /* EMFILE */
510 {25, "Not a typewriter"}, /* ENOTTY */
511 {26, "Text file busy"}, /* ETXTBSY */
512 {27, "File too large"}, /* EFBIG */
513 {28, "No space left on device"}, /* ENOSPC */
514 {29, "Illegal seek"}, /* ESPIPE */
515 {30, "Read-only file system"}, /* EROFS */
516 {31, "Too many links"}, /* EMLINK */
517 {32, "Broken pipe"}, /* EPIPE */
518 {33, "Math argument out of domain of func"}, /* EDOM */
519 {34, "Math result not representable"}, /* ERANGE */
520 {35, "Resource deadlock would occur"}, /* EDEADLK */
521 {36, "File name too long"}, /* ENAMETOOLONG */
522 {37, "No record locks available"}, /* ENOLCK */
523 {38, "Function not implemented"}, /* ENOSYS */
524 {39, "Directory not empty"}, /* ENOTEMPTY */
525 {40, "Too many symbolic links encountered"}, /* ELOOP */
526 {41, "Operation would block"}, /* EWOULDBLOCK */
527 {42, "No message of desired type"}, /* ENOMSG */
528 {43, "Identifier removed"}, /* EIDRM */
529 {44, "Channel number out of range"}, /* ECHRNG */
530 {45, "Level 2 not synchronized"}, /* EL2NSYNC */
531 {46, "Level 3 halted"}, /* EL3HLT */
532 {47, "Level 3 reset"}, /* EL3RST */
533 {48, "Link number out of range"}, /* ELNRNG */
534 {49, "Protocol driver not attached"}, /* EUNATCH */
535 {50, "No CSI structure available"}, /* ENOCSI */
536 {51, "Level 2 halted"}, /* EL2HLT */
537 {52, "Invalid exchange"}, /* EBADE */
538 {53, "Invalid request descriptor"}, /* EBADR */
539 {54, "Exchange full"}, /* EXFULL */
540 {55, "No anode"}, /* ENOANO */
541 {56, "Invalid request code"}, /* EBADRQC */
542 {57, "Invalid slot"}, /* EBADSLT */
543 {58, "File locking deadlock error"}, /* EDEADLOCK */
544 {59, "Bad font file format"}, /* EBFONT */
545 {60, "Device not a stream"}, /* ENOSTR */
546 {61, "No data available"}, /* ENODATA */
547 {62, "Timer expired"}, /* ETIME */
548 {63, "Out of streams resources"}, /* ENOSR */
549 {64, "Machine is not on the network"}, /* ENONET */
550 {65, "Package not installed"}, /* ENOPKG */
551 {66, "Object is remote"}, /* EREMOTE */
552 {67, "Link has been severed"}, /* ENOLINK */
553 {68, "Advertise error"}, /* EADV */
554 {69, "Srmount error"}, /* ESRMNT */
555 {70, "Communication error on send"}, /* ECOMM */
556 {71, "Protocol error"}, /* EPROTO */
557 {72, "Multihop attempted"}, /* EMULTIHOP */
558 {73, "RFS specific error"}, /* EDOTDOT */
559 {74, "Not a data message"}, /* EBADMSG */
560 {75, "Value too large for defined data type"}, /* EOVERFLOW */
561 {76, "Name not unique on network"}, /* ENOTUNIQ */
562 {77, "File descriptor in bad state"}, /* EBADFD */
563 {78, "Remote address changed"}, /* EREMCHG */
564 {79, "Can not access a needed shared library"}, /* ELIBACC */
565 {80, "Accessing a corrupted shared library"}, /* ELIBBAD */
566 {81, ".lib section in a.out corrupted"}, /* ELIBSCN */
567 {82, "Attempting to link in too many shared libraries"}, /* ELIBMAX */
568 {83, "Cannot exec a shared library directly"}, /* ELIBEXEC */
569 {84, "Illegal byte sequence"}, /* EILSEQ */
570 {85, "Interrupted system call should be restarted"}, /* ERESTART */
571 {86, "Streams pipe error"}, /* ESTRPIPE */
572 {87, "Too many users"}, /* EUSERS */
573 {88, "Socket operation on non-socket"}, /* ENOTSOCK */
574 {89, "Destination address required"}, /* EDESTADDRREQ */
575 {90, "Message too long"}, /* EMSGSIZE */
576 {91, "Protocol wrong type for socket"}, /* EPROTOTYPE */
577 {92, "Protocol not available"}, /* ENOPROTOOPT */
578 {93, "Protocol not supported"}, /* EPROTONOSUPPORT */
579 {94, "Socket type not supported"}, /* ESOCKTNOSUPPORT */
580 {95, "Operation not supported on transport endpoint"}, /* EOPNOTSUPP */
581 {96, "Protocol family not supported"}, /* EPFNOSUPPORT */
582 {97, "Address family not supported by protocol"}, /* EAFNOSUPPORT */
583 {98, "Address already in use"}, /* EADDRINUSE */
584 {99, "Cannot assign requested address"}, /* EADDRNOTAVAIL */
585 {100, "Network is down"}, /* ENETDOWN */
586 {101, "Network is unreachable"}, /* ENETUNREACH */
587 {102, "Network dropped connection because of reset"}, /* ENETRESET */
588 {103, "Software caused connection abort"}, /* ECONNABORTED */
589 {104, "Connection reset by peer"}, /* ECONNRESET */
590 {105, "No buffer space available"}, /* ENOBUFS */
591 {106, "Transport endpoint is already connected"}, /* EISCONN */
592 {107, "Transport endpoint is not connected"}, /* ENOTCONN */
593 {108, "Cannot send after transport endpoint shutdown"}, /* ESHUTDOWN */
594 {109, "Too many references: cannot splice"}, /* ETOOMANYREFS */
595 {110, "Connection timed out"}, /* ETIMEDOUT */
596 {111, "Connection refused"}, /* ECONNREFUSED */
597 {112, "Host is down"}, /* EHOSTDOWN */
598 {113, "No route to host"}, /* EHOSTUNREACH */
599 {114, "Operation already in progress"}, /* EALREADY */
600 {115, "Operation now in progress"}, /* EINPROGRESS */
601 {116, "Stale NFS file handle"}, /* ESTALE */
602 {117, "Structure needs cleaning"}, /* EUCLEAN */
603 {118, "Not a XENIX named type file"}, /* ENOTNAM */
604 {119, "No XENIX semaphores available"}, /* ENAVAIL */
605 {120, "Is a named type file"}, /* EISNAM */
606 {121, "Remote I/O error"}, /* EREMOTEIO */
607 {122, "Quota exceeded"}, /* EDQUOT */
608 {123, "No medium found"}, /* ENOMEDIUM */
609 {124, "Wrong medium type"}, /* EMEDIUMTYPE */
610 {125, "Operation Canceled"}, /* ECANCELED */
611 {126, "Required key not available"}, /* ENOKEY */
612 {127, "Key has expired"}, /* EKEYEXPIRED */
613 {128, "Key has been revoked"}, /* EKEYREVOKED */
614 {129, "Key was rejected by service"}, /* EKEYREJECTED */
615 {130, "Owner died"}, /* EOWNERDEAD */
616 {131, "State not recoverable"}, /* ENOTRECOVERABLE */
617 {132, "Operation not possible due to RF-kill"}, /* ERFKILL */
618 {133, "Memory page has hardware error"}, /* EHWPOISON */
621 static value_string_ext linux_errno_ext
= VALUE_STRING_EXT_INIT(linux_errno
);
623 static const char *const invalid_fid_str
= "<invalid fid>";
624 static const char *const afid_str
= "<afid>";
626 /* Structures for Protocol Operations */
652 struct _9p_tlcreate
{
659 struct _9p_rlcreate
{
663 struct _9p_tsymlink
{
666 struct _9p_str symtgt
;
669 struct _9p_rsymlink
{
692 struct _9p_treadlink
{
695 struct _9p_rreadlink
{
696 struct _9p_str target
;
698 struct _9p_tgetattr
{
700 uint64_t request_mask
;
702 struct _9p_rgetattr
{
722 uint64_t data_version
;
724 struct _9p_tsetattr
{
737 struct _9p_rsetattr
{
740 struct _9p_txattrwalk
{
745 struct _9p_rxattrwalk
{
748 struct _9p_txattrcreate
{
755 struct _9p_rxattrcreate
{
758 struct _9p_treaddir
{
763 struct _9p_rreaddir
{
781 struct _9p_str client_id
;
786 struct _9p_tgetlock
{
792 struct _9p_str client_id
;
794 struct _9p_rgetlock
{
799 struct _9p_str client_id
;
819 struct _9p_trenameat
{
821 struct _9p_str oldname
;
823 struct _9p_str newname
;
826 struct _9p_rrenameat
{
829 struct _9p_tunlinkat
{
835 struct _9p_runlinkat
{
850 struct _9p_tversion
{
852 struct _9p_str version
;
854 struct _9p_rversion
{
856 struct _9p_str version
;
860 struct _9p_str uname
;
861 struct _9p_str aname
;
862 uint32_t n_uname
; /* 9P2000.u extensions */
868 struct _9p_str error
;
869 uint32_t errnum
; /* 9p2000.u extension */
881 struct _9p_str uname
;
882 struct _9p_str aname
;
883 uint32_t n_uname
; /* 9P2000.u extensions */
892 struct _9p_str wnames
[_9P_MAXWELEM
];
896 struct _9p_qid wqids
[_9P_MAXWELEM
];
911 struct _9p_str extension
;
954 /* Forward declarations */
955 void proto_register_9P(void);
956 void proto_reg_handoff_9P(void);
958 /* Initialize the protocol and registered fields */
960 static int hf_9P_msgsz
;
961 static int hf_9P_msgtype
;
962 static int hf_9P_tag
;
963 static int hf_9P_oldtag
;
964 static int hf_9P_parmsz
;
965 static int hf_9P_maxsize
;
966 static int hf_9P_fid
;
967 static int hf_9P_nqid
;
968 static int hf_9P_mode
;
969 static int hf_9P_mode_rwx
;
970 static int hf_9P_mode_t
;
971 static int hf_9P_mode_c
;
972 static int hf_9P_extension
;
973 static int hf_9P_iounit
;
974 static int hf_9P_count
;
975 static int hf_9P_offset
;
976 static int hf_9P_perm
;
977 static int hf_9P_qidtype
;
978 static int hf_9P_qidtype_dir
;
979 static int hf_9P_qidtype_append
;
980 static int hf_9P_qidtype_exclusive
;
981 static int hf_9P_qidtype_mount
;
982 static int hf_9P_qidtype_auth_file
;
983 static int hf_9P_qidtype_temp_file
;
984 static int hf_9P_qidvers
;
985 static int hf_9P_qidpath
;
986 static int hf_9P_dm_dir
;
987 static int hf_9P_dm_append
;
988 static int hf_9P_dm_exclusive
;
989 static int hf_9P_dm_mount
;
990 static int hf_9P_dm_auth_file
;
991 static int hf_9P_dm_temp_file
;
992 static int hf_9P_dm_read_owner
;
993 static int hf_9P_dm_write_owner
;
994 static int hf_9P_dm_exec_owner
;
995 static int hf_9P_dm_read_group
;
996 static int hf_9P_dm_write_group
;
997 static int hf_9P_dm_exec_group
;
998 static int hf_9P_dm_read_others
;
999 static int hf_9P_dm_write_others
;
1000 static int hf_9P_dm_exec_others
;
1001 static int hf_9P_stattype
;
1002 static int hf_9P_statmode
;
1003 static int hf_9P_atime
;
1004 static int hf_9P_mtime
;
1005 static int hf_9P_ctime
;
1006 static int hf_9P_btime
;
1007 static int hf_9P_length
;
1008 static int hf_9P_dev
;
1009 static int hf_9P_wname
;
1010 static int hf_9P_version
;
1011 static int hf_9P_afid
;
1012 static int hf_9P_uname
;
1013 static int hf_9P_aname
;
1014 static int hf_9P_ename
;
1015 static int hf_9P_enum
;
1016 /* static int hf_9P_name; */
1017 static int hf_9P_filename
;
1018 static int hf_9P_sdlen
;
1019 static int hf_9P_user
;
1020 static int hf_9P_group
;
1021 static int hf_9P_uid
;
1022 static int hf_9P_gid
;
1023 static int hf_9P_muid
;
1024 static int hf_9P_nwalk
;
1025 static int hf_9P_newfid
;
1026 static int hf_9P_dfid
;
1027 static int hf_9P_getattr_flags
;
1028 static int hf_9P_getattr_mode
;
1029 static int hf_9P_getattr_nlink
;
1030 static int hf_9P_getattr_uid
;
1031 static int hf_9P_getattr_gid
;
1032 static int hf_9P_getattr_rdev
;
1033 static int hf_9P_getattr_atime
;
1034 static int hf_9P_getattr_mtime
;
1035 static int hf_9P_getattr_ctime
;
1036 static int hf_9P_getattr_ino
;
1037 static int hf_9P_getattr_size
;
1038 static int hf_9P_getattr_blocks
;
1039 static int hf_9P_getattr_btime
;
1040 static int hf_9P_getattr_gen
;
1041 static int hf_9P_getattr_dataversion
;
1042 static int hf_9P_setattr_flags
;
1043 static int hf_9P_setattr_mode
;
1044 static int hf_9P_setattr_uid
;
1045 static int hf_9P_setattr_gid
;
1046 static int hf_9P_setattr_size
;
1047 static int hf_9P_setattr_atime
;
1048 static int hf_9P_setattr_mtime
;
1049 static int hf_9P_setattr_ctime
;
1050 static int hf_9P_setattr_atime_set
;
1051 static int hf_9P_setattr_mtime_set
;
1052 static int hf_9P_unlinkat_flags
;
1053 static int hf_9P_nlink
;
1054 static int hf_9P_rdev
;
1055 static int hf_9P_size
;
1056 static int hf_9P_blksize
;
1057 static int hf_9P_blocks
;
1058 static int hf_9P_gen
;
1059 static int hf_9P_dataversion
;
1060 static int hf_9P_fstype
;
1061 static int hf_9P_bfree
;
1062 static int hf_9P_bavail
;
1063 static int hf_9P_files
;
1064 static int hf_9P_ffree
;
1065 static int hf_9P_fsid
;
1066 static int hf_9P_namelen
;
1067 static int hf_9P_mknod_major
;
1068 static int hf_9P_mknod_minor
;
1069 static int hf_9P_lflags
;
1070 static int hf_9P_lflags_rdonly
;
1071 static int hf_9P_lflags_wronly
;
1072 static int hf_9P_lflags_rdwr
;
1073 static int hf_9P_lflags_create
;
1074 static int hf_9P_lflags_excl
;
1075 static int hf_9P_lflags_noctty
;
1076 static int hf_9P_lflags_trunc
;
1077 static int hf_9P_lflags_append
;
1078 static int hf_9P_lflags_nonblock
;
1079 static int hf_9P_lflags_dsync
;
1080 static int hf_9P_lflags_fasync
;
1081 static int hf_9P_lflags_direct
;
1082 static int hf_9P_lflags_largefile
;
1083 static int hf_9P_lflags_directory
;
1084 static int hf_9P_lflags_nofollow
;
1085 static int hf_9P_lflags_noatime
;
1086 static int hf_9P_lflags_cloexec
;
1087 static int hf_9P_lflags_sync
;
1088 static int hf_9P_xattr_flag
;
1089 static int hf_9P_lock_type
;
1090 static int hf_9P_lock_flag
;
1091 static int hf_9P_lock_start
;
1092 static int hf_9P_lock_length
;
1093 static int hf_9P_lock_procid
;
1094 static int hf_9P_lock_status
;
1095 static int hf_9P_unknown_message
;
1097 /* subtree pointers */
1099 static int ett_9P_omode
;
1100 static int ett_9P_dm
;
1101 static int ett_9P_wname
;
1102 static int ett_9P_aname
;
1103 static int ett_9P_ename
;
1104 static int ett_9P_uname
;
1105 static int ett_9P_user
;
1106 static int ett_9P_group
;
1107 static int ett_9P_muid
;
1108 static int ett_9P_filename
;
1109 static int ett_9P_version
;
1110 static int ett_9P_qid
;
1111 static int ett_9P_qidtype
;
1112 static int ett_9P_getattr_flags
;
1113 static int ett_9P_setattr_flags
;
1114 static int ett_9P_lflags
;
1116 static expert_field ei_9P_first_250
;
1117 static expert_field ei_9P_msgtype
;
1119 static wmem_map_t
*_9p_hashtable
;
1121 static void dissect_9P_dm(tvbuff_t
*tvb
, proto_item
*tree
, int offset
, int iscreate
);
1122 static void dissect_9P_qid(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
1123 static void dissect_9P_lflags(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
1124 static void dissect_9P_getattrflags(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
1125 static void dissect_9P_setattrflags(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
);
1127 static int * const _9P_modes
[] = {
1134 struct _9p_hashkey
{
1135 uint32_t conv_index
;
1140 struct _9p_hashval
{
1145 struct _9p_taginfo
{
1146 enum _9p_msg_t msgtype
;
1148 /* fid path used for create and lcreate */
1152 static int _9p_hash_equal(const void *k1
, const void *k2
) {
1153 const struct _9p_hashkey
*key1
= (const struct _9p_hashkey
*)k1
, *key2
= (const struct _9p_hashkey
*)k2
;
1155 return ((key1
->conv_index
== key2
->conv_index
) && (key1
->tag
== key2
->tag
) && (key1
->fid
== key2
->fid
));
1158 static unsigned _9p_hash_hash(const void *k
)
1160 const struct _9p_hashkey
*key
= (const struct _9p_hashkey
*)k
;
1162 return (key
->conv_index
^ key
->tag
^ key
->fid
);
1165 static struct _9p_hashval
*_9p_hash_new_val(size_t len
)
1167 struct _9p_hashval
*val
;
1168 val
= wmem_new(wmem_file_scope(), struct _9p_hashval
);
1170 val
->data
= wmem_alloc(wmem_file_scope(), len
);
1176 static void _9p_hash_set(packet_info
*pinfo
, uint16_t tag
, uint32_t fid
, struct _9p_hashval
*val
)
1178 struct _9p_hashkey
*key
;
1179 struct _9p_hashval
*oldval
;
1180 conversation_t
*conv
;
1182 conv
= find_or_create_conversation(pinfo
);
1184 key
= wmem_new(wmem_file_scope(), struct _9p_hashkey
);
1186 key
->conv_index
= conv
->conv_index
;
1190 /* remove eventual old entry */
1191 oldval
= (struct _9p_hashval
*)wmem_map_lookup(_9p_hashtable
, key
);
1193 wmem_map_remove(_9p_hashtable
, key
);
1195 wmem_map_insert(_9p_hashtable
, key
, val
);
1198 static struct _9p_hashval
*_9p_hash_get(packet_info
*pinfo
, uint16_t tag
, uint32_t fid
)
1200 struct _9p_hashkey key
;
1201 conversation_t
*conv
;
1203 conv
= find_or_create_conversation(pinfo
);
1205 key
.conv_index
= conv
->conv_index
;
1209 return (struct _9p_hashval
*)wmem_map_lookup(_9p_hashtable
, &key
);
1212 static void _9p_hash_free(packet_info
*pinfo
, uint16_t tag
, uint32_t fid
)
1214 struct _9p_hashkey key
;
1215 conversation_t
*conv
;
1217 conv
= find_or_create_conversation(pinfo
);
1219 key
.conv_index
= conv
->conv_index
;
1223 wmem_map_remove(_9p_hashtable
, &key
);
1226 static void conv_set_version(packet_info
*pinfo
, enum _9p_version version
)
1228 struct _9p_hashval
*val
;
1230 val
= _9p_hash_new_val(sizeof(enum _9p_version
));
1233 *(enum _9p_version
*)val
->data
= version
;
1235 _9p_hash_set(pinfo
, _9P_NOTAG
, _9P_NOFID
, val
);
1238 static enum _9p_version
conv_get_version(packet_info
*pinfo
)
1240 struct _9p_hashval
*val
;
1242 val
= _9p_hash_get(pinfo
, _9P_NOTAG
, _9P_NOFID
);
1244 return val
? *(enum _9p_version
*)val
->data
: _9P
;
1247 static void conv_set_fid_nocopy(packet_info
*pinfo
, uint32_t fid
, const char *path
)
1249 struct _9p_hashval
*val
;
1251 if (pinfo
->fd
->visited
|| fid
== _9P_NOFID
)
1254 /* get or create&insert fid tree */
1255 val
= _9p_hash_get(pinfo
, _9P_NOTAG
, fid
);
1257 val
= _9p_hash_new_val(0);
1258 val
->data
= wmem_tree_new(wmem_file_scope());
1259 /* val->len is intentionally left to 0 so the tree won't be freed */
1260 _9p_hash_set(pinfo
, _9P_NOTAG
, fid
, val
);
1264 wmem_tree_insert32((wmem_tree_t
*)val
->data
, pinfo
->num
, (void *)path
);
1267 static void conv_set_fid(packet_info
*pinfo
, uint32_t fid
, const char *path
, size_t len
)
1271 if (pinfo
->fd
->visited
|| fid
== _9P_NOFID
|| len
== 0)
1274 str
= (char*)wmem_alloc(wmem_file_scope(), len
);
1275 (void) g_strlcpy(str
, path
, len
);
1276 conv_set_fid_nocopy(pinfo
, fid
, str
);
1279 static const char *conv_get_fid(packet_info
*pinfo
, uint32_t fid
)
1281 struct _9p_hashval
*val
;
1283 if (fid
== _9P_NOFID
)
1284 return invalid_fid_str
;
1286 val
= _9p_hash_get(pinfo
, _9P_NOTAG
, fid
);
1288 return invalid_fid_str
;
1290 /* -1 because the fid needs to have been set on a previous message.
1291 Let's ignore the possibility of num == 0... */
1292 return (char*)wmem_tree_lookup32_le((wmem_tree_t
*)val
->data
, pinfo
->num
-1);
1295 static inline void conv_free_fid(packet_info
*pinfo
, uint32_t fid
)
1297 conv_set_fid_nocopy(pinfo
, fid
, invalid_fid_str
);
1300 static void conv_set_tag(packet_info
*pinfo
, uint16_t tag
, enum _9p_msg_t msgtype
, uint32_t fid
, wmem_strbuf_t
*fid_path
)
1302 struct _9p_hashval
*val
;
1303 struct _9p_taginfo
*taginfo
;
1305 if (pinfo
->fd
->visited
|| tag
== _9P_NOTAG
)
1308 val
= _9p_hash_new_val(sizeof(struct _9p_taginfo
));
1309 taginfo
= (struct _9p_taginfo
*)val
->data
;
1311 taginfo
->msgtype
= msgtype
;
1314 taginfo
->fid_path
= (char*)wmem_alloc(wmem_file_scope(), wmem_strbuf_get_len(fid_path
)+1);
1315 (void) g_strlcpy(taginfo
->fid_path
, wmem_strbuf_get_str(fid_path
), wmem_strbuf_get_len(fid_path
)+1);
1317 taginfo
->fid_path
= NULL
;
1320 _9p_hash_set(pinfo
, tag
, _9P_NOFID
, val
);
1323 static inline struct _9p_taginfo
*conv_get_tag(packet_info
*pinfo
, uint16_t tag
)
1325 struct _9p_hashval
*val
;
1327 /* get tag only makes sense on first pass, as tree isn't built like fid */
1328 if (pinfo
->fd
->visited
|| tag
== _9P_NOTAG
)
1331 /* check that length matches? */
1332 val
= _9p_hash_get(pinfo
, tag
, _9P_NOFID
);
1334 return val
? (struct _9p_taginfo
*)val
->data
: NULL
;
1337 static inline void conv_free_tag(packet_info
*pinfo
, uint16_t tag
)
1339 if (pinfo
->fd
->visited
|| tag
== _9P_NOTAG
)
1342 _9p_hash_free(pinfo
, tag
, _9P_NOFID
);
1345 /* dissects a string[s] (2 bytes followed by UTF-8 string) */
1346 static unsigned _9p_dissect_string(tvbuff_t
*tvb
, proto_tree
*ninep_tree
,
1347 unsigned offset
, int hf_string
, int ett_string
)
1351 proto_tree
*sub_tree
;
1353 _9p_len
= tvb_get_letohs(tvb
, offset
);
1354 ti
= proto_tree_add_item(ninep_tree
, hf_string
, tvb
, offset
+ 2,
1355 _9p_len
, ENC_UTF_8
|ENC_NA
);
1356 sub_tree
= proto_item_add_subtree(ti
, ett_string
);
1357 proto_tree_add_item(sub_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1362 /* Dissect 9P messages*/
1363 static int dissect_9P_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1365 uint32_t u32
, i
, fid
, dfid
, newfid
;
1366 uint16_t u16
, tag
, _9p_len
;
1367 enum _9p_msg_t ninemsg
;
1368 unsigned offset
= 0;
1369 const char *mname
, *fid_path
;
1371 wmem_strbuf_t
*tmppath
= NULL
;
1372 int len
, reportedlen
;
1374 proto_item
*ti
, *msg_item
;
1375 proto_tree
*ninep_tree
;
1376 struct _9p_taginfo
*taginfo
;
1379 _9p_version
= conv_get_version(pinfo
);
1380 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, val_to_str_ext_const(_9p_version
, &ninep_version_ext
, "9P"));
1382 col_clear(pinfo
->cinfo
, COL_INFO
);
1384 /*ninesz = tvb_get_letohl(tvb, offset);*/
1385 ninemsg
= (enum _9p_msg_t
)tvb_get_uint8(tvb
, offset
+ 4);
1387 mname
= val_to_str_ext_const(ninemsg
, &ninep_msg_type_ext
, "Unknown");
1389 if(strcmp(mname
, "Unknown") == 0) {
1390 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "9P Data (Message type %u)", (unsigned)ninemsg
);
1394 tag
= tvb_get_letohs(tvb
, offset
+5);
1395 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s Tag=%u", mname
, (unsigned)tag
);
1397 ti
= proto_tree_add_item(tree
, proto_9P
, tvb
, 0, -1, ENC_NA
);
1398 ninep_tree
= proto_item_add_subtree(ti
, ett_9P
);
1399 proto_tree_add_item(ninep_tree
, hf_9P_msgsz
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1402 msg_item
= proto_tree_add_item(ninep_tree
, hf_9P_msgtype
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1404 proto_tree_add_item(ninep_tree
, hf_9P_tag
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1410 proto_tree_add_item(ninep_tree
, hf_9P_maxsize
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1413 if (!pinfo
->fd
->visited
) {
1414 _9p_len
= tvb_get_letohs(tvb
, offset
);
1415 tvb_s
= (char *)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1417 if (!strcmp(tvb_s
, "9P2000.L")) {
1419 } else if (!strcmp(tvb_s
, "9P2000")) {
1421 } else if (!strcmp(tvb_s
, "9P2000.u")) {
1427 conv_set_version(pinfo
, (enum _9p_version
)u32
);
1429 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_version
, ett_9P_version
);
1431 /* don't set tag for tversion/free it for rversion,
1432 we need that for the actual version number */
1436 proto_tree_add_item(ninep_tree
, hf_9P_afid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1437 fid
= tvb_get_letohl(tvb
, offset
);
1438 conv_set_fid_nocopy(pinfo
, fid
, afid_str
);
1441 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_uname
, ett_9P_uname
);
1442 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_aname
, ett_9P_aname
);
1444 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
1448 if (_9p_version
== _9P2000_L
) {
1449 u32
= tvb_get_letohl(tvb
, offset
);
1450 ti
= proto_tree_add_item(ninep_tree
, hf_9P_enum
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1451 proto_item_append_text(ti
, " (%s)", val_to_str_ext_const(u32
, &linux_errno_ext
, "Unknown"));
1454 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_ename
, ett_9P_ename
);
1457 /* conv_get_tag checks we're in first pass */
1458 taginfo
= conv_get_tag(pinfo
, tag
);
1459 if (taginfo
&& (taginfo
->msgtype
== _9P_TWALK
|| taginfo
->msgtype
== _9P_TATTACH
))
1460 conv_free_fid(pinfo
, taginfo
->fid
);
1462 conv_free_tag(pinfo
, tag
);
1466 u16
= tvb_get_letohs(tvb
, offset
);
1467 proto_tree_add_item(ninep_tree
, hf_9P_oldtag
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1468 conv_free_tag(pinfo
, u16
);
1470 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1474 fid
= tvb_get_letohl(tvb
, offset
);
1475 proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1478 proto_tree_add_item(ninep_tree
, hf_9P_afid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1481 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_uname
, ett_9P_uname
);
1483 if(!pinfo
->fd
->visited
) {
1484 _9p_len
= tvb_get_letohs(tvb
, offset
);
1485 tvb_s
= (char*)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1486 conv_set_fid(pinfo
, fid
, tvb_s
, strlen(tvb_s
)+1);
1488 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_aname
, ett_9P_aname
);
1490 if (_9p_version
== _9P2000_u
|| _9p_version
== _9P2000_L
) {
1491 proto_tree_add_item(ninep_tree
, hf_9P_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1495 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
1499 fid
= tvb_get_letohl(tvb
, offset
);
1500 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1501 fid_path
= conv_get_fid(pinfo
, fid
);
1502 proto_item_append_text(ti
, " (%s)", fid_path
);
1503 if (!pinfo
->fd
->visited
) {
1504 tmppath
= wmem_strbuf_create(pinfo
->pool
);
1505 wmem_strbuf_append(tmppath
, fid_path
);
1509 fid
= tvb_get_letohl(tvb
, offset
);
1510 proto_tree_add_item(ninep_tree
, hf_9P_newfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1513 u16
= tvb_get_letohs(tvb
, offset
);
1514 proto_tree_add_item(ninep_tree
, hf_9P_nwalk
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1517 for(i
= 0 ; i
< u16
; i
++) {
1518 if (!pinfo
->fd
->visited
) {
1519 _9p_len
= tvb_get_letohs(tvb
, offset
);
1520 tvb_s
= (char*)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1521 wmem_strbuf_append_c(tmppath
, '/');
1522 wmem_strbuf_append(tmppath
, tvb_s
);
1526 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
1530 /* I can't imagine anyone having a directory depth more than 25,
1531 Limit to 10 times that to be sure, 2^16 is too much */
1533 expert_add_info(pinfo
, ti
, &ei_9P_first_250
);
1536 if (!pinfo
->fd
->visited
) {
1537 conv_set_fid(pinfo
, fid
, wmem_strbuf_get_str(tmppath
), wmem_strbuf_get_len(tmppath
)+1);
1540 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
1544 u16
= tvb_get_letohs(tvb
, offset
);
1545 ti
= proto_tree_add_item(ninep_tree
, hf_9P_nqid
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1547 /* I can't imagine anyone having a directory depth more than 25,
1548 Limit to 10 times that to be sure, 2^16 is too much */
1553 for(i
= 0; i
< u16
; i
++) {
1554 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1559 expert_add_info(pinfo
, ti
, &ei_9P_first_250
);
1562 conv_free_tag(pinfo
, tag
);
1565 fid
= tvb_get_letohl(tvb
, offset
);
1566 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1567 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1570 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1571 dissect_9P_lflags(tvb
, ti
, offset
);
1573 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1577 fid
= tvb_get_letohl(tvb
, offset
);
1578 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1579 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1582 proto_tree_add_bitmask(ninep_tree
, tvb
, offset
, hf_9P_mode
, ett_9P_omode
, _9P_modes
, ENC_LITTLE_ENDIAN
);
1585 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1589 fid
= tvb_get_letohl(tvb
, offset
);
1590 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1591 fid_path
= conv_get_fid(pinfo
, fid
);
1592 proto_item_append_text(ti
, " (%s)", fid_path
);
1595 if (!pinfo
->fd
->visited
) {
1596 _9p_len
= tvb_get_letohs(tvb
, offset
);
1597 tmppath
= wmem_strbuf_create(pinfo
->pool
);
1598 wmem_strbuf_append(tmppath
, fid_path
);
1599 wmem_strbuf_append_c(tmppath
, '/');
1600 tvb_s
= (char*)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1601 wmem_strbuf_append(tmppath
, tvb_s
);
1603 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_filename
, ett_9P_filename
);
1605 ti
= proto_tree_add_item(ninep_tree
, hf_9P_perm
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1606 dissect_9P_dm(tvb
, ti
, offset
, 1);
1609 proto_tree_add_bitmask(ninep_tree
, tvb
, offset
, hf_9P_mode
, ett_9P_omode
, _9P_modes
, ENC_LITTLE_ENDIAN
);
1612 if (_9p_version
== _9P2000_u
) {
1613 _9p_len
= tvb_get_letohs(tvb
, offset
);
1614 proto_tree_add_item(ninep_tree
, hf_9P_extension
, tvb
, offset
+2, 4, ENC_ASCII
);
1615 offset
+= 2 + _9p_len
;
1618 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, tmppath
);
1622 fid
= tvb_get_letohl(tvb
, offset
);
1623 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1624 fid_path
= conv_get_fid(pinfo
, fid
);
1625 proto_item_append_text(ti
, " (%s)", fid_path
);
1628 if (!pinfo
->fd
->visited
) {
1629 _9p_len
= tvb_get_letohs(tvb
, offset
);
1630 tmppath
= wmem_strbuf_create(pinfo
->pool
);
1631 wmem_strbuf_append(tmppath
, fid_path
);
1632 wmem_strbuf_append_c(tmppath
, '/');
1633 tvb_s
= (char*)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1634 wmem_strbuf_append(tmppath
, tvb_s
);
1636 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_filename
, ett_9P_filename
);
1638 ti
= proto_tree_add_item(ninep_tree
, hf_9P_lflags
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1639 dissect_9P_lflags(tvb
, ti
, offset
);
1642 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1643 dissect_9P_dm(tvb
, ti
, offset
, 0);
1646 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1649 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, tmppath
);
1654 fid
= tvb_get_letohl(tvb
, offset
);
1655 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1656 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1659 proto_tree_add_item(ninep_tree
, hf_9P_offset
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1662 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1665 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1670 u32
= tvb_get_letohl(tvb
, offset
);
1671 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1674 len
= tvb_reported_length_remaining(tvb
, offset
);
1675 reportedlen
= ((int)u32
&0xffff) > len
? len
: (int)u32
&0xffff;
1676 next_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, len
, reportedlen
);
1677 call_data_dissector(next_tvb
, pinfo
, tree
);
1680 conv_free_tag(pinfo
, tag
);
1684 fid
= tvb_get_letohl(tvb
, offset
);
1685 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1686 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1689 proto_tree_add_item(ninep_tree
, hf_9P_offset
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1692 u32
= tvb_get_letohl(tvb
, offset
);
1693 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1695 len
= tvb_reported_length_remaining(tvb
, offset
);
1696 reportedlen
= ((int)u32
&0xffff) > len
? len
: (int)u32
&0xffff;
1697 next_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, len
, reportedlen
);
1698 call_data_dissector(next_tvb
, pinfo
, tree
);
1701 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1705 proto_tree_add_item(ninep_tree
, hf_9P_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1708 conv_free_tag(pinfo
, tag
);
1712 proto_tree_add_item(ninep_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1715 proto_tree_add_item(ninep_tree
, hf_9P_sdlen
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1718 proto_tree_add_item(ninep_tree
, hf_9P_stattype
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1721 proto_tree_add_item(ninep_tree
, hf_9P_dev
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1724 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1727 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1728 dissect_9P_dm(tvb
, ti
, offset
, 0);
1731 proto_tree_add_item(ninep_tree
, hf_9P_atime
, tvb
, offset
, 4, ENC_TIME_SECS
|ENC_LITTLE_ENDIAN
);
1734 proto_tree_add_item(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 4, ENC_TIME_SECS
|ENC_LITTLE_ENDIAN
);
1737 proto_tree_add_item(ninep_tree
, hf_9P_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1740 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_filename
, ett_9P_filename
);
1741 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_user
, ett_9P_user
);
1742 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_group
, ett_9P_group
);
1743 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_muid
, ett_9P_muid
);
1745 conv_free_tag(pinfo
, tag
);
1749 fid
= tvb_get_letohl(tvb
, offset
);
1750 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1751 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1754 proto_tree_add_item(ninep_tree
, hf_9P_parmsz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1757 proto_tree_add_item(ninep_tree
, hf_9P_sdlen
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1760 proto_tree_add_item(ninep_tree
, hf_9P_stattype
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1763 proto_tree_add_item(ninep_tree
, hf_9P_dev
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1766 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1769 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1770 dissect_9P_dm(tvb
, ti
, offset
, 0);
1773 proto_tree_add_item(ninep_tree
, hf_9P_atime
, tvb
, offset
, 4, ENC_TIME_SECS
|ENC_LITTLE_ENDIAN
);
1776 proto_tree_add_item(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 4, ENC_TIME_SECS
|ENC_LITTLE_ENDIAN
);
1779 proto_tree_add_item(ninep_tree
, hf_9P_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1782 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_filename
, ett_9P_filename
);
1783 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_user
, ett_9P_user
);
1784 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_group
, ett_9P_group
);
1785 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_muid
, ett_9P_muid
);
1787 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1791 fid
= tvb_get_letohl(tvb
, offset
);
1792 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1793 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1796 ti
= proto_tree_add_item(ninep_tree
, hf_9P_getattr_flags
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1797 dissect_9P_getattrflags(tvb
, ti
, offset
);
1800 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1804 ti
= proto_tree_add_item(ninep_tree
, hf_9P_getattr_flags
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1805 dissect_9P_getattrflags(tvb
, ti
, offset
);
1808 dissect_9P_qid(tvb
, ninep_tree
, offset
);
1811 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1812 dissect_9P_dm(tvb
, ti
, offset
, 0);
1815 proto_tree_add_item(ninep_tree
, hf_9P_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1818 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1821 proto_tree_add_item(ninep_tree
, hf_9P_nlink
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1824 proto_tree_add_item(ninep_tree
, hf_9P_rdev
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1827 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1830 proto_tree_add_item(ninep_tree
, hf_9P_blksize
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1833 proto_tree_add_item(ninep_tree
, hf_9P_blocks
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1836 proto_tree_add_item(ninep_tree
, hf_9P_atime
, tvb
, offset
, 16, ENC_TIME_SECS_NSECS
|ENC_LITTLE_ENDIAN
);
1839 proto_tree_add_item(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 16, ENC_TIME_SECS_NSECS
|ENC_LITTLE_ENDIAN
);
1842 proto_tree_add_item(ninep_tree
, hf_9P_ctime
, tvb
, offset
, 16, ENC_TIME_SECS_NSECS
|ENC_LITTLE_ENDIAN
);
1845 proto_tree_add_item(ninep_tree
, hf_9P_btime
, tvb
, offset
, 16, ENC_TIME_SECS_NSECS
|ENC_LITTLE_ENDIAN
);
1848 proto_tree_add_item(ninep_tree
, hf_9P_gen
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1851 proto_tree_add_item(ninep_tree
, hf_9P_dataversion
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1854 conv_free_tag(pinfo
, tag
);
1858 fid
= tvb_get_letohl(tvb
, offset
);
1859 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1860 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1863 ti
= proto_tree_add_item(ninep_tree
, hf_9P_setattr_flags
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1864 dissect_9P_setattrflags(tvb
, ti
, offset
);
1867 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1868 dissect_9P_dm(tvb
, ti
, offset
, 0);
1871 proto_tree_add_item(ninep_tree
, hf_9P_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1874 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1877 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1880 proto_tree_add_item(ninep_tree
, hf_9P_atime
, tvb
, offset
, 16, ENC_TIME_SECS_NSECS
|ENC_LITTLE_ENDIAN
);
1883 proto_tree_add_item(ninep_tree
, hf_9P_mtime
, tvb
, offset
, 16, ENC_TIME_SECS_NSECS
|ENC_LITTLE_ENDIAN
);
1886 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1890 proto_tree_add_item(ninep_tree
, hf_9P_fstype
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1893 proto_tree_add_item(ninep_tree
, hf_9P_blksize
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1896 proto_tree_add_item(ninep_tree
, hf_9P_blocks
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1899 proto_tree_add_item(ninep_tree
, hf_9P_bfree
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1902 proto_tree_add_item(ninep_tree
, hf_9P_bavail
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1905 proto_tree_add_item(ninep_tree
, hf_9P_files
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1908 proto_tree_add_item(ninep_tree
, hf_9P_ffree
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1911 proto_tree_add_item(ninep_tree
, hf_9P_fsid
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1914 proto_tree_add_item(ninep_tree
, hf_9P_namelen
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1917 conv_free_tag(pinfo
, tag
);
1921 fid
= tvb_get_letohl(tvb
, offset
);
1922 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1923 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1927 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
1928 /* XXX: maybe use a new field for symtgt? */
1929 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
1931 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1934 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1938 fid
= tvb_get_letohl(tvb
, offset
);
1939 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1940 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1943 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
1945 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1946 dissect_9P_dm(tvb
, ti
, offset
, 0);
1949 proto_tree_add_item(ninep_tree
, hf_9P_mknod_major
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1952 proto_tree_add_item(ninep_tree
, hf_9P_mknod_minor
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1955 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1958 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1962 fid
= tvb_get_letohl(tvb
, offset
);
1963 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1964 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
1967 dfid
= tvb_get_letohl(tvb
, offset
);
1968 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1969 fid_path
= conv_get_fid(pinfo
, dfid
);
1970 proto_item_append_text(ti
, " (%s)", fid_path
);
1973 if (!pinfo
->fd
->visited
) {
1974 _9p_len
= tvb_get_letohs(tvb
, offset
);
1975 tmppath
= wmem_strbuf_create(pinfo
->pool
);
1976 wmem_strbuf_append(tmppath
, conv_get_fid(pinfo
, dfid
));
1977 wmem_strbuf_append_c(tmppath
, '/');
1979 tvb_s
= (char*)tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+2, _9p_len
, ENC_UTF_8
|ENC_NA
);
1980 wmem_strbuf_append(tmppath
, tvb_s
);
1982 conv_set_fid(pinfo
, fid
, wmem_strbuf_get_str(tmppath
), wmem_strbuf_get_len(tmppath
)+1);
1984 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
1986 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
1990 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
1992 conv_free_tag(pinfo
, tag
);
1995 case _9P_TXATTRWALK
:
1996 fid
= tvb_get_letohl(tvb
, offset
);
1997 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1998 fid_path
= conv_get_fid(pinfo
, fid
);
1999 proto_item_append_text(ti
, " (%s)", fid_path
);
2002 newfid
= tvb_get_letohl(tvb
, offset
);
2003 proto_tree_add_item(ninep_tree
, hf_9P_newfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2004 conv_set_fid_nocopy(pinfo
, newfid
, fid_path
);
2007 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2009 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2012 case _9P_RXATTRWALK
:
2013 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2016 conv_free_tag(pinfo
, tag
);
2019 case _9P_TXATTRCREATE
:
2020 fid
= tvb_get_letohl(tvb
, offset
);
2021 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2022 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2025 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2027 proto_tree_add_item(ninep_tree
, hf_9P_size
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2030 proto_tree_add_item(ninep_tree
, hf_9P_xattr_flag
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2033 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2038 fid
= tvb_get_letohl(tvb
, offset
);
2039 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2040 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2043 proto_tree_add_item(ninep_tree
, hf_9P_lock_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2046 proto_tree_add_item(ninep_tree
, hf_9P_lock_flag
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2049 proto_tree_add_item(ninep_tree
, hf_9P_lock_start
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2052 proto_tree_add_item(ninep_tree
, hf_9P_lock_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2055 proto_tree_add_item(ninep_tree
, hf_9P_lock_procid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2058 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2060 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2064 proto_tree_add_item(ninep_tree
, hf_9P_lock_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2067 conv_free_tag(pinfo
, tag
);
2071 proto_tree_add_item(ninep_tree
, hf_9P_lock_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2074 proto_tree_add_item(ninep_tree
, hf_9P_lock_flag
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2077 proto_tree_add_item(ninep_tree
, hf_9P_lock_start
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2080 proto_tree_add_item(ninep_tree
, hf_9P_lock_length
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2083 proto_tree_add_item(ninep_tree
, hf_9P_lock_procid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2086 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2088 conv_free_tag(pinfo
, tag
);
2092 fid
= tvb_get_letohl(tvb
, offset
);
2093 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2094 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2097 fid
= tvb_get_letohl(tvb
, offset
);
2098 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2099 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2102 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2104 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2108 fid
= tvb_get_letohl(tvb
, offset
);
2109 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2110 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2113 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2115 ti
= proto_tree_add_item(ninep_tree
, hf_9P_statmode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2116 dissect_9P_dm(tvb
, ti
, offset
, 0);
2119 proto_tree_add_item(ninep_tree
, hf_9P_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2122 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2126 fid
= tvb_get_letohl(tvb
, offset
);
2127 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2128 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2131 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2133 fid
= tvb_get_letohl(tvb
, offset
);
2134 ti
= proto_tree_add_item(ninep_tree
, hf_9P_newfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2135 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2138 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2140 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2144 fid
= tvb_get_letohl(tvb
, offset
);
2145 ti
= proto_tree_add_item(ninep_tree
, hf_9P_dfid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2146 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2149 offset
+= _9p_dissect_string(tvb
, ninep_tree
, offset
, hf_9P_wname
, ett_9P_wname
);
2151 proto_tree_add_item(ninep_tree
, hf_9P_unlinkat_flags
, tvb
,
2152 offset
, 4, ENC_LITTLE_ENDIAN
);
2155 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2160 fid
= tvb_get_letohl(tvb
, offset
);
2161 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2163 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2164 conv_free_fid(pinfo
, fid
);
2166 conv_set_tag(pinfo
, tag
, ninemsg
, fid
, NULL
);
2169 /* Request with only fid */
2174 fid
= tvb_get_letohl(tvb
, offset
);
2175 ti
= proto_tree_add_item(ninep_tree
, hf_9P_fid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2177 proto_item_append_text(ti
, " (%s)", conv_get_fid(pinfo
, fid
));
2179 conv_set_tag(pinfo
, tag
, ninemsg
, _9P_NOFID
, NULL
);
2182 /* Reply with qid and ionuit */
2185 dissect_9P_qid(tvb
, ninep_tree
, offset
);
2187 proto_tree_add_item(ninep_tree
, hf_9P_iounit
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2190 taginfo
= conv_get_tag(pinfo
, tag
);
2191 if (taginfo
&& taginfo
->fid_path
) {
2192 conv_set_fid_nocopy(pinfo
, taginfo
->fid
, taginfo
->fid_path
);
2195 conv_free_tag(pinfo
, tag
);
2200 dissect_9P_qid(tvb
, ninep_tree
, offset
);
2202 proto_tree_add_item(ninep_tree
, hf_9P_iounit
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2205 conv_free_tag(pinfo
, tag
);
2208 /* Reply with only qid */
2214 dissect_9P_qid(tvb
, ninep_tree
, offset
);
2217 conv_free_tag(pinfo
, tag
);
2223 case _9P_RXATTRCREATE
:
2231 /* Unhandled reply */
2234 conv_free_tag(pinfo
, tag
);
2237 /* Should-not-happen query */
2241 expert_add_info(pinfo
, msg_item
, &ei_9P_msgtype
);
2245 /* Show any extra data at the end of the message (but only
2246 if it was captured) */
2247 if (offset
!= tvb_captured_length(tvb
))
2248 proto_tree_add_item(ninep_tree
, hf_9P_unknown_message
, tvb
, offset
, -1, ENC_NA
);
2249 return tvb_captured_length(tvb
);
2252 static unsigned get_9P_message_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
2253 int offset
, void *data _U_
)
2255 return (unsigned) tvb_get_letohl(tvb
, offset
);
2258 static int dissect_9P(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
2260 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, 4,
2261 get_9P_message_len
, dissect_9P_message
, data
);
2262 return tvb_captured_length(tvb
);
2265 /* dissect 9P Qid */
2266 static void dissect_9P_qid(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
2268 proto_item
*qidtype_item
;
2269 proto_tree
*qid_tree
,*qidtype_tree
;
2277 type
= tvb_get_uint8(tvb
, offset
);
2278 vers
= tvb_get_letohs(tvb
, offset
+1);
2279 path
= tvb_get_letoh64(tvb
, offset
+1+4);
2281 qid_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 13, ett_9P_qid
, NULL
,
2282 "Qid type=0x%02x vers=%d path=%" PRIu64
, type
, vers
, path
);
2284 qidtype_item
= proto_tree_add_item(qid_tree
, hf_9P_qidtype
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2285 qidtype_tree
= proto_item_add_subtree(qidtype_item
, ett_9P_qidtype
);
2287 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_dir
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2288 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_append
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2289 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_exclusive
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2290 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_mount
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2291 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_auth_file
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2292 proto_tree_add_item(qidtype_tree
, hf_9P_qidtype_temp_file
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2294 proto_tree_add_item(qid_tree
, hf_9P_qidvers
, tvb
, offset
+1, 4, ENC_LITTLE_ENDIAN
);
2295 proto_tree_add_item(qid_tree
, hf_9P_qidpath
, tvb
, offset
+1+4, 8, ENC_LITTLE_ENDIAN
);
2298 /*dissect 9P stat mode and create perm flags */
2299 static void dissect_9P_dm(tvbuff_t
*tvb
, proto_item
*item
, int offset
, int iscreate
)
2301 proto_item
*mode_tree
;
2304 mode_tree
= proto_item_add_subtree(item
, ett_9P_dm
);
2308 proto_tree_add_item(mode_tree
, hf_9P_dm_dir
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2309 if(!iscreate
) { /* Not applicable to Tcreate (?) */
2310 proto_tree_add_item(mode_tree
, hf_9P_dm_append
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2311 proto_tree_add_item(mode_tree
, hf_9P_dm_exclusive
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2312 proto_tree_add_item(mode_tree
, hf_9P_dm_mount
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2313 proto_tree_add_item(mode_tree
, hf_9P_dm_auth_file
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2314 proto_tree_add_item(mode_tree
, hf_9P_dm_temp_file
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2317 proto_tree_add_item(mode_tree
, hf_9P_dm_read_owner
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2318 proto_tree_add_item(mode_tree
, hf_9P_dm_write_owner
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2319 proto_tree_add_item(mode_tree
, hf_9P_dm_exec_owner
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2320 proto_tree_add_item(mode_tree
, hf_9P_dm_read_group
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2321 proto_tree_add_item(mode_tree
, hf_9P_dm_write_group
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2322 proto_tree_add_item(mode_tree
, hf_9P_dm_exec_group
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2323 proto_tree_add_item(mode_tree
, hf_9P_dm_read_others
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2324 proto_tree_add_item(mode_tree
, hf_9P_dm_write_others
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2325 proto_tree_add_item(mode_tree
, hf_9P_dm_exec_others
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2328 /* Dissect 9P getattr_flags */
2329 static void dissect_9P_getattrflags(tvbuff_t
*tvb
, proto_item
*item
, int offset
)
2331 proto_item
*attrmask_tree
;
2333 attrmask_tree
= proto_item_add_subtree(item
, ett_9P_getattr_flags
);
2337 /* fixme: This is actually 8 bytes (64bit) long, but masks have to fit on 32bit. */
2338 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_mode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2339 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_nlink
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2340 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2341 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2342 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_rdev
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2343 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_atime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2344 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_mtime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2345 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_ctime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2346 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_ino
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2347 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2348 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_blocks
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2349 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_btime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2350 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_gen
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2351 proto_tree_add_item(attrmask_tree
, hf_9P_getattr_dataversion
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2354 /* Dissect 9P setattr_flags */
2355 static void dissect_9P_setattrflags(tvbuff_t
*tvb
, proto_item
*item
, int offset
)
2357 proto_item
*attrmask_tree
;
2359 attrmask_tree
= proto_item_add_subtree(item
, ett_9P_setattr_flags
);
2363 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_mode
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2364 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_uid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2365 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_gid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2366 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2367 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_atime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2368 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_mtime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2369 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_ctime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2370 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_atime_set
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2371 proto_tree_add_item(attrmask_tree
, hf_9P_setattr_mtime_set
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2374 /* Dissect 9P lflags */
2375 static void dissect_9P_lflags(tvbuff_t
*tvb
, proto_item
*item
, int offset
)
2377 proto_item
*attrmask_tree
;
2379 attrmask_tree
= proto_item_add_subtree(item
, ett_9P_lflags
);
2383 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_rdonly
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2384 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_wronly
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2385 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_rdwr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2386 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_create
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2387 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_excl
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2388 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_noctty
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2389 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_trunc
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2390 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_append
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2391 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_nonblock
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2392 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_dsync
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2393 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_fasync
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2394 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_direct
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2395 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_largefile
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2396 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_directory
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2397 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_nofollow
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2398 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_noatime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2399 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_cloexec
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2400 proto_tree_add_item(attrmask_tree
, hf_9P_lflags_sync
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2404 /* Register 9P with Wireshark */
2405 void proto_register_9P(void)
2407 static hf_register_info hf
[] = {
2409 {"Msg length", "9p.msglen", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2410 "9P Message Length", HFILL
}},
2412 {"Msg Type", "9p.msgtype", FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &ninep_msg_type_ext
, 0x0,
2413 "Message Type", HFILL
}},
2415 {"Tag", "9p.tag", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2418 {"Old tag", "9p.oldtag", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2421 {"Param length", "9p.paramsz", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2422 "Parameter length", HFILL
}},
2424 {"Max msg size", "9p.maxsize", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2425 "Max message size", HFILL
}},
2427 {"Fid", "9p.fid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2430 {"Nr Qids", "9p.nqid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2431 "Number of Qid results", HFILL
}},
2433 {"Mode", "9p.mode", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2436 {"Open/Create Mode", "9p.mode.rwx", FT_UINT8
, BASE_OCT
| BASE_EXT_STRING
, &ninep_mode_vals_ext
, _9P_MODEMASK
,
2439 {"Trunc", "9p.mode.trunc", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), _9P_OTRUNC
,
2440 "Truncate", HFILL
}},
2442 {"Remove on close", "9p.mode.orclose", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), _9P_ORCLOSE
,
2445 {"Extension string", "9p.extension", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2446 "Link target for DSYMLINK mode, major+minor for DMDEVICE, empty for normal files", HFILL
}},
2448 {"I/O Unit", "9p.iounit", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2451 {"Count", "9p.count", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2454 {"Offset", "9p.offset", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2457 {"Permissions", "9p.perm", FT_UINT32
, BASE_OCT
, NULL
, 0x0,
2458 "Permission bits", HFILL
}},
2460 {"Qid path", "9p.qidpath", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2463 {"Directory", "9p.dm.dir", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x80000000,
2466 {"Append only", "9p.dm.append", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x40000000,
2468 {&hf_9P_dm_exclusive
,
2469 {"Exclusive use", "9p.dm.exclusive", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x20000000,
2472 {"Mounted channel", "9p.dm.mount", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x10000000,
2474 {&hf_9P_dm_auth_file
,
2475 {"Authentication file", "9p.dm.auth_file", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x08000000,
2477 {&hf_9P_dm_temp_file
,
2478 {"Temporary file (not backed up)", "9p.dm.temp_file", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x04000000,
2480 {&hf_9P_dm_read_owner
,
2481 {"Read permission for owner", "9p.dm.read_owner", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000100,
2483 {&hf_9P_dm_write_owner
,
2484 {"Write permission for owner", "9p.dm.write_owner", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000080,
2486 {&hf_9P_dm_exec_owner
,
2487 {"Execute permission for owner", "9p.dm.exec_owner", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000040,
2489 {&hf_9P_dm_read_group
,
2490 {"Read permission for group", "9p.dm.read_group", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000020,
2492 {&hf_9P_dm_write_group
,
2493 {"Write permission for group", "9p.dm.write_group", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000010,
2495 {&hf_9P_dm_exec_group
,
2496 {"Execute permission for group", "9p.dm.exec_group", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000008,
2498 {&hf_9P_dm_read_others
,
2499 {"Read permission for others", "9p.dm.read_others", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000004,
2501 {&hf_9P_dm_write_others
,
2502 {"Write permission for others", "9p.dm.write_others", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000002,
2504 {&hf_9P_dm_exec_others
,
2505 {"Execute permission for others", "9p.dm.exec_others", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000001,
2508 {"Qid version", "9p.qidvers", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2511 {"Qid type", "9p.qidtype", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2513 {&hf_9P_qidtype_dir
,
2514 {"Directory", "9p.qidtype.dir", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x80,
2516 {&hf_9P_qidtype_append
,
2517 {"Append only", "9p.qidtype.append", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x40,
2519 {&hf_9P_qidtype_exclusive
,
2520 {"Exclusive use", "9p.qidtype.exclusive", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
2522 {&hf_9P_qidtype_mount
,
2523 {"Mounted channel", "9p.qidtype.mount", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
2525 {&hf_9P_qidtype_auth_file
,
2526 {"Authentication file", "9p.qidtype.auth_file", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
2528 {&hf_9P_qidtype_temp_file
,
2529 {"Temporary file (not backed up)", "9p.qidtype.temp_file", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
2532 {"Mode", "9p.statmode", FT_UINT32
, BASE_OCT
, NULL
, 0x0,
2533 "File mode flags", HFILL
}},
2535 {"Type", "9p.stattype", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2538 {"Atime", "9p.atime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2539 "Access Time", HFILL
}},
2541 {"Mtime", "9p.mtime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2542 "Modified Time", HFILL
}},
2544 {"Ctime", "9p.ctime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2545 "Creation Time", HFILL
}},
2547 {"Btime", "9p.btime", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2548 "Btime (Synchronization information)", HFILL
}},
2550 {"Length", "9p.length", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2551 "File Length", HFILL
}},
2553 {"Dev", "9p.dev", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2556 {"Wname", "9p.wname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2557 "Path Name Element", HFILL
}},
2559 {"Version", "9p.version", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2562 {"Afid", "9p.afid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2563 "Authenticating FID", HFILL
}},
2565 {"Uname", "9p.uname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2566 "User Name", HFILL
}},
2568 {"Aname", "9p.aname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2569 "Access Name", HFILL
}},
2571 {"Ename", "9p.ename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2574 {"Enum", "9p.enum", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2578 {"Name", "9p.name", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2579 "Name of file", HFILL
}},
2582 {"Stat data length", "9p.sdlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2585 {"File name", "9p.filename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2588 {"User", "9p.user", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2589 "User name", HFILL
}},
2591 {"Group", "9p.group", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2592 "Group name", HFILL
}},
2594 {"Uid", "9p.uid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2597 {"Gid", "9p.gid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2598 "Group id", HFILL
}},
2600 {"Muid", "9p.muid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2601 "Last modifiers uid", HFILL
}},
2603 {"New fid", "9p.newfid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2604 "New file ID", HFILL
}},
2606 {"Directory fid", "9p.dfid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2607 "Directory ID", HFILL
}},
2609 {"Nr Walks", "9p.nwalk", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2610 "Nr of walk items", HFILL
}},
2612 {"nlink", "9p.nlink", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2613 "Number of links", HFILL
}},
2614 {&hf_9P_getattr_flags
,
2615 {"getattr_flags", "9p.getattr.flags", FT_UINT64
, BASE_HEX
, NULL
, _9P_GETATTR_ALL
,
2616 "Getattr flags", HFILL
}},
2617 {&hf_9P_getattr_mode
,
2618 {"Mode", "9p.getattr.mode", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_MODE
,
2620 {&hf_9P_getattr_nlink
,
2621 {"Nlink", "9p.getattr.nlink", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_NLINK
,
2623 {&hf_9P_getattr_uid
,
2624 {"UID", "9p.getattr.uid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_UID
,
2626 {&hf_9P_getattr_gid
,
2627 {"GID", "9p.getattr.gid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_GID
,
2629 {&hf_9P_getattr_rdev
,
2630 {"Rdev", "9p.getattr.rdev", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_RDEV
,
2632 {&hf_9P_getattr_atime
,
2633 {"Atime", "9p.getattr.atime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_ATIME
,
2635 {&hf_9P_getattr_mtime
,
2636 {"Mtime", "9p.getattr.mtime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_MTIME
,
2638 {&hf_9P_getattr_ctime
,
2639 {"Ctime", "9p.getattr.ctime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_CTIME
,
2641 {&hf_9P_getattr_ino
,
2642 {"Inode", "9p.getattr.inode", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_INO
,
2644 {&hf_9P_getattr_size
,
2645 {"Size", "9p.getattr.size", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_SIZE
,
2647 {&hf_9P_getattr_blocks
,
2648 {"Blocks", "9p.getattr.blocks", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_BLOCKS
,
2650 {&hf_9P_getattr_btime
,
2651 {"Btime", "9p.getattr.btime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_BTIME
,
2653 {&hf_9P_getattr_gen
,
2654 {"Gen", "9p.getattr.gen", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_GEN
,
2656 {&hf_9P_getattr_dataversion
,
2657 {"Data version", "9p.getattr.dataversion", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_GETATTR_DATA_VERSION
,
2659 {&hf_9P_setattr_flags
,
2660 {"setattr_flags", "9p.setattr.flags", FT_UINT32
, BASE_HEX
, NULL
, _9P_SETATTR_ALL
,
2661 "Setattr flags", HFILL
}},
2662 {&hf_9P_setattr_mode
,
2663 {"Mode", "9p.setattr.mode", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_MODE
,
2665 {&hf_9P_setattr_uid
,
2666 {"UID", "9p.setattr.uid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_UID
,
2668 {&hf_9P_setattr_gid
,
2669 {"GID", "9p.setattr.gid", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_GID
,
2671 {&hf_9P_setattr_size
,
2672 {"Size", "9p.setattr.size", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_SIZE
,
2674 {&hf_9P_setattr_atime
,
2675 {"Atime", "9p.setattr.atime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_ATIME
,
2677 {&hf_9P_setattr_mtime
,
2678 {"Mtime", "9p.setattr.mtime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_MTIME
,
2680 {&hf_9P_setattr_ctime
,
2681 {"Ctime", "9p.setattr.ctime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_CTIME
,
2683 {&hf_9P_setattr_atime_set
,
2684 {"Atime set", "9p.setattr.atimeset", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_ATIME_SET
,
2686 {&hf_9P_setattr_mtime_set
,
2687 {"Mtime set", "9p.setattr.mtimeset", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_SETATTR_MTIME_SET
,
2689 {&hf_9P_unlinkat_flags
,
2690 {"unlinkat flags", "9p.unlinkat.flags", FT_UINT32
, BASE_HEX
, NULL
, 0,
2693 {"rdev", "9p.rdev", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2694 "Device associated with file", HFILL
}},
2696 {"Size", "9p.size", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2699 {"Blksize", "9p.blksize", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2700 "Block size", HFILL
}},
2702 {"Blocks", "9p.blocks", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2705 {"Gen", "9p.gen", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2706 "inode generation number", HFILL
}},
2707 {&hf_9P_dataversion
,
2708 {"Dataversion", "9p.dataversion", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2709 "Data version", HFILL
}},
2711 {"fstype", "9p.fstype", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2712 "Filesystem type", HFILL
}},
2714 {"bfree", "9p.bfree", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2715 "Free blocks", HFILL
}},
2717 {"bavail", "9p.bavail", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2718 "Available blocks", HFILL
}},
2720 {"files", "9p.files", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2721 "Total files", HFILL
}},
2723 {"ffree", "9p.ffree", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2724 "Free files", HFILL
}},
2726 {"fsid", "9p.fsid", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2727 "Filesystem id", HFILL
}},
2729 {"namelen", "9p.namelen", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2730 "Max name length", HFILL
}},
2731 {&hf_9P_mknod_major
,
2732 {"mknod_major", "9p.mknod.major", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2733 "Major node number", HFILL
}},
2734 {&hf_9P_mknod_minor
,
2735 {"mknod_minor", "9p.mknod.minor", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2736 "Minor node number", HFILL
}},
2738 {"lflags", "9p.lcreate.flags", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2739 "Lcreate flags", HFILL
}},
2740 /* rdonly is 0x00, check instead that we are neither wronly nor rdwrite */
2741 {&hf_9P_lflags_rdonly
,
2742 {"Read only", "9p.lflags.rdonly", FT_BOOLEAN
, 32, TFS(&tfs_no_yes
), _9P_DOTL_WRONLY
|_9P_DOTL_RDWR
,
2744 {&hf_9P_lflags_wronly
,
2745 {"Write only", "9p.lflags.wronly", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_WRONLY
,
2747 {&hf_9P_lflags_rdwr
,
2748 {"Read Write", "9p.lflags.rdwr", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_RDWR
,
2750 {&hf_9P_lflags_create
,
2751 {"Create", "9p.lflags.create", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_CREATE
,
2753 {&hf_9P_lflags_excl
,
2754 {"Exclusive", "9p.lflags.excl", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_EXCL
,
2756 {&hf_9P_lflags_noctty
,
2757 {"noctty", "9p.lflags.noctty", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NOCTTY
,
2759 {&hf_9P_lflags_trunc
,
2760 {"Truncate", "9p.lflags.trunc", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_TRUNC
,
2762 {&hf_9P_lflags_append
,
2763 {"Append", "9p.lflags.append", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_APPEND
,
2765 {&hf_9P_lflags_nonblock
,
2766 {"Nonblock", "9p.lflags.nonblock", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NONBLOCK
,
2768 {&hf_9P_lflags_dsync
,
2769 {"dsync", "9p.lflags.dsync", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_DSYNC
,
2771 {&hf_9P_lflags_fasync
,
2772 {"fasync", "9p.lflags.fasync", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_FASYNC
,
2774 {&hf_9P_lflags_direct
,
2775 {"Direct", "9p.lflags.direct", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_DIRECT
,
2777 {&hf_9P_lflags_largefile
,
2778 {"Large File", "9p.lflags.largefile", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_LARGEFILE
,
2780 {&hf_9P_lflags_directory
,
2781 {"Directory", "9p.lflags.directory", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_DIRECTORY
,
2783 {&hf_9P_lflags_nofollow
,
2784 {"No follow", "9p.lflags.nofollow", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NOFOLLOW
,
2786 {&hf_9P_lflags_noatime
,
2787 {"No atime", "9p.lflags.noatime", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_NOATIME
,
2789 {&hf_9P_lflags_cloexec
,
2790 {"cloexec", "9p.lflags.cloexec", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_CLOEXEC
,
2792 {&hf_9P_lflags_sync
,
2793 {"Sync", "9p.lflags.sync", FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), _9P_DOTL_SYNC
,
2796 {"xattr_flag", "9p.xattr.flag", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2797 "Xattr flag", HFILL
}},
2799 {"lock_type", "9p.lock.type", FT_UINT32
, BASE_HEX
| BASE_EXT_STRING
, &ninep_lock_type_ext
, 0x0,
2800 "Lock type", HFILL
}},
2802 {"lock_flag", "9p.lock.flag", FT_UINT32
, BASE_HEX
| BASE_EXT_STRING
, &ninep_lock_flag_ext
, 0x0,
2803 "Lock flag", HFILL
}},
2805 {"lock_start", "9p.lock.start", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2806 "Lock start", HFILL
}},
2807 {&hf_9P_lock_length
,
2808 {"lock_length", "9p.lock.length", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2809 "Lock length", HFILL
}},
2810 {&hf_9P_lock_procid
,
2811 {"lock_procid", "9p.lock.procid", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2812 "Lock procid", HFILL
}},
2813 {&hf_9P_lock_status
,
2814 {"lock_status", "9p.lock.status", FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &ninep_lock_status_ext
, 0x0,
2815 "Lock status", HFILL
}},
2816 {&hf_9P_unknown_message
,
2817 {"Message data", "9p.message_data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2821 static int *ett
[] = {
2836 &ett_9P_getattr_flags
,
2837 &ett_9P_setattr_flags
,
2841 expert_module_t
* expert_9P
;
2843 static ei_register_info ei
[] = {
2844 { &ei_9P_first_250
, { "9p.first_250", PI_PROTOCOL
, PI_NOTE
, "Only first 250 items shown", EXPFILL
}},
2845 { &ei_9P_msgtype
, { "9p.msgtype.unknown", PI_PROTOCOL
, PI_WARN
, "This message type should not happen", EXPFILL
}},
2848 proto_9P
= proto_register_protocol("Plan 9", "9P", "9p");
2850 proto_register_field_array(proto_9P
, hf
, array_length(hf
));
2851 proto_register_subtree_array(ett
, array_length(ett
));
2852 expert_9P
= expert_register_protocol(proto_9P
);
2853 expert_register_field_array(expert_9P
, ei
, array_length(ei
));
2855 _9p_hashtable
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), _9p_hash_hash
, _9p_hash_equal
);
2857 ninep_handle
= register_dissector("9p", dissect_9P
, proto_9P
);
2860 void proto_reg_handoff_9P(void)
2862 dissector_add_uint_with_preference("tcp.port", NINEPORT
, ninep_handle
);
2867 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2872 * indent-tabs-mode: t
2875 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2876 * :indentSize=8:tabSize=8:noTabs=false: