2 * Routines for mount dissection
4 * $Id: packet-mount.c,v 1.33 2002/08/28 21:00:22 jmayer Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include "packet-rpc.h"
35 #include "packet-mount.h"
36 #include "packet-nfs.h"
39 static int proto_mount = -1;
40 static int hf_mount_path = -1;
41 static int hf_mount3_status = -1;
42 static int hf_mount_mountlist_hostname = -1;
43 static int hf_mount_mountlist_directory = -1;
44 static int hf_mount_mountlist = -1;
45 static int hf_mount_groups_group = -1;
46 static int hf_mount_groups = -1;
47 static int hf_mount_exportlist_directory = -1;
48 static int hf_mount_exportlist = -1;
49 static int hf_mount_pathconf_link_max = -1;
50 static int hf_mount_pathconf_max_canon = -1;
51 static int hf_mount_pathconf_max_input = -1;
52 static int hf_mount_pathconf_name_max = -1;
53 static int hf_mount_pathconf_path_max = -1;
54 static int hf_mount_pathconf_pipe_buf = -1;
55 static int hf_mount_pathconf_vdisable = -1;
56 static int hf_mount_pathconf_mask = -1;
57 static int hf_mount_pathconf_error_all = -1;
58 static int hf_mount_pathconf_error_link_max = -1;
59 static int hf_mount_pathconf_error_max_canon = -1;
60 static int hf_mount_pathconf_error_max_input = -1;
61 static int hf_mount_pathconf_error_name_max = -1;
62 static int hf_mount_pathconf_error_path_max = -1;
63 static int hf_mount_pathconf_error_pipe_buf = -1;
64 static int hf_mount_pathconf_chown_restricted = -1;
65 static int hf_mount_pathconf_no_trunc = -1;
66 static int hf_mount_pathconf_error_vdisable = -1;
67 static int hf_mount_flavors = -1;
68 static int hf_mount_flavor = -1;
70 static gint ett_mount = -1;
71 static gint ett_mount_mountlist = -1;
72 static gint ett_mount_groups = -1;
73 static gint ett_mount_exportlist = -1;
74 static gint ett_mount_pathconf_mask = -1;
76 #define MAX_GROUP_NAME_LIST 128
77 static char group_name_list[MAX_GROUP_NAME_LIST];
78 static int group_names_len;
80 /* RFC 1094, Page 24 */
81 /* This function dissects fhstatus for v1 and v2 of the mount protocol.
82 * Formally, hf_mount3_status only define the status codes returned by version
84 * Though not formally defined in the standard, we use the same
85 * value-to-string mappings as version 3 since we belive that this mapping
86 * is consistant with most v1 and v2 implementations.
89 dissect_fhstatus(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
93 status=tvb_get_ntohl(tvb,offset);
94 offset = dissect_rpc_uint32(tvb,tree,hf_mount3_status,offset);
98 offset = dissect_fhandle(tvb,offset,pinfo,tree,"fhandle");
110 dissect_mount_dirpath_call(tvbuff_t *tvb, int offset, packet_info *pinfo,
113 if((!pinfo->fd->flags.visited) && nfs_file_name_snooping){
114 rpc_call_info_value *civ=pinfo->private_data;
116 if(civ->request && (civ->proc==1)){
117 unsigned char *host, *name;
118 unsigned const char *dir;
121 host=ip_to_str(pinfo->dst.data);
122 len=tvb_get_ntohl(tvb, offset);
124 dir=tvb_get_ptr(tvb, offset+4, len);
127 name=g_malloc(strlen(host)+1+len+1+200);
129 memcpy(ptr, host, strlen(host));
132 memcpy(ptr, dir, len);
136 nfs_name_snoop_add_name(civ->xid, tvb, -1, strlen(name), 0, 0, name);
143 offset = dissect_rpc_string(tvb,tree,hf_mount_path,offset,NULL);
150 /* RFC 1094, Page 25,26 */
152 dissect_mount1_mnt_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
154 offset = dissect_fhstatus(tvb,offset,pinfo,tree);
161 /* RFC 1094, Page 26 */
162 /* RFC 1813, Page 110 */
164 dissect_mountlist(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
166 proto_item* lock_item = NULL;
167 proto_tree* lock_tree = NULL;
168 int old_offset = offset;
173 lock_item = proto_tree_add_item(tree, hf_mount_mountlist, tvb,
176 lock_tree = proto_item_add_subtree(lock_item, ett_mount_mountlist);
179 offset = dissect_rpc_string(tvb, lock_tree,
180 hf_mount_mountlist_hostname, offset, &hostname);
181 offset = dissect_rpc_string(tvb, lock_tree,
182 hf_mount_mountlist_directory, offset, &directory);
185 /* now we have a nicer string */
186 proto_item_set_text(lock_item, "Mount List Entry: %s:%s", hostname, directory);
187 /* now we know, that mountlist is shorter */
188 proto_item_set_len(lock_item, offset - old_offset);
197 /* RFC 1094, Page 26 */
198 /* RFC 1813, Page 110 */
200 dissect_mount_dump_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
202 offset = dissect_rpc_list(tvb, pinfo, tree, offset, dissect_mountlist);
209 /* RFC 1094, Page 26 */
210 /* RFC 1813, Page 110 */
212 dissect_group(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
215 len=tvb_get_ntohl(tvb,offset);
216 str_len=tvb_get_nstringz(tvb,offset+4,
217 MAX_GROUP_NAME_LIST-5-group_names_len,
218 group_name_list+group_names_len);
219 if((group_names_len>=(MAX_GROUP_NAME_LIST-5))||(str_len<0)){
220 strcpy(group_name_list+(MAX_GROUP_NAME_LIST-5),"...");
221 group_names_len=MAX_GROUP_NAME_LIST-1;
223 group_names_len+=str_len;
224 group_name_list[group_names_len++]=' ';
226 group_name_list[group_names_len]=0;
228 offset = dissect_rpc_string(tvb, tree,
229 hf_mount_groups_group, offset, NULL);
235 /* RFC 1094, Page 26 */
236 /* RFC 1813, Page 113 */
238 dissect_exportlist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
240 proto_item* exportlist_item = NULL;
241 proto_tree* exportlist_tree = NULL;
242 int old_offset = offset;
244 proto_item* groups_item = NULL;
245 proto_item* groups_tree = NULL;
248 group_name_list[0]=0;
251 exportlist_item = proto_tree_add_item(tree, hf_mount_exportlist, tvb,
254 exportlist_tree = proto_item_add_subtree(exportlist_item, ett_mount_exportlist);
257 offset = dissect_rpc_string(tvb, exportlist_tree,
258 hf_mount_exportlist_directory, offset, &directory);
259 groups_offset = offset;
262 groups_item = proto_tree_add_item(exportlist_tree, hf_mount_groups, tvb,
265 groups_tree = proto_item_add_subtree(groups_item, ett_mount_groups);
268 offset = dissect_rpc_list(tvb, pinfo, groups_tree, offset, dissect_group);
270 /* mark empty lists */
271 if (offset - groups_offset == 4) {
272 proto_item_set_text(groups_item, "Groups: empty");
275 /* now we know, that groups is shorter */
276 proto_item_set_len(groups_item, offset - groups_offset);
279 if (exportlist_item) {
280 /* now we have a nicer string */
281 proto_item_set_text(exportlist_item, "Export List Entry: %s -> %s", directory,group_name_list);
282 /* now we know, that exportlist is shorter */
283 proto_item_set_len(exportlist_item, offset - old_offset);
291 /* RFC 1094, Page 26 */
292 /* RFC 1813, Page 113 */
294 dissect_mount_export_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
296 offset = dissect_rpc_list(tvb, pinfo, tree, offset, dissect_exportlist);
302 #define OFFS_MASK 32 /* offset of the "pc_mask" field */
304 #define PC_ERROR_ALL 0x0001
305 #define PC_ERROR_LINK_MAX 0x0002
306 #define PC_ERROR_MAX_CANON 0x0004
307 #define PC_ERROR_MAX_INPUT 0x0008
308 #define PC_ERROR_NAME_MAX 0x0010
309 #define PC_ERROR_PATH_MAX 0x0020
310 #define PC_ERROR_PIPE_BUF 0x0040
311 #define PC_CHOWN_RESTRICTED 0x0080
312 #define PC_NO_TRUNC 0x0100
313 #define PC_ERROR_VDISABLE 0x0200
315 static const true_false_string tos_error_all = {
317 "Some or all info valid"
320 static const true_false_string tos_error_link_max = {
325 static const true_false_string tos_error_max_canon = {
330 static const true_false_string tos_error_max_input = {
335 static const true_false_string tos_error_name_max = {
340 static const true_false_string tos_error_path_max = {
345 static const true_false_string tos_error_pipe_buf = {
350 static const true_false_string tos_chown_restricted = {
351 "Only a privileged user can change the ownership of a file",
352 "Users may give away their own files"
355 static const true_false_string tos_no_trunc = {
356 "File names that are too long will get an error",
357 "File names that are too long will be truncated"
360 static const true_false_string tos_error_vdisable = {
367 dissect_mount_pathconf_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
371 proto_item *lock_item;
372 proto_tree *lock_tree;
376 * Extract the mask first, so we know which other fields the
377 * server was able to return to us.
379 pc_mask = tvb_get_ntohl(tvb, offset+OFFS_MASK) & 0xffff;
380 if (!(pc_mask & (PC_ERROR_LINK_MAX|PC_ERROR_ALL))) {
382 dissect_rpc_uint32(tvb,tree,hf_mount_pathconf_link_max,offset);
387 if (!(pc_mask & (PC_ERROR_MAX_CANON|PC_ERROR_ALL))) {
389 proto_tree_add_item(tree,
390 hf_mount_pathconf_max_canon,tvb,offset+2,2,
391 tvb_get_ntohs(tvb,offset)&0xffff);
396 if (!(pc_mask & (PC_ERROR_MAX_INPUT|PC_ERROR_ALL))) {
398 proto_tree_add_item(tree,
399 hf_mount_pathconf_max_input,tvb,offset+2,2,
400 tvb_get_ntohs(tvb,offset)&0xffff);
405 if (!(pc_mask & (PC_ERROR_NAME_MAX|PC_ERROR_ALL))) {
407 proto_tree_add_item(tree,
408 hf_mount_pathconf_name_max,tvb,offset+2,2,
409 tvb_get_ntohs(tvb,offset)&0xffff);
414 if (!(pc_mask & (PC_ERROR_PATH_MAX|PC_ERROR_ALL))) {
416 proto_tree_add_item(tree,
417 hf_mount_pathconf_path_max,tvb,offset+2,2,
418 tvb_get_ntohs(tvb,offset)&0xffff);
423 if (!(pc_mask & (PC_ERROR_PIPE_BUF|PC_ERROR_ALL))) {
425 proto_tree_add_item(tree,
426 hf_mount_pathconf_pipe_buf,tvb,offset+2,2,
427 tvb_get_ntohs(tvb,offset)&0xffff);
432 offset += 4; /* skip "pc_xxx" pad field */
434 if (!(pc_mask & (PC_ERROR_VDISABLE|PC_ERROR_ALL))) {
436 proto_tree_add_item(tree,
437 hf_mount_pathconf_vdisable,tvb,offset+3,1,
438 tvb_get_ntohs(tvb,offset)&0xffff);
445 lock_item = proto_tree_add_item(tree, hf_mount_pathconf_mask, tvb,
448 lock_tree = proto_item_add_subtree(lock_item, ett_mount_pathconf_mask);
449 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_all, tvb,
450 offset + 2, 2, pc_mask);
452 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_link_max, tvb,
453 offset + 2, 2, pc_mask);
454 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_max_canon, tvb,
455 offset + 2, 2, pc_mask);
456 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_max_input, tvb,
457 offset + 2, 2, pc_mask);
458 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_name_max, tvb,
459 offset + 2, 2, pc_mask);
460 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_path_max, tvb,
461 offset + 2, 2, pc_mask);
462 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_pipe_buf, tvb,
463 offset + 2, 2, pc_mask);
464 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_chown_restricted, tvb,
465 offset + 2, 2, pc_mask);
466 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_no_trunc, tvb,
467 offset + 2, 2, pc_mask);
468 proto_tree_add_boolean(lock_tree, hf_mount_pathconf_error_vdisable, tvb,
469 offset + 2, 2, pc_mask);
476 /* RFC 1813, Page 107 */
477 static const value_string mount3_mountstat3[] =
483 { 13, "ERR_ACCESS" },
484 { 20, "ERR_NOTDIR" },
486 { 63, "ERR_NAMETOOLONG" },
487 { 10004, "ERR_NOTSUPP" },
488 { 10006, "ERR_SERVERFAULT" },
493 /* RFC 1813, Page 107 */
495 dissect_mountstat3(tvbuff_t *tvb, proto_tree *tree, int offset, int hfindex, guint32 *status)
499 mountstat3 = tvb_get_ntohl(tvb, offset);
501 offset = dissect_rpc_uint32(tvb,tree,hfindex,offset);
502 *status = mountstat3;
506 /* RFC 1831, Page 109 */
508 dissect_mount3_mnt_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
511 guint32 auth_flavors;
513 guint32 auth_flavor_i;
515 offset = dissect_mountstat3(tvb,tree,offset,hf_mount3_status,&status);
519 offset = dissect_nfs_fh3(tvb,offset,pinfo,tree,"fhandle");
521 auth_flavors = tvb_get_ntohl(tvb, offset);
522 proto_tree_add_uint(tree,hf_mount_flavors, tvb,
523 offset, 4, auth_flavors);
525 for (auth_flavor_i = 0 ; auth_flavor_i < auth_flavors ; auth_flavor_i++) {
526 auth_flavor = tvb_get_ntohl(tvb, offset);
527 proto_tree_add_uint(tree,hf_mount_flavor, tvb,
528 offset, 4, auth_flavor);
541 /* proc number, "proc name", dissect_request, dissect_reply */
542 /* NULL as function pointer means: type of arguments is "void". */
544 /* Mount protocol version 1, RFC 1094 */
545 static const vsff mount1_proc[] = {
546 { 0, "NULL", NULL, NULL },
547 { MOUNTPROC_MNT, "MNT",
548 dissect_mount_dirpath_call, dissect_mount1_mnt_reply },
549 { MOUNTPROC_DUMP, "DUMP",
550 NULL, dissect_mount_dump_reply },
551 { MOUNTPROC_UMNT, "UMNT",
552 dissect_mount_dirpath_call, NULL },
553 { MOUNTPROC_UMNTALL, "UMNTALL",
555 { MOUNTPROC_EXPORT, "EXPORT",
556 NULL, dissect_mount_export_reply },
557 { MOUNTPROC_EXPORTALL, "EXPORTALL",
558 NULL, dissect_mount_export_reply },
559 { 0, NULL, NULL, NULL }
561 /* end of mount version 1 */
564 /* Mount protocol version 2, private communication from somebody at Sun;
565 mount V2 is V1 plus MOUNTPROC_PATHCONF to fetch information for the
566 POSIX "pathconf()" call. */
567 static const vsff mount2_proc[] = {
568 { 0, "NULL", NULL, NULL },
569 { MOUNTPROC_MNT, "MNT",
570 dissect_mount_dirpath_call, dissect_mount1_mnt_reply },
571 { MOUNTPROC_DUMP, "DUMP",
572 NULL, dissect_mount_dump_reply },
573 { MOUNTPROC_UMNT, "UMNT",
574 dissect_mount_dirpath_call, NULL },
575 { MOUNTPROC_UMNTALL, "UMNTALL",
577 { MOUNTPROC_EXPORT, "EXPORT",
578 NULL, dissect_mount_export_reply },
579 { MOUNTPROC_EXPORTALL, "EXPORTALL",
580 NULL, dissect_mount_export_reply },
581 { MOUNTPROC_PATHCONF, "PATHCONF",
582 dissect_mount_dirpath_call, dissect_mount_pathconf_reply },
583 { 0, NULL, NULL, NULL }
585 /* end of mount version 2 */
588 /* Mount protocol version 3, RFC 1813 */
589 static const vsff mount3_proc[] = {
590 { 0, "NULL", NULL, NULL },
591 { MOUNTPROC_MNT, "MNT",
592 dissect_mount_dirpath_call, dissect_mount3_mnt_reply },
593 { MOUNTPROC_DUMP, "DUMP",
594 NULL, dissect_mount_dump_reply },
595 { MOUNTPROC_UMNT, "UMNT",
596 dissect_mount_dirpath_call, NULL },
597 { MOUNTPROC_UMNTALL, "UMNTALL",
599 { MOUNTPROC_EXPORT, "EXPORT",
600 NULL, dissect_mount_export_reply },
601 { 0, NULL, NULL, NULL }
603 /* end of Mount protocol version 3 */
607 proto_register_mount(void)
609 static hf_register_info hf[] = {
611 "Path", "mount.path", FT_STRING, BASE_DEC,
612 NULL, 0, "Path", HFILL }},
613 { &hf_mount3_status, {
614 "Status", "mount.status", FT_UINT32, BASE_DEC,
615 VALS(mount3_mountstat3), 0, "Status", HFILL }},
616 { &hf_mount_mountlist_hostname, {
617 "Hostname", "mount.dump.hostname", FT_STRING, BASE_DEC,
618 NULL, 0, "Hostname", HFILL }},
619 { &hf_mount_mountlist_directory, {
620 "Directory", "mount.dump.directory", FT_STRING, BASE_DEC,
621 NULL, 0, "Directory", HFILL }},
622 { &hf_mount_mountlist, {
623 "Mount List Entry", "mount.dump.entry", FT_NONE, 0,
624 NULL, 0, "Mount List Entry", HFILL }},
625 { &hf_mount_groups_group, {
626 "Group", "mount.export.group", FT_STRING, BASE_DEC,
627 NULL, 0, "Group", HFILL }},
628 { &hf_mount_groups, {
629 "Groups", "mount.export.groups", FT_NONE, 0,
630 NULL, 0, "Groups", HFILL }},
631 { &hf_mount_exportlist_directory, {
632 "Directory", "mount.export.directory", FT_STRING, BASE_DEC,
633 NULL, 0, "Directory", HFILL }},
634 { &hf_mount_exportlist, {
635 "Export List Entry", "mount.export.entry", FT_NONE, 0,
636 NULL, 0, "Export List Entry", HFILL }},
637 { &hf_mount_pathconf_link_max, {
638 "Maximum number of links to a file", "mount.pathconf.link_max",
640 NULL, 0, "Maximum number of links allowed to a file", HFILL }},
641 { &hf_mount_pathconf_max_canon, {
642 "Maximum terminal input line length", "mount.pathconf.max_canon",
644 NULL, 0, "Max tty input line length", HFILL }},
645 { &hf_mount_pathconf_max_input, {
646 "Terminal input buffer size", "mount.pathconf.max_input",
648 NULL, 0, "Terminal input buffer size", HFILL }},
649 { &hf_mount_pathconf_name_max, {
650 "Maximum file name length", "mount.pathconf.name_max",
652 NULL, 0, "Maximum file name length", HFILL }},
653 { &hf_mount_pathconf_path_max, {
654 "Maximum path name length", "mount.pathconf.path_max",
656 NULL, 0, "Maximum path name length", HFILL }},
657 { &hf_mount_pathconf_pipe_buf, {
658 "Pipe buffer size", "mount.pathconf.pipe_buf",
660 NULL, 0, "Maximum amount of data that can be written atomically to a pipe", HFILL }},
661 { &hf_mount_pathconf_vdisable, {
662 "VDISABLE character", "mount.pathconf.vdisable_char",
664 NULL, 0, "Character value to disable a terminal special character", HFILL }},
665 { &hf_mount_pathconf_mask, {
666 "Reply error/status bits", "mount.pathconf.mask",
668 NULL, 0, "Bit mask with error and status bits", HFILL }},
669 { &hf_mount_pathconf_error_all, {
670 "ERROR_ALL", "mount.pathconf.mask.error_all",
671 FT_BOOLEAN, 16, TFS(&tos_error_all),
672 PC_ERROR_ALL, "", HFILL }},
673 { &hf_mount_pathconf_error_link_max, {
674 "ERROR_LINK_MAX", "mount.pathconf.mask.error_link_max",
675 FT_BOOLEAN, 16, TFS(&tos_error_link_max),
676 PC_ERROR_LINK_MAX, "", HFILL }},
677 { &hf_mount_pathconf_error_max_canon, {
678 "ERROR_MAX_CANON", "mount.pathconf.mask.error_max_canon",
679 FT_BOOLEAN, 16, TFS(&tos_error_max_canon),
680 PC_ERROR_MAX_CANON, "", HFILL }},
681 { &hf_mount_pathconf_error_max_input, {
682 "ERROR_MAX_INPUT", "mount.pathconf.mask.error_max_input",
683 FT_BOOLEAN, 16, TFS(&tos_error_max_input),
684 PC_ERROR_MAX_INPUT, "", HFILL }},
685 { &hf_mount_pathconf_error_name_max, {
686 "ERROR_NAME_MAX", "mount.pathconf.mask.error_name_max",
687 FT_BOOLEAN, 16, TFS(&tos_error_name_max),
688 PC_ERROR_NAME_MAX, "", HFILL }},
689 { &hf_mount_pathconf_error_path_max, {
690 "ERROR_PATH_MAX", "mount.pathconf.mask.error_path_max",
691 FT_BOOLEAN, 16, TFS(&tos_error_path_max),
692 PC_ERROR_PATH_MAX, "", HFILL }},
693 { &hf_mount_pathconf_error_pipe_buf, {
694 "ERROR_PIPE_BUF", "mount.pathconf.mask.error_pipe_buf",
695 FT_BOOLEAN, 16, TFS(&tos_error_pipe_buf),
696 PC_ERROR_PIPE_BUF, "", HFILL }},
697 { &hf_mount_pathconf_chown_restricted, {
698 "CHOWN_RESTRICTED", "mount.pathconf.mask.chown_restricted",
699 FT_BOOLEAN, 16, TFS(&tos_chown_restricted),
700 PC_CHOWN_RESTRICTED, "", HFILL }},
701 { &hf_mount_pathconf_no_trunc, {
702 "NO_TRUNC", "mount.pathconf.mask.no_trunc",
703 FT_BOOLEAN, 16, TFS(&tos_no_trunc),
704 PC_NO_TRUNC, "", HFILL }},
705 { &hf_mount_pathconf_error_vdisable, {
706 "ERROR_VDISABLE", "mount.pathconf.mask.error_vdisable",
707 FT_BOOLEAN, 16, TFS(&tos_error_vdisable),
708 PC_ERROR_VDISABLE, "", HFILL }},
709 { &hf_mount_flavors, {
710 "Flavors", "mount.flavors", FT_UINT32, BASE_DEC,
711 NULL, 0, "Flavors", HFILL }},
712 { &hf_mount_flavor, {
713 "Flavor", "mount.flavor", FT_UINT32, BASE_DEC,
714 VALS(rpc_auth_flavor), 0, "Flavor", HFILL }},
716 static gint *ett[] = {
718 &ett_mount_mountlist,
720 &ett_mount_exportlist,
721 &ett_mount_pathconf_mask,
724 proto_mount = proto_register_protocol("Mount Service", "MOUNT", "mount");
725 proto_register_field_array(proto_mount, hf, array_length(hf));
726 proto_register_subtree_array(ett, array_length(ett));
730 proto_reg_handoff_mount(void)
732 /* Register the protocol as RPC */
733 rpc_init_prog(proto_mount, MOUNT_PROGRAM, ett_mount);
734 /* Register the procedure tables */
735 rpc_init_proc_table(MOUNT_PROGRAM, 1, mount1_proc);
736 rpc_init_proc_table(MOUNT_PROGRAM, 2, mount2_proc);
737 rpc_init_proc_table(MOUNT_PROGRAM, 3, mount3_proc);