Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-mount.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-mount.c
2
 * Routines for mount dissection
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * Copied from packet-smb.c
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
16
#include <epan/exceptions.h>
17
#include <epan/to_str.h>
18
#include <epan/strutil.h>
19
#include <epan/tfs.h>
20
#include <wsutil/array.h>
21
#include "packet-mount.h"
22
#include "packet-nfs.h"
23
24
void proto_register_mount(void);
25
void proto_reg_handoff_mount(void);
26
27
static int proto_mount;
28
static int proto_sgi_mount;
29
static int hf_mount_procedure_v1;
30
static int hf_mount_procedure_v2;
31
static int hf_mount_procedure_v3;
32
static int hf_sgi_mount_procedure_v1;
33
static int hf_mount_path;
34
static int hf_mount3_status;
35
static int hf_mount_mountlist_hostname;
36
static int hf_mount_mountlist_directory;
37
static int hf_mount_mountlist;
38
static int hf_mount_groups_group;
39
static int hf_mount_groups;
40
static int hf_mount_exportlist_directory;
41
static int hf_mount_exportlist;
42
static int hf_mount_has_options;
43
static int hf_mount_options;
44
static int hf_mount_pathconf_link_max;
45
static int hf_mount_pathconf_max_canon;
46
static int hf_mount_pathconf_max_input;
47
static int hf_mount_pathconf_name_max;
48
static int hf_mount_pathconf_path_max;
49
static int hf_mount_pathconf_pipe_buf;
50
static int hf_mount_pathconf_vdisable;
51
static int hf_mount_pathconf_mask;
52
static int hf_mount_pathconf_error_all;
53
static int hf_mount_pathconf_error_link_max;
54
static int hf_mount_pathconf_error_max_canon;
55
static int hf_mount_pathconf_error_max_input;
56
static int hf_mount_pathconf_error_name_max;
57
static int hf_mount_pathconf_error_path_max;
58
static int hf_mount_pathconf_error_pipe_buf;
59
static int hf_mount_pathconf_chown_restricted;
60
static int hf_mount_pathconf_no_trunc;
61
static int hf_mount_pathconf_error_vdisable;
62
static int hf_mount_statvfs_bsize;
63
static int hf_mount_statvfs_frsize;
64
static int hf_mount_statvfs_blocks;
65
static int hf_mount_statvfs_bfree;
66
static int hf_mount_statvfs_bavail;
67
static int hf_mount_statvfs_files;
68
static int hf_mount_statvfs_ffree;
69
static int hf_mount_statvfs_favail;
70
static int hf_mount_statvfs_fsid;
71
static int hf_mount_statvfs_basetype;
72
static int hf_mount_statvfs_flag;
73
static int hf_mount_statvfs_flag_rdonly;
74
static int hf_mount_statvfs_flag_nosuid;
75
static int hf_mount_statvfs_flag_notrunc;
76
static int hf_mount_statvfs_flag_nodev;
77
static int hf_mount_statvfs_flag_grpid;
78
static int hf_mount_statvfs_flag_local;
79
static int hf_mount_statvfs_namemax;
80
static int hf_mount_statvfs_fstr;
81
static int hf_mount_flavors;
82
static int hf_mount_flavor;
83
84
static int ett_mount;
85
static int ett_mount_mountlist;
86
static int ett_mount_groups;
87
static int ett_mount_exportlist;
88
static int ett_mount_pathconf_mask;
89
static int ett_mount_statvfs_flag;
90
91
/* RFC 1813, Page 107 */
92
static const value_string mount3_mountstat3[] =
93
{
94
  { 0,  "OK" },
95
  { 1,  "ERR_PERM" },
96
  { 2,  "ERR_NOENT" },
97
  { 5,  "ERR_IO" },
98
  { 13, "ERR_ACCESS" },
99
  { 20, "ERR_NOTDIR" },
100
  { 22, "ERR_INVAL" },
101
  { 63, "ERR_NAMETOOLONG" },
102
  { 10004,  "ERR_NOTSUPP" },
103
  { 10006,  "ERR_SERVERFAULT" },
104
  { 0,  NULL }
105
};
106
107
108
/* RFC 1094, Page 24 */
109
/* This function dissects fhstatus for v1 and v2 of the mount protocol.
110
 * Formally, hf_mount3_status only define the status codes returned by version
111
 * 3 of the protocol.
112
 * Though not formally defined in the standard, we use the same
113
 * value-to-string mappings as version 3 since we believe that this mapping
114
 * is consistent with most v1 and v2 implementations.
115
 */
116
static int
117
dissect_fhstatus(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value* civ)
118
0
{
119
0
  int32_t status;
120
121
0
  status=tvb_get_ntohl(tvb,offset);
122
0
  offset = dissect_rpc_uint32(tvb,tree,hf_mount3_status,offset);
123
124
0
  switch (status) {
125
0
    case 0:
126
0
      offset = dissect_fhandle(tvb,offset,pinfo,tree,"fhandle", NULL, civ);
127
0
    break;
128
0
    default:
129
      /* void */
130
0
      col_append_fstr(
131
0
          pinfo->cinfo, COL_INFO, " Error:%s",
132
0
          val_to_str(status, mount3_mountstat3,
133
0
              "Unknown (0x%08X)"));
134
0
    break;
135
0
  }
136
137
0
  return offset;
138
0
}
139
140
141
static int
142
dissect_mount_dirpath_call(tvbuff_t *tvb, packet_info *pinfo,
143
    proto_tree *tree, void* data)
