2 * Routines for mount dissection
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Copied from packet-smb.c
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/exceptions.h>
32 #include <epan/to_str.h>
33 #include "packet-rpc.h"
34 #include "packet-mount.h"
35 #include "packet-nfs.h"
39 static int proto_mount
= -1;
40 static int proto_sgi_mount
= -1;
41 static int hf_mount_procedure_v1
= -1;
42 static int hf_mount_procedure_v2
= -1;
43 static int hf_mount_procedure_v3
= -1;
44 static int hf_sgi_mount_procedure_v1
= -1;
45 static int hf_mount_path
= -1;
46 static int hf_mount3_status
= -1;
47 static int hf_mount_mountlist_hostname
= -1;
48 static int hf_mount_mountlist_directory
= -1;
49 static int hf_mount_mountlist
= -1;
50 static int hf_mount_groups_group
= -1;
51 static int hf_mount_groups
= -1;
52 static int hf_mount_exportlist_directory
= -1;
53 static int hf_mount_exportlist
= -1;
54 static int hf_mount_has_options
= -1;
55 static int hf_mount_options
= -1;
56 static int hf_mount_pathconf_link_max
= -1;
57 static int hf_mount_pathconf_max_canon
= -1;
58 static int hf_mount_pathconf_max_input
= -1;
59 static int hf_mount_pathconf_name_max
= -1;
60 static int hf_mount_pathconf_path_max
= -1;
61 static int hf_mount_pathconf_pipe_buf
= -1;
62 static int hf_mount_pathconf_vdisable
= -1;
63 static int hf_mount_pathconf_mask
= -1;
64 static int hf_mount_pathconf_error_all
= -1;
65 static int hf_mount_pathconf_error_link_max
= -1;
66 static int hf_mount_pathconf_error_max_canon
= -1;
67 static int hf_mount_pathconf_error_max_input
= -1;
68 static int hf_mount_pathconf_error_name_max
= -1;
69 static int hf_mount_pathconf_error_path_max
= -1;
70 static int hf_mount_pathconf_error_pipe_buf
= -1;
71 static int hf_mount_pathconf_chown_restricted
= -1;
72 static int hf_mount_pathconf_no_trunc
= -1;
73 static int hf_mount_pathconf_error_vdisable
= -1;
74 static int hf_mount_statvfs_bsize
= -1;
75 static int hf_mount_statvfs_frsize
= -1;
76 static int hf_mount_statvfs_blocks
= -1;
77 static int hf_mount_statvfs_bfree
= -1;
78 static int hf_mount_statvfs_bavail
= -1;
79 static int hf_mount_statvfs_files
= -1;
80 static int hf_mount_statvfs_ffree
= -1;
81 static int hf_mount_statvfs_favail
= -1;
82 static int hf_mount_statvfs_fsid
= -1;
83 static int hf_mount_statvfs_basetype
= -1;
84 static int hf_mount_statvfs_flag
= -1;
85 static int hf_mount_statvfs_flag_rdonly
= -1;
86 static int hf_mount_statvfs_flag_nosuid
= -1;
87 static int hf_mount_statvfs_flag_notrunc
= -1;
88 static int hf_mount_statvfs_flag_nodev
= -1;
89 static int hf_mount_statvfs_flag_grpid
= -1;
90 static int hf_mount_statvfs_flag_local
= -1;
91 static int hf_mount_statvfs_namemax
= -1;
92 static int hf_mount_statvfs_fstr
= -1;
93 static int hf_mount_flavors
= -1;
94 static int hf_mount_flavor
= -1;
96 static gint ett_mount
= -1;
97 static gint ett_mount_mountlist
= -1;
98 static gint ett_mount_groups
= -1;
99 static gint ett_mount_exportlist
= -1;
100 static gint ett_mount_pathconf_mask
= -1;
101 static gint ett_mount_statvfs_flag
= -1;
103 #define MAX_GROUP_NAME_LIST 128
104 static char group_name_list
[MAX_GROUP_NAME_LIST
];
105 static int group_names_len
;
107 /* RFC 1813, Page 107 */
108 static const value_string mount3_mountstat3
[] =
114 { 13, "ERR_ACCESS" },
115 { 20, "ERR_NOTDIR" },
117 { 63, "ERR_NAMETOOLONG" },
118 { 10004, "ERR_NOTSUPP" },
119 { 10006, "ERR_SERVERFAULT" },
124 /* RFC 1094, Page 24 */
125 /* This function dissects fhstatus for v1 and v2 of the mount protocol.
126 * Formally, hf_mount3_status only define the status codes returned by version
128 * Though not formally defined in the standard, we use the same
129 * value-to-string mappings as version 3 since we belive that this mapping
130 * is consistant with most v1 and v2 implementations.
133 dissect_fhstatus(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, rpc_call_info_value
* civ
)
137 status
=tvb_get_ntohl(tvb
,offset
);
138 offset
= dissect_rpc_uint32(tvb
,tree
,hf_mount3_status
,offset
);
142 offset
= dissect_fhandle(tvb
,offset
,pinfo
,tree
,"fhandle", NULL
, civ
);
147 pinfo
->cinfo
, COL_INFO
, " Error:%s",
148 val_to_str(status
, mount3_mountstat3
,
149 "Unknown (0x%08X)"));
158 dissect_mount_dirpath_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
159 proto_tree
*tree
, void* data
)
161 const char *mountpoint
=NULL
;
163 if((!pinfo
->fd
->flags
.visited
) && nfs_file_name_snooping
){
164 rpc_call_info_value
*civ
=(rpc_call_info_value
*)data
;
166 if(civ
->request
&& (civ
->proc
==1)){
172 host
=ip_to_str((guint8
*)pinfo
->dst
.data
);
173 len
=tvb_get_ntohl(tvb
, offset
);
174 if (len
>= ITEM_LABEL_LENGTH
)
175 THROW(ReportedBoundsError
);
177 name
=(unsigned char *)g_malloc(strlen(host
)+1+len
+1+200);
179 memcpy(ptr
, host
, strlen(host
));
182 tvb_memcpy(tvb
, ptr
, offset
+4, len
);
186 nfs_name_snoop_add_name(civ
->xid
, tvb
, -1, (gint
)strlen(name
), 0, 0, name
);
190 offset
= dissect_rpc_string(tvb
,tree
,hf_mount_path
,offset
,&mountpoint
);
191 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s", mountpoint
);
197 /* RFC 1094, Page 25,26 */
199 dissect_mount1_mnt_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
201 offset
= dissect_fhstatus(tvb
,offset
,pinfo
,tree
,(rpc_call_info_value
*)data
);
208 /* RFC 1094, Page 26 */
209 /* RFC 1813, Page 110 */
211 dissect_mountlist(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
213 proto_item
* lock_item
= NULL
;
214 proto_tree
* lock_tree
= NULL
;
215 int old_offset
= offset
;
216 const char* hostname
;
217 const char* directory
;
220 lock_item
= proto_tree_add_item(tree
, hf_mount_mountlist
, tvb
,
223 lock_tree
= proto_item_add_subtree(lock_item
, ett_mount_mountlist
);
226 offset
= dissect_rpc_string(tvb
, lock_tree
,
227 hf_mount_mountlist_hostname
, offset
, &hostname
);
228 offset
= dissect_rpc_string(tvb
, lock_tree
,
229 hf_mount_mountlist_directory
, offset
, &directory
);
232 /* now we have a nicer string */
233 proto_item_set_text(lock_item
, "Mount List Entry: %s:%s", hostname
, directory
);
234 /* now we know, that mountlist is shorter */
235 proto_item_set_len(lock_item
, offset
- old_offset
);
242 /* RFC 1094, Page 26 */
243 /* RFC 1813, Page 110 */
245 dissect_mount_dump_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
247 offset
= dissect_rpc_list(tvb
, pinfo
, tree
, offset
, dissect_mountlist
);
254 /* RFC 1094, Page 26 */
255 /* RFC 1813, Page 110 */
257 dissect_group(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
261 if (group_names_len
< MAX_GROUP_NAME_LIST
- 5) {
262 str_len
=tvb_get_nstringz(tvb
,offset
+4,
263 MAX_GROUP_NAME_LIST
-5-group_names_len
,
264 group_name_list
+group_names_len
);
265 if((group_names_len
>=(MAX_GROUP_NAME_LIST
-5))||(str_len
<0)){
266 g_snprintf(group_name_list
+(MAX_GROUP_NAME_LIST
-5), 5, "...");
267 group_names_len
=MAX_GROUP_NAME_LIST
- 1;
269 group_names_len
+=str_len
;
270 group_name_list
[group_names_len
++]=' ';
272 group_name_list
[group_names_len
]=0;
275 offset
= dissect_rpc_string(tvb
, tree
,
276 hf_mount_groups_group
, offset
, NULL
);
282 /* RFC 1094, Page 26 */
283 /* RFC 1813, Page 113 */
285 dissect_exportlist(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
287 proto_item
* exportlist_item
= NULL
;
288 proto_tree
* exportlist_tree
= NULL
;
289 int old_offset
= offset
;
291 proto_item
* groups_item
= NULL
;
292 proto_item
* groups_tree
= NULL
;
293 const char* directory
;
295 group_name_list
[0]=0;
298 exportlist_item
= proto_tree_add_item(tree
, hf_mount_exportlist
, tvb
, offset
, -1, ENC_NA
);
299 exportlist_tree
= proto_item_add_subtree(exportlist_item
, ett_mount_exportlist
);
302 offset
= dissect_rpc_string(tvb
, exportlist_tree
,
303 hf_mount_exportlist_directory
, offset
, &directory
);
304 groups_offset
= offset
;
307 groups_item
= proto_tree_add_item(exportlist_tree
, hf_mount_groups
, tvb
,
310 groups_tree
= proto_item_add_subtree(groups_item
, ett_mount_groups
);
313 offset
= dissect_rpc_list(tvb
, pinfo
, groups_tree
, offset
, dissect_group
);
315 /* mark empty lists */
316 if (offset
- groups_offset
== 4) {
317 proto_item_set_text(groups_item
, "Groups: empty");
320 /* now we know, that groups is shorter */
321 proto_item_set_len(groups_item
, offset
- groups_offset
);
324 if (exportlist_item
) {
325 /* now we have a nicer string */
326 proto_item_set_text(exportlist_item
, "Export List Entry: %s -> %s", directory
,group_name_list
);
327 /* now we know, that exportlist is shorter */
328 proto_item_set_len(exportlist_item
, offset
- old_offset
);
335 /* RFC 1094, Page 26 */
336 /* RFC 1813, Page 113 */
338 dissect_mount_export_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
340 offset
= dissect_rpc_list(tvb
, pinfo
, tree
, offset
, dissect_exportlist
);
346 #define OFFS_MASK 32 /* offset of the "pc_mask" field */
348 #define PC_ERROR_ALL 0x0001
349 #define PC_ERROR_LINK_MAX 0x0002
350 #define PC_ERROR_MAX_CANON 0x0004
351 #define PC_ERROR_MAX_INPUT 0x0008
352 #define PC_ERROR_NAME_MAX 0x0010
353 #define PC_ERROR_PATH_MAX 0x0020
354 #define PC_ERROR_PIPE_BUF 0x0040
355 #define PC_CHOWN_RESTRICTED 0x0080
356 #define PC_NO_TRUNC 0x0100
357 #define PC_ERROR_VDISABLE 0x0200
359 static const true_false_string tos_error_all
= {
361 "Some or all info valid"
364 static const true_false_string tos_error_link_max
= {
369 static const true_false_string tos_error_max_canon
= {
374 static const true_false_string tos_error_max_input
= {
379 static const true_false_string tos_error_name_max
= {
384 static const true_false_string tos_error_path_max
= {
389 static const true_false_string tos_error_pipe_buf
= {
394 static const true_false_string tos_chown_restricted
= {
395 "Only a privileged user can change the ownership of a file",
396 "Users may give away their own files"
399 static const true_false_string tos_no_trunc
= {
400 "File names that are too long will get an error",
401 "File names that are too long will be truncated"
404 static const true_false_string tos_error_vdisable
= {
411 dissect_mount_pathconf_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
414 proto_item
*lock_item
;
415 proto_tree
*lock_tree
;
418 * Extract the mask first, so we know which other fields the
419 * server was able to return to us.
421 pc_mask
= tvb_get_ntohl(tvb
, offset
+OFFS_MASK
) & 0xffff;
422 if (!(pc_mask
& (PC_ERROR_LINK_MAX
|PC_ERROR_ALL
))) {
424 dissect_rpc_uint32(tvb
,tree
,hf_mount_pathconf_link_max
,offset
);
429 if (!(pc_mask
& (PC_ERROR_MAX_CANON
|PC_ERROR_ALL
))) {
431 proto_tree_add_item(tree
,
432 hf_mount_pathconf_max_canon
,tvb
,offset
+2,2,
433 tvb_get_ntohs(tvb
,offset
)&0xffff);
438 if (!(pc_mask
& (PC_ERROR_MAX_INPUT
|PC_ERROR_ALL
))) {
440 proto_tree_add_item(tree
,
441 hf_mount_pathconf_max_input
,tvb
,offset
+2,2,
442 tvb_get_ntohs(tvb
,offset
)&0xffff);
447 if (!(pc_mask
& (PC_ERROR_NAME_MAX
|PC_ERROR_ALL
))) {
449 proto_tree_add_item(tree
,
450 hf_mount_pathconf_name_max
,tvb
,offset
+2,2,
451 tvb_get_ntohs(tvb
,offset
)&0xffff);
456 if (!(pc_mask
& (PC_ERROR_PATH_MAX
|PC_ERROR_ALL
))) {
458 proto_tree_add_item(tree
,
459 hf_mount_pathconf_path_max
,tvb
,offset
+2,2,
460 tvb_get_ntohs(tvb
,offset
)&0xffff);
465 if (!(pc_mask
& (PC_ERROR_PIPE_BUF
|PC_ERROR_ALL
))) {
467 proto_tree_add_item(tree
,
468 hf_mount_pathconf_pipe_buf
,tvb
,offset
+2,2,
469 tvb_get_ntohs(tvb
,offset
)&0xffff);
474 offset
+= 4; /* skip "pc_xxx" pad field */
476 if (!(pc_mask
& (PC_ERROR_VDISABLE
|PC_ERROR_ALL
))) {
478 proto_tree_add_item(tree
,
479 hf_mount_pathconf_vdisable
,tvb
,offset
+3,1,
480 tvb_get_ntohs(tvb
,offset
)&0xffff);
487 lock_item
= proto_tree_add_item(tree
, hf_mount_pathconf_mask
, tvb
,
488 offset
+2, 2, ENC_BIG_ENDIAN
);
490 lock_tree
= proto_item_add_subtree(lock_item
, ett_mount_pathconf_mask
);
491 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_all
, tvb
,
492 offset
+ 2, 2, pc_mask
);
494 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_link_max
, tvb
,
495 offset
+ 2, 2, pc_mask
);
496 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_max_canon
, tvb
,
497 offset
+ 2, 2, pc_mask
);
498 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_max_input
, tvb
,
499 offset
+ 2, 2, pc_mask
);
500 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_name_max
, tvb
,
501 offset
+ 2, 2, pc_mask
);
502 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_path_max
, tvb
,
503 offset
+ 2, 2, pc_mask
);
504 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_pipe_buf
, tvb
,
505 offset
+ 2, 2, pc_mask
);
506 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_chown_restricted
, tvb
,
507 offset
+ 2, 2, pc_mask
);
508 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_no_trunc
, tvb
,
509 offset
+ 2, 2, pc_mask
);
510 proto_tree_add_boolean(lock_tree
, hf_mount_pathconf_error_vdisable
, tvb
,
511 offset
+ 2, 2, pc_mask
);
519 /* RFC 1813, Page 107 */
521 dissect_mountstat3(packet_info
*pinfo
, tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, int hfindex
, guint32
*status
)
525 mountstat3
= tvb_get_ntohl(tvb
, offset
);
528 pinfo
->cinfo
, COL_INFO
, " Error:%s",
529 val_to_str(mountstat3
, mount3_mountstat3
,
530 "Unknown (0x%08X)"));
533 offset
= dissect_rpc_uint32(tvb
,tree
,hfindex
,offset
);
534 *status
= mountstat3
;
538 /* RFC 1831, Page 109 */
540 dissect_mount3_mnt_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
543 guint32 auth_flavors
;
545 guint32 auth_flavor_i
;
547 offset
= dissect_mountstat3(pinfo
,tvb
,tree
,offset
,hf_mount3_status
,&status
);
551 offset
= dissect_nfs3_fh(tvb
,offset
,pinfo
,tree
,"fhandle",NULL
,(rpc_call_info_value
*)data
);
553 auth_flavors
= tvb_get_ntohl(tvb
, offset
);
554 proto_tree_add_uint(tree
,hf_mount_flavors
, tvb
,
555 offset
, 4, auth_flavors
);
557 for (auth_flavor_i
= 0 ; auth_flavor_i
< auth_flavors
; auth_flavor_i
++) {
558 auth_flavor
= tvb_get_ntohl(tvb
, offset
);
559 proto_tree_add_uint(tree
,hf_mount_flavor
, tvb
,
560 offset
, 4, auth_flavor
);
573 dissect_sgi_exportlist(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
575 proto_item
* exportlist_item
= NULL
;
576 proto_tree
* exportlist_tree
= NULL
;
577 int old_offset
= offset
;
578 const char* directory
, *options
;
581 exportlist_item
= proto_tree_add_item(tree
, hf_mount_exportlist
,
582 tvb
, offset
, -1, ENC_NA
);
584 exportlist_tree
= proto_item_add_subtree(exportlist_item
,
585 ett_mount_exportlist
);
588 offset
= dissect_rpc_string(tvb
, exportlist_tree
,
589 hf_mount_exportlist_directory
, offset
, &directory
);
591 offset
= dissect_rpc_bool(tvb
, exportlist_tree
,
592 hf_mount_has_options
, offset
);
594 offset
= dissect_rpc_string(tvb
, exportlist_tree
, hf_mount_options
,
597 if (exportlist_item
) {
598 /* now we have a nicer string */
599 proto_item_set_text(exportlist_item
,
600 "Export List Entry: %s %s", directory
,
602 /* now we know, that exportlist is shorter */
603 proto_item_set_len(exportlist_item
, offset
- old_offset
);
610 dissect_mount_exportlist_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
612 offset
= dissect_rpc_list(tvb
, pinfo
, tree
, offset
, dissect_sgi_exportlist
);
617 #define ST_RDONLY 0x00000001
618 #define ST_NOSUID 0x00000002
619 #define ST_NOTRUNC 0x00000004
620 #define ST_NODEV 0x20000000
621 #define ST_GRPID 0x40000000
622 #define ST_LOCAL 0x80000000
624 static const true_false_string tos_st_rdonly
= {
625 "Read-only file system",
626 "Read/Write file system"
629 static const true_false_string tos_st_nosuid
= {
630 "Does not support setuid/setgid semantics",
631 "Supports setuid/setgid semantics"
634 static const true_false_string tos_st_notrunc
= {
635 "Does not truncate filenames longer than NAME_MAX",
636 "Truncates filenames longer than NAME_MAX"
639 static const true_false_string tos_st_nodev
= {
640 "Disallows opening of device files",
641 "Allows opening of device files"
644 static const true_false_string tos_st_grpid
= {
645 "Group ID assigned from directory",
646 "Group ID not assigned from directory"
649 static const true_false_string tos_st_local
= {
650 "File system is local",
651 "File system is not local"
655 dissect_mount_statvfs_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
657 proto_item
*flag_item
;
658 proto_tree
*flag_tree
;
659 guint32 statvfs_flags
;
661 statvfs_flags
= tvb_get_ntohl(tvb
, offset
+52);
663 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_bsize
, offset
);
667 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_frsize
, offset
);
671 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_blocks
, offset
);
675 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_bfree
, offset
);
679 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_bavail
, offset
);
683 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_files
, offset
);
687 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_ffree
, offset
);
691 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_favail
, offset
);
695 dissect_rpc_bytes(tvb
, tree
, hf_mount_statvfs_basetype
, offset
,
700 dissect_rpc_bytes(tvb
, tree
, hf_mount_statvfs_fstr
, offset
,
705 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_fsid
, offset
);
710 flag_item
= proto_tree_add_item(tree
, hf_mount_statvfs_flag
,
711 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
713 flag_tree
= proto_item_add_subtree(flag_item
,
714 ett_mount_statvfs_flag
);
715 proto_tree_add_boolean(flag_tree
,
716 hf_mount_statvfs_flag_rdonly
, tvb
, offset
, 4,
718 proto_tree_add_boolean(flag_tree
,
719 hf_mount_statvfs_flag_nosuid
, tvb
, offset
, 4,
721 proto_tree_add_boolean(flag_tree
,
722 hf_mount_statvfs_flag_notrunc
, tvb
, offset
, 4,
724 proto_tree_add_boolean(flag_tree
,
725 hf_mount_statvfs_flag_nodev
, tvb
, offset
, 4,
727 proto_tree_add_boolean(flag_tree
,
728 hf_mount_statvfs_flag_grpid
, tvb
, offset
, 4,
730 proto_tree_add_boolean(flag_tree
,
731 hf_mount_statvfs_flag_local
, tvb
, offset
, 4,
738 dissect_rpc_uint32(tvb
, tree
, hf_mount_statvfs_namemax
, offset
);
745 /* proc number, "proc name", dissect_request, dissect_reply */
746 /* NULL as function pointer means: type of arguments is "void". */
748 /* Mount protocol version 1, RFC 1094 */
749 static const vsff mount1_proc
[] = {
750 { 0, "NULL", NULL
, NULL
},
751 { MOUNTPROC_MNT
, "MNT",
752 dissect_mount_dirpath_call
, dissect_mount1_mnt_reply
},
753 { MOUNTPROC_DUMP
, "DUMP",
754 NULL
, dissect_mount_dump_reply
},
755 { MOUNTPROC_UMNT
, "UMNT",
756 dissect_mount_dirpath_call
, NULL
},
757 { MOUNTPROC_UMNTALL
, "UMNTALL",
759 { MOUNTPROC_EXPORT
, "EXPORT",
760 NULL
, dissect_mount_export_reply
},
761 { MOUNTPROC_EXPORTALL
, "EXPORTALL",
762 NULL
, dissect_mount_export_reply
},
763 { 0, NULL
, NULL
, NULL
}
765 static const value_string mount1_proc_vals
[] = {
767 { MOUNTPROC_MNT
, "MNT" },
768 { MOUNTPROC_DUMP
, "DUMP" },
769 { MOUNTPROC_UMNT
, "UMNT" },
770 { MOUNTPROC_UMNTALL
, "UMNTALL" },
771 { MOUNTPROC_EXPORT
, "EXPORT" },
772 { MOUNTPROC_EXPORTALL
, "EXPORTALL" },
775 /* end of mount version 1 */
778 /* Mount protocol version 2, private communication from somebody at Sun;
779 mount V2 is V1 plus MOUNTPROC_PATHCONF to fetch information for the
780 POSIX "pathconf()" call. */
781 static const vsff mount2_proc
[] = {
782 { 0, "NULL", NULL
, NULL
},
783 { MOUNTPROC_MNT
, "MNT",
784 dissect_mount_dirpath_call
, dissect_mount1_mnt_reply
},
785 { MOUNTPROC_DUMP
, "DUMP",
786 NULL
, dissect_mount_dump_reply
},
787 { MOUNTPROC_UMNT
, "UMNT",
788 dissect_mount_dirpath_call
, NULL
},
789 { MOUNTPROC_UMNTALL
, "UMNTALL",
791 { MOUNTPROC_EXPORT
, "EXPORT",
792 NULL
, dissect_mount_export_reply
},
793 { MOUNTPROC_EXPORTALL
, "EXPORTALL",
794 NULL
, dissect_mount_export_reply
},
795 { MOUNTPROC_PATHCONF
, "PATHCONF",
796 dissect_mount_dirpath_call
, dissect_mount_pathconf_reply
},
797 { 0, NULL
, NULL
, NULL
}
799 static const value_string mount2_proc_vals
[] = {
801 { MOUNTPROC_MNT
, "MNT" },
802 { MOUNTPROC_DUMP
, "DUMP" },
803 { MOUNTPROC_UMNT
, "UMNT" },
804 { MOUNTPROC_UMNTALL
, "UMNTALL" },
805 { MOUNTPROC_EXPORT
, "EXPORT" },
806 { MOUNTPROC_EXPORTALL
, "EXPORTALL" },
807 { MOUNTPROC_PATHCONF
, "PATHCONF" },
810 /* end of mount version 2 */
813 /* Mount protocol version 3, RFC 1813 */
814 static const vsff mount3_proc
[] = {
815 { 0, "NULL", NULL
, NULL
},
816 { MOUNTPROC_MNT
, "MNT",
817 dissect_mount_dirpath_call
, dissect_mount3_mnt_reply
},
818 { MOUNTPROC_DUMP
, "DUMP",
819 NULL
, dissect_mount_dump_reply
},
820 { MOUNTPROC_UMNT
, "UMNT",
821 dissect_mount_dirpath_call
, NULL
},
822 { MOUNTPROC_UMNTALL
, "UMNTALL",
824 { MOUNTPROC_EXPORT
, "EXPORT",
825 NULL
, dissect_mount_export_reply
},
826 { 0, NULL
, NULL
, NULL
}
828 static const value_string mount3_proc_vals
[] = {
830 { MOUNTPROC_MNT
, "MNT" },
831 { MOUNTPROC_DUMP
, "DUMP" },
832 { MOUNTPROC_UMNT
, "UMNT" },
833 { MOUNTPROC_UMNTALL
, "UMNTALL" },
834 { MOUNTPROC_EXPORT
, "EXPORT" },
837 /* end of Mount protocol version 3 */
839 /* SGI mount protocol version 1; actually the same as v1 plus
840 MOUNTPROC_EXPORTLIST and MOUNTPROC_STATVFS */
842 static const vsff sgi_mount1_proc
[] = {
843 { 0, "NULL", NULL
, NULL
},
844 { MOUNTPROC_MNT
, "MNT",
845 dissect_mount_dirpath_call
, dissect_mount1_mnt_reply
},
846 { MOUNTPROC_DUMP
, "DUMP",
847 NULL
, dissect_mount_dump_reply
},
848 { MOUNTPROC_UMNT
, "UMNT",
849 dissect_mount_dirpath_call
, NULL
},
850 { MOUNTPROC_UMNTALL
, "UMNTALL",
852 { MOUNTPROC_EXPORT
, "EXPORT",
853 NULL
, dissect_mount_export_reply
},
854 { MOUNTPROC_EXPORTALL
, "EXPORTALL",
855 NULL
, dissect_mount_export_reply
},
856 { MOUNTPROC_EXPORTLIST
,"EXPORTLIST",
857 NULL
, dissect_mount_exportlist_reply
},
858 { MOUNTPROC_STATVFS
, "STATVFS",
859 dissect_mount_dirpath_call
, dissect_mount_statvfs_reply
},
860 { 0, NULL
, NULL
, NULL
}
862 static const value_string sgi_mount1_proc_vals
[] = {
864 { MOUNTPROC_MNT
, "MNT" },
865 { MOUNTPROC_DUMP
, "DUMP" },
866 { MOUNTPROC_UMNT
, "UMNT" },
867 { MOUNTPROC_UMNTALL
, "UMNTALL" },
868 { MOUNTPROC_EXPORT
, "EXPORT" },
869 { MOUNTPROC_EXPORTALL
, "EXPORTALL" },
870 { MOUNTPROC_EXPORTLIST
, "EXPORTLIST" },
871 { MOUNTPROC_STATVFS
, "STATVFS" },
874 /* end of SGI mount protocol version 1 */
877 proto_register_mount(void)
879 static hf_register_info hf
[] = {
880 { &hf_mount_procedure_v1
, {
881 "V1 Procedure", "mount.procedure_v1", FT_UINT32
, BASE_DEC
,
882 VALS(mount1_proc_vals
), 0, NULL
, HFILL
}},
883 { &hf_mount_procedure_v2
, {
884 "V2 Procedure", "mount.procedure_v2", FT_UINT32
, BASE_DEC
,
885 VALS(mount2_proc_vals
), 0, NULL
, HFILL
}},
886 { &hf_mount_procedure_v3
, {
887 "V3 Procedure", "mount.procedure_v3", FT_UINT32
, BASE_DEC
,
888 VALS(mount3_proc_vals
), 0, NULL
, HFILL
}},
889 { &hf_sgi_mount_procedure_v1
, {
890 "SGI V1 procedure", "mount.procedure_sgi_v1", FT_UINT32
, BASE_DEC
,
891 VALS(sgi_mount1_proc_vals
), 0, NULL
, HFILL
}},
893 "Path", "mount.path", FT_STRING
, BASE_NONE
,
894 NULL
, 0, NULL
, HFILL
}},
895 { &hf_mount3_status
, {
896 "Status", "mount.status", FT_UINT32
, BASE_DEC
,
897 VALS(mount3_mountstat3
), 0, NULL
, HFILL
}},
898 { &hf_mount_mountlist_hostname
, {
899 "Hostname", "mount.dump.hostname", FT_STRING
, BASE_NONE
,
900 NULL
, 0, NULL
, HFILL
}},
901 { &hf_mount_mountlist_directory
, {
902 "Directory", "mount.dump.directory", FT_STRING
, BASE_NONE
,
903 NULL
, 0, NULL
, HFILL
}},
904 { &hf_mount_mountlist
, {
905 "Mount List Entry", "mount.dump.entry", FT_NONE
, BASE_NONE
,
906 NULL
, 0, NULL
, HFILL
}},
907 { &hf_mount_groups_group
, {
908 "Group", "mount.export.group", FT_STRING
, BASE_NONE
,
909 NULL
, 0, NULL
, HFILL
}},
910 { &hf_mount_groups
, {
911 "Groups", "mount.export.groups", FT_NONE
, BASE_NONE
,
912 NULL
, 0, NULL
, HFILL
}},
913 { &hf_mount_has_options
, {
914 "Has options", "mount.export.has_options", FT_UINT32
,
915 BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
916 { &hf_mount_options
, {
917 "Options", "mount.export.options", FT_STRING
, BASE_NONE
,
918 NULL
, 0, NULL
, HFILL
}},
919 { &hf_mount_exportlist_directory
, {
920 "Directory", "mount.export.directory", FT_STRING
, BASE_NONE
,
921 NULL
, 0, NULL
, HFILL
}},
922 { &hf_mount_exportlist
, {
923 "Export List Entry", "mount.export.entry", FT_NONE
, BASE_NONE
,
924 NULL
, 0, NULL
, HFILL
}},
925 { &hf_mount_pathconf_link_max
, {
926 "Maximum number of links to a file", "mount.pathconf.link_max",
928 NULL
, 0, "Maximum number of links allowed to a file", HFILL
}},
929 { &hf_mount_pathconf_max_canon
, {
930 "Maximum terminal input line length", "mount.pathconf.max_canon",
932 NULL
, 0, "Max tty input line length", HFILL
}},
933 { &hf_mount_pathconf_max_input
, {
934 "Terminal input buffer size", "mount.pathconf.max_input",
936 NULL
, 0, NULL
, HFILL
}},
937 { &hf_mount_pathconf_name_max
, {
938 "Maximum file name length", "mount.pathconf.name_max",
940 NULL
, 0, NULL
, HFILL
}},
941 { &hf_mount_pathconf_path_max
, {
942 "Maximum path name length", "mount.pathconf.path_max",
944 NULL
, 0, NULL
, HFILL
}},
945 { &hf_mount_pathconf_pipe_buf
, {
946 "Pipe buffer size", "mount.pathconf.pipe_buf",
948 NULL
, 0, "Maximum amount of data that can be written atomically to a pipe", HFILL
}},
949 { &hf_mount_pathconf_vdisable
, {
950 "VDISABLE character", "mount.pathconf.vdisable_char",
952 NULL
, 0, "Character value to disable a terminal special character", HFILL
}},
953 { &hf_mount_pathconf_mask
, {
954 "Reply error/status bits", "mount.pathconf.mask",
956 NULL
, 0, "Bit mask with error and status bits", HFILL
}},
957 { &hf_mount_pathconf_error_all
, {
958 "ERROR_ALL", "mount.pathconf.mask.error_all",
959 FT_BOOLEAN
, 16, TFS(&tos_error_all
),
960 PC_ERROR_ALL
, NULL
, HFILL
}},
961 { &hf_mount_pathconf_error_link_max
, {
962 "ERROR_LINK_MAX", "mount.pathconf.mask.error_link_max",
963 FT_BOOLEAN
, 16, TFS(&tos_error_link_max
),
964 PC_ERROR_LINK_MAX
, NULL
, HFILL
}},
965 { &hf_mount_pathconf_error_max_canon
, {
966 "ERROR_MAX_CANON", "mount.pathconf.mask.error_max_canon",
967 FT_BOOLEAN
, 16, TFS(&tos_error_max_canon
),
968 PC_ERROR_MAX_CANON
, NULL
, HFILL
}},
969 { &hf_mount_pathconf_error_max_input
, {
970 "ERROR_MAX_INPUT", "mount.pathconf.mask.error_max_input",
971 FT_BOOLEAN
, 16, TFS(&tos_error_max_input
),
972 PC_ERROR_MAX_INPUT
, NULL
, HFILL
}},
973 { &hf_mount_pathconf_error_name_max
, {
974 "ERROR_NAME_MAX", "mount.pathconf.mask.error_name_max",
975 FT_BOOLEAN
, 16, TFS(&tos_error_name_max
),
976 PC_ERROR_NAME_MAX
, NULL
, HFILL
}},
977 { &hf_mount_pathconf_error_path_max
, {
978 "ERROR_PATH_MAX", "mount.pathconf.mask.error_path_max",
979 FT_BOOLEAN
, 16, TFS(&tos_error_path_max
),
980 PC_ERROR_PATH_MAX
, NULL
, HFILL
}},
981 { &hf_mount_pathconf_error_pipe_buf
, {
982 "ERROR_PIPE_BUF", "mount.pathconf.mask.error_pipe_buf",
983 FT_BOOLEAN
, 16, TFS(&tos_error_pipe_buf
),
984 PC_ERROR_PIPE_BUF
, NULL
, HFILL
}},
985 { &hf_mount_pathconf_chown_restricted
, {
986 "CHOWN_RESTRICTED", "mount.pathconf.mask.chown_restricted",
987 FT_BOOLEAN
, 16, TFS(&tos_chown_restricted
),
988 PC_CHOWN_RESTRICTED
, NULL
, HFILL
}},
989 { &hf_mount_pathconf_no_trunc
, {
990 "NO_TRUNC", "mount.pathconf.mask.no_trunc",
991 FT_BOOLEAN
, 16, TFS(&tos_no_trunc
),
992 PC_NO_TRUNC
, NULL
, HFILL
}},
993 { &hf_mount_pathconf_error_vdisable
, {
994 "ERROR_VDISABLE", "mount.pathconf.mask.error_vdisable",
995 FT_BOOLEAN
, 16, TFS(&tos_error_vdisable
),
996 PC_ERROR_VDISABLE
, NULL
, HFILL
}},
997 { &hf_mount_statvfs_bsize
, {
998 "Block size", "mount.statvfs.f_bsize",
999 FT_UINT32
, BASE_DEC
, NULL
, 0,
1000 "File system block size", HFILL
}},
1001 { &hf_mount_statvfs_frsize
, {
1002 "Fragment size", "mount.statvfs.f_frsize",
1003 FT_UINT32
, BASE_DEC
, NULL
, 0,
1004 "File system fragment size", HFILL
}},
1005 { &hf_mount_statvfs_blocks
, {
1006 "Blocks", "mount.statvfs.f_blocks",
1007 FT_UINT32
, BASE_DEC
, NULL
, 0,
1008 "Total fragment sized blocks", HFILL
}},
1009 { &hf_mount_statvfs_bfree
, {
1010 "Blocks Free", "mount.statvfs.f_bfree",
1011 FT_UINT32
, BASE_DEC
, NULL
, 0,
1012 "Free fragment sized blocks", HFILL
}},
1013 { &hf_mount_statvfs_bavail
, {
1014 "Blocks Available", "mount.statvfs.f_bavail",
1015 FT_UINT32
, BASE_DEC
, NULL
, 0,
1016 "Available fragment sized blocks", HFILL
}},
1017 { &hf_mount_statvfs_files
, {
1018 "Files", "mount.statvfs.f_files",
1019 FT_UINT32
, BASE_DEC
, NULL
, 0,
1020 "Total files/inodes", HFILL
}},
1021 { &hf_mount_statvfs_ffree
, {
1022 "Files Free", "mount.statvfs.f_ffree",
1023 FT_UINT32
, BASE_DEC
, NULL
, 0,
1024 "Free files/inodes", HFILL
}},
1025 { &hf_mount_statvfs_favail
, {
1026 "Files Available", "mount.statvfs.f_favail",
1027 FT_UINT32
, BASE_DEC
, NULL
, 0,
1028 "Available files/inodes", HFILL
}},
1029 { &hf_mount_statvfs_fsid
, {
1030 "File system ID", "mount.statvfs.f_fsid",
1031 FT_UINT32
, BASE_DEC
, NULL
, 0,
1032 "File system identifier", HFILL
}},
1033 { &hf_mount_statvfs_basetype
, {
1034 "Type", "mount.statvfs.f_basetype",
1035 FT_STRING
, BASE_NONE
, NULL
, 0,
1036 "File system type", HFILL
}},
1037 { &hf_mount_statvfs_flag
, {
1038 "Flags", "mount.statvfs.f_flag",
1039 FT_UINT32
, BASE_HEX
, NULL
, 0,
1040 "Flags bit-mask", HFILL
}},
1041 { &hf_mount_statvfs_flag_rdonly
, {
1042 "ST_RDONLY", "mount.statvfs.f_flag.st_rdonly",
1043 FT_BOOLEAN
, 32, TFS(&tos_st_rdonly
), ST_RDONLY
,
1045 { &hf_mount_statvfs_flag_nosuid
, {
1046 "ST_NOSUID", "mount.statvfs.f_flag.st_nosuid",
1047 FT_BOOLEAN
, 32, TFS(&tos_st_nosuid
), ST_NOSUID
,
1049 { &hf_mount_statvfs_flag_notrunc
, {
1050 "ST_NOTRUNC", "mount.statvfs.f_flag.st_notrunc",
1051 FT_BOOLEAN
, 32, TFS(&tos_st_notrunc
), ST_NOTRUNC
,
1053 { &hf_mount_statvfs_flag_nodev
, {
1054 "ST_NODEV", "mount.statvfs.f_flag.st_nodev",
1055 FT_BOOLEAN
, 32, TFS(&tos_st_nodev
), ST_NODEV
,
1057 { &hf_mount_statvfs_flag_grpid
, {
1058 "ST_GRPID", "mount.statvfs.f_flag.st_grpid",
1059 FT_BOOLEAN
, 32, TFS(&tos_st_grpid
), ST_GRPID
,
1061 { &hf_mount_statvfs_flag_local
, {
1062 "ST_LOCAL", "mount.statvfs.f_flag.st_local",
1063 FT_BOOLEAN
, 32, TFS(&tos_st_local
), ST_LOCAL
,
1065 { &hf_mount_statvfs_namemax
, {
1066 "Maximum file name length", "mount.statvfs.f_namemax",
1067 FT_UINT32
, BASE_DEC
, NULL
, 0,
1069 { &hf_mount_statvfs_fstr
, {
1070 "File system specific string", "mount.statvfs.f_fstr",
1071 FT_BYTES
, BASE_NONE
, NULL
, 0,
1073 { &hf_mount_flavors
, {
1074 "Flavors", "mount.flavors", FT_UINT32
, BASE_DEC
,
1075 NULL
, 0, NULL
, HFILL
}},
1076 { &hf_mount_flavor
, {
1077 "Flavor", "mount.flavor", FT_UINT32
, BASE_DEC
,
1078 VALS(rpc_auth_flavor
), 0, NULL
, HFILL
}},
1080 static gint
*ett
[] = {
1082 &ett_mount_mountlist
,
1084 &ett_mount_exportlist
,
1085 &ett_mount_pathconf_mask
,
1086 &ett_mount_statvfs_flag
,
1089 proto_mount
= proto_register_protocol("Mount Service", "MOUNT",
1091 proto_sgi_mount
= proto_register_protocol("SGI Mount Service",
1092 "SGI MOUNT", "sgimount");
1093 proto_register_field_array(proto_mount
, hf
, array_length(hf
));
1094 proto_register_subtree_array(ett
, array_length(ett
));
1098 proto_reg_handoff_mount(void)
1100 /* Register the protocol as RPC */
1101 rpc_init_prog(proto_mount
, MOUNT_PROGRAM
, ett_mount
);
1102 rpc_init_prog(proto_sgi_mount
, SGI_MOUNT_PROGRAM
, ett_mount
);
1103 /* Register the procedure tables */
1104 rpc_init_proc_table(MOUNT_PROGRAM
, 1, mount1_proc
, hf_mount_procedure_v1
);
1105 rpc_init_proc_table(MOUNT_PROGRAM
, 2, mount2_proc
, hf_mount_procedure_v2
);
1106 rpc_init_proc_table(MOUNT_PROGRAM
, 3, mount3_proc
, hf_mount_procedure_v3
);
1107 rpc_init_proc_table(SGI_MOUNT_PROGRAM
, 1, sgi_mount1_proc
, hf_sgi_mount_procedure_v1
);