144
0
{
145
0
  const char *mountpoint=NULL;
146
0
  int offset = 0;
147
148
0
  if((!pinfo->fd->visited) && nfs_file_name_snooping){
149
0
    rpc_call_info_value *civ=(rpc_call_info_value *)data;
150
151
0
    if(civ->request && (civ->proc==1)){
152
0
      uint32_t len_field;
153
154
0
      len_field = tvb_get_ntohl(tvb, offset);
155
0
      if (len_field < ITEM_LABEL_LENGTH) {
156
0
        char *name, *ptr;
157
0
        int addr_len, name_len;
158
159
0
        name = address_to_str(pinfo->pool, &pinfo->dst);
160
0
        addr_len = (int)strlen(name);
161
        /* IP address, colon, path, terminating 0 */
162
0
        name_len = addr_len + 1 + len_field + 1;
163
164
0
        name = (char *)wmem_realloc(pinfo->pool,
165
0
            (void *)name, name_len);
166
0
        ptr = name + addr_len;
167
0
        *ptr++ = ':';
168
0
        tvb_memcpy(tvb, ptr, offset+4, len_field);
169
0
        ptr += len_field;
170
0
        *ptr = 0;
171
172
0
        nfs_name_snoop_add_name(civ->xid, tvb, -1, name_len, 0, 0, name);
173
0
      }
174
0
    }
175
0
  }
176
177
0
  offset = dissect_rpc_string(tvb,tree,hf_mount_path,offset,&mountpoint);
178
0
  col_append_fstr(pinfo->cinfo, COL_INFO," %s", mountpoint);
179
180
0
  return offset;
181
0
}
182
183
184
/* RFC 1094, Page 25,26 */
185
static int
186
dissect_mount1_mnt_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
187
0
{
188
0
  return dissect_fhstatus(tvb,0,pinfo,tree,(rpc_call_info_value*)data);
189
0
}
190
191
192
193
/* RFC 1094, Page 26 */
194
/* RFC 1813, Page 110 */
195
static int
196
dissect_mountlist(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
197
0
{
198
0
  proto_item* lock_item;
199
0
  proto_tree* lock_tree;
200
0
  int old_offset = offset;
201
0
  const char* hostname;
202
0
  const char* directory;
203
204
0
  lock_item = proto_tree_add_item(tree, hf_mount_mountlist, tvb,
205
0
          offset, -1, ENC_NA);
206
207
0
  lock_tree = proto_item_add_subtree(lock_item, ett_mount_mountlist);
208
209
0
  offset = dissect_rpc_string(tvb, lock_tree,
210
0
      hf_mount_mountlist_hostname, offset, &hostname);
211
0
  offset = dissect_rpc_string(tvb, lock_tree,
212
0
      hf_mount_mountlist_directory, offset, &directory);
213
214
0
  if (lock_item) {
215
    /* now we have a nicer string */
216
0
    proto_item_set_text(lock_item, "Mount List Entry: %s:%s", hostname, directory);
217
    /* now we know, that mountlist is shorter */
218
0
    proto_item_set_len(lock_item, offset - old_offset);
219
0
  }
220
221
0
  return offset;
222
0
}
223
224
225
/* RFC 1094, Page 26 */
226
/* RFC 1813, Page 110 */
227
static int
228
dissect_mount_dump_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
229
0
{
230
0
  return dissect_rpc_list(tvb, pinfo, tree, 0,
231
0
    dissect_mountlist, NULL);
232
0
}
233
234
235
236
/* RFC 1094, Page 26 */
237
/* RFC 1813, Page 110 */
238
static int
239
dissect_group(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void* data)
240
0
{
241
0
  wmem_strbuf_t *group_name_list = (wmem_strbuf_t *)data;
242
0
  const char *group_name;
243
244
0
  offset = dissect_rpc_string(tvb, tree,
245
0
      hf_mount_groups_group, offset, &group_name);
246
0
  if (wmem_strbuf_get_len(group_name_list) != 0)
247
0
    wmem_strbuf_append_c(group_name_list, ' ');
248
0
  wmem_strbuf_append(group_name_list, group_name);
249
250
0
  return offset;
251
0
}
252
253
254
/* RFC 1094, Page 26 */
255
/* RFC 1813, Page 113 */
256
static int
257
dissect_exportlist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
258
0
{
259
0
  proto_item* exportlist_item = NULL;
260
0
  proto_tree* exportlist_tree = NULL;
261
0
  int old_offset = offset;
262
0
  int groups_offset;
263
0
  proto_item* groups_item = NULL;
264
0
  proto_item* groups_tree = NULL;
265
0
  const char* directory;
266
0
  wmem_strbuf_t* group_name_list_strbuf;
267
0
  const char* group_name_list;
268
269
0
  if (tree) {
270
0
    exportlist_item = proto_tree_add_item(tree, hf_mount_exportlist, tvb, offset, -1, ENC_NA);
271
0
    exportlist_tree = proto_item_add_subtree(exportlist_item, ett_mount_exportlist);
272
0
  }
273
274
0
  offset = dissect_rpc_string(tvb, exportlist_tree,
275
0
      hf_mount_exportlist_directory, offset, &directory);
276
0
  groups_offset = offset;
277
278
0
  groups_item = proto_tree_add_item(exportlist_tree, hf_mount_groups, tvb, offset, -1, ENC_NA);
279
0
  groups_tree = proto_item_add_subtree(groups_item, ett_mount_groups);
280
281
0
  group_name_list_strbuf = wmem_strbuf_new(pinfo->pool, "");
282
0
  offset = dissect_rpc_list(tvb, pinfo, groups_tree, offset,
283
0
    dissect_group, (void *)group_name_list_strbuf);
284
0
  if (groups_item) {
285
    /* mark empty lists */
286
0
    if (offset - groups_offset == 4) {
287
0
      proto_item_set_text(groups_item, "Groups: empty");
288
0
    }
289
290
    /* now we know, that groups is shorter */
291
0
    proto_item_set_len(groups_item, offset - groups_offset);
292
0
  }
293
294
0
  group_name_list = wmem_strbuf_finalize(group_name_list_strbuf);
295
296
0
  if (exportlist_item) {
297
    /* now we have a nicer string */
298
0
    proto_item_set_text(exportlist_item,
299
0
        "Export List Entry: %s -> %s",
300
0
        format_text(pinfo->pool, directory, strlen(directory)),
301
0
        format_text(pinfo->pool, group_name_list, strlen(group_name_list)));
302
    /* now we know, that exportlist is shorter */
303
0
    proto_item_set_len(exportlist_item, offset - old_offset);
304
0
  }
305
306
0
  return offset;
307
0
}
308
309
310
/* RFC 1094, Page 26 */
311
/* RFC 1813, Page 113 */
312
static int
313
dissect_mount_export_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
314
0
{
315
0
  return dissect_rpc_list(tvb, pinfo, tree, 0,
316
0
    dissect_exportlist, NULL);
317
0
}
318
319
320
0
#define OFFS_MASK 32  /* offset of the "pc_mask" field */
321
322
14
#define PC_ERROR_ALL    0x0001
323
14
#define PC_ERROR_LINK_MAX 0x0002
324
14
#define PC_ERROR_MAX_CANON  0x0004
325
14
#define PC_ERROR_MAX_INPUT  0x0008
326
14
#define PC_ERROR_NAME_MAX 0x0010
327
14
#define PC_ERROR_PATH_MAX 0x0020
328
14
#define PC_ERROR_PIPE_BUF 0x0040
329
14
#define PC_CHOWN_RESTRICTED 0x0080
330
14
#define PC_NO_TRUNC   0x0100
331
14
#define PC_ERROR_VDISABLE 0x0200
332
333
static const true_false_string tos_error_all = {
334
  "All info invalid",
335
  "Some or all info valid"
336
};
337
338
static const true_false_string tos_error_link_max = {
339
  "LINK_MAX invalid",
340
  "LINK_MAX valid"
341
};
342
343
static const true_false_string tos_error_max_canon = {
344
  "MAX_CANON invalid",
345
  "MAX_CANON valid"
346
};
347
348
static const true_false_string tos_error_max_input = {
349
  "MAX_INPUT invalid",
350
  "MAX_INPUT valid"
351
};
352
353
static const true_false_string tos_error_name_max = {
354
  "NAME_MAX invalid",
355
  "NAME_MAX valid"
356
};
357
358
static const true_false_string tos_error_path_max = {
359
  "PATH_MAX invalid",
360
  "PATH_MAX valid"
361
};
362
363
static const true_false_string tos_error_pipe_buf = {
364
  "PIPE_BUF invalid",
365
  "PIPE_BUF valid"
366
};
367
368
static const true_false_string tos_chown_restricted = {
369
  "Only a privileged user can change the ownership of a file",
370
  "Users may give away their own files"
371
};
372
373
static const true_false_string tos_no_trunc = {
374
  "File names that are too long will get an error",
375
  "File names that are too long will be truncated"
376
};
377
378
static const true_false_string tos_error_vdisable = {
379
  "VDISABLE invalid",
380
  "VDISABLE valid"
381
};
382
383
384
static int
385
dissect_mount_pathconf_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
386
0
{
387
0
  uint32_t pc_mask;
388
0
  static int * const flags[] = {
389
0
    &hf_mount_pathconf_error_all,
390
0
    &hf_mount_pathconf_error_link_max,
391
0
    &hf_mount_pathconf_error_max_canon,
392
0
    &hf_mount_pathconf_error_max_input,
393
0
    &hf_mount_pathconf_error_name_max,
394
0
    &hf_mount_pathconf_error_path_max,
395
0
    &hf_mount_pathconf_error_pipe_buf,
396
0
    &hf_mount_pathconf_chown_restricted,
397
0
    &hf_mount_pathconf_no_trunc,
398
0
    &hf_mount_pathconf_error_vdisable,
399
0
    NULL
400
0
  };
401
0
  int offset = 0;
402
403
  /*
404
   * Extract the mask first, so we know which other fields the
405
   * server was able to return to us.
406
   */
407
0
  pc_mask = tvb_get_ntohl(tvb, offset+OFFS_MASK) & 0xffff;
408
0
  if (!(pc_mask & (PC_ERROR_LINK_MAX|PC_ERROR_ALL))) {
409
0
    dissect_rpc_uint32(tvb,tree,hf_mount_pathconf_link_max,offset);
410
0
  }
411
0
  offset += 4;
412
413
0
  if (!(pc_mask & (PC_ERROR_MAX_CANON|PC_ERROR_ALL))) {
414
0
    proto_tree_add_item(tree,
415
0
        hf_mount_pathconf_max_canon,tvb,offset+2,2,
416
0
        tvb_get_ntohs(tvb,offset)&0xffff);
417
0
  }
418
0
  offset += 4;
419
420
0
  if (!(pc_mask & (PC_ERROR_MAX_INPUT|PC_ERROR_ALL))) {
421
0
    proto_tree_add_item(tree,
422
0
        hf_mount_pathconf_max_input,tvb,offset+2,2,
423
0
        tvb_get_ntohs(tvb,offset)&0xffff);
424
0
  }
425
0
  offset += 4;
426
427
0
  if (!(pc_mask & (PC_ERROR_NAME_MAX|PC_ERROR_ALL))) {
428
0
    proto_tree_add_item(tree,
429
0
        hf_mount_pathconf_name_max,tvb,offset+2,2,
430
0
        tvb_get_ntohs(tvb,offset)&0xffff);
431
0
  }
432
0
  offset += 4;
433
434
0
  if (!(pc_mask & (PC_ERROR_PATH_MAX|PC_ERROR_ALL))) {
435
0
    proto_tree_add_item(tree,
436
0
        hf_mount_pathconf_path_max,tvb,offset+2,2,
437
0
        tvb_get_ntohs(tvb,offset)&0xffff);
438
0
  }
439
0
  offset += 4;
440
441
0
  if (!(pc_mask & (PC_ERROR_PIPE_BUF|PC_ERROR_ALL))) {
442
0
    proto_tree_add_item(tree,
443
0
        hf_mount_pathconf_pipe_buf,tvb,offset+2,2,
444
0
        tvb_get_ntohs(tvb,offset)&0xffff);
445
0
  }
446
0
  offset += 4;
447
448
0
  offset += 4;  /* skip "pc_xxx" pad field */
449
450
0
  if (!(pc_mask & (PC_ERROR_VDISABLE|PC_ERROR_ALL))) {
451
0
    proto_tree_add_item(tree,
452
0
        hf_mount_pathconf_vdisable,tvb,offset+3,1,
453
0
        tvb_get_ntohs(tvb,offset)&0xffff);
454
0
  }
455
0
  offset += 4;
456
457
0
  proto_tree_add_bitmask(tree, tvb, offset+2, hf_mount_pathconf_mask, ett_mount_pathconf_mask, flags, ENC_BIG_ENDIAN);
458
459
0
  offset += 8;
460
0
  return offset;
461
0
}
462
463
464
/* RFC 1813, Page 107 */
465
static int
466
dissect_mountstat3(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, int offset, int hfindex, uint32_t *status)
467
0
{
468
0
  uint32_t mountstat3;
469
470
0
  mountstat3 = tvb_get_ntohl(tvb, offset);
471
0
  if(mountstat3){
472
0
    col_append_fstr(
473
0
        pinfo->cinfo, COL_INFO, " Error:%s",
474
0
        val_to_str(mountstat3, mount3_mountstat3,
475
0
            "Unknown (0x%08X)"));
476
0
  }
477
478
0
  offset = dissect_rpc_uint32(tvb,tree,hfindex,offset);
479
0
  *status = mountstat3;
480
0
  return offset;
481
0
}
482
483
/* RFC 1831, Page 109 */
484
static int
485
dissect_mount3_mnt_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
486
0
{
487
0
  uint32_t status;
488
0
  uint32_t auth_flavors;
489
0
  uint32_t auth_flavor;
490
0
  uint32_t auth_flavor_i;
491
0
  int offset = 0;
492
493
0
  offset = dissect_mountstat3(pinfo,tvb,tree,offset,hf_mount3_status,&status);
494
495
0
  switch (status) {
496
0
    case 0:
497
0
      offset = dissect_nfs3_fh(tvb,offset,pinfo,tree,"fhandle",NULL,(rpc_call_info_value*)data);
498
499
0
      auth_flavors = tvb_get_ntohl(tvb, offset);
500
0
      proto_tree_add_uint(tree,hf_mount_flavors, tvb,
501
0
        offset, 4, auth_flavors);
502
0
      offset += 4;
503
0
      for (auth_flavor_i = 0 ; auth_flavor_i < auth_flavors ; auth_flavor_i++) {
504
0
        auth_flavor = tvb_get_ntohl(tvb, offset);
505
0
        proto_tree_add_uint(tree,hf_mount_flavor, tvb,
506
0
          offset, 4, auth_flavor);
507
0
        offset += 4;
508
0
      }
509
0
    break;
510
0
    default:
511
      /* void */
512
0
    break;
513
0
  }
514
515
0
  return offset;
516
0
}
517
518
static int
519
dissect_sgi_exportlist(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
520
0
{
521
0
  proto_item* exportlist_item = NULL;
522
0
  proto_tree* exportlist_tree = NULL;
523
0
  int old_offset = offset;
524
0
  const char* directory, *options;
525
526
0
  if (tree) {
527
0
    exportlist_item = proto_tree_add_item(tree, hf_mount_exportlist,
528
0
          tvb, offset, -1, ENC_NA);
529
0
    if (exportlist_item)
530
0
      exportlist_tree = proto_item_add_subtree(exportlist_item,
531
0
            ett_mount_exportlist);
532
0
  }
533
534
0
  offset = dissect_rpc_string(tvb, exportlist_tree,
535
0
      hf_mount_exportlist_directory, offset, &directory);
536
537
0
  offset = dissect_rpc_bool(tvb, exportlist_tree,
538
0
      hf_mount_has_options, offset);
539
540
0
  offset = dissect_rpc_string(tvb, exportlist_tree, hf_mount_options,
541
0
       offset, &options);
542
543
0
  if (exportlist_item) {
544
    /* now we have a nicer string */
545
0
    proto_item_set_text(exportlist_item,
546
0
      "Export List Entry: %s %s", directory,
547
0
      options);
548
    /* now we know, that exportlist is shorter */
549
0
    proto_item_set_len(exportlist_item, offset - old_offset);
550
0
  }
551
552
0
  return offset;
553
0
}
554
555
static int
556
dissect_mount_exportlist_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
557
0
{
558
0
  return dissect_rpc_list(tvb, pinfo, tree, 0,
559
0
    dissect_sgi_exportlist, NULL);
560
0
}
561
562
14
#define ST_RDONLY 0x00000001
563
14
#define ST_NOSUID 0x00000002
564
14
#define ST_NOTRUNC  0x00000004
565
14
#define ST_NODEV  0x20000000
566
14
#define ST_GRPID  0x40000000
567
14
#define ST_LOCAL  0x80000000
568
569
static const true_false_string tos_st_rdonly = {
570
  "Read-only file system",
571
  "Read/Write file system"
572
};
573
574
static const true_false_string tos_st_nosuid = {
575
  "Does not support setuid/setgid semantics",
576
  "Supports setuid/setgid semantics"
577
};
578
579
static const true_false_string tos_st_notrunc = {
580
  "Does not truncate filenames longer than NAME_MAX",
581
  "Truncates filenames longer than NAME_MAX"
582
};
583
584
static const true_false_string tos_st_nodev = {
585
  "Disallows opening of device files",
586
  "Allows opening of device files"
587
};
588
589
static const true_false_string tos_st_grpid = {
590
  "Group ID assigned from directory",
591
  "Group ID not assigned from directory"
592
};
593
594
static const true_false_string tos_st_local = {
595
  "File system is local",
596
  "File system is not local"
597
};
598
599
static int
600
dissect_mount_statvfs_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
601
0
{
602
0
  static int * const flags[] = {
603
0
    &hf_mount_statvfs_flag_rdonly,
604
0
    &hf_mount_statvfs_flag_nosuid,
605
0
    &hf_mount_statvfs_flag_notrunc,
606
0
    &hf_mount_statvfs_flag_nodev,
607
0
    &hf_mount_statvfs_flag_grpid,
608
0
    &hf_mount_statvfs_flag_local,
609
0
    NULL
610
0
  };
611
0
  int offset = 0;
612
613
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_bsize, offset);
614
0
  offset += 4;
615
616
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_frsize, offset);
617
0
  offset += 4;
618
619
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_blocks, offset);
620
0
  offset += 4;
621
622
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_bfree, offset);
623
0
  offset += 4;
624
625
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_bavail, offset);
626
0
  offset += 4;
627
628
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_files, offset);
629
0
  offset += 4;
630
631
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_ffree, offset);
632
0
  offset += 4;
633
634
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_favail, offset);
635
0
  offset += 4;
636
637
0
  dissect_rpc_bytes(tvb, tree, hf_mount_statvfs_basetype, offset,
638
0
      16, true, NULL);
639
0
  offset += 16;
640
641
0
  dissect_rpc_bytes(tvb, tree, hf_mount_statvfs_fstr, offset, 32, false, NULL);
642
0
  offset += 32;
643
644
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_fsid, offset);
645
0
  offset += 4;
646
647
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_mount_statvfs_flag, ett_mount_statvfs_flag, flags, ENC_BIG_ENDIAN);
648
0
  offset += 4;
649
650
0
  dissect_rpc_uint32(tvb, tree, hf_mount_statvfs_namemax, offset);
651
0
  offset += 4;
652
653
0
  return offset;
654
0
}
655
656
/* proc number, "proc name", dissect_request, dissect_reply */
657
658
/* Mount protocol version 1, RFC 1094 */
659
static const vsff mount1_proc[] = {
660
  { 0, "NULL",
661
    dissect_rpc_void, dissect_rpc_void },
662
  { MOUNTPROC_MNT,        "MNT",
663
    dissect_mount_dirpath_call, dissect_mount1_mnt_reply },
664
  { MOUNTPROC_DUMP,       "DUMP",
665
    dissect_rpc_void, dissect_mount_dump_reply },
666
  { MOUNTPROC_UMNT,      "UMNT",
667
    dissect_mount_dirpath_call, dissect_rpc_void },
668
  { MOUNTPROC_UMNTALL,   "UMNTALL",
669
    dissect_rpc_void, dissect_rpc_void },
670
  { MOUNTPROC_EXPORT,    "EXPORT",
671
    dissect_rpc_void, dissect_mount_export_reply },
672
  { MOUNTPROC_EXPORTALL, "EXPORTALL",
673
    dissect_rpc_void, dissect_mount_export_reply },
674
  { 0, NULL, NULL, NULL }
675
};
676
static const value_string mount1_proc_vals[] = {
677
  { 0, "NULL" },
678
  { MOUNTPROC_MNT,       "MNT" },
679
  { MOUNTPROC_DUMP,      "DUMP" },
680
  { MOUNTPROC_UMNT,      "UMNT" },
681
  { MOUNTPROC_UMNTALL,   "UMNTALL" },
682
  { MOUNTPROC_EXPORT,    "EXPORT" },
683
  { MOUNTPROC_EXPORTALL, "EXPORTALL" },
684
  { 0, NULL }
685
};
686
/* end of mount version 1 */
687
688
689
/* Mount protocol version 2, private communication from somebody at Sun;
690
   mount V2 is V1 plus MOUNTPROC_PATHCONF to fetch information for the
691
   POSIX "pathconf()" call. */
692
static const vsff mount2_proc[] = {
693
  { 0,                    "NULL",
694
    dissect_rpc_void, dissect_rpc_void },
695
  { MOUNTPROC_MNT,        "MNT",
696
    dissect_mount_dirpath_call, dissect_mount1_mnt_reply },
697
  { MOUNTPROC_DUMP,       "DUMP",
698
    dissect_rpc_void, dissect_mount_dump_reply },
699
  { MOUNTPROC_UMNT,      "UMNT",
700
    dissect_mount_dirpath_call, dissect_rpc_void },
701
  { MOUNTPROC_UMNTALL,   "UMNTALL",
702
    dissect_rpc_void, dissect_rpc_void },
703
  { MOUNTPROC_EXPORT,    "EXPORT",
704
    dissect_rpc_void, dissect_mount_export_reply },
705
  { MOUNTPROC_EXPORTALL, "EXPORTALL",
706
    dissect_rpc_void, dissect_mount_export_reply },
707
  { MOUNTPROC_PATHCONF,  "PATHCONF",
708
    dissect_mount_dirpath_call, dissect_mount_pathconf_reply },
709
  { 0, NULL, NULL, NULL }
710
};
711
static const value_string mount2_proc_vals[] = {
712
  { 0, "NULL" },
713
  { MOUNTPROC_MNT,       "MNT" },
714
  { MOUNTPROC_DUMP,      "DUMP" },
715
  { MOUNTPROC_UMNT,      "UMNT" },
716
  { MOUNTPROC_UMNTALL,   "UMNTALL" },
717
  { MOUNTPROC_EXPORT,    "EXPORT" },
718
  { MOUNTPROC_EXPORTALL, "EXPORTALL" },
719
  { MOUNTPROC_PATHCONF,  "PATHCONF" },
720
  { 0, NULL }
721
};
722
/* end of mount version 2 */
723
724
725
/* Mount protocol version 3, RFC 1813 */
726
static const vsff mount3_proc[] = {
727
  { 0, "NULL",
728
    dissect_rpc_void, dissect_rpc_void },
729
  { MOUNTPROC_MNT, "MNT",
730
    dissect_mount_dirpath_call, dissect_mount3_mnt_reply },
731
  { MOUNTPROC_DUMP, "DUMP",
732
    dissect_rpc_void, dissect_mount_dump_reply },
733
  { MOUNTPROC_UMNT, "UMNT",
734
    dissect_mount_dirpath_call, dissect_rpc_void },
735
  { MOUNTPROC_UMNTALL, "UMNTALL",
736
    dissect_rpc_void, dissect_rpc_void },
737
  { MOUNTPROC_EXPORT, "EXPORT",
738
    dissect_rpc_void, dissect_mount_export_reply },
739
  { 0, NULL, NULL, NULL }
740
};
741
static const value_string mount3_proc_vals[] = {
742
  { 0, "NULL" },
743
  { MOUNTPROC_MNT, "MNT" },
744
  { MOUNTPROC_DUMP, "DUMP" },
745
  { MOUNTPROC_UMNT, "UMNT" },
746
  { MOUNTPROC_UMNTALL, "UMNTALL" },
747
  { MOUNTPROC_EXPORT, "EXPORT" },
748
  { 0, NULL }
749
};
750
/* end of Mount protocol version 3 */
751
752
static const rpc_prog_vers_info mount_vers_info[] = {
753
  { 1, mount1_proc, &hf_mount_procedure_v1 },
754
  { 2, mount2_proc, &hf_mount_procedure_v2 },
755
  { 3, mount3_proc, &hf_mount_procedure_v3 },
756
};
757
758
/* SGI mount protocol version 1; actually the same as v1 plus
759
   MOUNTPROC_EXPORTLIST and MOUNTPROC_STATVFS */
760
761
static const vsff sgi_mount1_proc[] = {
762
  { 0, "NULL",
763
    dissect_rpc_void, dissect_rpc_void },
764
  { MOUNTPROC_MNT,        "MNT",
765
    dissect_mount_dirpath_call, dissect_mount1_mnt_reply },
766
  { MOUNTPROC_DUMP,       "DUMP",
767
    dissect_rpc_void, dissect_mount_dump_reply },
768
  { MOUNTPROC_UMNT,      "UMNT",
769
    dissect_mount_dirpath_call, dissect_rpc_void },
770
  { MOUNTPROC_UMNTALL,   "UMNTALL",
771
    dissect_rpc_void, dissect_rpc_void },
772
  { MOUNTPROC_EXPORT,    "EXPORT",
773
    dissect_rpc_void, dissect_mount_export_reply },
774
  { MOUNTPROC_EXPORTALL, "EXPORTALL",
775
    dissect_rpc_void, dissect_mount_export_reply },
776
  { MOUNTPROC_EXPORTLIST,"EXPORTLIST",
777
    dissect_rpc_void, dissect_mount_exportlist_reply },
778
  { MOUNTPROC_STATVFS,   "STATVFS",
779
    dissect_mount_dirpath_call, dissect_mount_statvfs_reply },
780
  { 0, NULL, NULL, NULL }
781
};
782
static const value_string sgi_mount1_proc_vals[] = {
783
  { 0, "NULL" },
784
  { MOUNTPROC_MNT,        "MNT" },
785
  { MOUNTPROC_DUMP,       "DUMP" },
786
  { MOUNTPROC_UMNT,       "UMNT" },
787
  { MOUNTPROC_UMNTALL,    "UMNTALL" },
788
  { MOUNTPROC_EXPORT,     "EXPORT" },
789
  { MOUNTPROC_EXPORTALL,  "EXPORTALL" },
790
  { MOUNTPROC_EXPORTLIST, "EXPORTLIST" },
791
  { MOUNTPROC_STATVFS,    "STATVFS" },
792
  { 0, NULL }
793
};
794
/* end of SGI mount protocol version 1 */
795
796
static const rpc_prog_vers_info sgi_mount_vers_info[] = {
797
  { 1, sgi_mount1_proc, &hf_sgi_mount_procedure_v1 },
798
};
799
800
void
801
proto_register_mount(void)
802
14
{
803
14
  static hf_register_info hf[] = {
804
14
    { &hf_mount_procedure_v1, {
805
14
      "V1 Procedure", "mount.procedure_v1", FT_UINT32, BASE_DEC,
806
14
      VALS(mount1_proc_vals), 0, NULL, HFILL }},
807
14
    { &hf_mount_procedure_v2, {
808
14
      "V2 Procedure", "mount.procedure_v2", FT_UINT32, BASE_DEC,
809
14
      VALS(mount2_proc_vals), 0, NULL, HFILL }},
810
14
    { &hf_mount_procedure_v3, {
811
14
      "V3 Procedure", "mount.procedure_v3", FT_UINT32, BASE_DEC,
812
14
      VALS(mount3_proc_vals), 0, NULL, HFILL }},
813
14
    { &hf_sgi_mount_procedure_v1, {
814
14
      "SGI V1 procedure", "mount.procedure_sgi_v1", FT_UINT32, BASE_DEC,
815
14
      VALS(sgi_mount1_proc_vals), 0, NULL, HFILL }},
816
14
    { &hf_mount_path, {
817
14
      "Path", "mount.path", FT_STRING, BASE_NONE,
818
14
      NULL, 0, NULL, HFILL }},
819
14
    { &hf_mount3_status, {
820
14
      "Status", "mount.status", FT_UINT32, BASE_DEC,
821
14
      VALS(mount3_mountstat3), 0, NULL, HFILL }},
822
14
    { &hf_mount_mountlist_hostname, {
823
14
      "Hostname", "mount.dump.hostname", FT_STRING, BASE_NONE,
824
14
      NULL, 0, NULL, HFILL }},
825
14
    { &hf_mount_mountlist_directory, {
826
14
      "Directory", "mount.dump.directory", FT_STRING, BASE_NONE,
827
14
      NULL, 0, NULL, HFILL }},
828
14
    { &hf_mount_mountlist, {
829
14
      "Mount List Entry", "mount.dump.entry", FT_NONE, BASE_NONE,
830
14
      NULL, 0, NULL, HFILL }},
831
14
    { &hf_mount_groups_group, {
832
14
      "Group", "mount.export.group", FT_STRING, BASE_NONE,
833
14
      NULL, 0, NULL, HFILL }},
834
14
    { &hf_mount_groups, {
835
14
      "Groups", "mount.export.groups", FT_NONE, BASE_NONE,
836
14
      NULL, 0, NULL, HFILL }},
837
14
    { &hf_mount_has_options, {
838
14
      "Has options", "mount.export.has_options", FT_UINT32,
839
14
       BASE_DEC, NULL, 0, NULL, HFILL }},
840
14
    { &hf_mount_options, {
841
14
      "Options", "mount.export.options", FT_STRING, BASE_NONE,
842
14
      NULL, 0, NULL, HFILL }},
843
14
    { &hf_mount_exportlist_directory, {
844
14
      "Directory", "mount.export.directory", FT_STRING, BASE_NONE,
845
14
      NULL, 0, NULL, HFILL }},
846
14
    { &hf_mount_exportlist, {
847
14
      "Export List Entry", "mount.export.entry", FT_NONE, BASE_NONE,
848
14
      NULL, 0, NULL, HFILL }},
849
14
    { &hf_mount_pathconf_link_max, {
850
14
      "Maximum number of links to a file", "mount.pathconf.link_max",
851
14
      FT_UINT32, BASE_DEC,
852
14
      NULL, 0, "Maximum number of links allowed to a file", HFILL }},
853
14
    { &hf_mount_pathconf_max_canon, {
854
14
      "Maximum terminal input line length", "mount.pathconf.max_canon",
855
14
      FT_UINT16, BASE_DEC,
856
14
      NULL, 0, "Max tty input line length", HFILL }},
857
14
    { &hf_mount_pathconf_max_input, {
858
14
      "Terminal input buffer size", "mount.pathconf.max_input",
859
14
      FT_UINT16, BASE_DEC,
860
14
      NULL, 0, NULL, HFILL }},
861
14
    { &hf_mount_pathconf_name_max, {
862
14
      "Maximum file name length", "mount.pathconf.name_max",
863
14
      FT_UINT16, BASE_DEC,
864
14
      NULL, 0, NULL, HFILL }},
865
14
    { &hf_mount_pathconf_path_max, {
866
14
      "Maximum path name length", "mount.pathconf.path_max",
867
14
      FT_UINT16, BASE_DEC,
868
14
      NULL, 0, NULL, HFILL }},
869
14
    { &hf_mount_pathconf_pipe_buf, {
870
14
      "Pipe buffer size", "mount.pathconf.pipe_buf",
871
14
      FT_UINT16, BASE_DEC,
872
14
      NULL, 0, "Maximum amount of data that can be written atomically to a pipe", HFILL }},
873
14
    { &hf_mount_pathconf_vdisable, {
874
14
      "VDISABLE character", "mount.pathconf.vdisable_char",
875
14
      FT_UINT8, BASE_HEX,
876
14
      NULL, 0, "Character value to disable a terminal special character", HFILL }},
877
14
    { &hf_mount_pathconf_mask, {
878
14
      "Reply error/status bits", "mount.pathconf.mask",
879
14
      FT_UINT16, BASE_HEX,
880
14
      NULL, 0, "Bit mask with error and status bits", HFILL }},
881
14
    { &hf_mount_pathconf_error_all, {
882
14
      "ERROR_ALL",  "mount.pathconf.mask.error_all",
883
14
      FT_BOOLEAN, 16, TFS(&tos_error_all),
884
14
      PC_ERROR_ALL, NULL, HFILL }},
885
14
    { &hf_mount_pathconf_error_link_max, {
886
14
      "ERROR_LINK_MAX", "mount.pathconf.mask.error_link_max",
887
14
      FT_BOOLEAN, 16, TFS(&tos_error_link_max),
888
14
      PC_ERROR_LINK_MAX, NULL, HFILL }},
889
14
    { &hf_mount_pathconf_error_max_canon, {
890
14
      "ERROR_MAX_CANON", "mount.pathconf.mask.error_max_canon",
891
14
      FT_BOOLEAN, 16, TFS(&tos_error_max_canon),
892
14
      PC_ERROR_MAX_CANON, NULL, HFILL }},
893
14
    { &hf_mount_pathconf_error_max_input, {
894
14
      "ERROR_MAX_INPUT", "mount.pathconf.mask.error_max_input",
895
14
      FT_BOOLEAN, 16, TFS(&tos_error_max_input),
896
14
      PC_ERROR_MAX_INPUT, NULL, HFILL }},
897
14
    { &hf_mount_pathconf_error_name_max, {
898
14
      "ERROR_NAME_MAX", "mount.pathconf.mask.error_name_max",
899
14
      FT_BOOLEAN, 16, TFS(&tos_error_name_max),
900
14
      PC_ERROR_NAME_MAX, NULL, HFILL }},
901
14
    { &hf_mount_pathconf_error_path_max, {
902
14
      "ERROR_PATH_MAX", "mount.pathconf.mask.error_path_max",
903
14
      FT_BOOLEAN, 16, TFS(&tos_error_path_max),
904
14
      PC_ERROR_PATH_MAX, NULL, HFILL }},
905
14
    { &hf_mount_pathconf_error_pipe_buf, {
906
14
      "ERROR_PIPE_BUF", "mount.pathconf.mask.error_pipe_buf",
907
14
      FT_BOOLEAN, 16, TFS(&tos_error_pipe_buf),
908
14
      PC_ERROR_PIPE_BUF, NULL, HFILL }},
909
14
    { &hf_mount_pathconf_chown_restricted, {
910
14
      "CHOWN_RESTRICTED", "mount.pathconf.mask.chown_restricted",
911
14
      FT_BOOLEAN, 16, TFS(&tos_chown_restricted),
912
14
      PC_CHOWN_RESTRICTED, NULL, HFILL }},
913
14
    { &hf_mount_pathconf_no_trunc, {
914
14
      "NO_TRUNC", "mount.pathconf.mask.no_trunc",
915
14
      FT_BOOLEAN, 16, TFS(&tos_no_trunc),
916
14
      PC_NO_TRUNC, NULL, HFILL }},
917
14
    { &hf_mount_pathconf_error_vdisable, {
918
14
      "ERROR_VDISABLE", "mount.pathconf.mask.error_vdisable",
919
14
      FT_BOOLEAN, 16, TFS(&tos_error_vdisable),
920
14
      PC_ERROR_VDISABLE, NULL, HFILL }},
921
14
    { &hf_mount_statvfs_bsize, {
922
14
      "Block size", "mount.statvfs.f_bsize",
923
14
      FT_UINT32, BASE_DEC, NULL, 0,
924
14
      "File system block size", HFILL }},
925
14
    { &hf_mount_statvfs_frsize, {
926
14
      "Fragment size", "mount.statvfs.f_frsize",
927
14
      FT_UINT32, BASE_DEC, NULL, 0,
928
14
      "File system fragment size", HFILL }},
929
14
    { &hf_mount_statvfs_blocks, {
930
14
      "Blocks", "mount.statvfs.f_blocks",
931
14
      FT_UINT32, BASE_DEC, NULL, 0,
932
14
      "Total fragment sized blocks", HFILL }},
933
14
    { &hf_mount_statvfs_bfree, {
934
14
      "Blocks Free", "mount.statvfs.f_bfree",
935
14
      FT_UINT32, BASE_DEC, NULL, 0,
936
14
      "Free fragment sized blocks", HFILL }},
937
14
    { &hf_mount_statvfs_bavail, {
938
14
      "Blocks Available", "mount.statvfs.f_bavail",
939
14
      FT_UINT32, BASE_DEC, NULL, 0,
940
14
      "Available fragment sized blocks", HFILL }},
941
14
    { &hf_mount_statvfs_files, {
942
14
      "Files", "mount.statvfs.f_files",
943
14
      FT_UINT32, BASE_DEC, NULL, 0,
944
14
      "Total files/inodes", HFILL }},
945
14
    { &hf_mount_statvfs_ffree, {
946
14
      "Files Free", "mount.statvfs.f_ffree",
947
14
      FT_UINT32, BASE_DEC, NULL, 0,
948
14
      "Free files/inodes", HFILL }},
949
14
    { &hf_mount_statvfs_favail, {
950
14
      "Files Available", "mount.statvfs.f_favail",
951
14
      FT_UINT32, BASE_DEC, NULL, 0,
952
14
      "Available files/inodes",  HFILL }},
953
14
    { &hf_mount_statvfs_fsid, {
954
14
      "File system ID", "mount.statvfs.f_fsid",
955
14
      FT_UINT32, BASE_DEC, NULL, 0,
956
14
      "File system identifier", HFILL }},
957
14
    { &hf_mount_statvfs_basetype, {
958
14
      "Type", "mount.statvfs.f_basetype",
959
14
      FT_STRING, BASE_NONE, NULL, 0,
960
14
      "File system type", HFILL }},
961
14
    { &hf_mount_statvfs_flag, {
962
14
      "Flags", "mount.statvfs.f_flag",
963
14
      FT_UINT32, BASE_HEX, NULL, 0,
964
14
      "Flags bit-mask", HFILL }},
965
14
    { &hf_mount_statvfs_flag_rdonly, {
966
14
      "ST_RDONLY", "mount.statvfs.f_flag.st_rdonly",
967
14
      FT_BOOLEAN, 32, TFS(&tos_st_rdonly), ST_RDONLY,
968
14
      NULL, HFILL }},
969
14
    { &hf_mount_statvfs_flag_nosuid, {
970
14
      "ST_NOSUID", "mount.statvfs.f_flag.st_nosuid",
971
14
      FT_BOOLEAN, 32, TFS(&tos_st_nosuid), ST_NOSUID,
972
14
      NULL, HFILL }},
973
14
    { &hf_mount_statvfs_flag_notrunc, {
974
14
      "ST_NOTRUNC", "mount.statvfs.f_flag.st_notrunc",
975
14
      FT_BOOLEAN, 32, TFS(&tos_st_notrunc), ST_NOTRUNC,
976
14
      NULL, HFILL }},
977
14
    { &hf_mount_statvfs_flag_nodev, {
978
14
      "ST_NODEV", "mount.statvfs.f_flag.st_nodev",
979
14
       FT_BOOLEAN, 32, TFS(&tos_st_nodev), ST_NODEV,
980
14
      NULL, HFILL }},
981
14
    { &hf_mount_statvfs_flag_grpid, {
982
14
      "ST_GRPID", "mount.statvfs.f_flag.st_grpid",
983
14
      FT_BOOLEAN, 32, TFS(&tos_st_grpid), ST_GRPID,
984
14
      NULL, HFILL }},
985
14
    { &hf_mount_statvfs_flag_local, {
986
14
      "ST_LOCAL", "mount.statvfs.f_flag.st_local",
987
14
      FT_BOOLEAN, 32, TFS(&tos_st_local), ST_LOCAL,
988
14
      NULL, HFILL }},
989
14
    { &hf_mount_statvfs_namemax, {
990
14
      "Maximum file name length", "mount.statvfs.f_namemax",
991
14
      FT_UINT32, BASE_DEC, NULL, 0,
992
14
      NULL, HFILL }},
993
14
    { &hf_mount_statvfs_fstr, {
994
14
      "File system specific string", "mount.statvfs.f_fstr",
995
14
      FT_BYTES, BASE_NONE, NULL, 0,
996
14
      NULL, HFILL }},
997
14
    { &hf_mount_flavors, {
998
14
      "Flavors", "mount.flavors", FT_UINT32, BASE_DEC,
999
14
      NULL, 0, NULL, HFILL }},
1000
14
    { &hf_mount_flavor, {
1001
14
      "Flavor", "mount.flavor", FT_UINT32, BASE_DEC,
1002
14
      VALS(rpc_auth_flavor), 0, NULL, HFILL }},
1003
14
  };
1004
14
  static int *ett[] = {
1005
14
    &ett_mount,
1006
14
    &ett_mount_mountlist,
1007
14
    &ett_mount_groups,
1008
14
    &ett_mount_exportlist,
1009
14
    &ett_mount_pathconf_mask,
1010
14
    &ett_mount_statvfs_flag,
1011
14
  };
1012
1013
14
  proto_mount = proto_register_protocol("Mount Service", "MOUNT",
1014
14
      "mount");
1015
14
  proto_sgi_mount = proto_register_protocol("SGI Mount Service",
1016
14
      "SGI MOUNT", "sgimount");
1017
14
  proto_register_field_array(proto_mount, hf, array_length(hf));
1018
14
  proto_register_subtree_array(ett, array_length(ett));
1019
14
}
1020
1021
void
1022
proto_reg_handoff_mount(void)
1023
14
{
1024
  /* Register the protocols as RPC */
1025
14
  rpc_init_prog(proto_mount, MOUNT_PROGRAM, ett_mount,
1026
14
      G_N_ELEMENTS(mount_vers_info), mount_vers_info);
1027
14
  rpc_init_prog(proto_sgi_mount, SGI_MOUNT_PROGRAM, ett_mount,
1028
14
      G_N_ELEMENTS(sgi_mount_vers_info), sgi_mount_vers_info);
1029
14
}
1030
1031
/*
1032
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1033
 *
1034
 * Local variables:
1035
 * c-basic-offset: 8
1036
 * tab-width: 8
1037
 * indent-tabs-mode: t
1038
 * End:
1039
 *
1040
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1041
 * :indentSize=8:tabSize=8:noTabs=false:
1042
 */