Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-nfs.c
Line
Count
Source
1
/* packet-nfs.c
2
 * Routines for nfs dissection
3
 * Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
4
 * Copyright 2000-2004, Mike Frisch <frisch@hummingbird.com> (NFSv4 decoding)
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * Copied from packet-smb.c
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
#include "config.h"
16
17
#include <stdio.h>  /* for sscanf() */
18
19
#include <epan/packet.h>
20
#include <epan/prefs.h>
21
#include <epan/expert.h>
22
#include <epan/exceptions.h>
23
#include <epan/proto_data.h>
24
#include <epan/to_str.h>
25
#include <epan/decode_as.h>
26
#include <epan/crc16-tvb.h>
27
#include <epan/crc32-tvb.h>
28
#include <epan/srt_table.h>
29
#include <epan/tap.h>
30
#include <epan/tfs.h>
31
32
#include <wsutil/array.h>
33
#include <wsutil/str_util.h>
34
#include <wsutil/ws_padding_to.h>
35
36
#include "packet-nfs.h"
37
#include "packet-rpcrdma.h"
38
39
void proto_register_nfs(void);
40
void proto_reg_handoff_nfs(void);
41
42
/* NON-NFS-version-specific hf variables */
43
static int proto_nfs;
44
static int proto_nfs_unknown;
45
static int proto_nfs_svr4;
46
static int proto_nfs_knfsd_le;
47
static int proto_nfs_nfsd_le;
48
static int proto_nfs_knfsd_new;
49
static int proto_nfs_ontap_v3;
50
static int proto_nfs_ontap_v4;
51
static int proto_nfs_ontap_gx_v3;
52
static int proto_nfs_celerra_vnx;
53
static int proto_nfs_gluster;
54
static int proto_nfs_dcache;
55
static int proto_nfs_primary_data;
56
static int proto_nfs_cb;
57
static int proto_nfsv4;
58
static int hf_nfs_access_check;
59
static int hf_nfs_access_supported;
60
static int hf_nfs_access_rights;
61
static int hf_nfs_access_supp_read;
62
static int hf_nfs_access_supp_lookup;
63
static int hf_nfs_access_supp_modify;
64
static int hf_nfs_access_supp_extend;
65
static int hf_nfs_access_supp_delete;
66
static int hf_nfs_access_supp_execute;
67
static int hf_nfs_access_supp_xattr_read;
68
static int hf_nfs_access_supp_xattr_write;
69
static int hf_nfs_access_supp_xattr_list;
70
static int hf_nfs_access_read;
71
static int hf_nfs_access_lookup;
72
static int hf_nfs_access_modify;
73
static int hf_nfs_access_extend;
74
static int hf_nfs_access_delete;
75
static int hf_nfs_access_execute;
76
static int hf_nfs_access_xattr_read;
77
static int hf_nfs_access_xattr_write;
78
static int hf_nfs_access_xattr_list;
79
static int hf_nfs_access_denied;
80
static int hf_nfs_fh_length;
81
static int hf_nfs_fh_hash;
82
static int hf_nfs_fh_fhandle_data;
83
static int hf_nfs_fh_mount_fileid;
84
static int hf_nfs_fh_mount_generation;
85
static int hf_nfs_fh_snapid;
86
static int hf_nfs_fh_unused;
87
static int hf_nfs_fh_flags;
88
static int hf_nfs_fh_fileid;
89
static int hf_nfs_fh_generation;
90
static int hf_nfs_fh_fsid;
91
static int hf_nfs_fh_export_fileid;
92
static int hf_nfs_fh_export_generation;
93
static int hf_nfs_fh_export_snapid;
94
static int hf_nfs_fh_exportid;
95
static int hf_nfs_fh_file_flag_mntpoint;
96
static int hf_nfs_fh_file_flag_snapdir;
97
static int hf_nfs_fh_file_flag_snapdir_ent;
98
static int hf_nfs_fh_file_flag_empty;
99
static int hf_nfs_fh_file_flag_vbn_access;
100
static int hf_nfs_fh_file_flag_multivolume;
101
static int hf_nfs_fh_file_flag_metadata;
102
static int hf_nfs_fh_file_flag_orphan;
103
static int hf_nfs_fh_file_flag_foster;
104
static int hf_nfs_fh_file_flag_named_attr;
105
static int hf_nfs_fh_file_flag_exp_snapdir;
106
static int hf_nfs_fh_file_flag_vfiler;
107
static int hf_nfs_fh_file_flag_aggr;
108
static int hf_nfs_fh_file_flag_striped;
109
static int hf_nfs_fh_file_flag_private;
110
static int hf_nfs_fh_file_flag_next_gen;
111
static int hf_nfs_fh_gfid;
112
static int hf_nfs_fh_handle_type;
113
static int hf_nfs_fh_fsid_major16_mask;
114
static int hf_nfs_fh_fsid_minor16_mask;
115
static int hf_nfs_fh_fsid_major16;
116
static int hf_nfs_fh_fsid_minor16;
117
static int hf_nfs_fh_fsid_major32;
118
static int hf_nfs_fh_fsid_minor32;
119
static int hf_nfs_fh_fsid_inode;
120
static int hf_nfs_fh_xfsid_major;
121
static int hf_nfs_fh_xfsid_minor;
122
static int hf_nfs_fh_fstype;
123
static int hf_nfs_fh_fn;
124
static int hf_nfs_fh_fn_len;
125
static int hf_nfs_fh_fn_inode;
126
static int hf_nfs_fh_fn_generation;
127
static int hf_nfs_fh_xfn;
128
static int hf_nfs_fh_xfn_len;
129
static int hf_nfs_fh_xfn_inode;
130
static int hf_nfs_fh_xfn_generation;
131
static int hf_nfs_fh_dentry;
132
/* static int hf_nfs_fh_dev; */
133
/* static int hf_nfs_fh_xdev; */
134
static int hf_nfs_fh_dirinode;
135
static int hf_nfs_fh_pinode;
136
static int hf_nfs_fh_hp_len;
137
static int hf_nfs_fh_hp_key;
138
static int hf_nfs_fh_version;
139
static int hf_nfs_fh_auth_type;
140
static int hf_nfs_fh_fsid_type;
141
static int hf_nfs_fh_fileid_type;
142
static int hf_nfs_fh_obj_id;
143
static int hf_nfs_fh_ro_node;
144
static int hf_nfs_fh_obj;
145
static int hf_nfs_fh_obj_fsid;
146
static int hf_nfs_fh_obj_treeid;
147
static int hf_nfs_fh_obj_kindid;
148
static int hf_nfs_fh_obj_inode;
149
static int hf_nfs_fh_obj_gen;
150
static int hf_nfs_fh_ex;
151
static int hf_nfs_fh_ex_fsid;
152
static int hf_nfs_fh_ex_treeid;
153
static int hf_nfs_fh_ex_kindid;
154
static int hf_nfs_fh_ex_inode;
155
static int hf_nfs_fh_ex_gen;
156
static int hf_nfs_fh_flag;
157
static int hf_nfs_fh_endianness;
158
static int hf_nfs_fh_dc_opaque;
159
static int hf_nfs_fh_dc_exportid;
160
static int hf_nfs_fh_dc_handle_type;
161
static int hf_nfs4_fh_pd_share;
162
static int hf_nfs4_fh_pd_flags;
163
static int hf_nfs4_fh_pd_flags_reserved;
164
static int hf_nfs4_fh_pd_flags_version;
165
static int hf_nfs4_fh_pd_container;
166
static int hf_nfs4_fh_pd_inum;
167
static int hf_nfs4_fh_pd_sites;
168
static int hf_nfs4_fh_pd_sites_inum;
169
static int hf_nfs4_fh_pd_sites_siteid;
170
static int hf_nfs4_fh_pd_spaces;
171
static int hf_nfs4_fh_pd_spaces_snapid;
172
static int hf_nfs4_fh_pd_spaces_container;
173
static int hf_nfs_full_name;
174
static int hf_nfs_name;
175
static int hf_nfs_data;
176
static int hf_nfs_symlink_to;
177
static int hf_nfs_readdir_eof;
178
static int hf_nfs_readdir_entry;
179
static int hf_nfs_atime;
180
static int hf_nfs_atime_sec;
181
static int hf_nfs_atime_nsec;
182
static int hf_nfs_atime_usec;
183
static int hf_nfs_mtime;
184
static int hf_nfs_mtime_sec;
185
static int hf_nfs_mtime_nsec;
186
static int hf_nfs_mtime_usec;
187
static int hf_nfs_ctime;
188
static int hf_nfs_ctime_sec;
189
static int hf_nfs_ctime_nsec;
190
static int hf_nfs_ctime_usec;
191
static int hf_nfs_dtime;
192
static int hf_nfs_dtime_sec;
193
static int hf_nfs_dtime_nsec;
194
195
/* Hidden field for v2, v3, and v4 status; also used in dissect-nfsacl.c */
196
int hf_nfs_status;
197
198
/* NFSv2 RFC 1094 hf variables */
199
static int hf_nfs2_procedure;
200
static int hf_nfs2_status;
201
static int hf_nfs2_readlink_data;
202
/* static int hf_nfs2_fattr_type; */
203
static int hf_nfs2_fattr_nlink;
204
static int hf_nfs2_fattr_uid;
205
static int hf_nfs2_fattr_gid;
206
static int hf_nfs2_fattr_size;
207
static int hf_nfs2_fattr_blocksize;
208
static int hf_nfs2_fattr_rdev;
209
static int hf_nfs2_fattr_blocks;
210
static int hf_nfs2_fattr_fsid;
211
static int hf_nfs2_fattr_fileid;
212
static int hf_nfs2_ftype;
213
static int hf_nfs2_mode;
214
static int hf_nfs2_mode_name;
215
static int hf_nfs2_mode_set_user_id;
216
static int hf_nfs2_mode_set_group_id;
217
static int hf_nfs2_mode_save_swap_text;
218
static int hf_nfs2_mode_read_owner;
219
static int hf_nfs2_mode_write_owner;
220
static int hf_nfs2_mode_exec_owner;
221
static int hf_nfs2_mode_read_group;
222
static int hf_nfs2_mode_write_group;
223
static int hf_nfs2_mode_exec_group;
224
static int hf_nfs2_mode_read_other;
225
static int hf_nfs2_mode_write_other;
226
static int hf_nfs2_mode_exec_other;
227
static int hf_nfs2_read_offset;
228
static int hf_nfs2_read_count;
229
static int hf_nfs2_read_totalcount;
230
static int hf_nfs2_write_beginoffset;
231
static int hf_nfs2_write_offset;
232
static int hf_nfs2_write_totalcount;
233
static int hf_nfs2_readdir_cookie;
234
static int hf_nfs2_readdir_count;
235
static int hf_nfs2_readdir_entry_fileid;
236
static int hf_nfs2_readdir_entry_name;
237
static int hf_nfs2_readdir_entry_cookie;
238
static int hf_nfs2_statfs_tsize;
239
static int hf_nfs2_statfs_bsize;
240
static int hf_nfs2_statfs_blocks;
241
static int hf_nfs2_statfs_bfree;
242
static int hf_nfs2_statfs_bavail;
243
244
/* NFSv3 RFC 1813 header format variables */
245
static int hf_nfs3_procedure;
246
static int hf_nfs3_fattr_type;
247
static int hf_nfs3_fattr_nlink;
248
static int hf_nfs3_fattr_uid;
249
static int hf_nfs3_fattr_gid;
250
static int hf_nfs3_fattr_size;
251
static int hf_nfs3_fattr_used;
252
/* static int hf_nfs3_fattr_rdev; */
253
static int hf_nfs3_fattr_fsid;
254
static int hf_nfs3_fattr_fileid;
255
static int hf_nfs3_wcc_attr_size;
256
static int hf_nfs3_set_size;
257
static int hf_nfs3_cookie;
258
static int hf_nfs3_fsstat_resok_tbytes;
259
static int hf_nfs3_fsstat_resok_fbytes;
260
static int hf_nfs3_fsstat_resok_abytes;
261
static int hf_nfs3_fsstat_resok_tfiles;
262
static int hf_nfs3_fsstat_resok_ffiles;
263
static int hf_nfs3_fsstat_resok_afiles;
264
static int hf_nfs3_uid;
265
static int hf_nfs3_gid;
266
static int hf_nfs3_offset;
267
static int hf_nfs3_count;
268
static int hf_nfs3_count_maxcount;
269
static int hf_nfs3_count_dircount;
270
static int hf_nfs3_mode;
271
static int hf_nfs3_mode_suid;
272
static int hf_nfs3_mode_sgid;
273
static int hf_nfs3_mode_sticky;
274
static int hf_nfs3_mode_rusr;
275
static int hf_nfs3_mode_wusr;
276
static int hf_nfs3_mode_xusr;
277
static int hf_nfs3_mode_rgrp;
278
static int hf_nfs3_mode_wgrp;
279
static int hf_nfs3_mode_xgrp;
280
static int hf_nfs3_mode_roth;
281
static int hf_nfs3_mode_woth;
282
static int hf_nfs3_mode_xoth;
283
static int hf_nfs3_readdir_entry_fileid;
284
static int hf_nfs3_readdir_entry_name;
285
static int hf_nfs3_readdir_entry_cookie;
286
static int hf_nfs3_readdirplus_entry_fileid;
287
static int hf_nfs3_readdirplus_entry_name;
288
static int hf_nfs3_readdirplus_entry_cookie;
289
static int hf_nfs3_ftype;
290
static int hf_nfs3_status;
291
static int hf_nfs3_read_eof;
292
static int hf_nfs3_write_stable;
293
static int hf_nfs3_write_committed;
294
static int hf_nfs3_createmode;
295
static int hf_nfs3_fsstat_invarsec;
296
static int hf_nfs3_fsinfo_rtmax;
297
static int hf_nfs3_fsinfo_rtpref;
298
static int hf_nfs3_fsinfo_rtmult;
299
static int hf_nfs3_fsinfo_wtmax;
300
static int hf_nfs3_fsinfo_wtpref;
301
static int hf_nfs3_fsinfo_wtmult;
302
static int hf_nfs3_fsinfo_dtpref;
303
static int hf_nfs3_fsinfo_maxfilesize;
304
static int hf_nfs3_fsinfo_properties;
305
static int hf_nfs3_fsinfo_properties_setattr;
306
static int hf_nfs3_fsinfo_properties_pathconf;
307
static int hf_nfs3_fsinfo_properties_symlinks;
308
static int hf_nfs3_fsinfo_properties_hardlinks;
309
static int hf_nfs3_pathconf_linkmax;
310
static int hf_nfs3_pathconf_name_max;
311
static int hf_nfs3_pathconf_no_trunc;
312
static int hf_nfs3_pathconf_chown_restricted;
313
static int hf_nfs3_pathconf_case_insensitive;
314
static int hf_nfs3_pathconf_case_preserving;
315
static int hf_nfs3_gxfh_utlfield;
316
static int hf_nfs3_gxfh_utlfield_tree;
317
static int hf_nfs3_gxfh_utlfield_jun;
318
static int hf_nfs3_gxfh_utlfield_ver;
319
static int hf_nfs3_gxfh_volcnt;
320
static int hf_nfs3_gxfh_epoch;
321
static int hf_nfs3_gxfh_ldsid;
322
static int hf_nfs3_gxfh_cid;
323
static int hf_nfs3_gxfh_resv;
324
static int hf_nfs3_gxfh_sfhflags;
325
static int hf_nfs3_gxfh_sfhflags_resv1;
326
static int hf_nfs3_gxfh_sfhflags_resv2;
327
static int hf_nfs3_gxfh_sfhflags_ontap7G;
328
static int hf_nfs3_gxfh_sfhflags_ontapGX;
329
static int hf_nfs3_gxfh_sfhflags_striped;
330
static int hf_nfs3_gxfh_sfhflags_empty;
331
static int hf_nfs3_gxfh_sfhflags_snapdirent;
332
static int hf_nfs3_gxfh_sfhflags_snapdir;
333
static int hf_nfs3_gxfh_sfhflags_streamdir;
334
static int hf_nfs3_gxfh_spinfid;
335
static int hf_nfs3_gxfh_spinfuid;
336
static int hf_nfs3_gxfh_exportptid;
337
static int hf_nfs3_gxfh_exportptuid;
338
static int hf_nfs3_verifier;
339
static int hf_nfs3_specdata1;
340
static int hf_nfs3_specdata2;
341
static int hf_nfs3_attributes_follow;
342
static int hf_nfs3_handle_follow;
343
static int hf_nfs3_sattrguard3;
344
345
346
/* NFSv4 RFC 5661 header format variables */
347
static int hf_nfs4_procedure;
348
static int hf_nfs4_status;
349
static int hf_nfs4_op;
350
static int hf_nfs4_main_opcode;
351
static int hf_nfs4_linktext;
352
static int hf_nfs4_tag;
353
static int hf_nfs4_ops_count;
354
static int hf_nfs4_pathname_components;
355
static int hf_nfs4_component;
356
static int hf_nfs4_clientid;
357
/* static int hf_nfs4_ace; */
358
static int hf_nfs4_recall;
359
static int hf_nfs4_open_claim_type;
360
static int hf_nfs4_opentype;
361
static int hf_nfs4_state_protect_how;
362
static int hf_nfs4_limit_by;
363
static int hf_nfs4_open_delegation_type;
364
static int hf_nfs4_why_no_delegation;
365
static int hf_nfs4_ftype;
366
static int hf_nfs4_change_info_atomic;
367
static int hf_nfs4_open_share_access;
368
static int hf_nfs4_open_share_deny;
369
static int hf_nfs4_want_flags;
370
static int hf_nfs4_want_notify_flags;
371
static int hf_nfs4_want_signal_deleg_when_resrc_avail;
372
static int hf_nfs4_want_push_deleg_when_uncontended;
373
static int hf_nfs4_want_deleg_timestamps;
374
static int hf_nfs4_seqid;
375
static int hf_nfs4_lock_seqid;
376
static int hf_nfs4_reqd_attr;
377
static int hf_nfs4_reco_attr;
378
static int hf_nfs4_attr_mask;
379
static int hf_nfs4_attr_count;
380
static int hf_nfs4_set_it_value_follows;
381
static int hf_nfs4_time_how;
382
static int hf_nfs4_time_how4;
383
static int hf_nfs4_fattr_link_support;
384
static int hf_nfs4_fattr_symlink_support;
385
static int hf_nfs4_fattr_named_attr;
386
static int hf_nfs4_fattr_unique_handles;
387
static int hf_nfs4_fattr_archive;
388
static int hf_nfs4_fattr_cansettime;
389
static int hf_nfs4_fattr_case_insensitive;
390
static int hf_nfs4_fattr_case_preserving;
391
static int hf_nfs4_fattr_chown_restricted;
392
static int hf_nfs4_fattr_fh_expire_type;
393
static int hf_nfs4_fattr_fh_expiry_noexpire_with_open;
394
static int hf_nfs4_fattr_fh_expiry_volatile_any;
395
static int hf_nfs4_fattr_fh_expiry_vol_migration;
396
static int hf_nfs4_fattr_fh_expiry_vol_rename;
397
static int hf_nfs4_fattr_hidden;
398
static int hf_nfs4_fattr_homogeneous;
399
static int hf_nfs4_fattr_mimetype;
400
static int hf_nfs4_fattr_no_trunc;
401
static int hf_nfs4_fattr_system;
402
static int hf_nfs4_fattr_owner;
403
static int hf_nfs4_fattr_owner_group;
404
static int hf_nfs4_fattr_size;
405
static int hf_nfs4_fattr_aclsupport;
406
static int hf_nfs4_aclsupport_allow_acl;
407
static int hf_nfs4_aclsupport_deny_acl;
408
static int hf_nfs4_aclsupport_audit_acl;
409
static int hf_nfs4_aclsupport_alarm_acl;
410
static int hf_nfs4_fattr_lease_time;
411
static int hf_nfs4_fattr_fs_charset_cap;
412
static int hf_nfs4_fs_charset_cap_nonutf8;
413
static int hf_nfs4_fs_charset_cap_utf8;
414
static int hf_nfs4_fattr_fileid;
415
static int hf_nfs4_fattr_files_avail;
416
static int hf_nfs4_fattr_files_free;
417
static int hf_nfs4_fattr_files_total;
418
static int hf_nfs4_fattr_maxfilesize;
419
static int hf_nfs4_fattr_maxlink;
420
static int hf_nfs4_fattr_maxname;
421
static int hf_nfs4_fattr_numlinks;
422
static int hf_nfs4_fattr_maxread;
423
static int hf_nfs4_fattr_maxwrite;
424
static int hf_nfs4_fattr_quota_hard;
425
static int hf_nfs4_fattr_quota_soft;
426
static int hf_nfs4_fattr_quota_used;
427
static int hf_nfs4_fattr_space_avail;
428
static int hf_nfs4_fattr_space_free;
429
static int hf_nfs4_fattr_space_total;
430
static int hf_nfs4_fattr_space_used;
431
static int hf_nfs4_fattr_mounted_on_fileid;
432
static int hf_nfs4_fattr_layout_blksize;
433
static int hf_nfs4_mdsthreshold_item;
434
static int hf_nfs4_mdsthreshold_hint_mask;
435
static int hf_nfs4_mdsthreshold_hint_count;
436
static int hf_nfs4_mdsthreshold_mask_count;
437
static int hf_nfs4_mdsthreshold_hint_file;
438
static int hf_nfs4_fattr_security_label_lfs;
439
static int hf_nfs4_fattr_security_label_pi;
440
static int hf_nfs4_fattr_security_label_context;
441
static int hf_nfs4_fattr_umask_mask;
442
static int hf_nfs4_fattr_xattr_support;
443
static int hf_nfs4_fattr_offline;
444
static int hf_nfs4_who;
445
static int hf_nfs4_server;
446
static int hf_nfs4_servers;
447
static int hf_nfs4_fslocation;
448
static int hf_nfs4_stable_how;
449
static int hf_nfs4_dirlist_eof;
450
static int hf_nfs4_offset;
451
static int hf_nfs4_specdata1;
452
static int hf_nfs4_specdata2;
453
static int hf_nfs4_lock_type;
454
static int hf_nfs4_open_rflags;
455
static int hf_nfs4_open_rflags_confirm;
456
static int hf_nfs4_open_rflags_locktype_posix;
457
static int hf_nfs4_open_rflags_preserve_unlinked;
458
static int hf_nfs4_open_rflags_may_notify_lock;
459
static int hf_nfs4_reclaim;
460
static int hf_nfs4_length;
461
static int hf_nfs4_changeid;
462
static int hf_nfs4_changeid_before;
463
static int hf_nfs4_changeid_after;
464
static int hf_nfs4_time;
465
static int hf_nfs4_time_seconds;
466
static int hf_nfs4_time_nseconds;
467
static int hf_nfs4_fsid_major;
468
static int hf_nfs4_fsid_minor;
469
static int hf_nfs4_acetype;
470
static int hf_nfs4_aceflags;
471
static int hf_nfs4_aceflag_file_inherit;
472
static int hf_nfs4_aceflag_dir_inherit;
473
static int hf_nfs4_aceflag_no_prop_inherit;
474
static int hf_nfs4_aceflag_inherit_only;
475
static int hf_nfs4_aceflag_successful_access;
476
static int hf_nfs4_aceflag_failed_access;
477
static int hf_nfs4_aceflag_id_group;
478
static int hf_nfs4_aceflag_inherited_ace;
479
static int hf_nfs4_acemask;
480
static int hf_nfs4_ace_permission;
481
static int hf_nfs4_delegate_type;
482
static int hf_nfs4_secinfo_flavor;
483
static int hf_nfs4_secinfo_arr;
484
static int hf_nfs4_num_blocks;
485
static int hf_nfs4_bytes_per_block;
486
static int hf_nfs4_eof;
487
static int hf_nfs4_verifier;
488
static int hf_nfs4_value_follows;
489
static int hf_nfs4_cookie;
490
static int hf_nfs4_dir_entry_name;
491
static int hf_nfs4_cookie_verf;
492
static int hf_nfs4_cb_program;
493
/* static int hf_nfs4_cb_location; */
494
static int hf_nfs4_recall4;
495
static int hf_nfs4_filesize;
496
static int hf_nfs4_count;
497
static int hf_nfs4_count_dircount;
498
static int hf_nfs4_count_maxcount;
499
static int hf_nfs4_minorversion;
500
static int hf_nfs4_open_owner;
501
static int hf_nfs4_lock_owner;
502
static int hf_nfs4_new_lock_owner;
503
static int hf_nfs4_ond_server_will_push_deleg;
504
static int hf_nfs4_ond_server_will_signal_avail;
505
static int hf_nfs4_sec_oid;
506
static int hf_nfs4_qop;
507
static int hf_nfs4_secinfo_rpcsec_gss_info_service;
508
static int hf_nfs4_attr_dir_create;
509
static int hf_nfs4_client_id;
510
static int hf_nfs4_stateid;
511
static int hf_nfs4_seqid_stateid;
512
static int hf_nfs4_stateid_other;
513
static int hf_nfs4_stateid_hash;
514
static int hf_nfs4_stateid_other_hash;
515
static int hf_nfs4_lock_reclaim;
516
static int hf_nfs4_aclflags;
517
static int hf_nfs4_aclflag_auto_inherit;
518
static int hf_nfs4_aclflag_protected;
519
static int hf_nfs4_aclflag_defaulted;
520
static int hf_nfs4_num_aces;
521
static int hf_nfs4_callback_ident;
522
static int hf_nfs4_r_netid;
523
static int hf_nfs4_gsshandle;
524
static int hf_nfs4_r_addr;
525
static int hf_nfs4_createmode;
526
static int hf_nfs4_op_mask;
527
static int hf_nfs4_read_data_length;
528
static int hf_nfs4_write_data_length;
529
static int hf_nfs4_length_minlength;
530
static int hf_nfs4_layout_type;
531
static int hf_nfs4_layout_return_type;
532
static int hf_nfs4_iomode;
533
/* static int hf_nfs4_stripetype; */
534
/* static int hf_nfs4_mdscommit; */
535
static int hf_nfs4_stripeunit;
536
static int hf_nfs4_newtime;
537
static int hf_nfs4_newoffset;
538
static int hf_nfs4_layout_avail;
539
static int hf_nfs4_newsize;
540
static int hf_nfs4_layoutupdate;
541
static int hf_nfs4_deviceid;
542
static int hf_nfs4_devicenum;
543
static int hf_nfs4_deviceidx;
544
static int hf_nfs4_layout;
545
/* static int hf_nfs4_stripedevs; */
546
/* static int hf_nfs4_devaddr; */
547
static int hf_nfs4_devaddr_ssv_start;
548
static int hf_nfs4_devaddr_ssv_length;
549
static int hf_nfs4_devaddr_scsi_vol_type;
550
static int hf_nfs4_devaddr_scsi_vol_index;
551
static int hf_nfs4_devaddr_scsi_vol_ref_index;
552
static int hf_nfs4_devaddr_ssv_stripe_unit;
553
static int hf_nfs4_devaddr_scsi_vpd_code_set;
554
static int hf_nfs4_devaddr_scsi_vpd_designator_type;
555
static int hf_nfs4_devaddr_scsi_vpd_designator;
556
static int hf_nfs4_devaddr_scsi_private_key;
557
static int hf_nfs4_scsil_ext_file_offset;
558
static int hf_nfs4_scsil_ext_length;
559
static int hf_nfs4_scsil_ext_vol_offset;
560
static int hf_nfs4_scsil_ext_state;
561
static int hf_nfs4_return_on_close;
562
static int hf_nfs4_slotid;
563
static int hf_nfs4_high_slotid;
564
static int hf_nfs4_target_high_slotid;
565
static int hf_nfs4_serverscope4;
566
static int hf_nfs4_minorid;
567
static int hf_nfs4_majorid;
568
static int hf_nfs4_padsize;
569
/* static int hf_nfs4_cbrenforce; */
570
/* static int hf_nfs4_hashalg; */
571
/* static int hf_nfs4_ssvlen; */
572
static int hf_nfs4_maxreqsize;
573
static int hf_nfs4_maxrespsize;
574
static int hf_nfs4_maxrespsizecached;
575
static int hf_nfs4_maxops;
576
static int hf_nfs4_maxreqs;
577
static int hf_nfs4_rdmachanattrs;
578
static int hf_nfs4_machinename;
579
static int hf_nfs4_flavor;
580
static int hf_nfs4_stamp;
581
static int hf_nfs4_uid;
582
static int hf_nfs4_gid;
583
static int hf_nfs4_service;
584
static int hf_nfs4_sessionid;
585
static int hf_nfs4_exchid_call_flags;
586
static int hf_nfs4_exchid_reply_flags;
587
static int hf_nfs4_exchid_flags_moved_refer;
588
static int hf_nfs4_exchid_flags_moved_migr;
589
static int hf_nfs4_exchid_flags_bind_princ;
590
static int hf_nfs4_exchid_flags_non_pnfs;
591
static int hf_nfs4_exchid_flags_pnfs_mds;
592
static int hf_nfs4_exchid_flags_pnfs_ds;
593
static int hf_nfs4_exchid_flags_upd_conf_rec_a;
594
static int hf_nfs4_exchid_flags_confirmed_r;
595
static int hf_nfs4_state_protect_window;
596
static int hf_nfs4_state_protect_num_gss_handles;
597
static int hf_nfs4_sp_parms_hash_algs;
598
static int hf_nfs4_sp_parms_encr_algs;
599
static int hf_nfs4_prot_info_spi_window;
600
static int hf_nfs4_prot_info_svv_length;
601
static int hf_nfs4_prot_info_encr_alg;
602
static int hf_nfs4_prot_info_hash_alg;
603
static int hf_nfs4_nii_domain;
604
static int hf_nfs4_nii_name;
605
static int hf_nfs4_create_session_flags_csa;
606
static int hf_nfs4_create_session_flags_csr;
607
static int hf_nfs4_create_session_flags_persist;
608
static int hf_nfs4_create_session_flags_conn_back_chan;
609
static int hf_nfs4_create_session_flags_conn_rdma;
610
static int hf_nfs4_cachethis;
611
/* static int hf_nfs4_util; */
612
/* static int hf_nfs4_first_stripe_idx; */
613
/* static int hf_nfs4_layout_count; */
614
/* static int hf_nfs4_pattern_offset; */
615
static int hf_nfs4_notify_mask;
616
static int hf_nfs4_notify_type;
617
static int hf_nfs4_notify_deviceid_mask;
618
static int hf_nfs4_notify_deviceid_type;
619
static int hf_nfs4_lrs_present;
620
static int hf_nfs4_nfl_mirrors;
621
static int hf_nfs4_nfl_util;
622
static int hf_nfs4_nfl_util_stripe_size;
623
static int hf_nfs4_nfl_util_commit_thru_mds;
624
static int hf_nfs4_nfl_util_dense;
625
static int hf_nfs4_nfl_fhs;
626
static int hf_nfs4_mirror_eff;
627
static int hf_nfs4_nfl_first_stripe_index;
628
static int hf_nfs4_lrf_body_content;
629
static int hf_nfs4_reclaim_one_fs;
630
static int hf_nfs4_bctsa_dir;
631
static int hf_nfs4_bctsa_use_conn_in_rdma_mode;
632
static int hf_nfs4_bctsr_dir;
633
static int hf_nfs4_bctsr_use_conn_in_rdma_mode;
634
static int hf_nfs4_sequence_status_flags;
635
static int hf_nfs4_sequence_status_flags_cb_path_down;
636
static int hf_nfs4_sequence_status_flags_cb_gss_contexts_expiring;
637
static int hf_nfs4_sequence_status_flags_cb_gss_contexts_expired;
638
static int hf_nfs4_sequence_status_flags_expired_all_state_revoked;
639
static int hf_nfs4_sequence_status_flags_expired_some_state_revoked;
640
static int hf_nfs4_sequence_status_flags_admin_state_revoked;
641
static int hf_nfs4_sequence_status_flags_recallable_state_revoked;
642
static int hf_nfs4_sequence_status_flags_lease_moved;
643
static int hf_nfs4_sequence_status_flags_restart_reclaim_needed;
644
static int hf_nfs4_sequence_status_flags_cb_path_down_session;
645
static int hf_nfs4_sequence_status_flags_backchannel_fault;
646
static int hf_nfs4_sequence_status_flags_devid_changed;
647
static int hf_nfs4_sequence_status_flags_devid_deleted;
648
static int hf_nfs4_secinfo_style;
649
static int hf_nfs4_test_stateid_arg;
650
static int hf_nfs4_test_stateid_res;
651
static int hf_nfs4_seek_data_content;
652
/* static int hf_nfs4_impl_id_len; */
653
static int hf_nfs4_bitmap_data;
654
static int hf_nfs4_huge_bitmap_length;
655
static int hf_nfs4_universal_address_ipv4;
656
static int hf_nfs4_universal_address_ipv6;
657
static int hf_nfs4_getdevinfo;
658
static int hf_nfs4_ff_version;
659
static int hf_nfs4_ff_minorversion;
660
static int hf_nfs4_ff_tightly_coupled;
661
static int hf_nfs4_ff_rsize;
662
static int hf_nfs4_ff_wsize;
663
static int hf_nfs4_fattr_clone_blocksize;
664
static int hf_nfs4_fattr_space_freed;
665
static int hf_nfs4_fattr_change_attr_type;
666
static int hf_nfs4_ff_layout_flags;
667
static int hf_nfs4_ff_layout_flags_no_layoutcommit;
668
static int hf_nfs4_ff_layout_flags_no_io_thru_mds;
669
static int hf_nfs4_ff_layout_flags_no_read_io;
670
static int hf_nfs4_ff_stats_collect_hint;
671
static int hf_nfs4_ff_synthetic_owner;
672
static int hf_nfs4_ff_synthetic_owner_group;
673
static int hf_nfs4_ff_bytes_completed;
674
static int hf_nfs4_ff_bytes_not_delivered;
675
static int hf_nfs4_ff_bytes_requested;
676
static int hf_nfs4_ff_local;
677
static int hf_nfs4_ff_ops_completed;
678
static int hf_nfs4_ff_ops_requested;
679
static int hf_nfs4_io_bytes;
680
static int hf_nfs4_io_count;
681
static int hf_nfs4_layoutstats;
682
static int hf_nfs4_callback_stateids;
683
static int hf_nfs4_callback_stateids_index;
684
static int hf_nfs4_num_offload_status;
685
static int hf_nfs4_offload_status_index;
686
static int hf_nfs4_consecutive;
687
static int hf_nfs4_netloc;
688
static int hf_nfs4_netloc_type;
689
static int hf_nfs4_nl_name;
690
static int hf_nfs4_nl_url;
691
static int hf_nfs4_source_server_index;
692
static int hf_nfs4_source_servers;
693
static int hf_nfs4_synchronous;
694
static int hf_nfs4_device_error_count;
695
static int hf_nfs4_device_errors_index;
696
static int hf_nfs4_ff_ioerrs_count;
697
static int hf_nfs4_ff_ioerrs_index;
698
static int hf_nfs4_ff_ioerrs_length;
699
static int hf_nfs4_ff_ioerrs_offset;
700
static int hf_nfs4_ff_iostats_count;
701
static int hf_nfs4_ff_iostats_index;
702
static int hf_nfs4_io_error_op;
703
static int hf_nfs4_io_hints_mask;
704
static int hf_nfs4_io_hint_count;
705
static int hf_nfs4_io_advise_hint;
706
static int hf_nfs4_cb_recall_any_objs;
707
static int hf_nfs4_cb_recall_any_count;
708
static int hf_nfs4_cb_recall_any_mask;
709
static int hf_nfs4_cb_recall_any_item;
710
static int hf_nfs4_bytes_copied;
711
static int hf_nfs4_read_plus_contents;
712
static int hf_nfs4_read_plus_content_type;
713
static int hf_nfs4_block_size;
714
static int hf_nfs4_block_count;
715
static int hf_nfs4_reloff_blocknum;
716
static int hf_nfs4_blocknum;
717
static int hf_nfs4_reloff_pattern;
718
static int hf_nfs4_pattern_hash;
719
static int hf_nfs4_setxattr_options;
720
static int hf_nfs4_listxattr_maxcount;
721
static int hf_nfs4_listxattr_cookie;
722
static int hf_nfs4_listxattr_names_len;
723
static int hf_nfs4_xattrkey;
724
static int hf_nfs4_listxattr_eof;
725
static int hf_nfs4_gdd_signal_deleg_avail;
726
static int hf_nfs4_gdd_non_fatal_status;
727
static int hf_nfs4_gdd_child_attr_delay;
728
static int hf_nfs4_gdd_dir_attr_delay;
729
static int hf_nfs4_gdd_child_attrs;
730
static int hf_nfs4_gdd_dir_attrs;
731
static int hf_nfs4_nad_last_entry;
732
733
static int ett_nfs;
734
static int ett_nfs_fh_encoding;
735
static int ett_nfs_fh_mount;
736
static int ett_nfs_fh_file;
737
static int ett_nfs_fh_export;
738
static int ett_nfs_fh_fsid;
739
static int ett_nfs_fh_xfsid;
740
static int ett_nfs_fh_fn;
741
static int ett_nfs_fh_xfn;
742
static int ett_nfs_fh_hp;
743
static int ett_nfs_fh_auth;
744
static int ett_nfs_fhandle;
745
static int ett_nfs_timeval;
746
static int ett_nfs_fattr;
747
static int ett_nfs_readdir_entry;
748
static int ett_nfs_fh_obj;
749
static int ett_nfs_fh_ex;
750
static int ett_nfs_utf8string;
751
752
static int ett_nfs2_mode;
753
static int ett_nfs2_sattr;
754
static int ett_nfs2_diropargs;
755
756
static int ett_nfs3_mode;
757
static int ett_nfs3_specdata;
758
static int ett_nfs3_fh;
759
static int ett_nfs3_nfstime;
760
static int ett_nfs3_fattr;
761
static int ett_nfs3_post_op_fh;
762
static int ett_nfs3_sattr;
763
static int ett_nfs3_diropargs;
764
static int ett_nfs3_sattrguard;
765
static int ett_nfs3_set_mode;
766
static int ett_nfs3_set_uid;
767
static int ett_nfs3_set_gid;
768
static int ett_nfs3_set_size;
769
static int ett_nfs3_set_atime;
770
static int ett_nfs3_set_mtime;
771
static int ett_nfs3_pre_op_attr;
772
static int ett_nfs3_post_op_attr;
773
static int ett_nfs3_wcc_attr;
774
static int ett_nfs3_wcc_data;
775
static int ett_nfs3_access;
776
static int ett_nfs3_fsinfo_properties;
777
static int ett_nfs3_gxfh_utlfield;
778
static int ett_nfs3_gxfh_sfhfield;
779
static int ett_nfs3_gxfh_sfhflags;
780
static int ett_nfs4_fh_pd_flags;
781
static int ett_nfs4_fh_pd_sites;
782
static int ett_nfs4_fh_pd_spaces;
783
784
static int ett_nfs4_compound_call;
785
static int ett_nfs4_request_op;
786
static int ett_nfs4_response_op;
787
static int ett_nfs4_access;
788
static int ett_nfs4_access_supp;
789
static int ett_nfs4_close;
790
static int ett_nfs4_commit;
791
static int ett_nfs4_create;
792
static int ett_nfs4_delegpurge;
793
static int ett_nfs4_delegreturn;
794
static int ett_nfs4_getattr;
795
static int ett_nfs4_getattr_args;
796
static int ett_nfs4_getattr_resp;
797
static int ett_nfs4_resok4;
798
static int ett_nfs4_obj_attrs;
799
static int ett_nfs4_fattr_new_attr_vals;
800
static int ett_nfs4_fattr4_attrmask;
801
static int ett_nfs4_attribute;
802
static int ett_nfs4_getfh;
803
static int ett_nfs4_link;
804
static int ett_nfs4_lock;
805
static int ett_nfs4_lockt;
806
static int ett_nfs4_locku;
807
static int ett_nfs4_lookup;
808
static int ett_nfs4_lookupp;
809
static int ett_nfs4_nverify;
810
static int ett_nfs4_open;
811
static int ett_nfs4_openattr;
812
static int ett_nfs4_open_confirm;
813
static int ett_nfs4_open_downgrade;
814
static int ett_nfs4_putfh;
815
static int ett_nfs4_putpubfh;
816
static int ett_nfs4_putrootfh;
817
static int ett_nfs4_read;
818
static int ett_nfs4_readdir;
819
static int ett_nfs4_readlink;
820
static int ett_nfs4_remove;
821
static int ett_nfs4_rename;
822
static int ett_nfs4_renew;
823
static int ett_nfs4_restorefh;
824
static int ett_nfs4_savefh;
825
static int ett_nfs4_secinfo;
826
static int ett_nfs4_setattr;
827
static int ett_nfs4_setclientid;
828
static int ett_nfs4_setclientid_confirm;
829
static int ett_nfs4_verify;
830
static int ett_nfs4_write;
831
static int ett_nfs4_release_lockowner;
832
static int ett_nfs4_backchannel_ctl;
833
static int ett_nfs4_illegal;
834
static int ett_nfs4_verifier;
835
static int ett_nfs4_dirlist;
836
static int ett_nfs4_dir_entry;
837
static int ett_nfs4_pathname;
838
static int ett_nfs4_change_info;
839
static int ett_nfs4_open_delegation;
840
static int ett_nfs4_open_why_no_deleg;
841
static int ett_nfs4_open_claim;
842
static int ett_nfs4_opentype;
843
static int ett_nfs4_lock_owner;
844
static int ett_nfs4_cb_client;
845
static int ett_nfs4_client_id;
846
static int ett_nfs4_clientowner;
847
static int ett_nfs4_exchangeid_call_flags;
848
static int ett_nfs4_exchangeid_reply_flags;
849
static int ett_nfs4_server_owner;
850
static int ett_nfs4_bitmap;
851
static int ett_nfs4_attr_request;
852
static int ett_nfs4_fattr;
853
static int ett_nfs4_fsid;
854
static int ett_nfs4_fs_locations;
855
static int ett_nfs4_fs_location;
856
static int ett_nfs4_open_result_flags;
857
static int ett_nfs4_secinfo_flavor_info;
858
static int ett_nfs4_stateid;
859
static int ett_nfs4_fattr_fh_expire_type;
860
static int ett_nfs4_fattr_fs_charset_cap;
861
static int ett_nfs4_fattr_aclsupport;
862
static int ett_nfs4_aclflag;
863
static int ett_nfs4_ace;
864
static int ett_nfs4_clientaddr;
865
static int ett_nfs4_aceflag;
866
static int ett_nfs4_acemask;
867
static int ett_nfs4_create_session_flags;
868
static int ett_nfs4_sequence_status_flags;
869
static int ett_nfs4_fh_file;
870
static int ett_nfs4_fh_file_flags;
871
static int ett_nfs4_fh_export;
872
static int ett_nfs4_layoutget;
873
static int ett_nfs4_layoutcommit;
874
static int ett_nfs4_layoutreturn;
875
static int ett_nfs4_getdevinfo;
876
static int ett_nfs4_getdevlist;
877
static int ett_nfs4_bind_conn_to_session;
878
static int ett_nfs4_exchange_id;
879
static int ett_nfs4_create_session;
880
static int ett_nfs4_destroy_session;
881
static int ett_nfs4_free_stateid;
882
static int ett_nfs4_get_dir_delegation;
883
static int ett_nfs4_secinfo_no_name;
884
static int ett_nfs4_sequence;
885
static int ett_nfs4_slotid;
886
static int ett_nfs4_sr_status;
887
static int ett_nfs4_serverscope;
888
static int ett_nfs4_minorid;
889
static int ett_nfs4_majorid;
890
static int ett_nfs4_persist;
891
static int ett_nfs4_backchan;
892
static int ett_nfs4_rdmamode;
893
static int ett_nfs4_padsize;
894
static int ett_nfs4_cbrenforce;
895
static int ett_nfs4_hashalg;
896
static int ett_nfs4_ssvlen;
897
static int ett_nfs4_maxreqsize;
898
static int ett_nfs4_maxrespsize;
899
static int ett_nfs4_maxrespsizecached;
900
static int ett_nfs4_maxops;
901
static int ett_nfs4_maxreqs;
902
static int ett_nfs4_streamchanattrs;
903
static int ett_nfs4_rdmachanattrs;
904
static int ett_nfs4_sec_parms_array;
905
static int ett_nfs4_sec_parms_item;
906
static int ett_nfs4_gids;
907
static int ett_nfs4_machinename;
908
static int ett_nfs4_flavor;
909
static int ett_nfs4_stamp;
910
static int ett_nfs4_uid;
911
static int ett_nfs4_gid;
912
static int ett_nfs4_service;
913
static int ett_nfs4_sessionid;
914
static int ett_nfs4_layoutseg;
915
static int ett_nfs4_layoutseg_sub;
916
static int ett_nfs4_nfl_util;
917
static int ett_nfs4_test_stateid;
918
static int ett_nfs4_destroy_clientid;
919
static int ett_nfs4_reclaim_complete;
920
static int ett_nfs4_allocate;
921
static int ett_nfs4_deallocate;
922
static int ett_nfs4_seek;
923
static int ett_nfs4_chan_attrs;
924
static int ett_nfs4_want_notify_flags;
925
static int ett_nfs4_ff_layout_flags;
926
static int ett_nfs4_scsi_layout_vol;
927
static int ett_nfs4_scsi_layout_vol_indices;
928
static int ett_nfs4_layoutstats;
929
static int ett_nfs4_io_info;
930
static int ett_nfs4_io_latency;
931
static int ett_nfs4_io_time;
932
static int ett_nfs4_callback_stateids_sub;
933
static int ett_nfs4_source_servers_sub;
934
static int ett_nfs4_copy;
935
static int ett_nfs4_copy_notify;
936
static int ett_nfs4_device_errors_sub;
937
static int ett_nfs4_layouterror;
938
static int ett_nfs4_ff_ioerrs_sub;
939
static int ett_nfs4_ff_iostats_sub;
940
static int ett_nfs4_clone;
941
static int ett_nfs4_getxattr;
942
static int ett_nfs4_setxattr;
943
static int ett_nfs4_listxattr;
944
static int ett_nfs4_removexattr;
945
static int ett_nfs4_offload_cancel;
946
static int ett_nfs4_offload_status;
947
static int ett_nfs4_osr_complete_sub;
948
static int ett_nfs4_io_advise;
949
static int ett_nfs4_read_plus;
950
static int ett_nfs4_read_plus_content_sub;
951
static int ett_nfs4_write_same;
952
static int ett_nfs4_listxattr_names;
953
static int ett_nfs4_notify_delay;
954
static int ett_nfs4_notify_attrs;
955
static int ett_nfs4_cb_notify_changes;
956
static int ett_nfs4_cb_notify_list_entries;
957
static int ett_nfs4_cb_notify_attr4_dir;
958
static int ett_nfs4_cb_notify_attr4_child;
959
static int ett_nfs4_cb_notify_remove4;
960
static int ett_nfs4_cb_notify_add4;
961
static int ett_nfs4_cb_notify_rename4;
962
static int ett_nfs4_nfstime;
963
964
static expert_field ei_nfs_too_many_ops;
965
static expert_field ei_nfs_not_vnx_file;
966
static expert_field ei_nfs_too_many_bitmaps;
967
static expert_field ei_nfs_bitmap_no_dissector;
968
static expert_field ei_nfs_bitmap_skip_value;
969
static expert_field ei_nfs_bitmap_undissected_data;
970
static expert_field ei_nfs4_stateid_deprecated;
971
static expert_field ei_nfs_file_system_cycle;
972
973
static int nfsv4_tap;
974
975
static const true_false_string tfs_read_write = { "Read", "Write" };
976
977
/*
978
 * Bitmaps are currently used for attributes and state_protect bits.
979
 * Currently we don't expect more than 4 words, but future protocol
980
 * revisions might add more bits, and in theory an implementation
981
 * might legally zero-pad a bitmask out to something longer.  We keep
982
 * a generous maximum here just as a sanity check:
983
 */
984
0
#define MAX_BITMAPS 100
985
986
/* Prototype for function to dissect attribute value */
987
typedef unsigned (dissect_bitmap_item_t)(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
988
    rpc_call_info_value *civ, uint32_t opcode, uint32_t fh_idx,
989
    proto_tree *attr_tree, proto_item *attr_item,
990
    uint32_t bit_num, void *battr_data);
991
992
/* Prototype for function to return the header field for the item label */
993
typedef unsigned (get_bitmap_hinfo_t)(uint32_t bit_num);
994
995
/* Bitmap type */
996
typedef enum {
997
  NFS4_BITMAP_MASK,   /* Dissect the bitmap mask only */
998
  NFS4_BITMAP_VALUES  /* Dissect the bitmap mask and their values */
999
} nfs4_bitmap_type_t;
1000
1001
/*
1002
 * Bitmap info structure to customize dissect_nfs4_bitmap() behavior
1003
 * Do not display the item when its corresponding hf_* label is set to NULL
1004
 */
1005
typedef struct _nfs4_bitmap_info_t {
1006
  value_string_ext       *vse_names_ext; /* Extended value strings which maps bit number to attribute name,
1007
            * append list of attribute names to the attr mask header line */
1008
  dissect_bitmap_item_t  *dissect_battr; /* Function to dissect attribute value given by the bit number */
1009
1010
  void *battr_data;      /* Data pass to function dissect_battr */
1011
1012
  int  *hf_mask_label;   /* Label for bitmap mask. If this is set to NULL the mask bytes are just consumed */
1013
  int  *hf_item_label;   /* Label for bitmap item (see get_item_label below) */
1014
  int  *hf_item_count;   /* Label for hidden attribute to display the number of bits set */
1015
  int  *hf_mask_count;   /* Label to display the number of masks in the bitmap */
1016
  int  *hf_btmap_data;   /* Label to display bitmap value data as an opaque */
1017
1018
  get_bitmap_hinfo_t  *get_item_label;   /* Pointer to function to return a dynamically generated hf variable
1019
            * for the item label, this takes precedence over hf_item_label */
1020
} nfs4_bitmap_info_t;
1021
1022
/* Types of fhandles we can dissect */
1023
static dissector_table_t nfs_fhandle_table;
1024
1025
typedef struct nfs_fhandle_data {
1026
  int len;
1027
  const unsigned char *fh;
1028
} nfs_fhandle_data_t;
1029
1030
/* For dissector helpers which take a "levels" argument to indicate how
1031
 * many expansions up they should populate the expansion items with
1032
 * text to enhance useability, this flag to "levels" specify that the
1033
 * text should also be appended to COL_INFO
1034
 */
1035
0
#define COL_INFO_LEVEL 0x80000000
1036
1037
1038
/* fhandle displayfilters to match also corresponding request/response
1039
   packet in addition to the one containing the actual filehandle */
1040
bool nfs_fhandle_reqrep_matching;
1041
static wmem_tree_t *nfs_fhandle_frame_table;
1042
1043
1044
/* file name snooping */
1045
bool nfs_file_name_snooping;
1046
static bool nfs_file_name_full_snooping;
1047
typedef struct nfs_name_snoop {
1048
  int        fh_length;
1049
  unsigned char *fh;
1050
  int        name_len;
1051
  char        *name;
1052
  int        parent_len;
1053
  unsigned char *parent;
1054
  int        full_name_len;
1055
  char        *full_name;
1056
  bool         fs_cycle;
1057
} nfs_name_snoop_t;
1058
1059
typedef struct nfs_name_snoop_key {
1060
  int key;
1061
  int fh_length;
1062
  const unsigned char *fh;
1063
} nfs_name_snoop_key_t;
1064
1065
static GHashTable *nfs_name_snoop_readdir;
1066
static GHashTable *nfs_name_snoop_unmatched;
1067
1068
static GHashTable *nfs_name_snoop_matched;
1069
1070
static wmem_tree_t *nfs_name_snoop_known;
1071
static wmem_tree_t *nfs_file_handles;
1072
1073
static bool nfs_display_v4_tag = true;
1074
static bool display_major_nfs4_ops = true;
1075
1076
/* Types of RDMA reduced opaque data */
1077
typedef enum {
1078
  R_UTF8STRING,
1079
  R_NFS2_PATH,
1080
  R_NFS3_PATH,
1081
  R_NFSDATA,
1082
} rdma_reduce_type_t;
1083
1084
static unsigned dissect_nfsdata_reduced(rdma_reduce_type_t rtype, tvbuff_t *tvb, packet_info* pinfo,
1085
      unsigned offset, proto_tree *tree, int hf, const char **name);
1086
1087
static unsigned dissect_nfs4_stateid(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint16_t *hash);
1088
1089
static void nfs4_cb_register_prog(tvbuff_t *tvb, int offset);
1090
1091
static void nfs_prompt(packet_info *pinfo _U_, char* result)
1092
0
{
1093
0
  snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Decode NFS file handles as");
1094
0
}
1095
1096
/* This function will store one nfs filehandle in our global tree of
1097
 * filehandles.
1098
 * We store all filehandles we see in this tree so that every unique
1099
 * filehandle is only stored once with a unique pointer.
1100
 * We need to store pointers to filehandles in several of our other
1101
 * structures and this is a way to make sure we don't keep any redundant
1102
 * copies around for a specific filehandle.
1103
 *
1104
 * If this is the first time this filehandle has been seen an se block
1105
 * is allocated to store the filehandle in.
1106
 * If this filehandle has already been stored in the tree this function returns
1107
 * a pointer to the original copy.
1108
 */
1109
static nfs_fhandle_data_t *
1110
store_nfs_file_handle(nfs_fhandle_data_t *nfs_fh)
1111
0
{
1112
0
  uint32_t        fhlen;
1113
0
  uint32_t       *fhdata;
1114
0
  wmem_tree_key_t     fhkey[3];
1115
0
  nfs_fhandle_data_t *new_nfs_fh;
1116
1117
0
  fhlen = nfs_fh->len/4;
1118
  /* align the file handle data */
1119
0
  fhdata = (uint32_t *)g_memdup2(nfs_fh->fh, fhlen*4);
1120
0
  fhkey[0].length = 1;
1121
0
  fhkey[0].key  = &fhlen;
1122
0
  fhkey[1].length = fhlen;
1123
0
  fhkey[1].key  = fhdata;
1124
0
  fhkey[2].length = 0;
1125
1126
0
  new_nfs_fh = (nfs_fhandle_data_t *)wmem_tree_lookup32_array(nfs_file_handles, &fhkey[0]);
1127
0
  if (new_nfs_fh) {
1128
0
    g_free(fhdata);
1129
0
    return new_nfs_fh;
1130
0
  }
1131
1132
0
  new_nfs_fh = wmem_new(wmem_file_scope(), nfs_fhandle_data_t);
1133
0
  new_nfs_fh->len = nfs_fh->len;
1134
0
  new_nfs_fh->fh = (const unsigned char *)wmem_memdup(wmem_file_scope(), nfs_fh->fh, nfs_fh->len);
1135
0
  fhlen = nfs_fh->len/4;
1136
0
  fhkey[0].length = 1;
1137
0
  fhkey[0].key  = &fhlen;
1138
0
  fhkey[1].length = fhlen;
1139
0
  fhkey[1].key  = fhdata;
1140
0
  fhkey[2].length = 0;
1141
0
  wmem_tree_insert32_array(nfs_file_handles, &fhkey[0], new_nfs_fh);
1142
1143
0
  g_free(fhdata);
1144
0
  return new_nfs_fh;
1145
0
}
1146
1147
1148
static int
1149
nfs_name_snoop_matched_equal(const void *k1, const void *k2)
1150
0
{
1151
0
  const nfs_name_snoop_key_t *key1 = (const nfs_name_snoop_key_t *)k1;
1152
0
  const nfs_name_snoop_key_t *key2 = (const nfs_name_snoop_key_t *)k2;
1153
1154
0
  return (key1->key == key2->key)
1155
0
       &&(key1->fh_length == key2->fh_length)
1156
0
       &&(!memcmp(key1->fh, key2->fh, key1->fh_length));
1157
0
}
1158
1159
1160
static unsigned
1161
nfs_name_snoop_matched_hash(const void *k)
1162
0
{
1163
0
  const nfs_name_snoop_key_t *key = (const nfs_name_snoop_key_t *)k;
1164
0
  int i;
1165
0
  unsigned hash;
1166
1167
0
  hash = key->key;
1168
0
  for (i=0; i<key->fh_length; i++)
1169
0
    hash ^= key->fh[i];
1170
1171
0
  return hash;
1172
0
}
1173
1174
1175
static void
1176
nfs_name_snoop_value_destroy(void *value)
1177
0
{
1178
0
  nfs_name_snoop_t *nns = (nfs_name_snoop_t *)value;
1179
1180
0
  g_free((void *)nns->name);
1181
0
  g_free((void *)nns->full_name);
1182
0
  wmem_free(NULL, nns->parent);
1183
0
  wmem_free(NULL, nns->fh);
1184
0
  g_free(nns);
1185
0
}
1186
1187
1188
static void
1189
nfs_name_snoop_init(void)
1190
16
{
1191
16
  nfs_name_snoop_readdir =
1192
16
    g_hash_table_new_full(g_int64_hash,
1193
16
    g_int64_equal,
1194
16
    g_free, nfs_name_snoop_value_destroy);
1195
16
  nfs_name_snoop_unmatched =
1196
16
    g_hash_table_new_full(g_int64_hash,
1197
16
    g_int64_equal,
1198
16
    g_free, nfs_name_snoop_value_destroy);
1199
16
  nfs_name_snoop_matched =
1200
16
    g_hash_table_new_full(nfs_name_snoop_matched_hash,
1201
16
    nfs_name_snoop_matched_equal,
1202
16
    NULL, nfs_name_snoop_value_destroy);
1203
16
}
1204
1205
static void
1206
nfs_name_snoop_cleanup(void)
1207
0
{
1208
0
  g_hash_table_destroy(nfs_name_snoop_readdir);
1209
0
  g_hash_table_destroy(nfs_name_snoop_unmatched);
1210
0
  g_hash_table_destroy(nfs_name_snoop_matched);
1211
0
}
1212
1213
1214
void
1215
nfs_name_snoop_add_name(uint64_t id, tvbuff_t *tvb, unsigned name_offset, unsigned name_len, unsigned parent_offset,
1216
  unsigned parent_len, const char *name)
1217
0
{
1218
0
  nfs_name_snoop_t *nns;
1219
0
  const char   *ptr;
1220
0
  uint64_t   *key;
1221
1222
0
  if (name_len <= 0) {
1223
    /* Do we need some way to signal an error here? This could be
1224
     * programmatic or just a corrupt packet, depending on the
1225
     * caller... */
1226
0
    return;
1227
0
  }
1228
1229
  /* filter out all '.' and '..' names */
1230
0
  if (!name) {
1231
0
    ptr = (const char *)tvb_get_ptr(tvb, name_offset, name_len);
1232
0
  } else {
1233
0
    ptr = name;
1234
0
  }
1235
0
  if (ptr[0] == '.') {
1236
0
    if (name_len <= 1 || ptr[1] == 0) {
1237
0
      return;
1238
0
    }
1239
0
    if (ptr[1] == '.') {
1240
0
      if (name_len <= 2 || ptr[2] == 0) {
1241
0
        return;
1242
0
      }
1243
0
    }
1244
0
  }
1245
1246
0
  nns = g_new(nfs_name_snoop_t, 1);
1247
1248
0
  nns->fh_length = 0;
1249
0
  nns->fh = NULL;
1250
1251
0
  if (parent_len) {
1252
0
    nns->parent_len = parent_len;
1253
0
    nns->parent = (unsigned char *)tvb_memdup(NULL, tvb, parent_offset, parent_len);
1254
0
  } else {
1255
0
    nns->parent_len = 0;
1256
0
    nns->parent = NULL;
1257
0
  }
1258
1259
0
  if (name) {
1260
0
    nns->name_len = (int)strlen(name);
1261
0
    nns->name = g_strdup(name);
1262
0
  } else {
1263
0
    nns->name_len = name_len;
1264
0
    nns->name = (char *)g_malloc(name_len+1);
1265
0
    memcpy(nns->name, ptr, name_len);
1266
0
  }
1267
0
  nns->name[nns->name_len] = 0;
1268
1269
0
  nns->full_name_len = 0;
1270
0
  nns->full_name = NULL;
1271
0
  nns->fs_cycle = false;
1272
1273
  /* any old entry will be deallocated and removed */
1274
0
  key = g_new0(uint64_t, 1);
1275
0
  *key = id;
1276
0
  g_hash_table_insert(nfs_name_snoop_unmatched, key, nns);
1277
0
}
1278
1279
1280
static void
1281
nfs_name_snoop_add_fh(uint64_t id, tvbuff_t *tvb, int fh_offset, int fh_length)
1282
0
{
1283
0
  unsigned char      *fh;
1284
0
  nfs_name_snoop_t     *nns;
1285
0
  nfs_name_snoop_key_t *key;
1286
0
  gpointer             stolen_key;
1287
1288
0
  if (fh_length <= 0 || fh_length > 128 /* NFS4_FHSIZE */)
1289
0
    return;
1290
1291
  /* find which request we correspond to */
1292
0
  nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_unmatched, &id);
1293
0
  if (!nns) {
1294
    /* oops couldn't find matching request, bail out */
1295
0
    return;
1296
0
  }
1297
1298
  /* if we have already seen this response earlier */
1299
0
  if (nns->fh) {
1300
0
    return;
1301
0
  }
1302
1303
  /* oki, we have a new entry */
1304
0
  fh = (unsigned char *)tvb_memdup(NULL, tvb, fh_offset, fh_length);
1305
0
  nns->fh = fh;
1306
0
  nns->fh_length = fh_length;
1307
1308
0
  key = wmem_new(wmem_file_scope(), nfs_name_snoop_key_t);
1309
0
  key->key = 0;
1310
0
  key->fh_length = nns->fh_length;
1311
0
  key->fh = nns->fh;
1312
1313
0
  g_hash_table_steal_extended(nfs_name_snoop_unmatched, &id, &stolen_key, NULL);
1314
0
  g_free(stolen_key);
1315
0
  g_hash_table_replace(nfs_name_snoop_matched, key, nns);
1316
0
}
1317
1318
static void
1319
nfs_name_snoop_readdir_add_parent_fh(uint64_t id, tvbuff_t *tvb, int fh_offset, int fh_length)
1320
0
{
1321
0
  nfs_name_snoop_t     *nns;
1322
0
  unsigned char        *fh;
1323
0
  uint64_t             *key;
1324
1325
0
  if (fh_length <= 0 || fh_length > 128 /* NFS4_FHSIZE */)
1326
0
    return;
1327
1328
0
  fh = (unsigned char *)tvb_memdup(NULL, tvb, fh_offset, fh_length);
1329
1330
0
  nns = g_new0(nfs_name_snoop_t, 1);
1331
0
  nns->parent_len = fh_length;
1332
0
  nns->parent = fh;
1333
1334
0
  key = g_new0(uint64_t, 1);
1335
0
  *key = id;
1336
0
  g_hash_table_insert(nfs_name_snoop_readdir, key, nns);
1337
0
}
1338
1339
static void
1340
nfs_name_snoop_readdir_add_child_fh_name(uint64_t id, tvbuff_t *tvb, int fh_offset, int fh_length, const char *name)
1341
0
{
1342
0
  nfs_name_snoop_t     *readdir_nns;
1343
0
  unsigned char        *fh;
1344
0
  nfs_name_snoop_t     *nns;
1345
0
  nfs_name_snoop_key_t *key;
1346
1347
0
  if (fh_length <= 0 || fh_length > 128 /* NFS4_FHSIZE */)
1348
0
    return;
1349
1350
0
  if (name[0] == '\0' || strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
1351
0
    return;
1352
1353
0
  readdir_nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_readdir, &id);
1354
0
  if (!readdir_nns)
1355
0
    return;
1356
1357
0
  fh = (unsigned char *)tvb_memdup(NULL, tvb, fh_offset, fh_length);
1358
1359
0
  nns = g_new(nfs_name_snoop_t, 1);
1360
0
  nns->fh_length = fh_length;
1361
0
  nns->fh = fh;
1362
0
  nns->parent_len = readdir_nns->parent_len;
1363
0
  nns->parent = g_malloc(readdir_nns->parent_len);
1364
0
  memcpy(nns->parent, readdir_nns->parent, readdir_nns->parent_len);
1365
0
  nns->name_len = (int)strlen(name);
1366
0
  nns->name = g_strdup(name);
1367
0
  nns->full_name_len = 0;
1368
0
  nns->full_name = NULL;
1369
0
  nns->fs_cycle = false;
1370
1371
0
  key = wmem_new(wmem_file_scope(), nfs_name_snoop_key_t);
1372
0
  key->key = 0;
1373
0
  key->fh_length = nns->fh_length;
1374
0
  key->fh = nns->fh;
1375
1376
0
  g_hash_table_replace(nfs_name_snoop_matched, key, nns);
1377
1378
  /* do not remove entry from the nfs_name_snoop_readdir as it is used for more child names, not just this one */
1379
0
}
1380
1381
0
#define NFS_MAX_FS_DEPTH 100
1382
1383
static void
1384
// NOLINTNEXTLINE(misc-no-recursion)
1385
nfs_full_name_snoop(packet_info *pinfo, nfs_name_snoop_t *nns, int *len, char **name, char **pos)
1386
0
{
1387
0
  nfs_name_snoop_t     *parent_nns = NULL;
1388
0
  nfs_name_snoop_key_t  key;
1389
1390
  /* check if the nns component ends with a '/' else we just allocate
1391
     an extra byte to len to accommodate for it later */
1392
0
  if (nns->name_len > 0 && nns->name[nns->name_len-1] != '/') {
1393
0
    (*len)++;
1394
0
  }
1395
1396
0
  (*len) += nns->name_len;
1397
1398
0
  if (nns->parent == NULL) {
1399
0
    *name = (char *)g_malloc((*len)+1);
1400
0
    *pos = *name;
1401
1402
0
    *pos += snprintf(*pos, (*len)+1, "%s", nns->name);
1403
0
    DISSECTOR_ASSERT((*pos-*name) <= *len);
1404
0
    return;
1405
0
  }
1406
1407
0
  key.key = 0;
1408
0
  key.fh_length = nns->parent_len;
1409
0
  key.fh = nns->parent;
1410
1411
0
  parent_nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_matched, &key);
1412
1413
0
  if (parent_nns) {
1414
0
    unsigned fs_depth = p_get_proto_depth(pinfo, proto_nfs);
1415
0
    if (++fs_depth >= NFS_MAX_FS_DEPTH) {
1416
0
      nns->fs_cycle = true;
1417
0
      return;
1418
0
    }
1419
0
    p_set_proto_depth(pinfo, proto_nfs, fs_depth);
1420
1421
0
    nfs_full_name_snoop(pinfo, parent_nns, len, name, pos);
1422
0
    if (*name) {
1423
      /* make sure components are '/' separated */
1424
0
      *pos += snprintf(*pos, (*len+1) - (*pos-*name), "%s%s",
1425
0
             (*pos > *name && (*pos)[-1] != '/')?"/":"", nns->name);
1426
0
      DISSECTOR_ASSERT((*pos-*name) <= *len);
1427
0
    }
1428
0
    p_set_proto_depth(pinfo, proto_nfs, fs_depth - 1);
1429
0
    return;
1430
0
  }
1431
1432
0
  return;
1433
0
}
1434
1435
1436
static void
1437
nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_offset,
1438
          int fh_length, bool hidden)
1439
0
{
1440
0
  nfs_name_snoop_key_t  key;
1441
0
  nfs_name_snoop_t     *nns = NULL;
1442
1443
  /* if this is a new packet, see if we can register the mapping */
1444
0
  if (!pinfo->fd->visited) {
1445
0
    key.key = 0;
1446
0
    key.fh_length = fh_length;
1447
0
    key.fh = (const unsigned char *)tvb_get_ptr(tvb, fh_offset, fh_length);
1448
1449
0
    nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_matched, &key);
1450
0
    if (nns) {
1451
0
      uint32_t fhlen;
1452
0
      uint32_t *fhdata;
1453
0
      wmem_tree_key_t fhkey[3];
1454
1455
0
      fhlen = nns->fh_length;
1456
      /* align it */
1457
0
      fhdata = (uint32_t *)g_memdup2(nns->fh, fhlen);
1458
0
      fhkey[0].length = 1;
1459
0
      fhkey[0].key  = &fhlen;
1460
0
      fhkey[1].length = fhlen/4;
1461
0
      fhkey[1].key  = fhdata;
1462
0
      fhkey[2].length = 0;
1463
0
      wmem_tree_insert32_array(nfs_name_snoop_known, &fhkey[0], nns);
1464
0
      g_free(fhdata);
1465
1466
0
      if (nfs_file_name_full_snooping) {
1467
0
        char *name = NULL, *pos = NULL;
1468
0
        int len = 0;
1469
1470
0
        nfs_full_name_snoop(pinfo, nns, &len, &name, &pos);
1471
0
        if (name) {
1472
0
          g_free(nns->full_name);
1473
0
          nns->full_name = name;
1474
0
          nns->full_name_len = len;
1475
0
        }
1476
0
      }
1477
0
    }
1478
0
  }
1479
1480
  /* see if we know this mapping */
1481
0
  if (!nns) {
1482
0
    uint32_t fhlen;
1483
0
    uint32_t *fhdata;
1484
0
    wmem_tree_key_t fhkey[3];
1485
1486
0
    fhlen = fh_length;
1487
    /* align it */
1488
0
    fhdata = (uint32_t *)tvb_memdup(pinfo->pool, tvb, fh_offset, fh_length);
1489
0
    fhkey[0].length = 1;
1490
0
    fhkey[0].key  = &fhlen;
1491
0
    fhkey[1].length = fhlen/4;
1492
0
    fhkey[1].key  = fhdata;
1493
0
    fhkey[2].length = 0;
1494
1495
0
    nns = (nfs_name_snoop_t *)wmem_tree_lookup32_array(nfs_name_snoop_known, &fhkey[0]);
1496
0
  }
1497
1498
  /* if we know the mapping, print the filename */
1499
0
  if (nns) {
1500
0
    proto_item *fh_item = NULL;
1501
1502
0
    if (hidden) {
1503
0
      fh_item = proto_tree_add_string(tree, hf_nfs_name, NULL,
1504
0
        0, 0, nns->name);
1505
0
      proto_item_set_hidden(fh_item);
1506
0
    } else {
1507
0
      fh_item = proto_tree_add_string(tree, hf_nfs_name, tvb,
1508
0
        fh_offset, 0, nns->name);
1509
0
    }
1510
0
    proto_item_set_generated(fh_item);
1511
1512
0
    if (nns->full_name) {
1513
0
      if (hidden) {
1514
0
        fh_item = proto_tree_add_string(tree, hf_nfs_full_name, NULL,
1515
0
          0, 0, nns->full_name);
1516
0
        proto_item_set_hidden(fh_item);
1517
0
      } else {
1518
0
        fh_item = proto_tree_add_string_format_value(tree, hf_nfs_full_name, tvb,
1519
0
          fh_offset, 0, nns->full_name, "%s", nns->full_name);
1520
0
      }
1521
0
      proto_item_set_generated(fh_item);
1522
0
    }
1523
1524
0
    if (nns->fs_cycle) {
1525
0
      proto_tree_add_expert(tree, pinfo, &ei_nfs_file_system_cycle, tvb, 0, 0);
1526
0
    }
1527
0
  }
1528
0
}
1529
1530
1531
/* file handle dissection */
1532
1533
static const true_false_string tfs_endianness = { "Little Endian", "Big Endian" };
1534
1535
static void
1536
nfs_fmt_fsid( char *result, uint32_t revision )
1537
0
{
1538
0
  uint32_t fsid_major;
1539
0
  uint32_t fsid_minor;
1540
1541
0
  fsid_major = ( revision>>18 ) &  0x3fff; /* 14 bits */
1542
0
  fsid_minor = ( revision     ) & 0x3ffff; /* 18 bits */
1543
1544
0
   snprintf( result, ITEM_LABEL_LENGTH, "%u,%u", fsid_major, fsid_minor);
1545
0
}
1546
1547
/* SVR4: checked with ReliantUNIX (5.43, 5.44, 5.45), OpenSolaris (build 101a) */
1548
static int
1549
dissect_fhandle_data_SVR4(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1550
0
{
1551
0
  unsigned encoding = ENC_BIG_ENDIAN; /* We support little endian and big endian. Default is big endian*/
1552
0
  bool have_flag = false;  /* The flag field at the end is optional. Assume no flag is there */
1553
0
  bool found = false;    /* Did we really detect the file handle format? */
1554
0
  uint32_t   nof = 0;
1555
0
  uint32_t   len1;
1556
0
  uint32_t   len2;
1557
0
  uint32_t   fhlen;   /* File handle length. */
1558
1559
0
  static int * const fsid_fields[] = {
1560
0
    &hf_nfs_fh_fsid_major32,
1561
0
    &hf_nfs_fh_fsid_minor32,
1562
0
    NULL
1563
0
  };
1564
1565
  /* Somehow this is no calling argument, so we have to re-calculate it. */
1566
0
  fhlen = tvb_reported_length(tvb);
1567
1568
  /* Check for little endianness. */
1569
0
  len1 = tvb_get_letohs(tvb, 8);
1570
0
  if (tvb_bytes_exist(tvb, 10+len1, 2)) {
1571
0
    len2 = tvb_get_letohs(tvb, 10+len1);
1572
1573
0
    if (12+len1+len2 == fhlen) {
1574
0
      encoding = ENC_LITTLE_ENDIAN;
1575
0
      have_flag = false;
1576
0
      found = true;
1577
0
    }
1578
0
    if (16+len1+len2 == fhlen) {
1579
0
      encoding = ENC_LITTLE_ENDIAN;
1580
0
      have_flag = true;
1581
0
      found = true;
1582
0
    }
1583
0
  }
1584
1585
0
  if (!found) {
1586
    /* Check for big endianness. */
1587
0
    len1 = tvb_get_ntohs(tvb, 8);
1588
0
    if (tvb_bytes_exist(tvb, 10+len1, 2)) {
1589
0
      len2 = tvb_get_ntohs(tvb, 10+len1);
1590
1591
0
      if (12+len1+len2 == fhlen) {
1592
0
        have_flag = false;
1593
0
      }
1594
0
      if (16+len1+len2 == fhlen) {
1595
0
        have_flag = true;
1596
0
      }
1597
0
    }
1598
0
  }
1599
1600
0
  proto_tree_add_boolean(tree, hf_nfs_fh_endianness, tvb, 0, fhlen, (encoding == ENC_LITTLE_ENDIAN));
1601
1602
  /* We are fairly sure, that when found == false, the following code will
1603
  throw an exception. */
1604
1605
  /* file system id */
1606
0
  proto_tree_add_bitmask(tree, tvb, nof, hf_nfs_fh_fsid,
1607
0
          ett_nfs_fh_fsid, fsid_fields, encoding);
1608
0
  nof += 4;
1609
1610
  /* file system type */
1611
0
  proto_tree_add_item(tree, hf_nfs_fh_fstype, tvb, nof, 4, encoding);
1612
0
  nof += 4;
1613
1614
  /* file number */
1615
0
  {
1616
0
    uint32_t fn_O;
1617
0
    uint32_t fn_len_O;
1618
0
    uint32_t fn_len_L;
1619
0
    uint32_t fn_len;
1620
0
    uint32_t fn_data_O;
1621
0
    uint32_t fn_data_inode_O;
1622
0
    uint32_t fn_data_inode_L;
1623
0
    uint32_t inode;
1624
0
    uint32_t fn_data_gen_O;
1625
0
    uint32_t fn_data_gen_L;
1626
0
    uint32_t gen;
1627
0
    uint32_t fn_L;
1628
1629
0
    fn_O = nof;
1630
0
    fn_len_O = fn_O;
1631
0
    fn_len_L = 2;
1632
0
    fn_len = tvb_get_uint16(tvb, fn_len_O, encoding);
1633
0
    fn_data_O = fn_O + fn_len_L;
1634
0
    fn_data_inode_O = fn_data_O + 2;
1635
0
    fn_data_inode_L = 4;
1636
0
    inode = tvb_get_uint32(tvb, fn_data_inode_O, encoding);
1637
0
    fn_data_gen_O = fn_data_inode_O + fn_data_inode_L;
1638
0
    fn_data_gen_L = 4;
1639
0
    gen = tvb_get_uint32(tvb, fn_data_gen_O, encoding);
1640
0
    fn_L = fn_len_L + fn_len;
1641
0
    if (tree) {
1642
0
      proto_item *fn_item = NULL;
1643
0
      proto_tree *fn_tree = NULL;
1644
1645
0
      fn_item = proto_tree_add_uint(tree, hf_nfs_fh_fn, tvb,
1646
0
                  fn_O, fn_L, inode);
1647
0
      fn_tree = proto_item_add_subtree(fn_item,
1648
0
               ett_nfs_fh_fn);
1649
0
      proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_len,
1650
0
              tvb, fn_len_O, fn_len_L, fn_len);
1651
0
      proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_inode,
1652
0
              tvb, fn_data_inode_O, fn_data_inode_L, inode);
1653
0
      proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_generation,
1654
0
              tvb, fn_data_gen_O, fn_data_gen_L, gen);
1655
0
    }
1656
0
    nof = fn_O + fn_len_L + fn_len;
1657
0
  }
1658
1659
  /* exported file number */
1660
0
  {
1661
0
    uint32_t xfn_O;
1662
0
    uint32_t xfn_len_O;
1663
0
    uint32_t xfn_len_L;
1664
0
    uint32_t xfn_len;
1665
0
    uint32_t xfn_data_O;
1666
0
    uint32_t xfn_data_inode_O;
1667
0
    uint32_t xfn_data_inode_L;
1668
0
    uint32_t xinode;
1669
0
    uint32_t xfn_data_gen_O;
1670
0
    uint32_t xfn_data_gen_L;
1671
0
    uint32_t xgen;
1672
0
    uint32_t xfn_L;
1673
1674
0
    xfn_O = nof;
1675
0
    xfn_len_O = xfn_O;
1676
0
    xfn_len_L = 2;
1677
0
    xfn_len = tvb_get_uint16(tvb, xfn_len_O, encoding);
1678
0
    xfn_data_O = xfn_O + xfn_len_L;
1679
0
    xfn_data_inode_O = xfn_data_O + 2;
1680
0
    xfn_data_inode_L = 4;
1681
0
    xinode = tvb_get_uint32(tvb, xfn_data_inode_O, encoding);
1682
0
    xfn_data_gen_O = xfn_data_inode_O + xfn_data_inode_L;
1683
0
    xfn_data_gen_L = 4;
1684
0
    xgen = tvb_get_uint32(tvb, xfn_data_gen_O, encoding);
1685
0
    xfn_L = xfn_len_L + xfn_len;
1686
1687
0
    if (tree) {
1688
0
      proto_item *xfn_item = NULL;
1689
0
      proto_tree *xfn_tree = NULL;
1690
1691
0
      xfn_item = proto_tree_add_uint(tree, hf_nfs_fh_xfn, tvb,
1692
0
                   xfn_O, xfn_L, xinode);
1693
0
      xfn_tree = proto_item_add_subtree(xfn_item,
1694
0
                ett_nfs_fh_xfn);
1695
0
      proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_len,
1696
0
              tvb, xfn_len_O, xfn_len_L, xfn_len);
1697
0
      proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_inode,
1698
0
              tvb, xfn_data_inode_O, xfn_data_inode_L, xinode);
1699
0
      proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_generation,
1700
0
              tvb, xfn_data_gen_O, xfn_data_gen_L, xgen);
1701
0
    }
1702
0
    nof = xfn_O + xfn_len_L + xfn_len;
1703
0
  }
1704
1705
  /* flag */
1706
0
  if (have_flag)
1707
0
    proto_tree_add_item(tree, hf_nfs_fh_flag, tvb, nof, 4, encoding);
1708
1709
0
  return tvb_captured_length(tvb);
1710
0
}
1711
1712
1713
/* Checked with RedHat Linux 6.2 (kernel 2.2.14 knfsd) */
1714
1715
static int
1716
dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1717
0
{
1718
0
  if (tree) {
1719
0
    int offset = 0;
1720
0
    uint32_t temp;
1721
0
    uint32_t fsid_major;
1722
0
    uint32_t fsid_minor;
1723
0
    uint32_t xfsid_major;
1724
0
    uint32_t xfsid_minor;
1725
1726
0
    temp      = tvb_get_letohs (tvb, offset+12);
1727
0
    fsid_major  = (temp >> 8) & 0xff;
1728
0
    fsid_minor  = (temp     ) & 0xff;
1729
0
    temp      = tvb_get_letohs(tvb, offset+16);
1730
0
    xfsid_major = (temp >> 8) & 0xff;
1731
0
    xfsid_minor = (temp     ) & 0xff;
1732
1733
0
    proto_tree_add_item(tree, hf_nfs_fh_dentry, tvb, offset+0, 4, ENC_LITTLE_ENDIAN);
1734
0
    proto_tree_add_item(tree, hf_nfs_fh_fn_inode, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
1735
0
    proto_tree_add_item(tree, hf_nfs_fh_dirinode, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
1736
1737
    /* file system id (device) */
1738
0
    {
1739
0
      proto_tree *fsid_tree;
1740
1741
0
      fsid_tree = proto_tree_add_subtree_format(tree, tvb,
1742
0
              offset+12, 4, ett_nfs_fh_fsid, NULL,
1743
0
              "file system ID: %u,%u",
1744
0
              fsid_major, fsid_minor);
1745
0
      proto_tree_add_item(fsid_tree, hf_nfs_fh_fsid_major16_mask, tvb, offset+12, 2, ENC_LITTLE_ENDIAN);
1746
0
      proto_tree_add_item(fsid_tree, hf_nfs_fh_fsid_minor16_mask, tvb, offset+12, 2, ENC_LITTLE_ENDIAN);
1747
0
    }
1748
1749
    /* exported file system id (device) */
1750
0
    {
1751
0
      proto_tree *xfsid_tree;
1752
1753
0
      xfsid_tree = proto_tree_add_subtree_format(tree, tvb,
1754
0
               offset+16, 4, ett_nfs_fh_xfsid, NULL,
1755
0
               "exported file system ID: %u,%u", xfsid_major, xfsid_minor);
1756
0
      proto_tree_add_item(xfsid_tree, hf_nfs_fh_xfsid_major, tvb, offset+16, 2, ENC_LITTLE_ENDIAN);
1757
0
      proto_tree_add_item(xfsid_tree, hf_nfs_fh_xfsid_minor, tvb, offset+16, 2, ENC_LITTLE_ENDIAN);
1758
0
    }
1759
1760
0
    proto_tree_add_item(tree, hf_nfs_fh_xfn_inode, tvb, offset+20, 4, ENC_LITTLE_ENDIAN);
1761
0
    proto_tree_add_item(tree, hf_nfs_fh_fn_generation, tvb, offset+24, 4, ENC_LITTLE_ENDIAN);
1762
0
  }
1763
0
  return tvb_captured_length(tvb);
1764
0
}
1765
1766
1767
/* Checked with RedHat Linux 5.2 (nfs-server 2.2beta47 user-land nfsd) */
1768
1769
static int
1770
dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1771
0
{
1772
0
  unsigned offset = 0;
1773
1774
  /* pseudo inode */
1775
0
  proto_tree_add_item(tree, hf_nfs_fh_pinode, tvb, offset+0, 4, ENC_LITTLE_ENDIAN);
1776
1777
  /* hash path */
1778
0
  {
1779
0
    uint32_t hashlen;
1780
1781
0
    hashlen  = tvb_get_uint8(tvb, offset+4);
1782
0
    if (tree) {
1783
0
      proto_tree *hash_tree;
1784
1785
0
      hash_tree = proto_tree_add_subtree_format(tree, tvb, offset+4, hashlen + 1, ett_nfs_fh_hp, NULL,
1786
0
                  "hash path: %s", tvb_bytes_to_str(pinfo->pool, tvb, offset+5, hashlen));
1787
0
      proto_tree_add_uint(hash_tree,
1788
0
              hf_nfs_fh_hp_len, tvb, offset+4, 1,
1789
0
              hashlen);
1790
0
      proto_tree_add_item(hash_tree, hf_nfs_fh_hp_key, tvb, offset+5, hashlen, ENC_NA);
1791
0
    }
1792
0
  }
1793
0
  return tvb_captured_length(tvb);
1794
0
}
1795
1796
1797
static int
1798
dissect_fhandle_data_NETAPP(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1799
0
{
1800
0
  unsigned offset = 0;
1801
0
  static int * const flags[] = {
1802
0
    &hf_nfs_fh_file_flag_mntpoint,
1803
0
    &hf_nfs_fh_file_flag_snapdir,
1804
0
    &hf_nfs_fh_file_flag_snapdir_ent,
1805
0
    &hf_nfs_fh_file_flag_empty,
1806
0
    &hf_nfs_fh_file_flag_vbn_access,
1807
0
    &hf_nfs_fh_file_flag_multivolume,
1808
0
    &hf_nfs_fh_file_flag_metadata,
1809
0
    NULL
1810
0
  };
1811
1812
0
  if (tree) {
1813
0
    uint32_t mount         = tvb_get_letohl(tvb, offset +  0);
1814
1815
0
    uint32_t inum        = tvb_get_ntohl( tvb, offset + 12);
1816
0
    uint32_t nfsexport      = tvb_get_letohl(tvb, offset + 24);
1817
0
    uint32_t export_snapgen = tvb_get_letohl(tvb, offset + 28);
1818
1819
0
    proto_tree *subtree = NULL;
1820
1821
0
    subtree = proto_tree_add_subtree_format(tree, tvb, offset + 0, 8,
1822
0
             ett_nfs_fh_mount, NULL, "mount (inode %u)", mount);
1823
0
    proto_tree_add_uint(subtree, hf_nfs_fh_mount_fileid,
1824
0
             tvb, offset + 0, 4, mount);
1825
0
    proto_tree_add_item(subtree, hf_nfs_fh_mount_generation, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1826
0
    subtree = proto_tree_add_subtree_format(tree, tvb, offset + 8, 16,
1827
0
             ett_nfs_fh_file, NULL, "file (inode %u)", inum);
1828
1829
0
    proto_tree_add_bitmask_with_flags(subtree, tvb, offset + 8, hf_nfs_fh_flags, ett_nfs4_fh_file_flags, flags, ENC_LITTLE_ENDIAN, BMT_NO_FALSE);
1830
1831
0
    proto_tree_add_item(subtree, hf_nfs_fh_snapid, tvb, offset + 10, 1, ENC_NA);
1832
0
    proto_tree_add_item(subtree, hf_nfs_fh_unused, tvb, offset + 11, 1, ENC_NA);
1833
0
    proto_tree_add_item(subtree, hf_nfs_fh_fileid, tvb, offset + 12, 4, ENC_BIG_ENDIAN);
1834
0
    proto_tree_add_item(subtree, hf_nfs_fh_generation, tvb, offset + 16, 4, ENC_LITTLE_ENDIAN);
1835
0
    proto_tree_add_item(subtree, hf_nfs_fh_fsid, tvb, offset + 20, 4, ENC_LITTLE_ENDIAN);
1836
0
    subtree = proto_tree_add_subtree_format(tree, tvb, offset + 24, 8,
1837
0
             ett_nfs_fh_export, NULL, "export (inode %u)", nfsexport);
1838
0
    proto_tree_add_uint(subtree, hf_nfs_fh_export_fileid,
1839
0
             tvb, offset + 24, 4, nfsexport);
1840
0
    proto_tree_add_uint(subtree,
1841
0
             hf_nfs_fh_export_generation,
1842
0
             tvb, offset + 28, 3,
1843
0
             export_snapgen & 0xffffff);
1844
0
    proto_tree_add_uint(subtree, hf_nfs_fh_export_snapid,
1845
0
             tvb, offset + 31, 1,
1846
0
             export_snapgen >> 24);
1847
0
  }
1848
0
  return tvb_captured_length(tvb);
1849
0
}
1850
1851
static const value_string handle_type_strings[] = {
1852
  { 0, "NORMAL" },
1853
  { 1, "UNEXP" },
1854
  { 2, "VOLDIR" },
1855
  { 3, "ROOT" },
1856
  { 4, "ABSENT" },
1857
  { 0, NULL }
1858
};
1859
1860
static int
1861
dissect_fhandle_data_NETAPP_V4(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1862
0
{
1863
0
  static int * const flags[] = {
1864
0
    &hf_nfs_fh_file_flag_mntpoint,
1865
0
    &hf_nfs_fh_file_flag_snapdir,
1866
0
    &hf_nfs_fh_file_flag_snapdir_ent,
1867
0
    &hf_nfs_fh_file_flag_empty,
1868
0
    &hf_nfs_fh_file_flag_vbn_access,
1869
0
    &hf_nfs_fh_file_flag_multivolume,
1870
0
    &hf_nfs_fh_file_flag_metadata,
1871
0
    &hf_nfs_fh_file_flag_orphan,
1872
0
    &hf_nfs_fh_file_flag_foster,
1873
0
    &hf_nfs_fh_file_flag_named_attr,
1874
0
    &hf_nfs_fh_file_flag_exp_snapdir,
1875
0
    &hf_nfs_fh_file_flag_vfiler,
1876
0
    &hf_nfs_fh_file_flag_aggr,
1877
0
    &hf_nfs_fh_file_flag_striped,
1878
0
    &hf_nfs_fh_file_flag_private,
1879
0
    &hf_nfs_fh_file_flag_next_gen,
1880
0
    NULL
1881
0
  };
1882
1883
0
  if (tree == NULL)
1884
0
    return tvb_captured_length(tvb);
1885
1886
0
  {
1887
0
    int     offset = 0;
1888
0
    proto_tree *subtree;
1889
0
    uint32_t      fileid;
1890
0
    uint32_t      handle_type;
1891
0
    uint32_t      inum;
1892
0
    unsigned encoding;
1893
1894
0
    handle_type = tvb_get_ntohl(tvb, offset + 24);
1895
0
    inum      = tvb_get_ntohl(tvb, offset + 12);
1896
1897
0
    if ( handle_type != 0 && handle_type <= 255) {
1898
0
      encoding = ENC_BIG_ENDIAN;
1899
0
    } else {
1900
0
      encoding = ENC_LITTLE_ENDIAN;
1901
0
    }
1902
0
        fileid = tvb_get_uint32(tvb, offset, encoding);
1903
0
    subtree = proto_tree_add_subtree_format(tree, tvb, offset + 0, 8, ett_nfs4_fh_export, NULL, "export (inode %u)", fileid);
1904
1905
0
    proto_tree_add_item(subtree, hf_nfs_fh_export_fileid, tvb, offset + 0, 4, encoding);
1906
0
    proto_tree_add_item(subtree, hf_nfs_fh_export_generation, tvb, offset + 4, 4, encoding);
1907
0
    subtree = proto_tree_add_subtree_format(tree, tvb, offset + 8, 16, ett_nfs4_fh_file, NULL, "file (inode %u)", inum);
1908
1909
0
    proto_tree_add_bitmask_with_flags(subtree, tvb, offset + 8, hf_nfs_fh_flags, ett_nfs4_fh_file_flags, flags, encoding, BMT_NO_FALSE);
1910
1911
0
    proto_tree_add_item(subtree, hf_nfs_fh_snapid, tvb, offset + 10, 1, ENC_NA);
1912
0
    proto_tree_add_item(subtree, hf_nfs_fh_unused, tvb, offset + 11, 1, ENC_NA);
1913
0
    proto_tree_add_item(subtree, hf_nfs_fh_fileid, tvb, offset + 12, 4, encoding);
1914
0
    proto_tree_add_item(subtree, hf_nfs_fh_generation, tvb, offset + 16, 4, encoding);
1915
0
    proto_tree_add_item(subtree, hf_nfs_fh_fsid, tvb, offset + 20, 4, encoding);
1916
0
    proto_tree_add_item(tree, hf_nfs_fh_handle_type, tvb, offset+24, 4, encoding);
1917
0
  }
1918
0
  return tvb_captured_length(tvb);
1919
0
}
1920
1921
#define NETAPP_GX_FH3_LENGTH    44
1922
16
#define NFS3GX_FH_TREE_MASK   0x80
1923
16
#define NFS3GX_FH_JUN_MASK    0x40
1924
16
#define NFS3GX_FH_VER_MASK    0x3F
1925
16
#define SPINNP_FH_FLAG_RESV1            0x80
1926
16
#define SPINNP_FH_FLAG_RESV2            0x40
1927
32
#define SPINNP_FH_FLAG_ONTAP_MASK 0x20
1928
16
#define SPINNP_FH_FLAG_STRIPED_MASK 0x10
1929
16
#define SPINNP_FH_FLAG_EMPTY_MASK 0x08
1930
16
#define SPINNP_FH_FLAG_SNAPDIR_ENT_MASK 0x04
1931
16
#define SPINNP_FH_FLAG_SNAPDIR_MASK 0x02
1932
16
#define SPINNP_FH_FLAG_STREAMDIR_MASK 0x01
1933
1934
static int
1935
dissect_fhandle_data_NETAPP_GX_v3(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1936
0
{
1937
0
  if (tree) {
1938
0
    proto_tree *field_tree;
1939
0
    uint8_t     flags;
1940
0
    uint32_t    offset = 0;
1941
0
    static int * const fh_flags[] = {
1942
0
      &hf_nfs3_gxfh_sfhflags_resv1,
1943
0
      &hf_nfs3_gxfh_sfhflags_resv2,
1944
0
      &hf_nfs3_gxfh_sfhflags_ontapGX,
1945
0
      &hf_nfs3_gxfh_sfhflags_striped,
1946
0
      &hf_nfs3_gxfh_sfhflags_empty,
1947
0
      &hf_nfs3_gxfh_sfhflags_snapdirent,
1948
0
      &hf_nfs3_gxfh_sfhflags_snapdir,
1949
0
      &hf_nfs3_gxfh_sfhflags_streamdir,
1950
0
      NULL
1951
0
    };
1952
1953
0
    static int * const fh_flags_ontap[] = {
1954
0
      &hf_nfs3_gxfh_sfhflags_resv1,
1955
0
      &hf_nfs3_gxfh_sfhflags_resv2,
1956
0
      &hf_nfs3_gxfh_sfhflags_ontap7G,
1957
0
      &hf_nfs3_gxfh_sfhflags_striped,
1958
0
      &hf_nfs3_gxfh_sfhflags_empty,
1959
0
      &hf_nfs3_gxfh_sfhflags_snapdirent,
1960
0
      &hf_nfs3_gxfh_sfhflags_snapdir,
1961
0
      &hf_nfs3_gxfh_sfhflags_streamdir,
1962
0
      NULL
1963
0
    };
1964
1965
0
    static int * const utility_flags[] = {
1966
0
      &hf_nfs3_gxfh_utlfield_tree,
1967
0
      &hf_nfs3_gxfh_utlfield_jun,
1968
0
      &hf_nfs3_gxfh_utlfield_ver,
1969
0
      NULL
1970
0
    };
1971
1972
    /* = utility = */
1973
0
    proto_tree_add_bitmask(tree, tvb, offset, hf_nfs3_gxfh_utlfield, ett_nfs3_gxfh_utlfield, utility_flags, ENC_NA);
1974
1975
    /* = volume count== */
1976
0
    proto_tree_add_item(tree, hf_nfs3_gxfh_volcnt, tvb, offset+1, 1, ENC_NA);
1977
    /* = epoch = */
1978
0
    proto_tree_add_item(tree, hf_nfs3_gxfh_epoch, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1979
    /* = spin file handle = */
1980
0
    flags        = tvb_get_uint8(tvb, offset+11);
1981
1982
0
    field_tree = proto_tree_add_subtree(tree, tvb, offset+4, 16,
1983
0
           ett_nfs3_gxfh_sfhfield, NULL, "  spin file handle");
1984
1985
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_ldsid, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1986
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_cid, tvb, offset+8, 2, ENC_BIG_ENDIAN);
1987
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_resv, tvb, offset+10, 1, ENC_BIG_ENDIAN);
1988
1989
0
    if (flags & SPINNP_FH_FLAG_ONTAP_MASK) {
1990
0
      proto_tree_add_bitmask(field_tree, tvb, offset+11, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags_ontap, ENC_NA);
1991
0
    }
1992
0
    else {
1993
0
      proto_tree_add_bitmask(field_tree, tvb, offset+11, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags, ENC_NA);
1994
0
    }
1995
1996
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfid, tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
1997
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfuid, tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
1998
1999
    /* = spin file handle (mount point) = */
2000
0
    flags        = tvb_get_uint8(tvb, offset+27);
2001
2002
0
    field_tree = proto_tree_add_subtree(tree, tvb, offset+20, 16,
2003
0
           ett_nfs3_gxfh_sfhfield, NULL, "  spin (mount point) file handle");
2004
2005
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_ldsid, tvb, offset+20, 4, ENC_BIG_ENDIAN);
2006
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_cid, tvb, offset+24, 2, ENC_BIG_ENDIAN);
2007
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_resv, tvb, offset+26, 1, ENC_BIG_ENDIAN);
2008
2009
0
    if (flags & SPINNP_FH_FLAG_ONTAP_MASK) {
2010
0
      proto_tree_add_bitmask(field_tree, tvb, offset+27, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags_ontap, ENC_NA);
2011
0
    }
2012
0
    else {
2013
0
      proto_tree_add_bitmask(field_tree, tvb, offset+27, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags, ENC_NA);
2014
0
    }
2015
2016
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfid, tvb, offset+28, 4, ENC_LITTLE_ENDIAN);
2017
0
    proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfuid, tvb, offset+32, 4, ENC_LITTLE_ENDIAN);
2018
    /* = export point id  = */
2019
0
    proto_tree_add_item(tree, hf_nfs3_gxfh_exportptid, tvb, offset+36, 4, ENC_LITTLE_ENDIAN);
2020
    /* = export point unique id  = */
2021
0
    proto_tree_add_item(tree, hf_nfs3_gxfh_exportptuid, tvb, offset+40, 4, ENC_LITTLE_ENDIAN);
2022
2023
0
  }  /* end of (tree) */
2024
0
  return tvb_captured_length(tvb);
2025
0
}
2026
2027
/* Checked with SuSE 7.1 (kernel 2.4.0 knfsd) */
2028
/* read linux-2.4.5/include/linux/nfsd/nfsfh.h for more details */
2029
2030
#define AUTH_TYPE_NONE 0
2031
static const value_string auth_type_names[] = {
2032
  { AUTH_TYPE_NONE,       "no authentication"   },
2033
  { 0,  NULL}
2034
};
2035
2036
#define FSID_TYPE_MAJOR_MINOR_INODE 0
2037
static const value_string fsid_type_names[] = {
2038
  { FSID_TYPE_MAJOR_MINOR_INODE,    "major/minor/inode"   },
2039
  { 0,  NULL}
2040
};
2041
2042
#define FILEID_TYPE_ROOT      0
2043
#define FILEID_TYPE_INODE_GENERATION    1
2044
#define FILEID_TYPE_INODE_GENERATION_PARENT 2
2045
static const value_string fileid_type_names[] = {
2046
  { FILEID_TYPE_ROOT,     "root"        },
2047
  { FILEID_TYPE_INODE_GENERATION,   "inode/generation"    },
2048
  { FILEID_TYPE_INODE_GENERATION_PARENT,  "inode/generation/parent" },
2049
  { 0,  NULL}
2050
};
2051
2052
static int
2053
dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2054
0
{
2055
0
  int    offset = 0;
2056
0
  uint32_t version;
2057
0
  uint8_t auth_type = 0;
2058
0
  uint8_t fsid_type;
2059
0
  uint8_t fileid_type;
2060
0
  proto_tree *fileid_tree;
2061
0
  proto_item *fileid_item;
2062
2063
0
  proto_tree_add_item_ret_uint(tree, hf_nfs_fh_version, tvb, offset+0, 1, ENC_NA, &version);
2064
2065
0
  switch (version) {
2066
0
    case 1:
2067
0
      auth_type   = tvb_get_uint8(tvb, offset + 1);
2068
0
      fsid_type   = tvb_get_uint8(tvb, offset + 2);
2069
0
      fileid_type = tvb_get_uint8(tvb, offset + 3);
2070
0
      if (tree) {
2071
0
        proto_tree *encoding_tree = proto_tree_add_subtree_format(tree, tvb,
2072
0
          offset + 1, 3,
2073
0
          ett_nfs_fh_encoding, NULL, "encoding: %u %u %u",
2074
0
          auth_type, fsid_type, fileid_type);
2075
2076
0
        proto_tree_add_uint(encoding_tree, hf_nfs_fh_auth_type,
2077
0
              tvb, offset+1, 1, auth_type);
2078
0
        proto_tree_add_uint(encoding_tree, hf_nfs_fh_fsid_type,
2079
0
              tvb, offset+2, 1, fsid_type);
2080
0
        proto_tree_add_uint(encoding_tree, hf_nfs_fh_fileid_type,
2081
0
              tvb, offset+3, 1, fileid_type);
2082
0
      }
2083
0
      offset += 4;
2084
0
      break;
2085
0
    default: {
2086
      /* unknown version */
2087
0
      return 1;
2088
0
    }
2089
0
  }
2090
2091
0
  if (auth_type != 0)
2092
0
  {
2093
    /* unknown authentication type */
2094
0
    return 2;
2095
0
  }
2096
2097
0
  if (fsid_type != 0)
2098
0
  {
2099
    /* unknown authentication type */
2100
0
    return 3;
2101
0
  }
2102
2103
0
  {
2104
0
  uint16_t fsid_major;
2105
0
  uint16_t fsid_minor;
2106
0
  uint32_t fsid_inode;
2107
2108
0
  fsid_major = tvb_get_ntohs(tvb, offset + 0);
2109
0
  fsid_minor = tvb_get_ntohs(tvb, offset + 2);
2110
0
  fsid_inode = tvb_get_letohl(tvb, offset + 4);
2111
0
  if (tree) {
2112
0
    proto_tree *fsid_tree = proto_tree_add_subtree_format(tree, tvb,
2113
0
      offset+0, 8, ett_nfs_fh_fsid, NULL,
2114
0
      "file system ID: %u,%u (inode %u)",
2115
0
      fsid_major, fsid_minor, fsid_inode);
2116
2117
0
    proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_major16,
2118
0
          tvb, offset+0, 2, fsid_major);
2119
0
    proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_minor16,
2120
0
          tvb, offset+2, 2, fsid_minor);
2121
0
    proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_inode,
2122
0
          tvb, offset+4, 4, fsid_inode);
2123
0
  }
2124
2125
0
  offset += 8;
2126
0
  }
2127
2128
0
  fileid_tree = proto_tree_add_subtree_format(tree, tvb,
2129
0
          offset, 0, ett_nfs_fh_fn, &fileid_item, "file ID");
2130
2131
0
  switch (fileid_type) {
2132
0
    case 0: {
2133
0
      proto_item_append_text(fileid_item, ": root inode");
2134
0
    } break;
2135
0
    case 1: {
2136
0
      uint32_t inode;
2137
0
      uint32_t generation;
2138
2139
0
      inode = tvb_get_letohl(tvb, offset + 0);
2140
0
      generation = tvb_get_letohl(tvb, offset + 4);
2141
2142
0
      if (tree) {
2143
0
        proto_item_append_text(fileid_item, ": %u (%u)", inode, generation);
2144
0
        proto_item_set_len(fileid_item, 8);
2145
2146
0
        proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_inode,
2147
0
            tvb, offset+0, 4, inode);
2148
0
        proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_generation,
2149
0
            tvb, offset+4, 4, generation);
2150
0
      }
2151
2152
      /*offset += 8;*/
2153
0
    } break;
2154
0
    case 2: {
2155
0
      uint32_t inode;
2156
0
      uint32_t generation;
2157
2158
0
      inode = tvb_get_letohl(tvb, offset + 0);
2159
0
      generation = tvb_get_letohl(tvb, offset + 4);
2160
2161
0
      if (tree) {
2162
0
        proto_item_append_text(fileid_item, ": %u (%u)", inode, generation);
2163
0
        proto_item_set_len(fileid_item, 12);
2164
2165
0
        proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_inode,
2166
0
            tvb, offset+0, 4, inode);
2167
0
        proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_generation,
2168
0
            tvb, offset+4, 4, generation);
2169
0
        proto_tree_add_item(fileid_tree, hf_nfs_fh_dirinode,
2170
0
            tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
2171
0
      }
2172
2173
      /*offset += 12;*/
2174
0
    } break;
2175
0
    default: {
2176
0
      proto_item_append_text(fileid_item, ": unknown");
2177
      /* unknown fileid type */
2178
0
      return offset;
2179
0
    }
2180
0
  }
2181
0
  return tvb_captured_length(tvb);
2182
0
}
2183
2184
2185
/*
2186
 * Dissect GlusterFS/NFS NFSv3 File Handle - glusterfs-3.3+
2187
 * The filehandle is always 32 bytes and first 4 bytes of ident ":OGL"
2188
 */
2189
static int
2190
dissect_fhandle_data_GLUSTER(tvbuff_t* tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2191
0
{
2192
0
  uint16_t offset=0;
2193
0
  uint16_t  fhlen;
2194
0
  char *ident;
2195
2196
0
  if (!tree)
2197
0
    return tvb_captured_length(tvb);
2198
2199
0
  fhlen = tvb_reported_length(tvb);
2200
0
  if (fhlen != 36)
2201
0
    return tvb_captured_length(tvb);
2202
2203
0
  ident = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, 4, ENC_ASCII);
2204
0
  if (strncmp(":OGL", ident, 4))
2205
0
    return 4;
2206
0
  offset += 4;
2207
2208
0
  proto_tree_add_item(tree, hf_nfs_fh_exportid, tvb, offset, 16, ENC_BIG_ENDIAN);
2209
0
  offset += 16;
2210
0
  proto_tree_add_item(tree, hf_nfs_fh_gfid, tvb, offset, 16, ENC_BIG_ENDIAN);
2211
0
  offset += 16;
2212
0
  return offset;
2213
0
}
2214
2215
/*
2216
 * Dissect dCache NFS File Handle - dcache > 2.6
2217
 */
2218
2219
0
#define DCACHE_MAGIC_MASK   0x00FFFFFF
2220
0
#define DCACHE_VERSION_MASK 0xFF000000
2221
0
#define DCACHE_MAGIC        0xCAFFEE
2222
2223
static const value_string dcache_handle_types[] = {
2224
  { 0, "INODE" },
2225
  { 1, "TAG" },
2226
  { 2, "TAGS" },
2227
  { 3, "ID" },
2228
  { 4, "PATHOF" },
2229
  { 5, "PARENT" },
2230
  { 6, "NAMEOF" },
2231
  { 7, "PGET" },
2232
  { 8, "PSET" },
2233
  { 9, "CONST" },
2234
  { 0, NULL }
2235
};
2236
2237
static int
2238
dissect_fhandle_data_DCACHE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2239
0
{
2240
0
  unsigned offset = 0;
2241
0
  uint32_t version;
2242
0
  uint32_t magic;
2243
0
  uint8_t obj_len;
2244
2245
0
  if (!tree)
2246
0
    return tvb_captured_length(tvb);
2247
2248
0
  version = (tvb_get_ntohl(tvb, offset) & DCACHE_VERSION_MASK) >> 24;
2249
0
  magic   = (tvb_get_ntohl(tvb, offset) & DCACHE_MAGIC_MASK);
2250
2251
0
  if ((version != 1) || (magic != DCACHE_MAGIC)) {
2252
    /* unknown file handle */
2253
0
    return 0;
2254
0
  }
2255
2256
0
  proto_tree_add_item(tree, hf_nfs_fh_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2257
0
  proto_tree_add_item(tree, hf_nfs_fh_generation, tvb, offset+4, 4, ENC_BIG_ENDIAN);
2258
0
  proto_tree_add_item(tree, hf_nfs_fh_dc_exportid, tvb, offset+8, 4, ENC_BIG_ENDIAN);
2259
0
  proto_tree_add_item(tree, hf_nfs_fh_dc_handle_type, tvb, offset+15, 1, ENC_BIG_ENDIAN);
2260
0
  obj_len = tvb_get_uint8(tvb, offset + 16);
2261
0
  proto_tree_add_item(tree, hf_nfs_fh_dc_opaque, tvb, offset + 17, obj_len, ENC_NA);
2262
0
  return tvb_captured_length(tvb);
2263
0
}
2264
2265
16
#define PD_VERSION_MASK   0xf0000000
2266
16
#define PD_RESERVED_MASK  0x0ffffffF
2267
16
#define PD_INUM_MASK      UINT64_C(0x0007ffffffffffff)
2268
16
#define PD_SITEID_MASK    UINT64_C(0xfff8000000000000)
2269
16
#define PD_SNAPID_MASK    UINT64_C(0x0000000000001fff)
2270
16
#define PD_CONTAINER_MASK UINT64_C(0xffffffffffffe000)
2271
2272
static int
2273
dissect_fhandle_data_PRIMARY_DATA(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2274
0
{
2275
0
  unsigned offset = 0;
2276
0
  uint32_t version;
2277
2278
0
  static int * const fh_flags[] = {
2279
0
    &hf_nfs4_fh_pd_flags_version,
2280
0
    &hf_nfs4_fh_pd_flags_reserved,
2281
0
    NULL
2282
0
  };
2283
2284
0
  static int * const fh_sites[] = {
2285
0
    &hf_nfs4_fh_pd_sites_inum,
2286
0
    &hf_nfs4_fh_pd_sites_siteid,
2287
0
    NULL
2288
0
  };
2289
2290
0
  static int * const fh_spaces[] = {
2291
0
    &hf_nfs4_fh_pd_spaces_snapid,
2292
0
    &hf_nfs4_fh_pd_spaces_container,
2293
0
    NULL
2294
0
  };
2295
2296
2297
0
  if (!tree)
2298
0
    return tvb_captured_length(tvb);
2299
2300
2301
0
  version = (tvb_get_letohl(tvb, offset + 4) & PD_VERSION_MASK) >> 28;
2302
0
  if (version > 2) {
2303
0
    return 0;
2304
0
  }
2305
2306
0
  proto_tree_add_item(tree, hf_nfs4_fh_pd_share, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2307
0
  proto_tree_add_bitmask(tree, tvb, offset + 4, hf_nfs4_fh_pd_flags, ett_nfs4_fh_pd_flags, fh_flags, ENC_LITTLE_ENDIAN);
2308
2309
0
  if (version == 0) {
2310
0
    proto_tree_add_item(tree, hf_nfs4_fh_pd_inum, tvb, offset + 8, 8, ENC_LITTLE_ENDIAN);
2311
0
  } else if (version == 1) {
2312
0
    proto_tree_add_item(tree, hf_nfs4_fh_pd_container, tvb, offset + 8, 8, ENC_LITTLE_ENDIAN);
2313
0
    proto_tree_add_item(tree, hf_nfs4_fh_pd_inum, tvb, offset + 16, 8, ENC_LITTLE_ENDIAN);
2314
0
  } else if (version == 2) {
2315
0
    proto_tree_add_bitmask(tree, tvb, offset + 8, hf_nfs4_fh_pd_spaces, ett_nfs4_fh_pd_spaces, fh_spaces, ENC_LITTLE_ENDIAN);
2316
0
    proto_tree_add_bitmask(tree, tvb, offset + 16, hf_nfs4_fh_pd_sites, ett_nfs4_fh_pd_sites, fh_sites, ENC_LITTLE_ENDIAN);
2317
0
  }
2318
2319
0
  return tvb_captured_length(tvb);
2320
0
}
2321
2322
/* Dissect EMC Celerra or VNX NFSv3/v4 File Handle */
2323
static int
2324
dissect_fhandle_data_CELERRA_VNX(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2325
0
{
2326
0
  uint16_t offset = 0;
2327
0
  uint16_t  fhlen;
2328
0
  uint32_t  obj_id;
2329
2330
0
  fhlen = tvb_reported_length(tvb);
2331
2332
  /* Display the entire file handle */
2333
0
  proto_tree_add_item(tree, hf_nfs_fh_fhandle_data, tvb, 0, fhlen, ENC_NA);
2334
2335
  /*  If fhlen = 32, it's an NFSv3 file handle */
2336
0
  if (fhlen == 32) {
2337
    /* Create a "File/Dir" subtree: bytes 0 thru 15 of the 32-byte file handle   */
2338
0
    {
2339
0
    proto_item *obj_item;
2340
0
    proto_tree *obj_tree;
2341
2342
0
    if (!tree)
2343
0
      return tvb_captured_length(tvb);
2344
2345
0
    obj_item = proto_tree_add_item(tree, hf_nfs_fh_obj, tvb, offset+0, 16, ENC_NA );
2346
0
    obj_tree = proto_item_add_subtree(obj_item, ett_nfs_fh_obj);
2347
2348
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_fsid,   tvb,  offset+0, 4, ENC_LITTLE_ENDIAN);
2349
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_kindid, tvb,  offset+4, 2, ENC_LITTLE_ENDIAN);
2350
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_treeid, tvb,  offset+6, 2, ENC_LITTLE_ENDIAN);
2351
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_inode,  tvb,  offset+8, 4, ENC_LITTLE_ENDIAN);
2352
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_gen,    tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
2353
0
    }
2354
0
    {
2355
    /* Create "Export" subtree (NFSv3: Bytes 16 thru 31 of the 32-byte file handle  */
2356
0
    proto_item *ex_item;
2357
0
    proto_tree *ex_tree;
2358
0
    ex_item = proto_tree_add_item(tree, hf_nfs_fh_ex, tvb,  offset+16, 16, ENC_NA );
2359
0
    ex_tree = proto_item_add_subtree(ex_item, ett_nfs_fh_ex);
2360
2361
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_fsid,     tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
2362
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_kindid,   tvb, offset+20, 2, ENC_LITTLE_ENDIAN);
2363
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_treeid,   tvb, offset+22, 2, ENC_LITTLE_ENDIAN);
2364
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_inode,    tvb, offset+24, 4, ENC_LITTLE_ENDIAN);
2365
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_gen,      tvb, offset+28, 4, ENC_LITTLE_ENDIAN);
2366
0
    }
2367
0
  } else if (fhlen == 40) {
2368
    /*
2369
    If fhlen = 40, it's an NFSv4 file handle).  In Celerra|VNX NFSv4 file handles,
2370
    the first 4 bytes hold the Named Attribute ID, and the next 4 bytes hold the
2371
    RO_Node boolean which if true, the file/dir is Read Only. Unlike NFSv3 file
2372
    handles where the file/dir info precedes the export info, the next 16 bytes contain
2373
    the *export* info followed by 16 bytes containing the *file/dir* info.
2374
    */
2375
2376
0
    if (!tree)
2377
0
      return tvb_captured_length(tvb);
2378
2379
    /* "Named Attribute ID" or "Object ID" (bytes 0 thru 3) */
2380
0
    obj_id = tvb_get_letohl(tvb, offset+0);
2381
0
    if (obj_id <= 0 || obj_id > 9) obj_id = 1;
2382
0
    proto_tree_add_uint(tree, hf_nfs_fh_obj_id,         tvb,  offset+0, 4, obj_id);
2383
2384
    /* "RO_Node" boolean (bytes 4 thru 7) */
2385
0
    proto_tree_add_item(tree, hf_nfs_fh_ro_node,     tvb,  offset+4, 4, ENC_LITTLE_ENDIAN);
2386
2387
    /* Create "Export" subtree (bytes 8 thru 23 of the 40-byte file handle  */
2388
0
    {
2389
0
    proto_item *ex_item;
2390
0
    proto_tree *ex_tree;
2391
0
    ex_item = proto_tree_add_item(tree, hf_nfs_fh_ex,  tvb,  offset+8, 16, ENC_NA );
2392
0
    ex_tree = proto_item_add_subtree(ex_item, ett_nfs_fh_ex);
2393
2394
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_fsid,    tvb,  offset+8,  4, ENC_LITTLE_ENDIAN);
2395
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_kindid,  tvb, offset+12,  2, ENC_LITTLE_ENDIAN);
2396
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_treeid,  tvb, offset+14,  2, ENC_LITTLE_ENDIAN);
2397
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_inode,   tvb, offset+16,  4, ENC_LITTLE_ENDIAN);
2398
0
    proto_tree_add_item(ex_tree, hf_nfs_fh_ex_gen,     tvb, offset+20,  4, ENC_LITTLE_ENDIAN);
2399
0
    }
2400
    /* Create a "File/Dir/Object" subtree (bytes 24 thru 39 of the 40-byte file handle) */
2401
0
    {
2402
0
    proto_item *obj_item;
2403
0
    proto_tree *obj_tree;
2404
0
    obj_item = proto_tree_add_item(tree, hf_nfs_fh_obj, tvb, offset+24, 16, ENC_NA);
2405
0
    obj_tree = proto_item_add_subtree(obj_item, ett_nfs_fh_obj);
2406
2407
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_fsid,   tvb, offset+24,  4, ENC_LITTLE_ENDIAN);
2408
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_kindid, tvb, offset+28,  2, ENC_LITTLE_ENDIAN);
2409
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_treeid, tvb, offset+30,  2, ENC_LITTLE_ENDIAN);
2410
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_inode,  tvb, offset+32,  4, ENC_LITTLE_ENDIAN);
2411
0
    proto_tree_add_item(obj_tree, hf_nfs_fh_obj_gen,    tvb, offset+36,  4, ENC_LITTLE_ENDIAN);
2412
0
    }
2413
0
  } else {
2414
    /* This is not a Celerra|VNX file handle.  Display a warning. */
2415
0
    expert_add_info_format(pinfo, tree, &ei_nfs_not_vnx_file,
2416
0
      "Celerra|VNX file handles are 32 (NFSv3) or 40 (NFSv4) but the length is %u.\n"
2417
0
      "Change the 'Decode NFS file handles as' pref to the correct type or 'Unknown'.",
2418
0
      fhlen);
2419
0
  }
2420
0
  return tvb_captured_length(tvb);
2421
0
}
2422
2423
2424
static int
2425
dissect_fhandle_data_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2426
0
{
2427
0
  unsigned fhlen = tvb_reported_length(tvb);
2428
2429
0
  proto_tree_add_item(tree, hf_nfs_fh_fhandle_data, tvb, 0, fhlen, ENC_NA);
2430
0
  return tvb_captured_length(tvb);
2431
0
}
2432
2433
2434
static void
2435
dissect_fhandle_data(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
2436
         unsigned int fhlen, bool hidden, uint32_t *hash)
2437
0
{
2438
  /* this is to set up fhandle display filters to find both packets
2439
     of an RPC call */
2440
0
  if (nfs_fhandle_reqrep_matching && (!hidden) ) {
2441
0
    nfs_fhandle_data_t *old_fhd = NULL;
2442
2443
0
    if ( !pinfo->fd->visited ) {
2444
0
      nfs_fhandle_data_t fhd;
2445
2446
      /* first check if we have seen this fhandle before */
2447
0
      fhd.len = fhlen;
2448
0
      fhd.fh = (const unsigned char *)tvb_get_ptr(tvb, offset, fhlen);
2449
0
      old_fhd = store_nfs_file_handle(&fhd);
2450
2451
      /* XXX here we should really check that we haven't stored
2452
         this fhandle for this frame number already.
2453
         We should also make sure we can handle when we have multiple
2454
         fhandles seen for the same frame, which WILL happen for certain
2455
         nfs calls. For now, we don't handle this and those calls will
2456
         not work properly with this feature
2457
      */
2458
0
      wmem_tree_insert32(nfs_fhandle_frame_table, pinfo->num, old_fhd);
2459
0
    }
2460
0
  }
2461
2462
  /* Create a unique hash value for the filehandle using CRC32 */
2463
0
  {
2464
0
    uint32_t fhhash;
2465
0
    proto_item *fh_item = NULL;
2466
2467
0
    fhhash = crc32_ccitt_tvb_offset(tvb, offset, fhlen);
2468
2469
0
    if (hidden) {
2470
0
      fh_item = proto_tree_add_uint(tree, hf_nfs_fh_hash, NULL, 0,
2471
0
        0, fhhash);
2472
0
      proto_item_set_hidden(fh_item);
2473
0
    } else {
2474
0
      fh_item = proto_tree_add_uint(tree, hf_nfs_fh_hash, tvb, offset,
2475
0
        fhlen, fhhash);
2476
0
    }
2477
0
    proto_item_set_generated(fh_item);
2478
0
    if (hash) {
2479
0
      *hash = fhhash;
2480
0
    }
2481
0
  }
2482
0
  if (nfs_file_name_snooping) {
2483
0
    nfs_name_snoop_fh(pinfo, tree, tvb, offset, fhlen, hidden);
2484
0
  }
2485
2486
0
  if (!hidden) {
2487
0
    tvbuff_t *fh_tvb;
2488
2489
0
    fh_tvb = tvb_new_subset_length(tvb, offset, fhlen);
2490
0
    if (!dissector_try_payload_with_data(nfs_fhandle_table, fh_tvb, pinfo, tree, true, NULL))
2491
0
      dissect_fhandle_data_unknown(fh_tvb, pinfo, tree, NULL);
2492
0
  }
2493
0
}
2494
2495
2496
void
2497
dissect_fhandle_hidden(packet_info *pinfo, proto_tree *tree, int frame)
2498
0
{
2499
0
  nfs_fhandle_data_t *nfd;
2500
2501
0
  nfd = (nfs_fhandle_data_t *)wmem_tree_lookup32(nfs_fhandle_frame_table, frame);
2502
0
  if (nfd && nfd->len) {
2503
0
    tvbuff_t *tvb;
2504
0
    tvb = tvb_new_real_data(nfd->fh, nfd->len, nfd->len);
2505
    /* There's no need to call add_new_data_source() since
2506
       dissect_fhandle(), in the 'hidden' case, never refers
2507
       to the tvb when displaying a field based on the tvb */
2508
0
    dissect_fhandle_data(tvb, 0, pinfo, tree, nfd->len, true, NULL);
2509
0
    tvb_free(tvb);
2510
0
  }
2511
0
}
2512
2513
2514
/***************************/
2515
/* NFS Version 2, RFC 1094 */
2516
/***************************/
2517
2518
/* NFSv2 RFC 1094, Page 12..14 */
2519
static const value_string names_nfs2_stat[] =
2520
{
2521
  { 0,  "NFS_OK" },
2522
  { 1,  "NFS2ERR_PERM" },
2523
  { 2,  "NFS2ERR_NOENT" },
2524
  { 5,  "NFS2ERR_IO" },
2525
  { 6,  "NFS2ERR_NXIO" },
2526
  { 11, "NFS2ERR_EAGAIN" },
2527
  { 13, "NFS2ERR_ACCES" },
2528
  { 17, "NFS2ERR_EXIST" },
2529
  { 18, "NFS2ERR_XDEV" }, /* not in spec, but can happen */
2530
  { 19, "NFS2ERR_NODEV" },
2531
  { 20, "NFS2ERR_NOTDIR" },
2532
  { 21, "NFS2ERR_ISDIR" },
2533
  { 22, "NFS2ERR_INVAL" },  /* not in spec, but I think it can happen */
2534
  { 26, "NFS2ERR_TXTBSY" }, /* not in spec, but I think it can happen */
2535
  { 27, "NFS2ERR_FBIG" },
2536
  { 28, "NFS2ERR_NOSPC" },
2537
  { 30, "NFS2ERR_ROFS" },
2538
  { 31, "NFS2ERR_MLINK" },  /* not in spec, but can happen */
2539
  { 45, "NFS2ERR_OPNOTSUPP" },  /* not in spec, but I think it can happen */
2540
  { 63, "NFS2ERR_NAMETOOLONG" },
2541
  { 66, "NFS2ERR_NOTEMPTY" },
2542
  { 69, "NFS2ERR_DQUOT" },
2543
  { 70, "NFS2ERR_STALE" },
2544
  { 71, "NFS2ERR_REMOTE" },
2545
  { 99, "NFS2ERR_WFLUSH" },
2546
  { 10001,  "NFS2ERR_BADHANDLE" },
2547
  { 10002,  "NFS2ERR_NOT_SYNC" },
2548
  { 10003,  "NFS2ERR_BAD_COOKIE" },
2549
  { 10004,  "NFS2ERR_NOTSUPP" },
2550
  { 10005,  "NFS2ERR_TOOSMALL" },
2551
  { 10006,  "NFS2ERR_SERVERFAULT" },
2552
  { 10007,  "NFS2ERR_BADTYPE" },
2553
  { 10008,  "NFS2ERR_JUKEBOX" },
2554
  { 10009,  "NFS2ERR_SAME" },
2555
  { 10010,  "NFS2ERR_DENIED" },
2556
  { 10011,  "NFS2ERR_EXPIRED" },
2557
  { 10012,  "NFS2ERR_LOCKED" },
2558
  { 10013,  "NFS2ERR_GRACE" },
2559
  { 10014,  "NFS2ERR_FHEXPIRED" },
2560
  { 10015,  "NFS2ERR_SHARE_DENIED" },
2561
  { 10016,  "NFS2ERR_WRONGSEC" },
2562
  { 10017,  "NFS2ERR_CLID_INUSE" },
2563
  { 10018,  "NFS2ERR_RESOURCE" },
2564
  { 10019,  "NFS2ERR_MOVED" },
2565
  { 10020,  "NFS2ERR_NOFILEHANDLE" },
2566
  { 10021,  "NFS2ERR_MINOR_VERS_MISMATCH" },
2567
  { 10022,  "NFS2ERR_STALE_CLIENTID" },
2568
  { 10023,  "NFS2ERR_STALE_STATEID" },
2569
  { 10024,  "NFS2ERR_OLD_STATEID" },
2570
  { 10025,  "NFS2ERR_BAD_STATEID" },
2571
  { 10026,  "NFS2ERR_BAD_SEQID" },
2572
  { 10027,  "NFS2ERR_NOT_SAME" },
2573
  { 10028,  "NFS2ERR_LOCK_RANGE" },
2574
  { 10029,  "NFS2ERR_SYMLINK" },
2575
  { 10030,  "NFS2ERR_RESTOREFH" },
2576
  { 10031,  "NFS2ERR_LEASE_MOVED" },
2577
  { 10032,  "NFS2ERR_ATTRNOTSUPP" },
2578
  { 10033,  "NFS2ERR_NO_GRACE" },
2579
  { 10034,  "NFS2ERR_RECLAIM_BAD" },
2580
  { 10035,  "NFS2ERR_RECLAIM_CONFLICT" },
2581
  { 10036,  "NFS2ERR_BAD_XDR" },
2582
  { 10037,  "NFS2ERR_LOCKS_HELD" },
2583
  { 10038,  "NFS2ERR_OPENMODE" },
2584
  { 10039,  "NFS2ERR_BADOWNER" },
2585
  { 10040,  "NFS2ERR_BADCHAR" },
2586
  { 10041,  "NFS2ERR_BADNAME" },
2587
  { 10042,  "NFS2ERR_BAD_RANGE" },
2588
  { 10043,  "NFS2ERR_LOCK_NOTSUPP" },
2589
  { 10044,  "NFS2ERR_OP_ILLEGAL" },
2590
  { 10045,  "NFS2ERR_DEADLOCK" },
2591
  { 10046,  "NFS2ERR_FILE_OPEN" },
2592
  { 10047,  "NFS2ERR_ADMIN_REVOKED" },
2593
  { 10048,  "NFS2ERR_CB_PATH_DOWN" },
2594
  { 10049,  "NFS2ERR_REPLAY_ME" },
2595
  { 0,  NULL }
2596
};
2597
static value_string_ext names_nfs2_stat_ext = VALUE_STRING_EXT_INIT(names_nfs2_stat);
2598
2599
/* NFSv2 RFC 1094, Page 12..14 */
2600
static int
2601
dissect_nfs2_status(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint32_t *status)
2602
0
{
2603
0
  uint32_t      stat;
2604
0
  proto_item *stat_item;
2605
2606
0
  proto_tree_add_item_ret_uint(tree, hf_nfs2_status, tvb, offset+0, 4, ENC_BIG_ENDIAN, &stat);
2607
0
  stat_item = proto_tree_add_uint(tree, hf_nfs_status, tvb, offset+0, 4, stat);
2608
0
  proto_item_set_hidden(stat_item);
2609
2610
0
  offset += 4;
2611
2612
0
  if (status)
2613
0
    *status = stat;
2614
2615
0
  return offset;
2616
0
}
2617
2618
2619
/* NFSv2 RFC 1094, Page 12..14 */
2620
static int
2621
dissect_nfs2_rmdir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2622
0
{
2623
0
  uint32_t      status;
2624
0
  const char *err;
2625
0
  unsigned offset = 0;
2626
2627
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
2628
0
  switch (status) {
2629
0
    case 0:
2630
0
      proto_item_append_text(tree, ", RMDIR Reply");
2631
0
      break;
2632
0
    default:
2633
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
2634
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2635
0
      proto_item_append_text(tree, ", RMDIR Reply  Error: %s", err);
2636
0
  }
2637
2638
0
  return offset;
2639
0
}
2640
2641
2642
static int
2643
dissect_nfs2_symlink_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2644
0
{
2645
0
  uint32_t      status;
2646
0
  const char *err;
2647
0
  unsigned offset = 0;
2648
2649
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
2650
0
  switch (status) {
2651
0
    case 0:
2652
0
      proto_item_append_text(tree, ", SYMLINK Reply");
2653
0
      break;
2654
0
    default:
2655
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
2656
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2657
0
      proto_item_append_text(tree, ", SYMLINK Reply  Error: %s", err);
2658
0
  }
2659
2660
0
  return offset;
2661
0
}
2662
2663
2664
static int
2665
dissect_nfs2_link_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2666
0
{
2667
0
  uint32_t      status;
2668
0
  const char *err;
2669
0
  unsigned offset = 0;
2670
2671
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
2672
0
  switch (status) {
2673
0
    case 0:
2674
0
      proto_item_append_text(tree, ", LINK Reply");
2675
0
      break;
2676
0
    default:
2677
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
2678
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2679
0
      proto_item_append_text(tree, ", LINK Reply  Error: %s", err);
2680
0
  }
2681
2682
0
  return offset;
2683
0
}
2684
2685
2686
static int
2687
dissect_nfs2_rename_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2688
0
{
2689
0
  uint32_t      status;
2690
0
  const char *err;
2691
0
  unsigned offset = 0;
2692
2693
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
2694
0
  switch (status) {
2695
0
    case 0:
2696
0
      proto_item_append_text(tree, ", RENAME Reply");
2697
0
      break;
2698
0
    default:
2699
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
2700
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2701
0
      proto_item_append_text(tree, ", RENAME Reply  Error: %s", err);
2702
0
  }
2703
2704
0
  return offset;
2705
0
}
2706
2707
2708
static int
2709
dissect_nfs2_remove_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2710
0
{
2711
0
  uint32_t      status;
2712
0
  const char *err;
2713
0
  unsigned offset = 0;
2714
2715
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
2716
0
  switch (status) {
2717
0
    case 0:
2718
0
      proto_item_append_text(tree, ", REMOVE Reply");
2719
0
      break;
2720
0
    default:
2721
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
2722
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2723
0
      proto_item_append_text(tree, ", REMOVE Reply  Error: %s", err);
2724
0
  }
2725
2726
0
  return offset;
2727
0
}
2728
2729
2730
/* NFSv2 RFC 1094, Page 15 */
2731
static const value_string nfs2_ftype[] =
2732
{
2733
  { 0,  "Non-File" },
2734
  { 1,  "Regular File" },
2735
  { 2,  "Directory" },
2736
  { 3,  "Block Special Device" },
2737
  { 4,  "Character Special Device" },
2738
  { 5,  "Symbolic Link" },
2739
  { 0,  NULL }
2740
};
2741
static value_string_ext nfs2_ftype_ext = VALUE_STRING_EXT_INIT(nfs2_ftype);
2742
2743
static unsigned
2744
dissect_nfs2_ftype(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
2745
0
{
2746
0
  proto_tree_add_item(tree, hf_nfs2_ftype, tvb, offset, 4, ENC_BIG_ENDIAN);
2747
0
  offset += 4;
2748
0
  return offset;
2749
0
}
2750
2751
2752
/* NFSv2 RFC 1094, Page 15 */
2753
unsigned
2754
dissect_fhandle(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
2755
          const char *name, uint32_t *hash, rpc_call_info_value *civ)
2756
0
{
2757
0
  proto_tree *ftree;
2758
2759
0
  ftree = proto_tree_add_subtree(tree, tvb, offset, FHSIZE,
2760
0
        ett_nfs_fhandle, NULL, name);
2761
2762
2763
  /* are we snooping fh to filenames ?*/
2764
0
  if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
2765
2766
    /* NFS v2 LOOKUP, CREATE, MKDIR, SYMLINK calls might give us a mapping*/
2767
0
    if ( (civ->prog == 100003)
2768
0
      &&(civ->vers == 2)
2769
0
      &&(!civ->request)
2770
0
      &&((civ->proc == 4)||(civ->proc == 9)||(civ->proc == 13)||(civ->proc == 14))
2771
0
    ) {
2772
0
      nfs_name_snoop_add_fh(civ->xid, tvb,
2773
0
        offset, 32);
2774
0
    }
2775
2776
    /* MOUNT v1,v2 MNT replies might give us a filehandle*/
2777
0
    if ( (civ->prog == 100005)
2778
0
      &&(civ->proc == 1)
2779
0
      &&((civ->vers == 1)||(civ->vers == 2))
2780
0
      &&(!civ->request)
2781
0
    ) {
2782
0
      nfs_name_snoop_add_fh(civ->xid, tvb,
2783
0
        offset, 32);
2784
0
    }
2785
0
  }
2786
2787
0
  dissect_fhandle_data(tvb, offset, pinfo, ftree, FHSIZE, false, hash);
2788
2789
0
  offset += FHSIZE;
2790
0
  return offset;
2791
0
}
2792
2793
2794
/* NFSv2 RFC 1094, Page 15 */
2795
static int
2796
dissect_nfs2_statfs_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2797
0
{
2798
0
  uint32_t hash;
2799
0
  unsigned offset = 0;
2800
2801
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
2802
2803
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
2804
0
  proto_item_append_text(tree, ", STATFS Call FH: 0x%08x", hash);
2805
2806
0
  return offset;
2807
0
}
2808
2809
2810
static int
2811
dissect_nfs2_readlink_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2812
0
{
2813
0
  uint32_t hash;
2814
0
  unsigned offset = 0;
2815
2816
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
2817
2818
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
2819
0
  proto_item_append_text(tree, ", READLINK Call FH: 0x%08x", hash);
2820
2821
0
  return offset;
2822
0
}
2823
2824
2825
static int
2826
dissect_nfs2_getattr_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2827
0
{
2828
0
  uint32_t hash;
2829
0
  unsigned offset = 0;
2830
2831
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
2832
2833
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
2834
0
  proto_item_append_text(tree, ", GETATTR Call FH: 0x%08x", hash);
2835
2836
0
  return offset;
2837
0
}
2838
2839
2840
/* NFSv2 RFC 1094, Page 15 */
2841
static int
2842
dissect_timeval(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int hf_time, int hf_time_sec,
2843
          int hf_time_usec)
2844
0
{
2845
2846
0
  if (tree) {
2847
0
    proto_item *time_item;
2848
0
    proto_tree *time_tree;
2849
0
    uint32_t      seconds;
2850
0
    uint32_t      useconds;
2851
0
    nstime_t    ts;
2852
2853
0
    seconds  = tvb_get_ntohl(tvb, offset+0);
2854
0
    useconds = tvb_get_ntohl(tvb, offset+4);
2855
0
    ts.secs  = seconds;
2856
0
    ts.nsecs = useconds * 1000;
2857
2858
0
    time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8,
2859
0
        &ts);
2860
2861
0
    time_tree = proto_item_add_subtree(time_item, ett_nfs_timeval);
2862
2863
0
    proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4,
2864
0
            seconds);
2865
0
    proto_tree_add_uint(time_tree, hf_time_usec, tvb, offset+4, 4,
2866
0
            useconds);
2867
0
  }
2868
0
  offset += 8;
2869
0
  return offset;
2870
0
}
2871
2872
/* NFSv2 RFC 1094, Page 16 */
2873
static const value_string nfs2_mode_names[] = {
2874
  { 1,  "Character Special Device"  },
2875
  { 2,  "Directory" },
2876
  { 3,  "Block Special Device"  },
2877
  { 4,  "Regular File"  },
2878
  { 5,  "Symbolic Link" },
2879
  { 6,  "Named Socket"  },
2880
  { 0000000,  NULL    }
2881
};
2882
2883
static int
2884
dissect_nfs2_mode(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
2885
0
{
2886
0
  static int * const modes[] = {
2887
0
    &hf_nfs2_mode_name,
2888
0
    &hf_nfs2_mode_set_user_id,
2889
0
    &hf_nfs2_mode_set_group_id,
2890
0
    &hf_nfs2_mode_save_swap_text,
2891
0
    &hf_nfs2_mode_read_owner,
2892
0
    &hf_nfs2_mode_write_owner,
2893
0
    &hf_nfs2_mode_exec_owner,
2894
0
    &hf_nfs2_mode_read_group,
2895
0
    &hf_nfs2_mode_write_group,
2896
0
    &hf_nfs2_mode_exec_group,
2897
0
    &hf_nfs2_mode_read_other,
2898
0
    &hf_nfs2_mode_write_other,
2899
0
    &hf_nfs2_mode_exec_other,
2900
0
    NULL
2901
0
  };
2902
2903
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_nfs2_mode, ett_nfs2_mode, modes, ENC_BIG_ENDIAN);
2904
2905
0
  offset += 4;
2906
0
  return offset;
2907
0
}
2908
2909
2910
/* NFSv2 RFC 1094, Page 15 */
2911
unsigned
2912
dissect_nfs2_fattr(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
2913
0
{
2914
0
  proto_item *fattr_item;
2915
0
  proto_tree *fattr_tree;
2916
0
  unsigned    old_offset = offset;
2917
2918
0
  fattr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
2919
0
      ett_nfs_fattr, &fattr_item, name);
2920
2921
0
  offset = dissect_nfs2_ftype(tvb, offset, fattr_tree);
2922
0
  offset = dissect_nfs2_mode(tvb, offset, fattr_tree);
2923
  /* XXX - "Notice that the file type is specified both in the mode bits
2924
   * and in the file type." - Expert Info if inconsistent?
2925
   */
2926
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_nlink, offset);
2927
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_uid, offset);
2928
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_gid, offset);
2929
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_size, offset);
2930
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_blocksize, offset);
2931
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_rdev, offset);
2932
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_blocks, offset);
2933
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_fsid, offset);
2934
0
  offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_fileid, offset);
2935
2936
0
  offset = dissect_timeval(tvb, offset, fattr_tree,
2937
0
    hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_usec);
2938
0
  offset = dissect_timeval(tvb, offset, fattr_tree,
2939
0
    hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_usec);
2940
0
  offset = dissect_timeval(tvb, offset, fattr_tree,
2941
0
    hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_usec);
2942
2943
  /* now we know, that fattr is shorter */
2944
0
  proto_item_set_len(fattr_item, offset - old_offset);
2945
2946
0
  return offset;
2947
0
}
2948
2949
2950
/* NFSv2 RFC 1094, Page 17 */
2951
static int
2952
dissect_nfs2_sattr(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
2953
0
{
2954
0
  proto_item *sattr_item;
2955
0
  proto_tree *sattr_tree;
2956
0
  unsigned    old_offset = offset;
2957
2958
0
  sattr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
2959
0
          ett_nfs2_sattr, &sattr_item, name);
2960
2961
0
  if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2962
0
    offset = dissect_nfs2_mode(tvb, offset, sattr_tree);
2963
0
  else {
2964
0
    proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_mode, tvb, offset, 4, 0xffffffff, "no value");
2965
0
    offset += 4;
2966
0
  }
2967
2968
0
  if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2969
0
    offset = dissect_rpc_uint32(tvb, sattr_tree, hf_nfs2_fattr_uid,
2970
0
      offset);
2971
0
  else {
2972
0
    proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_fattr_uid, tvb, offset, 4, 0xffffffff, "no value");
2973
0
    offset += 4;
2974
0
  }
2975
2976
0
  if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2977
0
    offset = dissect_rpc_uint32(tvb, sattr_tree, hf_nfs2_fattr_gid,
2978
0
      offset);
2979
0
  else {
2980
0
    proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_fattr_gid, tvb, offset, 4, 0xffffffff, "no value");
2981
0
    offset += 4;
2982
0
  }
2983
2984
0
  if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2985
0
    offset = dissect_rpc_uint32(tvb, sattr_tree, hf_nfs2_fattr_size,
2986
0
      offset);
2987
0
  else {
2988
0
    proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_fattr_size, tvb, offset, 4, 0xffffffff, "no value");
2989
0
    offset += 4;
2990
0
  }
2991
2992
0
  if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) {
2993
0
    offset = dissect_timeval(tvb, offset, sattr_tree,
2994
0
      hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_usec);
2995
0
  } else {
2996
0
    nstime_t    ts;
2997
2998
0
    ts.secs  = 0xffffffff;
2999
0
    ts.nsecs = 0;
3000
3001
0
    proto_tree_add_time_format_value(sattr_tree, hf_nfs_atime, tvb, offset, 8, &ts, "no value");
3002
0
    offset += 8;
3003
0
  }
3004
3005
0
  if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) {
3006
0
    offset = dissect_timeval(tvb, offset, sattr_tree,
3007
0
      hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_usec);
3008
0
  } else {
3009
0
    nstime_t    ts;
3010
3011
0
    ts.secs  = 0xffffffff;
3012
0
    ts.nsecs = 0;
3013
3014
0
    proto_tree_add_time_format_value(sattr_tree, hf_nfs_mtime, tvb, offset, 8, &ts, "no value");
3015
0
    offset += 8;
3016
0
  }
3017
3018
  /* now we know, that sattr is shorter */
3019
0
  proto_item_set_len(sattr_item, offset - old_offset);
3020
3021
0
  return offset;
3022
0
}
3023
3024
3025
/* NFSv2 RFC 1094, Page 17 */
3026
static int
3027
dissect_filename(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree, int hf, const char **string_ret)
3028
0
{
3029
0
  offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, string_ret);
3030
0
  return offset;
3031
0
}
3032
3033
3034
/* NFSv2 RFC 1094, Page 17 */
3035
static int
3036
dissect_path(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree, int hf, const char **name)
3037
0
{
3038
0
  offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, name);
3039
0
  return offset;
3040
0
}
3041
3042
3043
/* NFSv2 RFC 1094, Page 17,18 */
3044
static int
3045
dissect_attrstat(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo, const char *funcname)
3046
0
{
3047
0
  uint32_t      status;
3048
0
  const char *err;
3049
3050
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
3051
0
  switch (status) {
3052
0
    case 0:
3053
0
      offset = dissect_nfs2_fattr(tvb, offset, tree, "attributes");
3054
0
      proto_item_append_text(tree, ", %s Reply", funcname);
3055
0
    break;
3056
0
    default:
3057
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
3058
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3059
0
      proto_item_append_text(tree, ", %s Reply  Error: %s", funcname, err);
3060
0
    break;
3061
0
  }
3062
3063
0
  return offset;
3064
0
}
3065
3066
3067
/* NFSv2 RFC 1094, Page 17,18 */
3068
static int
3069
dissect_nfs2_write_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3070
0
{
3071
0
  return dissect_attrstat(tvb, 0, tree, pinfo, "WRITE");
3072
0
}
3073
3074
3075
/* NFSv2 RFC 1094, Page 18 */
3076
static int
3077
dissect_nfs2_setattr_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3078
0
{
3079
0
  return dissect_attrstat(tvb, 0, tree, pinfo, "SETATTR");
3080
0
}
3081
3082
3083
/* NFSv2 RFC 1094, Page 18 */
3084
static int
3085
dissect_nfs2_getattr_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3086
0
{
3087
0
  return dissect_attrstat(tvb, 0, tree, pinfo, "GETATTR");
3088
0
}
3089
3090
3091
/* NFSv2 RFC 1094, Page 18 */
3092
static int
3093
dissect_diropargs(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
3094
          const char *label, uint32_t *hash, const char **name, rpc_call_info_value *civ)
3095
0
{
3096
0
  proto_item *diropargs_item;
3097
0
  proto_tree *diropargs_tree;
3098
0
  unsigned    old_offset     = offset;
3099
3100
0
  diropargs_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
3101
0
      ett_nfs2_diropargs, &diropargs_item, label);
3102
3103
  /* are we snooping fh to filenames ?*/
3104
0
  if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
3105
    /* v2 LOOKUP, CREATE, MKDIR, SYMLINK calls might give us a mapping*/
3106
3107
0
    if ( (civ->prog == 100003)
3108
0
      &&(civ->vers == 2)
3109
0
      &&(civ->request)
3110
0
      &&((civ->proc == 4)||(civ->proc == 9)||(civ->proc == 13)||(civ->proc == 14))
3111
0
    ) {
3112
0
      nfs_name_snoop_add_name(civ->xid, tvb,
3113
0
        offset+36, tvb_get_ntohl(tvb, offset+32),
3114
0
        offset, 32, NULL);
3115
0
    }
3116
0
  }
3117
3118
0
  offset = dissect_fhandle(tvb, offset, pinfo, diropargs_tree, "dir", hash, civ);
3119
0
  offset = dissect_filename(tvb, pinfo, offset, diropargs_tree, hf_nfs_name, name);
3120
3121
  /* now we know, that diropargs is shorter */
3122
0
  proto_item_set_len(diropargs_item, offset - old_offset);
3123
3124
0
  return offset;
3125
0
}
3126
3127
3128
/* NFSv2 RFC 1094, Page 18 */
3129
static int
3130
dissect_nfs2_rmdir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3131
0
{
3132
0
  uint32_t      hash;
3133
0
  const char *name = NULL;
3134
0
  unsigned offset = 0;
3135
3136
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3137
3138
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3139
0
  proto_item_append_text(tree, ", RMDIR Call DH: 0x%08x/%s", hash, name);
3140
3141
0
  return offset;
3142
0
}
3143
3144
3145
/* NFSv2 RFC 1094, Page 18 */
3146
static int
3147
dissect_nfs2_remove_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3148
0
{
3149
0
  uint32_t      hash;
3150
0
  const char *name = NULL;
3151
0
  unsigned offset = 0;
3152
3153
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3154
3155
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3156
0
  proto_item_append_text(tree, ", REMOVE Call DH: 0x%08x/%s", hash, name);
3157
3158
0
  return offset;
3159
0
}
3160
3161
3162
/* NFSv2 RFC 1094, Page 18 */
3163
static int
3164
dissect_nfs2_lookup_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3165
0
{
3166
0
  uint32_t      hash;
3167
0
  const char *name = NULL;
3168
0
  unsigned offset = 0;
3169
3170
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3171
3172
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3173
0
  proto_item_append_text(tree, ", LOOKUP Call DH: 0x%08x/%s", hash, name);
3174
3175
0
  return offset;
3176
0
}
3177
3178
3179
/* NFSv2 RFC 1094, Page 18 */
3180
static int
3181
dissect_diropres(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
3182
     proto_tree *tree, const char *funcname, rpc_call_info_value* civ)
3183
0
{
3184
0
  uint32_t      status;
3185
0
  uint32_t      hash;
3186
0
  const char *err;
3187
3188
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
3189
0
  switch (status) {
3190
0
    case 0:
3191
0
      offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, civ);
3192
0
      offset = dissect_nfs2_fattr  (tvb, offset, tree, "attributes");
3193
0
      col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
3194
0
      proto_item_append_text(tree, ", %s Reply FH: 0x%08x", funcname, hash);
3195
0
    break;
3196
0
    default:
3197
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
3198
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3199
0
      proto_item_append_text(tree, ", %s Reply  Error: %s", funcname, err);
3200
0
    break;
3201
0
  }
3202
3203
0
  return offset;
3204
0
}
3205
3206
3207
/* nfsdata is simply a chunk of RPC opaque data (length, data, fill bytes) */
3208
static int
3209
dissect_nfsdata(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree, int hf)
3210
0
{
3211
0
  offset = dissect_rpc_data(tvb, pinfo, tree, hf, offset);
3212
0
  return offset;
3213
0
}
3214
3215
3216
/* NFSv2 RFC 1094, Page 18 */
3217
static int
3218
dissect_nfs2_mkdir_reply(tvbuff_t *tvb, packet_info *pinfo,
3219
       proto_tree *tree, void *data)
3220
0
{
3221
0
  return dissect_diropres(tvb, 0, pinfo, tree, "MKDIR", (rpc_call_info_value*)data);
3222
0
}
3223
3224
3225
static int
3226
dissect_nfs2_create_reply(tvbuff_t *tvb, packet_info *pinfo,
3227
        proto_tree *tree, void *data _U_)
3228
0
{
3229
0
  return dissect_diropres(tvb, 0, pinfo, tree, "CREATE", (rpc_call_info_value*)data);
3230
0
}
3231
3232
3233
static int
3234
dissect_nfs2_lookup_reply(tvbuff_t *tvb, packet_info *pinfo,
3235
        proto_tree *tree, void *data _U_)
3236
0
{
3237
0
  return dissect_diropres(tvb, 0, pinfo, tree, "LOOKUP", (rpc_call_info_value*)data);
3238
0
}
3239
3240
3241
/* RFC 1094, Page 6 */
3242
static int
3243
dissect_nfs2_setattr_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3244
0
{
3245
0
  uint32_t hash;
3246
0
  unsigned offset = 0;
3247
3248
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
3249
0
  offset = dissect_nfs2_sattr  (tvb, offset,        tree, "attributes");
3250
3251
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
3252
0
  proto_item_append_text(tree, ", SETATTR Call FH: 0x%08x", hash);
3253
0
  return offset;
3254
0
}
3255
3256
3257
/* NFSv2 RFC 1094, Page 6 */
3258
static int
3259
dissect_nfs2_readlink_reply(tvbuff_t *tvb, packet_info *pinfo,
3260
          proto_tree *tree, void *data _U_)
3261
0
{
3262
0
  uint32_t      status;
3263
0
  const char *err;
3264
0
  const char *name = NULL;
3265
0
  unsigned offset = 0;
3266
3267
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
3268
0
  switch (status) {
3269
0
    case 0:
3270
0
      offset = dissect_nfsdata_reduced(R_NFS2_PATH, tvb, pinfo, offset, tree, hf_nfs2_readlink_data, &name);
3271
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Path: %s", name);
3272
0
      proto_item_append_text(tree, ", READLINK Reply Path: %s", name);
3273
0
    break;
3274
0
    default:
3275
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
3276
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3277
0
      proto_item_append_text(tree, ", READLINK Reply  Error: %s", err);
3278
0
    break;
3279
0
  }
3280
3281
0
  return offset;
3282
0
}
3283
3284
3285
/* NFSv2 RFC 1094, Page 7 */
3286
static int
3287
dissect_nfs2_read_call(tvbuff_t *tvb, packet_info *pinfo,
3288
           proto_tree *tree, void *data)
3289
0
{
3290
0
  uint32_t offset_value;
3291
0
  uint32_t count;
3292
0
  uint32_t totalcount;
3293
0
  uint32_t hash;
3294
0
  unsigned offset = 0;
3295
3296
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
3297
0
  proto_tree_add_item_ret_uint(tree, hf_nfs2_read_offset, tvb,
3298
0
    offset+0, 4, ENC_BIG_ENDIAN, &offset_value);
3299
0
  proto_tree_add_item_ret_uint(tree, hf_nfs2_read_count, tvb,
3300
0
    offset+4, 4, ENC_BIG_ENDIAN, &count);
3301
0
  proto_tree_add_item_ret_uint(tree, hf_nfs2_read_totalcount, tvb,
3302
0
    offset+8, 4, ENC_BIG_ENDIAN, &totalcount);
3303
0
  offset += 12;
3304
3305
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x Offset: %u Count: %u TotalCount: %u",
3306
0
    hash, offset_value, count, totalcount);
3307
0
  proto_item_append_text(tree, ", READ Call FH: 0x%08x Offset: %u Count: %u TotalCount: %u",
3308
0
    hash, offset_value, count, totalcount);
3309
3310
0
  return offset;
3311
0
}
3312
3313
3314
/* NFSv2 RFC 1094, Page 7 */
3315
static int
3316
dissect_nfs2_read_reply(tvbuff_t *tvb, packet_info *pinfo,
3317
      proto_tree *tree, void *data _U_)
3318
0
{
3319
0
  uint32_t      status;
3320
0
  const char *err;
3321
0
  unsigned offset = 0;
3322
3323
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
3324
0
  switch (status) {
3325
0
    case 0:
3326
0
      offset = dissect_nfs2_fattr(tvb, offset, tree, "attributes");
3327
0
      proto_item_append_text(tree, ", READ Reply");
3328
0
      offset = dissect_nfsdata_reduced(R_NFSDATA, tvb, pinfo, offset, tree, hf_nfs_data, NULL);
3329
0
    break;
3330
0
    default:
3331
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
3332
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3333
0
      proto_item_append_text(tree, ", READ Reply  Error: %s", err);
3334
0
    break;
3335
0
  }
3336
3337
0
  return offset;
3338
0
}
3339
3340
3341
/* NFSv2 RFC 1094, Page 8 */
3342
static int
3343
dissect_nfs2_write_call(tvbuff_t *tvb, packet_info *pinfo,
3344
      proto_tree *tree, void *data)
3345
0
{
3346
0
  uint32_t beginoffset;
3347
0
  uint32_t offset_value;
3348
0
  uint32_t totalcount;
3349
0
  uint32_t hash;
3350
0
  unsigned offset = 0;
3351
3352
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
3353
3354
0
  proto_tree_add_item_ret_uint(tree, hf_nfs2_write_beginoffset, tvb,
3355
0
    offset+0, 4, ENC_BIG_ENDIAN, &beginoffset);
3356
0
  proto_tree_add_item_ret_uint(tree, hf_nfs2_write_offset, tvb,
3357
0
    offset+4, 4, ENC_BIG_ENDIAN, &offset_value);
3358
0
  proto_tree_add_item_ret_uint(tree, hf_nfs2_write_totalcount, tvb,
3359
0
    offset+8, 4, ENC_BIG_ENDIAN, &totalcount);
3360
0
  offset += 12;
3361
3362
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x BeginOffset: %u Offset: %u TotalCount: %u",
3363
0
    hash, beginoffset, offset_value, totalcount);
3364
0
  proto_item_append_text(tree, ", WRITE Call FH: 0x%08x BeginOffset: %u Offset: %u TotalCount: %u",
3365
0
    hash, beginoffset, offset_value, totalcount);
3366
3367
0
  offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs_data);
3368
3369
0
  return offset;
3370
0
}
3371
3372
3373
/* NFSv2 RFC 1094, Page 8 */
3374
static int
3375
dissect_nfs2_mkdir_call(tvbuff_t *tvb, packet_info *pinfo,
3376
      proto_tree *tree, void *data)
3377
0
{
3378
0
  uint32_t      hash;
3379
0
  const char *name = NULL;
3380
0
  unsigned offset = 0;
3381
3382
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3383
0
  offset = dissect_nfs2_sattr    (tvb, offset,        tree, "attributes");
3384
3385
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3386
0
  proto_item_append_text(tree, ", MKDIR Call DH: 0x%08x/%s", hash, name);
3387
3388
0
  return offset;
3389
0
}
3390
3391
static int
3392
dissect_nfs2_create_call(tvbuff_t *tvb, packet_info *pinfo,
3393
       proto_tree *tree, void *data)
3394
0
{
3395
0
  uint32_t      hash;
3396
0
  const char *name = NULL;
3397
0
  unsigned offset = 0;
3398
3399
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3400
0
  offset = dissect_nfs2_sattr    (tvb, offset,        tree, "attributes");
3401
3402
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3403
0
  proto_item_append_text(tree, ", CREATE Call DH: 0x%08x/%s", hash, name);
3404
3405
0
  return offset;
3406
0
}
3407
3408
3409
/* NFSv2 RFC 1094, Page 9 */
3410
static int
3411
dissect_nfs2_rename_call(tvbuff_t *tvb, packet_info *pinfo,
3412
       proto_tree *tree, void *data)
3413
0
{
3414
0
  uint32_t      from_hash;
3415
0
  const char *from_name = NULL;
3416
0
  uint32_t      to_hash;
3417
0
  const char *to_name   = NULL;
3418
0
  unsigned offset = 0;
3419
3420
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "from", &from_hash, &from_name, (rpc_call_info_value*)data);
3421
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "to", &to_hash, &to_name, (rpc_call_info_value*)data);
3422
3423
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To DH: 0x%08x/%s",
3424
0
    from_hash, from_name, to_hash, to_name);
3425
0
  proto_item_append_text(tree, ", RENAME Call From DH: 0x%08x/%s To DH: 0x%08x/%s",
3426
0
    from_hash, from_name, to_hash, to_name);
3427
3428
0
  return offset;
3429
0
}
3430
3431
3432
/* NFSv2 RFC 1094, Page 9 */
3433
static int
3434
dissect_nfs2_link_call(tvbuff_t *tvb, packet_info *pinfo,
3435
           proto_tree *tree, void *data)
3436
0
{
3437
0
  uint32_t      from_hash;
3438
0
  uint32_t      to_hash;
3439
0
  const char *to_name = NULL;
3440
0
  unsigned offset = 0;
3441
3442
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "from", &from_hash, (rpc_call_info_value*)data);
3443
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "to", &to_hash, &to_name, (rpc_call_info_value*)data);
3444
3445
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x To DH: 0x%08x/%s",
3446
0
    from_hash, to_hash, to_name);
3447
0
  proto_item_append_text(tree, ", LINK Call From DH: 0x%08x To DH: 0x%08x/%s",
3448
0
    from_hash, to_hash, to_name);
3449
3450
0
  return offset;
3451
0
}
3452
3453
3454
/* NFSv2 RFC 1094, Page 10 */
3455
static int
3456
dissect_nfs2_symlink_call(tvbuff_t *tvb, packet_info *pinfo,
3457
        proto_tree *tree, void *data)
3458
0
{
3459
0
  uint32_t      from_hash;
3460
0
  const char *from_name = NULL;
3461
0
  const char *to_name   = NULL;
3462
0
  unsigned offset = 0;
3463
3464
0
  offset = dissect_diropargs(tvb, offset, pinfo, tree, "from", &from_hash, &from_name, (rpc_call_info_value*)data);
3465
0
  offset = dissect_path(tvb, pinfo, offset, tree, hf_nfs_symlink_to, &to_name);
3466
0
  offset = dissect_nfs2_sattr(tvb, offset, tree, "attributes");
3467
3468
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To %s",
3469
0
    from_hash, from_name, to_name);
3470
0
  proto_item_append_text(tree, ", SYMLINK Call From DH: 0x%08x/%s To %s",
3471
0
    from_hash, from_name, to_name);
3472
3473
0
  return offset;
3474
0
}
3475
3476
3477
/* NFSv2 RFC 1094, Page 11 */
3478
static int
3479
dissect_nfs2_readdir_call(tvbuff_t *tvb, packet_info *pinfo,
3480
        proto_tree *tree, void *data)
3481
0
{
3482
0
  uint32_t hash;
3483
0
  unsigned offset = 0;
3484
3485
0
  offset = dissect_fhandle(tvb, offset, pinfo, tree, "dir", &hash, (rpc_call_info_value*)data);
3486
3487
0
  proto_tree_add_item(tree, hf_nfs2_readdir_cookie, tvb, offset+ 0, 4, ENC_BIG_ENDIAN);
3488
0
  proto_tree_add_item(tree, hf_nfs2_readdir_count, tvb, offset+ 4, 4, ENC_BIG_ENDIAN);
3489
0
  offset += 8;
3490
3491
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
3492
0
  proto_item_append_text(tree, ", READDIR Call FH: 0x%08x", hash);
3493
3494
0
  return offset;
3495
0
}
3496
3497
3498
/* NFSv2 RFC 1094, Page 11 */
3499
static int
3500
dissect_readdir_entry(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data _U_)
3501
0
{
3502
0
  proto_item *entry_item = NULL;
3503
0
  proto_tree *entry_tree = NULL;
3504
0
  unsigned    old_offset = offset;
3505
0
  uint32_t      fileid;
3506
0
  const char *name;
3507
3508
0
  if (tree) {
3509
0
    entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb,
3510
0
      offset+0, -1, ENC_NA);
3511
0
    entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
3512
0
  }
3513
3514
0
  proto_tree_add_item_ret_uint(entry_tree, hf_nfs2_readdir_entry_fileid, tvb,
3515
0
      offset, 4, ENC_BIG_ENDIAN, &fileid);
3516
0
  offset += 4;
3517
3518
0
  offset = dissect_filename(tvb, pinfo, offset, entry_tree,
3519
0
    hf_nfs2_readdir_entry_name, &name);
3520
0
  if (entry_item)
3521
0
    proto_item_set_text(entry_item, "Entry: file ID %u, name %s", fileid, name);
3522
3523
0
  proto_tree_add_item(entry_tree, hf_nfs2_readdir_entry_cookie, tvb, offset, 4, ENC_BIG_ENDIAN);
3524
0
  offset += 4;
3525
3526
  /* now we know, that a readdir entry is shorter */
3527
0
  if (entry_item) {
3528
0
    proto_item_set_len(entry_item, offset - old_offset);
3529
0
  }
3530
3531
0
  return offset;
3532
0
}
3533
3534
3535
/* NFSv2 RFC 1094, Page 11 */
3536
static int
3537
dissect_nfs2_readdir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3538
0
{
3539
0
  uint32_t      status;
3540
0
  uint32_t      eof_value;
3541
0
  const char *err;
3542
0
  unsigned offset = 0;
3543
3544
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
3545
0
  switch (status) {
3546
0
    case 0:
3547
0
      proto_item_append_text(tree, ", READDIR Reply");
3548
3549
0
      offset = dissect_rpc_list(tvb, pinfo, tree, offset,
3550
0
        dissect_readdir_entry, NULL);
3551
0
      proto_tree_add_item_ret_uint(tree, hf_nfs_readdir_eof, tvb,
3552
0
          offset, 4, ENC_BIG_ENDIAN, &eof_value);
3553
0
      offset += 4;
3554
0
    break;
3555
0
    default:
3556
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
3557
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3558
0
      proto_item_append_text(tree, ", READDIR Reply  Error: %s", err);
3559
0
    break;
3560
0
  }
3561
3562
0
  return offset;
3563
0
}
3564
3565
3566
/* NFSv2 RFC 1094, Page 12 */
3567
static int
3568
dissect_nfs2_statfs_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3569
0
{
3570
0
  uint32_t      status;
3571
0
  const char *err;
3572
0
  unsigned offset = 0;
3573
3574
0
  offset = dissect_nfs2_status(tvb, offset, tree, &status);
3575
0
  switch (status) {
3576
0
    case 0:
3577
0
      proto_tree_add_item(tree, hf_nfs2_statfs_tsize, tvb, offset+ 0, 4, ENC_BIG_ENDIAN);
3578
0
      proto_tree_add_item(tree, hf_nfs2_statfs_bsize, tvb, offset+ 4, 4, ENC_BIG_ENDIAN);
3579
0
      proto_tree_add_item(tree, hf_nfs2_statfs_blocks, tvb, offset+ 8, 4, ENC_BIG_ENDIAN);
3580
0
      proto_tree_add_item(tree, hf_nfs2_statfs_bfree, tvb, offset+12, 4, ENC_BIG_ENDIAN);
3581
0
      proto_tree_add_item(tree, hf_nfs2_statfs_bavail, tvb, offset+16, 4, ENC_BIG_ENDIAN);
3582
0
      offset += 20;
3583
0
      proto_item_append_text(tree, ", STATFS Reply");
3584
0
    break;
3585
0
    default:
3586
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs2_stat_ext, "Unknown error: %u");
3587
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3588
0
      proto_item_append_text(tree, ", STATFS Reply  Error: %s", err);
3589
0
    break;
3590
0
  }
3591
3592
0
  return offset;
3593
0
}
3594
3595
3596
/* proc number, "proc name", dissect_request, dissect_reply */
3597
static const vsff nfs2_proc[] = {
3598
  { 0,  "NULL",   /* OK */
3599
  dissect_rpc_void,   dissect_rpc_void },
3600
  { 1,  "GETATTR",  /* OK */
3601
  dissect_nfs2_getattr_call,  dissect_nfs2_getattr_reply },
3602
  { 2,  "SETATTR",  /* OK */
3603
  dissect_nfs2_setattr_call,  dissect_nfs2_setattr_reply },
3604
  { 3,  "ROOT",   /* OK */
3605
  dissect_rpc_void,   dissect_rpc_void },
3606
  { 4,  "LOOKUP", /* OK */
3607
  dissect_nfs2_lookup_call, dissect_nfs2_lookup_reply },
3608
  { 5,  "READLINK", /* OK */
3609
  dissect_nfs2_readlink_call, dissect_nfs2_readlink_reply },
3610
  { 6,  "READ",   /* OK */
3611
  dissect_nfs2_read_call,   dissect_nfs2_read_reply },
3612
  { 7,  "WRITECACHE", /* OK */
3613
  dissect_rpc_void,   dissect_rpc_void },
3614
  { 8,  "WRITE",  /* OK */
3615
  dissect_nfs2_write_call,  dissect_nfs2_write_reply },
3616
  { 9,  "CREATE", /* OK */
3617
  dissect_nfs2_create_call, dissect_nfs2_create_reply },
3618
  { 10, "REMOVE", /* OK */
3619
  dissect_nfs2_remove_call, dissect_nfs2_remove_reply },
3620
  { 11, "RENAME", /* OK */
3621
  dissect_nfs2_rename_call, dissect_nfs2_rename_reply },
3622
  { 12, "LINK",   /* OK */
3623
  dissect_nfs2_link_call,   dissect_nfs2_link_reply },
3624
  { 13, "SYMLINK",  /* OK */
3625
  dissect_nfs2_symlink_call,  dissect_nfs2_symlink_reply },
3626
  { 14, "MKDIR",  /* OK */
3627
  dissect_nfs2_mkdir_call,  dissect_nfs2_mkdir_reply },
3628
  { 15, "RMDIR",  /* OK */
3629
  dissect_nfs2_rmdir_call,  dissect_nfs2_rmdir_reply },
3630
  { 16, "READDIR",  /* OK */
3631
  dissect_nfs2_readdir_call,  dissect_nfs2_readdir_reply },
3632
  { 17, "STATFS", /* OK */
3633
  dissect_nfs2_statfs_call, dissect_nfs2_statfs_reply },
3634
  { 0,  NULL, NULL, NULL }
3635
};
3636
3637
static const value_string nfs2_proc_vals[] = {
3638
  { 0,  "NULL" },
3639
  { 1,  "GETATTR" },
3640
  { 2,  "SETATTR" },
3641
  { 3,  "ROOT" },
3642
  { 4,  "LOOKUP" },
3643
  { 5,  "READLINK" },
3644
  { 6,  "READ" },
3645
  { 7,  "WRITECACHE" },
3646
  { 8,  "WRITE" },
3647
  { 9,  "CREATE" },
3648
  { 10, "REMOVE" },
3649
  { 11, "RENAME" },
3650
  { 12, "LINK" },
3651
  { 13, "SYMLINK" },
3652
  { 14, "MKDIR" },
3653
  { 15, "RMDIR" },
3654
  { 16, "READDIR" },
3655
  { 17, "STATFS" },
3656
  { 0,  NULL }
3657
};
3658
static value_string_ext nfs2_proc_vals_ext = VALUE_STRING_EXT_INIT(nfs2_proc_vals);
3659
3660
/* end of NFS Version 2 */
3661
3662
3663
/***************************/
3664
/* NFS Version 3, RFC 1813 */
3665
/***************************/
3666
3667
/* NFSv3 RFC 1813, Page 15 */
3668
static unsigned
3669
dissect_nfs3_filename(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree, int hf, const char **string_ret)
3670
0
{
3671
0
  offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, string_ret);
3672
0
  return offset;
3673
0
}
3674
3675
3676
/* NFSv3 RFC 1813, Page 15 */
3677
static unsigned
3678
dissect_nfs3_path(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree, int hf, const char **name)
3679
0
{
3680
0
  offset = dissect_rpc_string(tvb, pinfo, tree, hf, offset, name);
3681
0
  return offset;
3682
0
}
3683
3684
3685
/* NFSv3 RFC 1813, Page 15 */
3686
static unsigned
3687
dissect_nfs3_cookie_verf(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
3688
0
{
3689
0
  proto_tree_add_bytes_format_value(tree, hf_nfs3_verifier, tvb, offset, NFS3_COOKIEVERFSIZE, NULL, "Opaque Data");
3690
0
  offset += NFS3_COOKIEVERFSIZE;
3691
0
  return offset;
3692
0
}
3693
3694
3695
/* NFSv3 RFC 1813, Page 16 */
3696
static unsigned
3697
dissect_nfs3_create_verf(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
3698
0
{
3699
0
  proto_tree_add_bytes_format_value(tree, hf_nfs3_verifier, tvb, offset, NFS3_CREATEVERFSIZE, NULL, "Opaque Data");
3700
0
  offset += NFS3_CREATEVERFSIZE;
3701
0
  return offset;
3702
0
}
3703
3704
3705
/* NFSv3 RFC 1813, Page 16 */
3706
static unsigned
3707
dissect_nfs3_write_verf(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
3708
0
{
3709
0
  proto_tree_add_bytes_format_value(tree, hf_nfs3_verifier, tvb, offset, NFS3_WRITEVERFSIZE, NULL, "Opaque Data");
3710
0
  offset += NFS3_WRITEVERFSIZE;
3711
0
  return offset;
3712
0
}
3713
3714
3715
/* RFC 1813, Page 16 */
3716
static unsigned
3717
dissect_nfs3_mode(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint32_t *mode)
3718
0
{
3719
0
  static int * const mode_bits[] = {
3720
0
    &hf_nfs3_mode_suid,
3721
0
    &hf_nfs3_mode_sgid,
3722
0
    &hf_nfs3_mode_sticky,
3723
0
    &hf_nfs3_mode_rusr,
3724
0
    &hf_nfs3_mode_wusr,
3725
0
    &hf_nfs3_mode_xusr,
3726
0
    &hf_nfs3_mode_rgrp,
3727
0
    &hf_nfs3_mode_wgrp,
3728
0
    &hf_nfs3_mode_xgrp,
3729
0
    &hf_nfs3_mode_roth,
3730
0
    &hf_nfs3_mode_woth,
3731
0
    &hf_nfs3_mode_xoth,
3732
0
    NULL
3733
0
  };
3734
3735
3736
0
  if (mode) {
3737
0
    *mode = tvb_get_ntohl(tvb, offset+0);
3738
0
  }
3739
3740
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_nfs3_mode, ett_nfs3_mode, mode_bits, ENC_BIG_ENDIAN);
3741
3742
0
  offset += 4;
3743
0
  return offset;
3744
0
}
3745
3746
3747
/* NFSv3 RFC 1813, Page 16,17 */
3748
static const value_string names_nfs_nfsstat3[] =
3749
{
3750
  { 0,  "NFS3_OK" },
3751
  { 1,  "NFS3ERR_PERM" },
3752
  { 2,  "NFS3ERR_NOENT" },
3753
  { 5,  "NFS3ERR_IO" },
3754
  { 6,  "NFS3ERR_NXIO" },
3755
  { 13, "NFS3ERR_ACCES" },
3756
  { 17, "NFS3ERR_EXIST" },
3757
  { 18, "NFS3ERR_XDEV" },
3758
  { 19, "NFS3ERR_NODEV" },
3759
  { 20, "NFS3ERR_NOTDIR" },
3760
  { 21, "NFS3ERR_ISDIR" },
3761
  { 22, "NFS3ERR_INVAL" },
3762
  { 27, "NFS3ERR_FBIG" },
3763
  { 28, "NFS3ERR_NOSPC" },
3764
  { 30, "NFS3ERR_ROFS" },
3765
  { 31, "NFS3ERR_MLINK" },
3766
  { 63, "NFS3ERR_NAMETOOLONG" },
3767
  { 66, "NFS3ERR_NOTEMPTY" },
3768
  { 69, "NFS3ERR_DQUOT" },
3769
  { 70, "NFS3ERR_STALE" },
3770
  { 71, "NFS3ERR_REMOTE" },
3771
  { 10001,  "NFS3ERR_BADHANDLE" },
3772
  { 10002,  "NFS3ERR_NOT_SYNC" },
3773
  { 10003,  "NFS3ERR_BAD_COOKIE" },
3774
  { 10004,  "NFS3ERR_NOTSUPP" },
3775
  { 10005,  "NFS3ERR_TOOSMALL" },
3776
  { 10006,  "NFS3ERR_SERVERFAULT" },
3777
  { 10007,  "NFS3ERR_BADTYPE" },
3778
  { 10008,  "NFS3ERR_JUKEBOX" },
3779
  { 0,  NULL }
3780
};
3781
static value_string_ext names_nfs3_status_ext = VALUE_STRING_EXT_INIT(names_nfs_nfsstat3);
3782
3783
/* NFSv3 RFC 1813, Page 16 */
3784
static unsigned
3785
dissect_nfs3_status(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint32_t *status)
3786
0
{
3787
0
  uint32_t      nfsstat3;
3788
3789
0
  nfsstat3 = tvb_get_ntohl(tvb, offset+0);
3790
3791
0
  if (tree) {
3792
0
    proto_item *stat_item;
3793
0
    proto_tree_add_uint(tree, hf_nfs3_status, tvb, offset+0, 4, nfsstat3);
3794
0
    stat_item = proto_tree_add_uint(tree, hf_nfs_status, tvb, offset+0, 4, nfsstat3);
3795
0
    proto_item_set_hidden(stat_item);
3796
0
  }
3797
3798
0
  offset += 4;
3799
0
  *status = nfsstat3;
3800
0
  return offset;
3801
0
}
3802
3803
3804
static const value_string names_nfs_ftype3[] =
3805
{
3806
  { NF3REG,  "Regular File" },
3807
  { NF3DIR,  "Directory" },
3808
  { NF3BLK,  "Block Special Device" },
3809
  { NF3CHR,  "Character Special Device" },
3810
  { NF3LNK,  "Symbolic Link" },
3811
  { NF3SOCK, "Socket" },
3812
  { NF3FIFO, "Named Pipe" },
3813
  { 0,  NULL }
3814
};
3815
static value_string_ext names_nfs_ftype3_ext = VALUE_STRING_EXT_INIT(names_nfs_ftype3);
3816
3817
/* NFSv3 RFC 1813, Page 20 */
3818
static unsigned
3819
dissect_ftype3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int hf,
3820
         uint32_t* ftype3)
3821
0
{
3822
0
  uint32_t type;
3823
3824
0
  proto_tree_add_item_ret_uint(tree, hf, tvb, offset, 4, ENC_BIG_ENDIAN, &type);
3825
3826
0
  offset += 4;
3827
0
  *ftype3 = type;
3828
0
  return offset;
3829
0
}
3830
3831
3832
/* NFSv3 RFC 1813, Page 20 */
3833
static unsigned
3834
dissect_nfs3_specdata(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
3835
0
{
3836
0
  uint32_t      specdata1;
3837
0
  uint32_t      specdata2;
3838
3839
0
  specdata1 = tvb_get_ntohl(tvb, offset+0);
3840
0
  specdata2 = tvb_get_ntohl(tvb, offset+4);
3841
3842
0
  if (tree) {
3843
0
    proto_tree *specdata3_tree;
3844
3845
0
    specdata3_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
3846
0
      ett_nfs3_specdata, NULL, "%s: %u,%u", name, specdata1, specdata2);
3847
3848
0
    proto_tree_add_uint(specdata3_tree, hf_nfs3_specdata1, tvb, offset+0, 4, specdata1);
3849
0
    proto_tree_add_uint(specdata3_tree, hf_nfs3_specdata2, tvb, offset+4, 4, specdata2);
3850
0
  }
3851
3852
0
  offset += 8;
3853
0
  return offset;
3854
0
}
3855
3856
3857
/* NFSv3 RFC 1813, Page 21 */
3858
unsigned
3859
dissect_nfs3_fh(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
3860
    const char *name, uint32_t *hash, rpc_call_info_value *civ)
3861
0
{
3862
0
  unsigned      fh3_len;
3863
0
  unsigned      fh3_len_full;
3864
  /*unsigned    fh3_fill;*/
3865
0
  proto_tree *ftree;
3866
0
  int     fh_offset, fh_length;
3867
3868
0
  fh3_len = tvb_get_ntohl(tvb, offset+0);
3869
0
  fh3_len_full = rpc_roundup(fh3_len);
3870
  /*fh3_fill = fh3_len_full - fh3_len;*/
3871
3872
0
  ftree = proto_tree_add_subtree(tree, tvb, offset, 4+fh3_len_full,
3873
0
      ett_nfs3_fh, NULL, name);
3874
3875
  /* are we snooping fh to filenames ?*/
3876
0
  if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
3877
    /* NFS v3 LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD
3878
      calls might give us a mapping*/
3879
0
    if ( ((civ->prog == 100003)
3880
0
      &&((civ->vers == 3)
3881
0
      &&(!civ->request)
3882
0
      &&((civ->proc == 3)||(civ->proc == 8)||(civ->proc == 9)||(civ->proc == 10)||(civ->proc == 11))))
3883
0
    ) {
3884
0
      fh_length = tvb_get_ntohl(tvb, offset);
3885
0
      fh_offset = offset+4;
3886
0
      nfs_name_snoop_add_fh(civ->xid, tvb, fh_offset,
3887
0
                fh_length);
3888
0
    }
3889
3890
    /* NFS v3 READDIRPLUS calls might give us a mapping */
3891
0
    if ( (civ->prog == 100003)
3892
0
      &&(civ->vers == 3)
3893
0
      &&(civ->request)
3894
0
      &&((civ->proc == 17))
3895
0
    ) {
3896
0
      fh_length = tvb_get_ntohl(tvb, offset);
3897
0
      fh_offset = offset+4;
3898
0
      nfs_name_snoop_readdir_add_parent_fh(civ->xid, tvb, fh_offset, fh_length);
3899
0
    }
3900
3901
    /* MOUNT v3 MNT replies might give us a filehandle */
3902
0
    if ( (civ->prog == 100005)
3903
0
      &&(civ->vers == 3)
3904
0
      &&(!civ->request)
3905
0
      &&(civ->proc == 1)
3906
0
    ) {
3907
0
      fh_length = tvb_get_ntohl(tvb, offset);
3908
0
      fh_offset = offset+4;
3909
0
      nfs_name_snoop_add_fh(civ->xid, tvb, fh_offset,
3910
0
                fh_length);
3911
0
    }
3912
0
  }
3913
3914
0
  proto_tree_add_uint(ftree, hf_nfs_fh_length, tvb, offset+0, 4,
3915
0
      fh3_len);
3916
3917
  /* Handle WebNFS requests where filehandle may be 0 length */
3918
0
  if (fh3_len > 0)
3919
0
  {
3920
0
    dissect_fhandle_data(tvb, offset+4, pinfo, ftree, fh3_len, false, hash);
3921
3922
0
    offset += fh3_len_full;
3923
0
  }
3924
0
  else if (hash) {
3925
    /* Make sure hash is set regardless, as our caller expects it
3926
     * to be initialized */
3927
0
    *hash = 0;
3928
0
  }
3929
3930
0
  offset += 4;
3931
3932
0
  return offset;
3933
0
}
3934
3935
3936
/* NFSv3 RFC 1813, Page 21 */
3937
static unsigned
3938
dissect_nfstime3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int hf_time,
3939
     int hf_time_sec, int hf_time_nsec)
3940
0
{
3941
0
  uint32_t   seconds;
3942
0
  uint32_t   nseconds;
3943
0
  nstime_t ts;
3944
3945
0
  seconds = tvb_get_ntohl(tvb, offset+0);
3946
0
  nseconds = tvb_get_ntohl(tvb, offset+4);
3947
0
  ts.secs = seconds;
3948
0
  ts.nsecs = nseconds;
3949
3950
0
  if (tree) {
3951
0
    proto_item *time_item;
3952
0
    proto_tree *time_tree;
3953
3954
0
    time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8,
3955
0
        &ts);
3956
3957
0
    time_tree = proto_item_add_subtree(time_item, ett_nfs3_nfstime);
3958
3959
0
    proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4,
3960
0
          seconds);
3961
0
    proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset+4, 4,
3962
0
          nseconds);
3963
0
  }
3964
0
  offset += 8;
3965
0
  return offset;
3966
0
}
3967
3968
3969
/* NFSv3 RFC 1813, Page 22
3970
 * The levels parameter tells this helper how many levels up in the tree it
3971
 * should display useful info such as type,mode,uid,gid
3972
 * If level has the COL_INFO_LEVEL flag set it will also display
3973
 * this info in the info column.
3974
 */
3975
static unsigned
3976
dissect_nfs_fattr3(packet_info *pinfo, tvbuff_t *tvb, unsigned offset,
3977
       proto_tree *tree, const char *name, uint32_t levels)
3978
0
{
3979
0
  proto_item *fattr3_item = NULL;
3980
0
  proto_tree *fattr3_tree = NULL;
3981
0
  unsigned    old_offset  = offset;
3982
0
  uint32_t      type, mode, uid, gid;
3983
3984
0
  fattr3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
3985
0
      ett_nfs3_fattr, &fattr3_item, name);
3986
3987
  /* ftype */
3988
0
  offset = dissect_ftype3(tvb, offset, fattr3_tree, hf_nfs3_fattr_type, &type);
3989
3990
  /* mode */
3991
0
  offset = dissect_nfs3_mode(tvb, offset, fattr3_tree, &mode);
3992
3993
  /* nlink */
3994
0
  offset = dissect_rpc_uint32(tvb, fattr3_tree, hf_nfs3_fattr_nlink,
3995
0
    offset);
3996
3997
  /* uid */
3998
0
  uid = tvb_get_ntohl(tvb, offset);
3999
0
  offset = dissect_rpc_uint32(tvb, fattr3_tree, hf_nfs3_fattr_uid,
4000
0
    offset);
4001
4002
  /* gid */
4003
0
  gid = tvb_get_ntohl(tvb, offset);
4004
0
  offset = dissect_rpc_uint32(tvb, fattr3_tree, hf_nfs3_fattr_gid,
4005
0
    offset);
4006
4007
  /* size*/
4008
0
  offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_size,
4009
0
    offset);
4010
4011
  /* used */
4012
0
  offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_used,
4013
0
    offset);
4014
4015
  /* rdev */
4016
0
  offset = dissect_nfs3_specdata(tvb, offset, fattr3_tree, "rdev");
4017
4018
  /* fsid */
4019
0
  offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_fsid,
4020
0
    offset);
4021
4022
  /* fileid */
4023
0
  offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_fileid,
4024
0
    offset);
4025
4026
  /* atime */
4027
0
  offset = dissect_nfstime3 (tvb, offset, fattr3_tree, hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_nsec);
4028
4029
  /* mtime */
4030
0
  offset = dissect_nfstime3 (tvb, offset, fattr3_tree, hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_nsec);
4031
4032
  /* ctime */
4033
0
  offset = dissect_nfstime3 (tvb, offset, fattr3_tree, hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_nsec);
4034
4035
  /* now we know, that fattr3 is shorter */
4036
0
  proto_item_set_len(fattr3_item, offset - old_offset);
4037
4038
  /* put some nice info in COL_INFO for GETATTR replies */
4039
0
  if (levels & COL_INFO_LEVEL) {
4040
0
    levels &= (~COL_INFO_LEVEL);
4041
0
    col_append_fstr(pinfo->cinfo, COL_INFO,
4042
0
        "  %s mode: %04o uid: %u gid: %u",
4043
0
        val_to_str_ext(pinfo->pool, type, &names_nfs_ftype3_ext, "Unknown Type: 0x%x"),
4044
0
        mode&0x0fff, uid, gid);
4045
0
  }
4046
  /* populate the expansion lines with some nice useable info */
4047
0
  while ( fattr3_tree && levels-- ) {
4048
0
    proto_item_append_text(fattr3_tree, "  %s mode: %04o uid: %u gid: %u",
4049
0
        val_to_str_ext(pinfo->pool, type, &names_nfs_ftype3_ext, "Unknown Type: 0x%x"),
4050
0
        mode&0x0fff, uid, gid);
4051
0
    fattr3_tree = fattr3_tree->parent;
4052
0
  }
4053
4054
0
  return offset;
4055
0
}
4056
4057
4058
static const value_string value_follows[] =
4059
{
4060
  { 0, "no value" },
4061
  { 1, "value follows" },
4062
  { 0, NULL }
4063
};
4064
4065
4066
/* NFSv3 RFC 1813, Page 23 */
4067
unsigned
4068
dissect_nfs3_post_op_attr(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
4069
       const char *name)
4070
0
{
4071
0
  proto_item *post_op_attr_item;
4072
0
  proto_tree *post_op_attr_tree;
4073
0
  unsigned    old_offset        = offset;
4074
0
  uint32_t      attributes_follow = 0;
4075
4076
0
  attributes_follow = tvb_get_ntohl(tvb, offset+0);
4077
4078
0
  post_op_attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4079
0
      ett_nfs3_post_op_attr, &post_op_attr_item, name);
4080
4081
0
  proto_tree_add_uint(post_op_attr_tree, hf_nfs3_attributes_follow, tvb, offset, 4, attributes_follow);
4082
4083
0
  offset += 4;
4084
0
  switch (attributes_follow) {
4085
0
    case true:
4086
0
      offset = dissect_nfs_fattr3(pinfo, tvb, offset,
4087
0
                post_op_attr_tree,
4088
0
                "attributes", 2);
4089
0
    break;
4090
0
    case false:
4091
      /* void */
4092
0
    break;
4093
0
  }
4094
4095
  /* now we know, that post_op_attr_tree is shorter */
4096
0
  proto_item_set_len(post_op_attr_item, offset - old_offset);
4097
4098
0
  return offset;
4099
0
}
4100
4101
4102
/* NFSv3 RFC 1813, Page 24 */
4103
static unsigned
4104
dissect_wcc_attr(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4105
0
{
4106
0
  proto_item *wcc_attr_item;
4107
0
  proto_tree *wcc_attr_tree;
4108
0
  unsigned    old_offset    = offset;
4109
4110
0
  wcc_attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4111
0
      ett_nfs3_wcc_attr, &wcc_attr_item, name);
4112
4113
0
  offset = dissect_rpc_uint64(tvb, wcc_attr_tree, hf_nfs3_wcc_attr_size,
4114
0
    offset);
4115
0
  offset = dissect_nfstime3(tvb, offset, wcc_attr_tree, hf_nfs_mtime,
4116
0
    hf_nfs_mtime_sec, hf_nfs_mtime_nsec);
4117
0
  offset = dissect_nfstime3(tvb, offset, wcc_attr_tree, hf_nfs_ctime,
4118
0
    hf_nfs_ctime_sec, hf_nfs_ctime_nsec);
4119
  /* now we know, that wcc_attr_tree is shorter */
4120
0
  proto_item_set_len(wcc_attr_item, offset - old_offset);
4121
4122
0
  return offset;
4123
0
}
4124
4125
4126
/* NFSv3 RFC 1813, Page 24 */
4127
static unsigned
4128
dissect_pre_op_attr(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4129
0
{
4130
0
  proto_item *pre_op_attr_item;
4131
0
  proto_tree *pre_op_attr_tree;
4132
0
  unsigned    old_offset       = offset;
4133
0
  uint32_t      attributes_follow;
4134
4135
0
  pre_op_attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4136
0
      ett_nfs3_pre_op_attr, &pre_op_attr_item, name);
4137
4138
0
  proto_tree_add_item_ret_uint(pre_op_attr_tree, hf_nfs3_attributes_follow, tvb, offset, 4, ENC_BIG_ENDIAN, &attributes_follow);
4139
0
  offset += 4;
4140
0
  switch (attributes_follow) {
4141
0
    case true:
4142
0
      offset = dissect_wcc_attr(tvb, offset, pre_op_attr_tree,
4143
0
          "attributes");
4144
0
    break;
4145
0
    case false:
4146
      /* void */
4147
0
    break;
4148
0
  }
4149
4150
  /* now we know, that pre_op_attr_tree is shorter */
4151
0
  proto_item_set_len(pre_op_attr_item, offset - old_offset);
4152
4153
0
  return offset;
4154
0
}
4155
4156
4157
/* NFSv3 RFC 1813, Page 24 */
4158
static unsigned
4159
dissect_wcc_data(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, const char *name)
4160
0
{
4161
0
  proto_item *wcc_data_item;
4162
0
  proto_tree *wcc_data_tree;
4163
0
  unsigned    old_offset    = offset;
4164
4165
0
  wcc_data_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4166
0
      ett_nfs3_wcc_data, &wcc_data_item, name);
4167
4168
0
  offset = dissect_pre_op_attr (tvb, offset, wcc_data_tree, "before");
4169
0
  offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, wcc_data_tree, "after" );
4170
4171
  /* now we know, that wcc_data is shorter */
4172
0
  proto_item_set_len(wcc_data_item, offset - old_offset);
4173
4174
0
  return offset;
4175
0
}
4176
4177
4178
/* NFSv3 RFC 1813, Page 25 */
4179
static unsigned
4180
dissect_nfs3_post_op_fh(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
4181
        proto_tree *tree, const char *name, rpc_call_info_value *civ)
4182
0
{
4183
0
  proto_item *post_op_fh3_item;
4184
0
  proto_tree *post_op_fh3_tree;
4185
0
  unsigned    old_offset       = offset;
4186
0
  uint32_t      handle_follows;
4187
4188
0
  post_op_fh3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4189
0
      ett_nfs3_post_op_fh, &post_op_fh3_item, name);
4190
4191
0
  proto_tree_add_item_ret_uint(post_op_fh3_tree, hf_nfs3_handle_follow, tvb, offset, 4, ENC_BIG_ENDIAN, &handle_follows);
4192
0
  offset += 4;
4193
0
  switch (handle_follows) {
4194
0
    case true:
4195
0
      offset = dissect_nfs3_fh(tvb, offset, pinfo, post_op_fh3_tree,
4196
0
          "handle", NULL, civ);
4197
0
    break;
4198
0
    case false:
4199
      /* void */
4200
0
    break;
4201
0
  }
4202
4203
  /* now we know, that post_op_fh3_tree is shorter */
4204
0
  if (post_op_fh3_item) {
4205
0
    proto_item_set_len(post_op_fh3_item, offset - old_offset);
4206
0
  }
4207
4208
0
  return offset;
4209
0
}
4210
4211
4212
/* NFSv3 RFC 1813, Page 25 */
4213
static unsigned
4214
dissect_set_mode3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4215
0
{
4216
0
  proto_item *set_mode3_item;
4217
0
  proto_tree *set_mode3_tree;
4218
0
  unsigned    old_offset     = offset;
4219
0
  uint32_t      set_it;
4220
0
  const char *set_it_name;
4221
4222
0
  set_it = tvb_get_ntohl(tvb, offset+0);
4223
4224
0
  set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4225
4226
0
  set_mode3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4227
0
      ett_nfs3_set_mode, &set_mode3_item, "%s: %s", name, set_it_name);
4228
4229
0
  proto_tree_add_uint(set_mode3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4230
4231
0
  offset += 4;
4232
4233
0
  switch (set_it) {
4234
0
    case 1:
4235
0
      offset = dissect_nfs3_mode(tvb, offset, set_mode3_tree, NULL);
4236
0
    break;
4237
0
    default:
4238
      /* void */
4239
0
    break;
4240
0
  }
4241
4242
  /* now we know, that set_mode3 is shorter */
4243
0
  proto_item_set_len(set_mode3_item, offset - old_offset);
4244
4245
0
  return offset;
4246
0
}
4247
4248
4249
/* NFSv3 RFC 1813, Page 26 */
4250
static unsigned
4251
dissect_set_uid3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4252
0
{
4253
0
  proto_item *set_uid3_item;
4254
0
  proto_tree *set_uid3_tree;
4255
0
  unsigned    old_offset    = offset;
4256
0
  uint32_t      set_it;
4257
0
  const char *set_it_name;
4258
4259
0
  set_it = tvb_get_ntohl(tvb, offset+0);
4260
0
  set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4261
4262
0
  set_uid3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4263
0
      ett_nfs3_set_uid, &set_uid3_item, "%s: %s", name, set_it_name);
4264
4265
0
  proto_tree_add_uint(set_uid3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4266
0
  offset += 4;
4267
4268
0
  switch (set_it) {
4269
0
    case 1:
4270
0
      offset = dissect_rpc_uint32(tvb, set_uid3_tree,
4271
0
                hf_nfs3_uid, offset);
4272
0
    break;
4273
0
    default:
4274
      /* void */
4275
0
    break;
4276
0
  }
4277
4278
  /* now we know, that set_uid3 is shorter */
4279
0
  proto_item_set_len(set_uid3_item, offset - old_offset);
4280
4281
0
  return offset;
4282
0
}
4283
4284
4285
/* NFSv3 RFC 1813, Page 26 */
4286
static unsigned
4287
dissect_set_gid3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4288
0
{
4289
0
  proto_item *set_gid3_item;
4290
0
  proto_tree *set_gid3_tree;
4291
0
  unsigned    old_offset    = offset;
4292
0
  uint32_t      set_it;
4293
0
  const char *set_it_name;
4294
4295
0
  set_it = tvb_get_ntohl(tvb, offset+0);
4296
4297
0
  set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4298
0
  set_gid3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4299
0
      ett_nfs3_set_gid, &set_gid3_item, "%s: %s", name, set_it_name);
4300
4301
0
  proto_tree_add_uint(set_gid3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4302
4303
0
  offset += 4;
4304
4305
0
  switch (set_it) {
4306
0
    case 1:
4307
0
      offset = dissect_rpc_uint32(tvb, set_gid3_tree,
4308
0
        hf_nfs3_gid, offset);
4309
0
    break;
4310
0
    default:
4311
      /* void */
4312
0
    break;
4313
0
  }
4314
4315
  /* now we know, that set_gid3 is shorter */
4316
0
  proto_item_set_len(set_gid3_item, offset - old_offset);
4317
4318
0
  return offset;
4319
0
}
4320
4321
4322
/* NFSv3 RFC 1813, Page 26 */
4323
static unsigned
4324
dissect_set_size3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4325
0
{
4326
0
  proto_item *set_size3_item;
4327
0
  proto_tree *set_size3_tree;
4328
0
  unsigned    old_offset     = offset;
4329
0
  uint32_t      set_it;
4330
0
  const char *set_it_name;
4331
4332
0
  set_it = tvb_get_ntohl(tvb, offset+0);
4333
4334
0
  set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4335
4336
0
  set_size3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4337
0
      ett_nfs3_set_size, &set_size3_item, "%s: %s", name, set_it_name);
4338
0
  proto_tree_add_uint(set_size3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4339
4340
0
  offset += 4;
4341
4342
0
  switch (set_it) {
4343
0
    case 1:
4344
0
      offset = dissect_rpc_uint64(tvb, set_size3_tree,
4345
0
        hf_nfs3_set_size, offset);
4346
0
    break;
4347
0
    default:
4348
      /* void */
4349
0
    break;
4350
0
  }
4351
4352
  /* now we know, that set_size3 is shorter */
4353
0
  proto_item_set_len(set_size3_item, offset - old_offset);
4354
4355
0
  return offset;
4356
0
}
4357
4358
4359
/* NFSv3 RFC 1813, Page 25 */
4360
#define DONT_CHANGE 0
4361
#define SET_TO_SERVER_TIME 1
4362
0
#define SET_TO_CLIENT_TIME 2
4363
4364
static const value_string time_how[] =
4365
{
4366
  { DONT_CHANGE,    "don't change" },
4367
  { SET_TO_SERVER_TIME, "set to server time" },
4368
  { SET_TO_CLIENT_TIME, "set to client time" },
4369
  { 0, NULL }
4370
};
4371
4372
4373
/* NFSv3 RFC 1813, Page 26 */
4374
static unsigned
4375
dissect_set_atime(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4376
0
{
4377
0
  proto_item *set_atime_item;
4378
0
  proto_tree *set_atime_tree;
4379
0
  unsigned    old_offset     = offset;
4380
0
  uint32_t      set_it;
4381
0
  const char *set_it_name;
4382
4383
0
  set_it = tvb_get_ntohl(tvb, offset+0);
4384
4385
0
  set_it_name = val_to_str_const(set_it, time_how, "Unknown");
4386
4387
0
  set_atime_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4388
0
      ett_nfs3_set_atime, &set_atime_item, "%s: %s", name, set_it_name);
4389
4390
0
  proto_tree_add_uint(set_atime_tree, hf_nfs4_time_how, tvb, offset, 4, set_it);
4391
0
  offset += 4;
4392
4393
0
  switch (set_it) {
4394
0
    case SET_TO_CLIENT_TIME:
4395
0
      offset = dissect_nfstime3(tvb, offset, set_atime_tree,
4396
0
          hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_nsec);
4397
0
    break;
4398
0
    default:
4399
      /* void */
4400
0
    break;
4401
0
  }
4402
4403
  /* now we know, that set_atime is shorter */
4404
0
  proto_item_set_len(set_atime_item, offset - old_offset);
4405
4406
0
  return offset;
4407
0
}
4408
4409
4410
/* NFSv3 RFC 1813, Page 26 */
4411
static unsigned
4412
dissect_set_mtime(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4413
0
{
4414
0
  proto_item *set_mtime_item;
4415
0
  proto_tree *set_mtime_tree;
4416
0
  unsigned    old_offset     = offset;
4417
0
  uint32_t      set_it;
4418
0
  const char *set_it_name;
4419
4420
0
  set_it = tvb_get_ntohl(tvb, offset+0);
4421
4422
0
  set_it_name = val_to_str_const(set_it, time_how, "Unknown");
4423
4424
0
  set_mtime_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4425
0
      ett_nfs3_set_mtime, &set_mtime_item, "%s: %s", name, set_it_name);
4426
0
  proto_tree_add_uint(set_mtime_tree, hf_nfs4_time_how, tvb, offset, 4, set_it);
4427
4428
0
  offset += 4;
4429
4430
0
  switch (set_it) {
4431
0
    case SET_TO_CLIENT_TIME:
4432
0
      offset = dissect_nfstime3(tvb, offset, set_mtime_tree,
4433
0
          hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_nsec);
4434
0
    break;
4435
0
    default:
4436
      /* void */
4437
0
    break;
4438
0
  }
4439
4440
  /* now we know, that set_mtime is shorter */
4441
0
  proto_item_set_len(set_mtime_item, offset - old_offset);
4442
4443
0
  return offset;
4444
0
}
4445
4446
4447
/* NFSv3 RFC 1813, Page 25..27 */
4448
static unsigned
4449
dissect_nfs3_sattr(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4450
0
{
4451
0
  proto_item *sattr3_item;
4452
0
  proto_tree *sattr3_tree;
4453
0
  unsigned    old_offset  = offset;
4454
4455
0
  sattr3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4456
0
      ett_nfs3_sattr, &sattr3_item, name);
4457
4458
0
  offset = dissect_set_mode3(tvb, offset, sattr3_tree, "mode");
4459
0
  offset = dissect_set_uid3 (tvb, offset, sattr3_tree, "uid");
4460
0
  offset = dissect_set_gid3 (tvb, offset, sattr3_tree, "gid");
4461
0
  offset = dissect_set_size3(tvb, offset, sattr3_tree, "size");
4462
0
  offset = dissect_set_atime(tvb, offset, sattr3_tree, "atime");
4463
0
  offset = dissect_set_mtime(tvb, offset, sattr3_tree, "mtime");
4464
4465
  /* now we know, that sattr3 is shorter */
4466
0
  proto_item_set_len(sattr3_item, offset - old_offset);
4467
4468
0
  return offset;
4469
0
}
4470
4471
4472
/* NFSv3 RFC 1813, Page 27 */
4473
static unsigned
4474
dissect_diropargs3(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
4475
           const char *label, uint32_t *hash, const char **name, rpc_call_info_value *civ)
4476
0
{
4477
0
  proto_item *diropargs3_item;
4478
0
  proto_tree *diropargs3_tree;
4479
0
  unsigned    old_offset      = offset;
4480
0
  int     parent_offset, parent_len;
4481
0
  int     name_offset, name_len;
4482
4483
0
  diropargs3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4484
0
      ett_nfs3_diropargs, &diropargs3_item, label);
4485
4486
0
  parent_offset = offset+4;
4487
0
  parent_len = tvb_get_ntohl(tvb, offset);
4488
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, diropargs3_tree, "dir", hash, civ);
4489
0
  name_offset = offset+4;
4490
0
  name_len = tvb_get_ntohl(tvb, offset);
4491
0
  offset = dissect_nfs3_filename(tvb, pinfo, offset, diropargs3_tree,
4492
0
    hf_nfs_name, name);
4493
4494
  /* are we snooping fh to filenames ?*/
4495
0
  if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
4496
    /* v3 LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD calls might give us a mapping*/
4497
0
    if ( (civ->prog == 100003)
4498
0
      &&(civ->vers == 3)
4499
0
      &&(civ->request)
4500
0
      &&((civ->proc == 3)||(civ->proc == 8)||(civ->proc == 9)||(civ->proc == 10)||(civ->proc == 11))
4501
0
    ) {
4502
0
      nfs_name_snoop_add_name(civ->xid, tvb,
4503
0
        name_offset, name_len,
4504
0
        parent_offset, parent_len, NULL);
4505
0
    }
4506
0
  }
4507
4508
4509
  /* now we know, that diropargs3 is shorter */
4510
0
  proto_item_set_len(diropargs3_item, offset - old_offset);
4511
4512
0
  return offset;
4513
0
}
4514
4515
4516
static int
4517
dissect_nfs3_remove_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4518
0
{
4519
0
  uint32_t      hash = 0;
4520
0
  const char *name = NULL;
4521
0
  unsigned offset = 0;
4522
4523
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object", &hash, &name, (rpc_call_info_value*)data);
4524
4525
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
4526
0
  proto_item_append_text(tree, ", REMOVE Call DH: 0x%08x/%s", hash, name);
4527
4528
0
  return offset;
4529
0
}
4530
4531
4532
static int
4533
dissect_nfs3_null_call(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4534
0
{
4535
0
  proto_item_append_text(tree, ", NULL Call");
4536
4537
0
  return 0;
4538
0
}
4539
4540
4541
static int
4542
dissect_nfs3_null_reply(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
4543
0
{
4544
0
  proto_item_append_text(tree, ", NULL Reply");
4545
4546
0
  return 0;
4547
0
}
4548
4549
4550
static int
4551
dissect_nfs3_rmdir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4552
0
{
4553
0
  uint32_t      hash = 0;
4554
0
  const char *name = NULL;
4555
0
  unsigned offset = 0;
4556
4557
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object", &hash, &name, (rpc_call_info_value*)data);
4558
4559
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
4560
0
  proto_item_append_text(tree, ", RMDIR Call DH: 0x%08x/%s", hash, name);
4561
4562
0
  return offset;
4563
0
}
4564
4565
4566
/* NFSv3 RFC 1813, Page 32,33 */
4567
static int
4568
dissect_nfs3_getattr_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4569
0
{
4570
0
  uint32_t hash = 0;
4571
0
  unsigned offset = 0;
4572
4573
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
4574
4575
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
4576
0
  proto_item_append_text(tree, ", GETATTR Call FH: 0x%08x", hash);
4577
4578
0
  return offset;
4579
0
}
4580
4581
4582
/* NFSv3 RFC 1813, Page 32,33 */
4583
static int
4584
dissect_nfs3_getattr_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4585
0
{
4586
0
  uint32_t      status;
4587
0
  const char *err;
4588
0
  unsigned offset = 0;
4589
4590
0
  proto_item_append_text(tree, ", GETATTR Reply");
4591
4592
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
4593
0
  switch (status) {
4594
0
    case 0:
4595
0
      offset = dissect_nfs_fattr3(pinfo, tvb, offset, tree, "obj_attributes", 2|COL_INFO_LEVEL);
4596
0
    break;
4597
0
    default:
4598
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
4599
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4600
0
      proto_item_append_text(tree, "  Error: %s", err);
4601
0
    break;
4602
0
  }
4603
4604
0
  return offset;
4605
0
}
4606
4607
4608
/* NFSv3 RFC 1813, Page 33 */
4609
static unsigned
4610
dissect_sattrguard3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
4611
0
{
4612
0
  proto_item *sattrguard3_item;
4613
0
  proto_tree *sattrguard3_tree;
4614
0
  unsigned    old_offset       = offset;
4615
0
  uint32_t      check;
4616
0
  const char *check_name;
4617
4618
0
  check = tvb_get_ntohl(tvb, offset+0);
4619
4620
0
  check_name = val_to_str_const(check, value_follows, "Unknown");
4621
4622
0
  sattrguard3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4623
0
      ett_nfs3_sattrguard, &sattrguard3_item, "%s: %s", name, check_name);
4624
4625
0
  proto_tree_add_uint(sattrguard3_tree, hf_nfs3_sattrguard3, tvb, offset, 4, check);
4626
4627
4628
0
  offset += 4;
4629
4630
0
  switch (check) {
4631
0
    case true:
4632
0
      offset = dissect_nfstime3(tvb, offset, sattrguard3_tree,
4633
0
          hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_nsec);
4634
0
    break;
4635
0
    case false:
4636
      /* void */
4637
0
    break;
4638
0
  }
4639
4640
  /* now we know, that sattrguard3 is shorter */
4641
0
  proto_item_set_len(sattrguard3_item, offset - old_offset);
4642
4643
0
  return offset;
4644
0
}
4645
4646
4647
/* NFSv3 RFC 1813, Page 33..36 */
4648
static int
4649
dissect_nfs3_setattr_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4650
0
{
4651
0
  uint32_t hash = 0;
4652
0
  unsigned offset = 0;
4653
4654
0
  offset = dissect_nfs3_fh    (tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
4655
0
  offset = dissect_nfs3_sattr     (tvb, offset,        tree, "new_attributes");
4656
0
  offset = dissect_sattrguard3(tvb, offset,        tree, "guard");
4657
4658
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
4659
0
  proto_item_append_text(tree, ", SETATTR Call FH: 0x%08x", hash);
4660
4661
0
  return offset;
4662
0
}
4663
4664
4665
/* NFSv3 RFC 1813, Page 33..36 */
4666
static int
4667
dissect_nfs3_setattr_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4668
0
{
4669
0
  uint32_t      status;
4670
0
  const char *err;
4671
0
  unsigned offset = 0;
4672
4673
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
4674
0
  switch (status) {
4675
0
    case 0:
4676
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "obj_wcc");
4677
0
      proto_item_append_text(tree, ", SETATTR Reply");
4678
0
    break;
4679
0
    default:
4680
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "obj_wcc");
4681
4682
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
4683
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4684
0
      proto_item_append_text(tree, ", SETATTR Reply  Error: %s", err);
4685
0
    break;
4686
0
  }
4687
4688
0
  return offset;
4689
0
}
4690
4691
4692
/* NFSv3 RFC 1813, Page 37..39 */
4693
static int
4694
dissect_nfs3_lookup_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4695
0
{
4696
0
  uint32_t      hash = 0;
4697
0
  const char *name = NULL;
4698
0
  unsigned offset = 0;
4699
4700
0
  offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "what", &hash, &name, (rpc_call_info_value*)data);
4701
4702
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
4703
0
  proto_item_append_text(tree, ", LOOKUP Call DH: 0x%08x/%s", hash, name);
4704
4705
0
  return offset;
4706
0
}
4707
4708
4709
/* NFSv3 RFC 1813, Page 37..39 */
4710
static int
4711
dissect_nfs3_lookup_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4712
0
{
4713
0
  uint32_t      status;
4714
0
  const char *err;
4715
0
  uint32_t      hash = 0;
4716
0
  unsigned offset = 0;
4717
4718
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
4719
0
  switch (status) {
4720
0
    case 0:
4721
0
      offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
4722
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4723
0
        "obj_attributes");
4724
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4725
0
        "dir_attributes");
4726
4727
0
      col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
4728
0
      proto_item_append_text(tree, ", LOOKUP Reply FH: 0x%08x", hash);
4729
0
    break;
4730
0
    default:
4731
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4732
0
        "dir_attributes");
4733
4734
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
4735
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4736
0
      proto_item_append_text(tree, ", LOOKUP Reply  Error: %s", err);
4737
0
    break;
4738
0
  }
4739
4740
0
  return offset;
4741
0
}
4742
4743
4744
static gchar*
4745
proto_item_get_text(wmem_allocator_t *pool, proto_item *item)
4746
0
{
4747
0
  field_info *fi = NULL;
4748
0
  gchar *result;
4749
4750
0
  if (item == NULL)
4751
0
    return NULL;
4752
4753
0
  fi = PITEM_FINFO(item);
4754
4755
0
  if (fi == NULL)
4756
0
    return NULL;
4757
4758
0
  if (fi->rep == NULL) {
4759
0
    fi->rep = wmem_new(PNODE_POOL(item), item_label_t);
4760
0
    proto_item_fill_label(fi, fi->rep->representation, NULL);
4761
0
  }
4762
4763
0
  result = wmem_strdup(pool, fi->rep->representation);
4764
0
  return result;
4765
0
}
4766
4767
static const value_string accvs[] = {
4768
  { 0x001,  "RD" },
4769
  { 0x002,  "LU" },
4770
  { 0x004,  "MD" },
4771
  { 0x008,  "XT" },
4772
  { 0x010,  "DL" },
4773
  { 0x020,  "XE" },
4774
  { 0x040,  "XAR" },
4775
  { 0x080,  "XAW" },
4776
  { 0x100,  "XAL" },
4777
  { 0,    NULL }
4778
};
4779
4780
static const true_false_string tfs_access_supp   = { "supported", "!NOT Supported!"};
4781
static const true_false_string tfs_access_rights = {"allowed", "*Access Denied*"};
4782
4783
proto_tree*
4784
display_access_items(tvbuff_t* tvb, unsigned offset, packet_info* pinfo, proto_tree *tree,
4785
         uint32_t amask, uint32_t rmask, char mtype, int version, wmem_strbuf_t* optext, const char *label)
4786
0
{
4787
0
  bool        nfsv3    = ((version == 3) ? true : false);
4788
0
  proto_item *access_item    = NULL;
4789
0
  proto_tree *access_subtree = NULL;
4790
0
  proto_item *access_subitem = NULL;
4791
0
  uint32_t      itype;
4792
4793
  /* XXX Legend (delete if desired)
4794
4795
     'C' CHECK access:      append label to both headers and create subtree and list
4796
     'N' NOT SUPPORTED:     append label to both headers
4797
     'S' SUPPORTED or not:  create subtree and list
4798
     'D' DENIED:            append label to both headers
4799
     'A' ALLOWED:           append label to both headers
4800
     'R' RIGHTS:            create subtree and list */
4801
4802
0
  switch (mtype) {
4803
0
    case 'C':
4804
0
      access_item = proto_tree_add_item(tree, hf_nfs_access_check, tvb,
4805
0
        offset, 4, ENC_BIG_ENDIAN);
4806
0
      access_subtree = proto_item_add_subtree(access_item,
4807
0
        (nfsv3 ? ett_nfs3_access : ett_nfs4_access));
4808
0
      break;
4809
0
    case 'S':
4810
0
      access_item = proto_tree_add_item(tree, hf_nfs_access_supported, tvb,
4811
0
        offset, 4, ENC_BIG_ENDIAN);
4812
0
      access_subtree = proto_item_add_subtree(access_item, ett_nfs4_access_supp);
4813
0
      break;
4814
0
    case 'R':
4815
0
      access_item = proto_tree_add_item(tree, hf_nfs_access_rights, tvb,
4816
0
        offset, 4, ENC_BIG_ENDIAN);
4817
0
      access_subtree = proto_item_add_subtree(access_item,
4818
0
        (nfsv3 ? ett_nfs3_access : ett_nfs4_access));
4819
0
      break;
4820
0
  }
4821
  /* Append label to the Info column and tree */
4822
0
  if (mtype != 'S' && mtype != 'R') {
4823
0
    if (nfsv3) {
4824
0
      col_append_fstr(pinfo->cinfo, COL_INFO, ", [%s:", label);
4825
0
    } else {
4826
0
      wmem_strbuf_append_printf (optext, ", [%s:", label);
4827
0
    }
4828
0
    proto_item_append_text(tree, ", [%s:", label);
4829
0
  }
4830
4831
0
  for (itype=0; itype < 9; itype++) {
4832
0
      if (mtype != 'S' && mtype != 'R' && (amask & accvs[itype].value)) {
4833
        /* List access type in Info column and tree */
4834
0
        if (nfsv3) {
4835
0
          col_append_fstr(pinfo->cinfo, COL_INFO, " %s", accvs[itype].strptr);
4836
0
        } else {
4837
0
          wmem_strbuf_append_printf (optext, " %s", accvs[itype].strptr);
4838
0
        }
4839
0
        proto_item_append_text(tree, " %s", accvs[itype].strptr);
4840
0
      }
4841
0
      if (mtype == 'C' || mtype == 'S' || mtype == 'R') {
4842
4843
0
        switch (itype) {
4844
0
          case 0:
4845
0
            access_subitem = proto_tree_add_item (access_subtree,
4846
0
              (mtype == 'S' ? hf_nfs_access_supp_read : hf_nfs_access_read),
4847
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4848
0
            break;
4849
0
          case 1:
4850
0
            access_subitem = proto_tree_add_item (access_subtree,
4851
0
              (mtype == 'S' ? hf_nfs_access_supp_lookup : hf_nfs_access_lookup),
4852
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4853
0
            break;
4854
0
          case 2:
4855
0
            access_subitem = proto_tree_add_item (access_subtree,
4856
0
              (mtype == 'S' ? hf_nfs_access_supp_modify : hf_nfs_access_modify),
4857
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4858
0
            break;
4859
0
          case 3:
4860
0
            access_subitem = proto_tree_add_item (access_subtree,
4861
0
              (mtype == 'S' ? hf_nfs_access_supp_extend : hf_nfs_access_extend),
4862
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4863
0
            break;
4864
0
          case 4:
4865
0
            access_subitem = proto_tree_add_item (access_subtree,
4866
0
              (mtype == 'S' ? hf_nfs_access_supp_delete : hf_nfs_access_delete),
4867
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4868
0
            break;
4869
0
          case 5:
4870
0
            access_subitem = proto_tree_add_item (access_subtree,
4871
0
              (mtype == 'S' ? hf_nfs_access_supp_execute : hf_nfs_access_execute),
4872
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4873
0
            break;
4874
0
          case 6:
4875
0
            if (nfsv3) access_subitem = NULL; else
4876
0
            access_subitem = proto_tree_add_item (access_subtree,
4877
0
              (mtype == 'S' ? hf_nfs_access_supp_xattr_read : hf_nfs_access_xattr_read),
4878
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4879
0
            break;
4880
0
          case 7:
4881
0
            if (nfsv3) access_subitem = NULL; else
4882
0
            access_subitem = proto_tree_add_item (access_subtree,
4883
0
              (mtype == 'S' ? hf_nfs_access_supp_xattr_write : hf_nfs_access_xattr_write),
4884
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4885
0
            break;
4886
0
          case 8:
4887
0
            if (nfsv3) access_subitem = NULL; else
4888
0
            access_subitem = proto_tree_add_item (access_subtree,
4889
0
              (mtype == 'S' ? hf_nfs_access_supp_xattr_list : hf_nfs_access_xattr_list),
4890
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
4891
0
            break;
4892
0
          default:
4893
0
            access_subitem = NULL;
4894
0
            break;
4895
0
        }
4896
0
        if (!(rmask & accvs[itype].value) && access_subitem) {
4897
0
          const char* text_start = proto_item_get_text(pinfo->pool, access_subitem);
4898
0
          const char* text_end = text_start ? strrchr(text_start, ':') : NULL;
4899
0
          if (text_start && text_end)
4900
0
            proto_item_set_text(access_subitem, "%.*s: %s", (int)(text_end - text_start), text_start, mtype == 'C' ? "not asked" : "unknown");
4901
0
        } else if (mtype == 'C' && access_subitem) {
4902
0
          proto_item_append_text(access_subitem, "?" );
4903
0
        }
4904
0
      }
4905
0
  }
4906
0
  if (mtype != 'S' && mtype != 'R') {
4907
0
    if (nfsv3) {
4908
0
      col_append_str(pinfo->cinfo, COL_INFO, "]");
4909
0
    } else {
4910
0
      wmem_strbuf_append_printf (optext, "]");
4911
0
    }
4912
0
    proto_item_append_text(tree, "]");
4913
0
  }
4914
0
  return access_subtree = NULL;
4915
0
}
4916
4917
/* NFSv3 RFC 1813, Page 40..43 */
4918
/* NFSv4 RFC 3530, Page 140..142 */
4919
unsigned
4920
dissect_access_reply(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
4921
         int version, wmem_strbuf_t *optext, rpc_call_info_value *civ)
4922
0
{
4923
0
  uint32_t     *acc_req;
4924
0
  uint32_t      acc_supp;
4925
0
  uint32_t      acc_rights;
4926
0
  uint32_t      mask_not_supp;
4927
0
  uint32_t      mask_denied;
4928
0
  uint32_t      mask_allowed;
4929
0
  uint32_t      mask_result;
4930
0
  uint32_t      e_check, e_rights;
4931
0
  bool        nfsv3   = ((version == 3) ? true : false);
4932
0
  bool        nfsv4   = ((version == 4) ? true : false);
4933
0
  bool        have_acc_supp = true;
4934
0
  proto_tree *access_tree;
4935
0
  proto_item *ditem;
4936
4937
  /* Retrieve the access mask from the call if available. It
4938
     will not be available if the packet containing the call is
4939
     missing or truncated. */
4940
0
  acc_req = (uint32_t *)civ->private_data;
4941
0
  if (nfsv4) {
4942
0
    acc_supp = tvb_get_ntohl(tvb, offset+0);
4943
0
  } else if (acc_req) {
4944
0
    acc_supp = *acc_req;
4945
0
  } else {
4946
0
    have_acc_supp = false;
4947
0
  }
4948
  /*  V3/V4 - Get access rights mask and create a subtree for it */
4949
0
  acc_rights = tvb_get_ntohl(tvb, (nfsv3 ? offset+0: offset+4));
4950
0
  if (!have_acc_supp) {
4951
    /* The v3 access call isn't available. Using acc_rights for
4952
       acc_supp ensures mask_allowed will be correct */
4953
0
    acc_supp = acc_rights;
4954
0
  }
4955
4956
  /* Create access masks: not_supported, denied, and allowed */
4957
0
  if (acc_req && have_acc_supp)
4958
0
    mask_not_supp = *acc_req ^ acc_supp;
4959
0
  else
4960
0
    mask_not_supp = 0;
4961
4962
0
  if (acc_req)
4963
0
    mask_result = *acc_req;
4964
0
  else
4965
0
    mask_result = acc_supp;
4966
4967
0
  e_check = acc_supp;
4968
0
  e_rights = acc_supp & acc_rights;  /* guard against broken implementations */
4969
0
  mask_denied =  e_check ^ e_rights;
4970
0
  mask_allowed = e_check & e_rights;
4971
4972
0
  if (nfsv4) {
4973
0
    if (mask_not_supp > 0) {
4974
0
      display_access_items(tvb, offset, pinfo, tree, mask_not_supp, mask_result, 'N', 4,
4975
0
        optext, "NOT Supported") ;
4976
0
    }
4977
0
    display_access_items(tvb, offset, pinfo, tree, acc_supp, mask_result, 'S', 4,
4978
0
      optext, "Supported");
4979
0
    offset+=4;
4980
0
  }
4981
0
  if (mask_denied > 0) {
4982
0
    display_access_items(tvb, offset, pinfo, tree, mask_denied, mask_result, 'D', version,
4983
0
      optext, "Access Denied") ;
4984
0
  }
4985
0
  if (mask_allowed > 0) {
4986
0
    display_access_items(tvb, offset, pinfo, tree, mask_allowed, mask_result, 'A', version,
4987
0
      optext, "Allowed") ;
4988
0
  }
4989
  /* Pass the OR'd masks rather than acc_rights so that display_access_items will
4990
     process types that have been denied access. Since proto_tree_add_item uses the
4991
     mask in the tvb (not the passed mask), the correct (denied) access is displayed. */
4992
0
  access_tree = display_access_items(tvb, offset, pinfo, tree,
4993
0
    (mask_allowed | mask_denied), mask_result, 'R', version, optext, NULL) ;
4994
4995
0
  ditem = proto_tree_add_boolean(access_tree, hf_nfs_access_denied, tvb,
4996
0
        offset, 4, (mask_denied > 0 ? true : false ));
4997
0
  proto_item_set_generated(ditem);
4998
4999
0
  return offset+4;
5000
0
}
5001
5002
5003
/* NFSv3 RFC 1813, Page 40..43 */
5004
static int
5005
dissect_nfs3_access_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5006
0
{
5007
0
  unsigned offset = 0;
5008
0
  uint32_t fhhash = 0, *acc_request, amask;
5009
0
  rpc_call_info_value *civ = (rpc_call_info_value*)data;
5010
5011
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &fhhash, civ);
5012
5013
  /* Get access mask to check and save it for comparison to the access reply. */
5014
0
  amask = tvb_get_ntohl(tvb, offset);
5015
0
  acc_request = (uint32_t *)wmem_memdup(wmem_file_scope(),  &amask, sizeof(uint32_t));
5016
0
  civ->private_data = acc_request;
5017
5018
  /* Append filehandle to Info column and main tree header */
5019
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", fhhash);
5020
0
  proto_item_append_text(tree, ", ACCESS Call, FH: 0x%08x", fhhash);
5021
5022
0
  display_access_items(tvb, offset, pinfo, tree, amask, amask, 'C', 3, NULL, "Check") ;
5023
5024
0
  offset+=4;
5025
0
  return offset;
5026
0
}
5027
5028
5029
/* NFSv3 RFC 1813, Page 40..43 */
5030
static int
5031
dissect_nfs3_access_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5032
0
{
5033
0
  uint32_t      status;
5034
0
  const char *err;
5035
0
  unsigned offset = 0;
5036
5037
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5038
0
  offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5039
0
          "obj_attributes");
5040
5041
0
  if (status == 0) {
5042
0
    proto_item_append_text(tree, ", ACCESS Reply");
5043
0
    offset = dissect_access_reply(tvb, offset, pinfo, tree, 3, NULL, (rpc_call_info_value*)data);
5044
0
  } else {
5045
0
    err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5046
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5047
0
    proto_item_append_text(tree, ", ACCESS Reply  Error: %s", err);
5048
0
  }
5049
0
  return offset;
5050
0
}
5051
5052
5053
/* NFSv3 RFC 1813, Page 44,45 */
5054
static int
5055
dissect_nfs3_readlink_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5056
0
{
5057
0
  uint32_t hash = 0;
5058
0
  unsigned offset = 0;
5059
5060
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
5061
5062
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5063
0
  proto_item_append_text(tree, ", READLINK Call FH: 0x%08x", hash);
5064
5065
0
  return offset;
5066
0
}
5067
5068
5069
static int
5070
dissect_nfs3_readlink_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5071
0
{
5072
0
  uint32_t      status;
5073
0
  const char *err;
5074
0
  const char *name = NULL;
5075
0
  unsigned offset = 0;
5076
5077
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5078
0
  switch (status) {
5079
0
    case 0:
5080
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5081
0
        "symlink_attributes");
5082
0
      offset = dissect_nfsdata_reduced(R_NFS3_PATH, tvb, pinfo, offset, tree,
5083
0
        hf_nfs2_readlink_data, &name);
5084
5085
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Path: %s", name);
5086
0
      proto_item_append_text(tree, ", READLINK Reply Path: %s", name);
5087
0
    break;
5088
0
    default:
5089
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5090
0
        "symlink_attributes");
5091
5092
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5093
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5094
0
      proto_item_append_text(tree, ", READLINK Reply  Error: %s", err);
5095
0
    break;
5096
0
  }
5097
5098
0
  return offset;
5099
0
}
5100
5101
5102
/* NFSv3 RFC 1813, Page 46..48 */
5103
static int
5104
dissect_nfs3_read_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5105
0
{
5106
0
  uint64_t off;
5107
0
  uint32_t len;
5108
0
  uint32_t hash = 0;
5109
0
  unsigned offset = 0;
5110
5111
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
5112
5113
0
  off = tvb_get_ntoh64(tvb, offset);
5114
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_offset, offset);
5115
5116
0
  len = tvb_get_ntohl(tvb, offset);
5117
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
5118
5119
5120
0
  col_append_fstr(pinfo->cinfo, COL_INFO,
5121
0
    ", FH: 0x%08x Offset: %" PRIu64 " Len: %u", hash, off, len);
5122
0
  proto_item_append_text(tree,
5123
0
    ", READ Call FH: 0x%08x Offset: %" PRIu64 " Len: %u", hash, off, len);
5124
5125
0
  return offset;
5126
0
}
5127
5128
5129
/* NFSv3 RFC 1813, Page 46..48 */
5130
static int
5131
dissect_nfs3_read_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5132
0
{
5133
0
  uint32_t      status;
5134
0
  uint32_t      len;
5135
0
  const char *err;
5136
0
  unsigned offset = 0;
5137
5138
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5139
0
  switch (status) {
5140
0
    case 0:
5141
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5142
0
        "file_attributes");
5143
0
      len = tvb_get_ntohl(tvb, offset);
5144
0
      offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count,
5145
0
        offset);
5146
0
      offset = dissect_rpc_bool(tvb, tree, hf_nfs3_read_eof,
5147
0
        offset);
5148
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Len: %u", len);
5149
0
      proto_item_append_text(tree, ", READ Reply Len: %u", len);
5150
0
      offset = dissect_nfsdata_reduced(R_NFSDATA, tvb, pinfo, offset, tree, hf_nfs_data, NULL);
5151
0
    break;
5152
0
    default:
5153
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5154
0
        "file_attributes");
5155
5156
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5157
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5158
0
      proto_item_append_text(tree, ", READ Reply  Error: %s", err);
5159
0
    break;
5160
0
  }
5161
5162
0
  return offset;
5163
0
}
5164
5165
5166
/* NFSv3 RFC 1813, Page 49 */
5167
static const value_string names_stable_how[] = {
5168
  { UNSTABLE,  "UNSTABLE"  },
5169
  { DATA_SYNC, "DATA_SYNC" },
5170
  { FILE_SYNC, "FILE_SYNC" },
5171
  { 0, NULL }
5172
};
5173
5174
/* NFSv3 RFC 1813, Page 49 */
5175
static unsigned
5176
dissect_stable_how(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int hfindex)
5177
0
{
5178
0
  proto_tree_add_item(tree, hfindex, tvb, offset, 4, ENC_BIG_ENDIAN);
5179
0
  offset += 4;
5180
5181
0
  return offset;
5182
0
}
5183
5184
/* NFSv3 RFC 1813, Page 49..54 */
5185
static int
5186
dissect_nfs3_write_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5187
0
{
5188
0
  uint64_t off;
5189
0
  uint32_t len;
5190
0
  uint32_t stable;
5191
0
  uint32_t hash = 0;
5192
0
  unsigned offset = 0;
5193
0
  char* str_stable;
5194
5195
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
5196
5197
0
  off = tvb_get_ntoh64(tvb, offset);
5198
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_offset, offset);
5199
5200
0
  len = tvb_get_ntohl(tvb, offset);
5201
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
5202
5203
0
  stable = tvb_get_ntohl(tvb, offset);
5204
0
  offset = dissect_stable_how(tvb, offset, tree, hf_nfs3_write_stable);
5205
5206
0
  str_stable = val_to_str(pinfo->pool, stable, names_stable_how, "Stable: %u");
5207
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x Offset: %" PRIu64 " Len: %u %s",
5208
0
    hash, off, len, str_stable);
5209
0
  proto_item_append_text(tree, ", WRITE Call FH: 0x%08x Offset: %" PRIu64 " Len: %u %s",
5210
0
    hash, off, len, str_stable);
5211
5212
0
  offset = dissect_nfsdata   (tvb, pinfo, offset, tree, hf_nfs_data);
5213
5214
0
  return offset;
5215
0
}
5216
5217
5218
/* NFSv3 RFC 1813, Page 49..54 */
5219
static int
5220
dissect_nfs3_write_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5221
0
{
5222
0
  uint32_t      status;
5223
0
  uint32_t      len;
5224
0
  uint32_t      stable;
5225
0
  const char *err;
5226
0
  unsigned offset = 0;
5227
0
  char* str_stable;
5228
5229
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5230
0
  switch (status) {
5231
0
    case 0:
5232
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc");
5233
0
      len = tvb_get_ntohl(tvb, offset);
5234
0
      offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count,
5235
0
        offset);
5236
0
      stable = tvb_get_ntohl(tvb, offset);
5237
0
      offset = dissect_stable_how(tvb, offset, tree,
5238
0
        hf_nfs3_write_committed);
5239
0
      offset = dissect_nfs3_write_verf(tvb, offset, tree);
5240
5241
0
      str_stable = val_to_str(pinfo->pool, stable, names_stable_how, "Stable: %u");
5242
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Len: %u %s", len, str_stable);
5243
0
      proto_item_append_text(tree, ", WRITE Reply Len: %u %s", len, str_stable);
5244
0
    break;
5245
0
    default:
5246
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc");
5247
5248
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5249
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5250
0
      proto_item_append_text(tree, ", WRITE Reply  Error: %s", err);
5251
0
    break;
5252
0
  }
5253
5254
0
  return offset;
5255
0
}
5256
5257
5258
/* NFSv3 RFC 1813, Page 54 */
5259
static const value_string names_createmode3[] = {
5260
  { UNCHECKED, "UNCHECKED" },
5261
  { GUARDED,   "GUARDED" },
5262
  { EXCLUSIVE, "EXCLUSIVE" },
5263
  { 0, NULL }
5264
};
5265
5266
/* NFSv3 RFC 1813, Page 54 */
5267
static unsigned
5268
dissect_createmode3(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint32_t* mode)
5269
0
{
5270
0
  uint32_t mode_value;
5271
5272
0
  mode_value = tvb_get_ntohl(tvb, offset + 0);
5273
0
  if (tree)
5274
0
    proto_tree_add_uint(tree, hf_nfs3_createmode, tvb, offset+0, 4, mode_value);
5275
0
  offset += 4;
5276
5277
0
  *mode = mode_value;
5278
0
  return offset;
5279
0
}
5280
5281
5282
/* NFSv3 RFC 1813, Page 54..58 */
5283
static int
5284
dissect_nfs3_create_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5285
0
{
5286
0
  uint32_t      mode;
5287
0
  uint32_t      hash = 0;
5288
0
  const char *name = NULL;
5289
0
  unsigned offset = 0;
5290
0
  char* str_mode;
5291
5292
0
  offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
5293
0
  offset = dissect_createmode3(tvb, offset, tree, &mode);
5294
0
  switch (mode) {
5295
0
    case UNCHECKED:
5296
0
    case GUARDED:
5297
0
      offset = dissect_nfs3_sattr(tvb, offset, tree, "obj_attributes");
5298
0
    break;
5299
0
    case EXCLUSIVE:
5300
0
      offset = dissect_nfs3_create_verf(tvb, offset, tree);
5301
0
    break;
5302
0
  }
5303
5304
0
  str_mode = val_to_str(pinfo->pool, mode, names_createmode3, "Unknown Mode: %u");
5305
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s Mode: %s", hash, name, str_mode);
5306
0
  proto_item_append_text(tree, ", CREATE Call DH: 0x%08x/%s Mode: %s", hash, name, str_mode);
5307
5308
0
  return offset;
5309
0
}
5310
5311
5312
/* NFSv3 RFC 1813, Page 54..58 */
5313
static int
5314
dissect_nfs3_create_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5315
0
{
5316
0
  uint32_t      status;
5317
0
  const char *err;
5318
0
  unsigned offset = 0;
5319
5320
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5321
0
  switch (status) {
5322
0
    case 0:
5323
0
      offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5324
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5325
0
        "obj_attributes");
5326
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5327
0
      proto_item_append_text(tree, ", CREATE Reply");
5328
0
    break;
5329
0
    default:
5330
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5331
5332
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5333
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5334
0
      proto_item_append_text(tree, ", CREATE Reply  Error: %s", err);
5335
0
    break;
5336
0
  }
5337
5338
0
  return offset;
5339
0
}
5340
5341
5342
/* NFSv3 RFC 1813, Page 58..60 */
5343
static int
5344
dissect_nfs3_mkdir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5345
0
{
5346
0
  uint32_t      hash = 0;
5347
0
  const char *name = NULL;
5348
0
  unsigned offset = 0;
5349
5350
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
5351
0
  offset = dissect_nfs3_sattr    (tvb, offset, tree, "attributes");
5352
5353
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
5354
0
  proto_item_append_text(tree, ", MKDIR Call DH: 0x%08x/%s", hash, name);
5355
5356
0
  return offset;
5357
0
}
5358
5359
5360
static int
5361
dissect_nfs3_mkdir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5362
0
{
5363
0
  uint32_t      status;
5364
0
  const char *err;
5365
0
  unsigned offset = 0;
5366
5367
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5368
0
  switch (status) {
5369
0
    case 0:
5370
0
      offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5371
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5372
0
        "obj_attributes");
5373
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5374
0
      proto_item_append_text(tree, ", MKDIR Reply");
5375
0
    break;
5376
0
    default:
5377
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5378
5379
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5380
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5381
0
      proto_item_append_text(tree, ", MKDIR Reply  Error: %s", err);
5382
0
    break;
5383
0
  }
5384
5385
0
  return offset;
5386
0
}
5387
5388
5389
/* NFSv3 RFC 1813, Page 61..63 */
5390
static int
5391
dissect_nfs3_symlink_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5392
0
{
5393
0
  uint32_t      from_hash = 0;
5394
0
  const char *from_name = NULL;
5395
0
  const char *to_name   = NULL;
5396
0
  unsigned offset = 0;
5397
5398
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &from_hash, &from_name, (rpc_call_info_value*)data);
5399
0
  offset = dissect_nfs3_sattr    (tvb, offset,        tree, "symlink_attributes");
5400
0
  offset = dissect_nfs3_path  (tvb, pinfo, offset,        tree, hf_nfs_symlink_to, &to_name);
5401
5402
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To %s",
5403
0
    from_hash, from_name, to_name);
5404
0
  proto_item_append_text(tree, ", SYMLINK Call From DH: 0x%08x/%s To %s",
5405
0
    from_hash, from_name, to_name);
5406
5407
0
  return offset;
5408
0
}
5409
5410
5411
static int
5412
dissect_nfs3_symlink_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5413
0
{
5414
0
  uint32_t      status;
5415
0
  const char *err;
5416
0
  unsigned offset = 0;
5417
5418
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5419
0
  switch (status) {
5420
0
    case 0:
5421
0
      offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5422
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5423
0
        "obj_attributes");
5424
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5425
0
      proto_item_append_text(tree, ", SYMLINK Reply");
5426
0
    break;
5427
0
    default:
5428
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5429
5430
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5431
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5432
0
      proto_item_append_text(tree, ", SYMLINK Reply  Error: %s", err);
5433
0
    break;
5434
0
  }
5435
5436
0
  return offset;
5437
0
}
5438
5439
5440
/* NFSv3 RFC 1813, Page 63..66 */
5441
static int
5442
dissect_nfs3_mknod_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5443
0
{
5444
0
  uint32_t      type;
5445
0
  uint32_t      hash = 0;
5446
0
  const char *name = NULL;
5447
0
  const char *type_str;
5448
0
  unsigned offset = 0;
5449
5450
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
5451
0
  offset = dissect_ftype3(tvb, offset, tree, hf_nfs3_ftype, &type);
5452
0
  switch (type) {
5453
0
    case NF3CHR:
5454
0
    case NF3BLK:
5455
0
      offset = dissect_nfs3_sattr(tvb, offset, tree, "dev_attributes");
5456
0
      offset = dissect_nfs3_specdata(tvb, offset, tree, "spec");
5457
0
    break;
5458
0
    case NF3SOCK:
5459
0
    case NF3FIFO:
5460
0
      offset = dissect_nfs3_sattr(tvb, offset, tree, "pipe_attributes");
5461
0
    break;
5462
0
    default:
5463
      /* nothing to do */
5464
0
    break;
5465
0
  }
5466
5467
0
  type_str = val_to_str_ext(pinfo->pool, type, &names_nfs_ftype3_ext, "Unknown type: %u");
5468
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x/%s %s", hash, name, type_str);
5469
0
  proto_item_append_text(tree, ", MKNOD Call FH: 0x%08x/%s %s", hash, name, type_str);
5470
5471
0
  return offset;
5472
0
}
5473
5474
5475
static int
5476
dissect_nfs3_mknod_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5477
0
{
5478
0
  uint32_t      status;
5479
0
  const char *err;
5480
0
  unsigned offset = 0;
5481
5482
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5483
0
  switch (status) {
5484
0
    case 0:
5485
0
      offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5486
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5487
0
        "obj_attributes");
5488
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5489
0
      proto_item_append_text(tree, ", MKNOD Reply");
5490
0
    break;
5491
0
    default:
5492
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5493
5494
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5495
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5496
0
      proto_item_append_text(tree, ", MKNOD Reply  Error: %s", err);
5497
0
    break;
5498
0
  }
5499
5500
0
  return offset;
5501
0
}
5502
5503
5504
/* NFSv3 RFC 1813, Page 67..69 */
5505
static int
5506
dissect_nfs3_remove_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5507
0
{
5508
0
  uint32_t      status;
5509
0
  const char *err;
5510
0
  unsigned offset = 0;
5511
5512
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5513
0
  switch (status) {
5514
0
    case 0:
5515
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5516
0
      proto_item_append_text(tree, ", REMOVE Reply");
5517
0
    break;
5518
0
    default:
5519
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5520
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5521
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5522
0
      proto_item_append_text(tree, ", REMOVE Reply  Error: %s", err);
5523
0
    break;
5524
0
  }
5525
5526
0
  return offset;
5527
0
}
5528
5529
5530
static int
5531
dissect_nfs3_rmdir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5532
0
{
5533
0
  uint32_t      status;
5534
0
  const char *err;
5535
0
  unsigned offset = 0;
5536
5537
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5538
0
  switch (status) {
5539
0
    case 0:
5540
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5541
0
      proto_item_append_text(tree, ", RMDIR Reply");
5542
0
    break;
5543
0
    default:
5544
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5545
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5546
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5547
0
      proto_item_append_text(tree, ", RMDIR Reply  Error: %s", err);
5548
0
    break;
5549
0
  }
5550
5551
0
  return offset;
5552
0
}
5553
5554
5555
/* NFSv3 RFC 1813, Page 71..74 */
5556
static int
5557
dissect_nfs3_rename_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5558
0
{
5559
0
  uint32_t      from_hash = 0;
5560
0
  const char *from_name = NULL;
5561
0
  uint32_t      to_hash   = 0;
5562
0
  const char *to_name   = NULL;
5563
0
  unsigned offset = 0;
5564
5565
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "from", &from_hash, &from_name, (rpc_call_info_value*)data);
5566
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "to", &to_hash, &to_name, (rpc_call_info_value*)data);
5567
5568
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To DH: 0x%08x/%s",
5569
0
    from_hash, from_name, to_hash, to_name);
5570
0
  proto_item_append_text(tree, ", RENAME Call From DH: 0x%08x/%s To DH: 0x%08x/%s",
5571
0
    from_hash, from_name, to_hash, to_name);
5572
5573
0
  return offset;
5574
0
}
5575
5576
5577
/* NFSv3 RFC 1813, Page 71..74 */
5578
static int
5579
dissect_nfs3_rename_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5580
0
{
5581
0
  uint32_t      status;
5582
0
  const char *err;
5583
0
  unsigned offset = 0;
5584
5585
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5586
0
  switch (status) {
5587
0
    case 0:
5588
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "fromdir_wcc");
5589
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "todir_wcc");
5590
0
      proto_item_append_text(tree, ", RENAME Reply");
5591
0
    break;
5592
0
    default:
5593
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "fromdir_wcc");
5594
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "todir_wcc");
5595
5596
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5597
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5598
0
      proto_item_append_text(tree, ", RENAME Reply  Error: %s", err);
5599
0
    break;
5600
0
  }
5601
5602
0
  return offset;
5603
0
}
5604
5605
5606
/* NFSv3 RFC 1813, Page 74..76 */
5607
static int
5608
dissect_nfs3_link_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5609
0
{
5610
0
  uint32_t      from_hash = 0;
5611
0
  uint32_t      to_hash   = 0;
5612
0
  const char *to_name   = NULL;
5613
0
  unsigned offset = 0;
5614
5615
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &from_hash, (rpc_call_info_value*)data);
5616
0
  offset = dissect_diropargs3(tvb, offset, pinfo, tree, "link", &to_hash, &to_name, (rpc_call_info_value*)data);
5617
5618
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x To DH: 0x%08x/%s",
5619
0
    from_hash, to_hash, to_name);
5620
0
  proto_item_append_text(tree, ", LINK Call From DH: 0x%08x To DH: 0x%08x/%s",
5621
0
    from_hash, to_hash, to_name);
5622
5623
0
  return offset;
5624
0
}
5625
5626
5627
/* NFSv3 RFC 1813, Page 74..76 */
5628
static int
5629
dissect_nfs3_link_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5630
0
{
5631
0
  uint32_t      status;
5632
0
  const char *err;
5633
0
  unsigned offset = 0;
5634
5635
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5636
0
  switch (status) {
5637
0
    case 0:
5638
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5639
0
        "file_attributes");
5640
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "linkdir_wcc");
5641
0
      proto_item_append_text(tree, ", LINK Reply");
5642
0
    break;
5643
0
    default:
5644
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5645
0
        "file_attributes");
5646
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "linkdir_wcc");
5647
5648
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5649
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5650
0
      proto_item_append_text(tree, ", LINK Reply  Error: %s", err);
5651
0
    break;
5652
0
  }
5653
5654
0
  return offset;
5655
0
}
5656
5657
5658
/* NFSv3 RFC 1813, Page 76..80 */
5659
static int
5660
dissect_nfs3_readdir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5661
0
{
5662
0
  uint32_t hash = 0;
5663
0
  unsigned offset = 0;
5664
5665
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "dir", &hash, (rpc_call_info_value*)data);
5666
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_cookie, offset);
5667
0
  offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5668
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
5669
5670
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5671
0
  proto_item_append_text(tree, ", READDIR Call FH: 0x%08x", hash);
5672
5673
0
  return offset;
5674
0
}
5675
5676
5677
/* NFSv3 RFC 1813, Page 76..80 */
5678
static int
5679
dissect_entry3(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data _U_)
5680
0
{
5681
0
  proto_item *entry_item;
5682
0
  proto_tree *entry_tree;
5683
0
  unsigned    old_offset = offset;
5684
0
  const char *name       = NULL;
5685
5686
0
  entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb, offset+0, -1, ENC_NA);
5687
0
  entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
5688
5689
0
  offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdir_entry_fileid, offset);
5690
5691
0
  offset = dissect_nfs3_filename(tvb, pinfo, offset, entry_tree,  hf_nfs3_readdir_entry_name, &name);
5692
0
  proto_item_set_text(entry_item, "Entry: name %s", name);
5693
5694
0
  col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
5695
5696
0
  offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdir_entry_cookie, offset);
5697
5698
  /* now we know, that a readdir entry is shorter */
5699
0
  proto_item_set_len(entry_item, offset - old_offset);
5700
5701
0
  return offset;
5702
0
}
5703
5704
5705
/* NFSv3 RFC 1813, Page 76..80 */
5706
static int
5707
dissect_nfs3_readdir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5708
0
{
5709
0
  uint32_t      status;
5710
0
  const char *err;
5711
0
  unsigned offset = 0;
5712
5713
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5714
0
  switch (status) {
5715
0
    case 0:
5716
0
      proto_item_append_text(tree, ", READDIR Reply");
5717
5718
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5719
0
        "dir_attributes");
5720
0
      offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5721
0
      offset = dissect_rpc_list(tvb, pinfo, tree, offset,
5722
0
        dissect_entry3, NULL);
5723
0
      proto_tree_add_item(tree, hf_nfs_readdir_eof, tvb,
5724
0
          offset+ 0, 4, ENC_BIG_ENDIAN);
5725
0
      offset += 4;
5726
0
    break;
5727
0
    default:
5728
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5729
0
        "dir_attributes");
5730
5731
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5732
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5733
0
      proto_item_append_text(tree, ", READDIR Reply  Error: %s", err);
5734
0
    break;
5735
0
  }
5736
5737
0
  return offset;
5738
0
}
5739
5740
5741
/* NFSv3 RFC 1813, Page 80..83 */
5742
static int
5743
dissect_nfs3_readdirplus_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5744
0
{
5745
0
  uint32_t hash = 0;
5746
0
  unsigned offset = 0;
5747
5748
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "dir", &hash, (rpc_call_info_value*)data);
5749
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_cookie, offset);
5750
0
  offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5751
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count_dircount,
5752
0
    offset);
5753
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count_maxcount,
5754
0
    offset);
5755
5756
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5757
0
  proto_item_append_text(tree, ", READDIRPLUS Call FH: 0x%08x", hash);
5758
5759
0
  return offset;
5760
0
}
5761
5762
5763
/* NFSv3 RFC 1813, Page 80..83 */
5764
static int
5765
dissect_nfs3_entryplus(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data)
5766
0
{
5767
0
  proto_item *entry_item;
5768
0
  proto_tree *entry_tree;
5769
0
  int fh_follows_offset;
5770
0
  bool fh_follows;
5771
0
  int fh_offset;
5772
0
  int fh_length;
5773
0
  unsigned    old_offset = offset;
5774
0
  const char *name       = NULL;
5775
0
  rpc_call_info_value *civ = (rpc_call_info_value *)data;
5776
5777
0
  entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb, offset+0, -1, ENC_NA);
5778
0
  entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
5779
5780
0
  offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdirplus_entry_fileid, offset);
5781
5782
0
  offset = dissect_nfs3_filename(tvb, pinfo, offset, entry_tree,  hf_nfs3_readdirplus_entry_name, &name);
5783
5784
0
  proto_item_set_text(entry_item, "Entry: name %s", name);
5785
5786
0
  col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
5787
5788
0
  offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdirplus_entry_cookie,
5789
0
    offset);
5790
5791
0
  offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, entry_tree, "name_attributes");
5792
5793
  /* are we snooping fh to filenames ?*/
5794
0
  if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
5795
    /* v3 READDIRPLUS replies might give us a mapping */
5796
0
    if ( (civ->prog == 100003)
5797
0
      &&(civ->vers == 3)
5798
0
      &&(!civ->request)
5799
0
      &&((civ->proc == 17))
5800
0
    ) {
5801
0
      fh_follows_offset = offset;
5802
0
      fh_follows = tvb_get_ntohl(tvb, fh_follows_offset);
5803
0
      if (fh_follows == true) {
5804
0
        fh_length = tvb_get_ntohl(tvb, fh_follows_offset+4);
5805
0
        fh_offset = fh_follows_offset+4+4;
5806
0
        nfs_name_snoop_readdir_add_child_fh_name(civ->xid, tvb, fh_offset, fh_length, name);
5807
0
      }
5808
0
    }
5809
0
  }
5810
5811
0
  offset = dissect_nfs3_post_op_fh(tvb, offset, pinfo, entry_tree, "name_handle", civ);
5812
5813
  /* now we know, that a readdirplus entry is shorter */
5814
0
  proto_item_set_len(entry_item, offset - old_offset);
5815
5816
0
  return offset;
5817
0
}
5818
5819
5820
/* NFSv3 RFC 1813, Page 80..83 */
5821
static int
5822
dissect_nfs3_readdirplus_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5823
0
{
5824
0
  uint32_t      status;
5825
0
  const char *err;
5826
0
  unsigned offset = 0;
5827
5828
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5829
0
  switch (status) {
5830
0
    case 0:
5831
0
      proto_item_append_text(tree, ", READDIRPLUS Reply");
5832
5833
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5834
0
        "dir_attributes");
5835
0
      offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5836
0
      offset = dissect_rpc_list(tvb, pinfo, tree, offset,
5837
0
        dissect_nfs3_entryplus, data);
5838
0
      proto_tree_add_item(tree, hf_nfs_readdir_eof, tvb,
5839
0
          offset+ 0, 4, ENC_BIG_ENDIAN);
5840
0
      offset += 4;
5841
0
    break;
5842
0
    default:
5843
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5844
0
        "dir_attributes");
5845
5846
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5847
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5848
0
      proto_item_append_text(tree, ", READDIRPLUS Reply  Error: %s", err);
5849
0
    break;
5850
0
  }
5851
5852
0
  return offset;
5853
0
}
5854
5855
5856
/* NFSv3 RFC 1813, Page 84..86 */
5857
static int
5858
dissect_nfs3_fsstat_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5859
0
{
5860
0
  uint32_t hash = 0;
5861
0
  unsigned offset = 0;
5862
5863
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
5864
5865
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5866
0
  proto_item_append_text(tree, ", FSSTAT Call DH: 0x%08x", hash);
5867
0
  return offset;
5868
0
}
5869
5870
5871
static int
5872
dissect_nfs3_fsstat_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5873
0
{
5874
0
  uint32_t      status;
5875
0
  uint32_t      invarsec;
5876
0
  const char *err;
5877
0
  unsigned offset = 0;
5878
5879
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5880
0
  switch (status) {
5881
0
    case 0:
5882
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5883
0
        "obj_attributes");
5884
0
      offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_tbytes,
5885
0
        offset);
5886
0
      offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_fbytes,
5887
0
        offset);
5888
0
      offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_abytes,
5889
0
        offset);
5890
0
      offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_tfiles,
5891
0
        offset);
5892
0
      offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_ffiles,
5893
0
        offset);
5894
0
      offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_afiles,
5895
0
        offset);
5896
0
      invarsec = tvb_get_ntohl(tvb, offset + 0);
5897
0
      if (tree)
5898
0
        proto_tree_add_uint(tree, hf_nfs3_fsstat_invarsec, tvb,
5899
0
        offset+0, 4, invarsec);
5900
0
      offset += 4;
5901
5902
0
      proto_item_append_text(tree, ", FSSTAT Reply");
5903
0
    break;
5904
0
    default:
5905
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5906
0
        "obj_attributes");
5907
5908
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5909
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5910
0
      proto_item_append_text(tree, ", FSSTAT Reply  Error: %s", err);
5911
0
    break;
5912
0
  }
5913
5914
0
  return offset;
5915
0
}
5916
5917
5918
16
#define FSF3_LINK        0x00000001
5919
16
#define FSF3_SYMLINK     0x00000002
5920
16
#define FSF3_HOMOGENEOUS 0x00000008
5921
16
#define FSF3_CANSETTIME  0x00000010
5922
5923
static const true_false_string tfs_nfs_pathconf =
5924
  { "is valid for all files", "should be get for every single file" };
5925
5926
5927
/* NFSv3 RFC 1813, Page 86..90 */
5928
static int
5929
dissect_nfs3_fsinfo_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5930
0
{
5931
0
  uint32_t hash = 0;
5932
0
  unsigned offset = 0;
5933
5934
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
5935
5936
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5937
0
  proto_item_append_text(tree, ", FSINFO Call DH: 0x%08x", hash);
5938
0
  return offset;
5939
0
}
5940
5941
5942
static int
5943
dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5944
0
{
5945
0
  uint32_t      status;
5946
0
  static int * const properties[] = {
5947
0
    &hf_nfs3_fsinfo_properties_setattr,
5948
0
    &hf_nfs3_fsinfo_properties_pathconf,
5949
0
    &hf_nfs3_fsinfo_properties_symlinks,
5950
0
    &hf_nfs3_fsinfo_properties_hardlinks,
5951
0
    NULL
5952
0
  };
5953
0
  unsigned offset = 0;
5954
5955
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
5956
0
  switch (status) {
5957
0
    case 0:
5958
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5959
0
        "obj_attributes");
5960
0
      proto_tree_add_item(tree, hf_nfs3_fsinfo_rtmax, tvb, offset, 4, ENC_BIG_ENDIAN);
5961
0
      offset += 4;
5962
0
      proto_tree_add_item(tree, hf_nfs3_fsinfo_rtpref, tvb, offset, 4, ENC_BIG_ENDIAN);
5963
0
      offset += 4;
5964
0
      proto_tree_add_item(tree, hf_nfs3_fsinfo_rtmult, tvb, offset, 4, ENC_BIG_ENDIAN);
5965
0
      offset += 4;
5966
0
      proto_tree_add_item(tree, hf_nfs3_fsinfo_wtmax, tvb, offset, 4, ENC_BIG_ENDIAN);
5967
0
      offset += 4;
5968
0
      proto_tree_add_item(tree, hf_nfs3_fsinfo_wtpref, tvb, offset, 4, ENC_BIG_ENDIAN);
5969
0
      offset += 4;
5970
0
      proto_tree_add_item(tree, hf_nfs3_fsinfo_wtmult, tvb, offset, 4, ENC_BIG_ENDIAN);
5971
0
      offset += 4;
5972
0
      proto_tree_add_item(tree, hf_nfs3_fsinfo_dtpref, tvb, offset, 4, ENC_BIG_ENDIAN);
5973
0
      offset += 4;
5974
5975
0
      offset = dissect_rpc_uint64(tvb, tree,  hf_nfs3_fsinfo_maxfilesize, offset);
5976
0
      offset = dissect_nfstime3(tvb, offset, tree, hf_nfs_dtime, hf_nfs_dtime_sec,
5977
0
        hf_nfs_dtime_nsec);
5978
5979
0
      proto_tree_add_bitmask(tree, tvb, offset, hf_nfs3_fsinfo_properties, ett_nfs3_fsinfo_properties, properties, ENC_BIG_ENDIAN);
5980
0
      offset += 4;
5981
5982
0
      proto_item_append_text(tree, ", FSINFO Reply");
5983
0
      break;
5984
0
    default:
5985
0
    {
5986
0
      const char *err;
5987
5988
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5989
0
        "obj_attributes");
5990
5991
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
5992
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5993
0
      proto_item_append_text(tree, ", FSINFO Reply  Error: %s", err);
5994
0
      break;
5995
0
    }
5996
0
  }
5997
5998
0
  return offset;
5999
0
}
6000
6001
6002
/* NFSv3 RFC 1813, Page 90..92 */
6003
static int
6004
dissect_nfs3_pathconf_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
6005
0
{
6006
0
  uint32_t hash = 0;
6007
0
  unsigned offset = 0;
6008
6009
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
6010
6011
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
6012
0
  proto_item_append_text(tree, ", PATHCONF Call DH: 0x%08x", hash);
6013
0
  return offset;
6014
0
}
6015
6016
6017
static int
6018
dissect_nfs3_pathconf_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
6019
0
{
6020
0
  uint32_t      status;
6021
0
  uint32_t      linkmax;
6022
0
  uint32_t      name_max;
6023
0
  const char *err;
6024
0
  unsigned offset = 0;
6025
6026
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
6027
0
  switch (status) {
6028
0
    case 0:
6029
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
6030
0
        "obj_attributes");
6031
0
      linkmax = tvb_get_ntohl(tvb, offset + 0);
6032
0
      if (tree)
6033
0
        proto_tree_add_uint(tree, hf_nfs3_pathconf_linkmax, tvb,
6034
0
        offset+0, 4, linkmax);
6035
0
      offset += 4;
6036
0
      name_max = tvb_get_ntohl(tvb, offset + 0);
6037
0
      if (tree)
6038
0
        proto_tree_add_uint(tree, hf_nfs3_pathconf_name_max, tvb,
6039
0
        offset+0, 4, name_max);
6040
0
      offset += 4;
6041
0
      offset = dissect_rpc_bool(tvb, tree,
6042
0
        hf_nfs3_pathconf_no_trunc, offset);
6043
0
      offset = dissect_rpc_bool(tvb, tree,
6044
0
        hf_nfs3_pathconf_chown_restricted, offset);
6045
0
      offset = dissect_rpc_bool(tvb, tree,
6046
0
        hf_nfs3_pathconf_case_insensitive, offset);
6047
0
      offset = dissect_rpc_bool(tvb, tree,
6048
0
        hf_nfs3_pathconf_case_preserving, offset);
6049
6050
0
      proto_item_append_text(tree, ", PATHCONF Reply");
6051
0
    break;
6052
0
    default:
6053
0
      offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
6054
0
        "obj_attributes");
6055
6056
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
6057
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
6058
0
      proto_item_append_text(tree, ", PATHCONF Reply  Error: %s", err);
6059
0
    break;
6060
0
  }
6061
6062
0
  return offset;
6063
0
}
6064
6065
6066
/* NFSv3 RFC 1813, Page 92..95 */
6067
static int
6068
dissect_nfs3_commit_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
6069
0
{
6070
0
  uint32_t hash = 0;
6071
0
  unsigned offset = 0;
6072
6073
0
  offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
6074
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_offset, offset);
6075
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
6076
6077
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
6078
0
  proto_item_append_text(tree, ", COMMIT Call FH: 0x%08x", hash);
6079
6080
0
  return offset;
6081
0
}
6082
6083
6084
/* NFSv3 RFC 1813, Page 92..95 */
6085
static int
6086
dissect_nfs3_commit_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
6087
0
{
6088
0
  uint32_t      status;
6089
0
  const char *err;
6090
0
  unsigned offset = 0;
6091
6092
0
  offset = dissect_nfs3_status(tvb, offset, tree, &status);
6093
0
  switch (status) {
6094
0
    case 0:
6095
0
      offset = dissect_wcc_data  (tvb, offset, pinfo, tree, "file_wcc");
6096
0
      offset = dissect_nfs3_write_verf(tvb, offset, tree);
6097
6098
0
      proto_item_append_text(tree, ", COMMIT Reply");
6099
0
    break;
6100
0
    default:
6101
0
      offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc");
6102
6103
0
      err = val_to_str_ext(pinfo->pool, status, &names_nfs3_status_ext, "Unknown error: %u");
6104
0
      col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
6105
0
      proto_item_append_text(tree, ", COMMIT Reply  Error: %s", err);
6106
0
    break;
6107
0
  }
6108
6109
0
  return offset;
6110
0
}
6111
6112
/*************************************************************************************
6113
*  NFS Version 4.1, RFC 5661.  Note that error 19 NFS4ERR_NOTDIR defined in RFC 3010
6114
*  was eliminated in RFC 3530 (NFSv4) which replaced RFC 3010 and remains so in
6115
*  RFC 5661. Nevertheless, it has been included in this table in the event that some
6116
*  RFC 3010 implementations still exist out there.
6117
**************************************************************************************/
6118
static const value_string names_nfs4_status[] = {
6119
  { 0,  "NFS4_OK"         },
6120
  { 1,  "NFS4ERR_PERM"          },
6121
  { 2,  "NFS4ERR_NOENT"         },
6122
  { 5,  "NFS4ERR_IO"          },
6123
  { 6,  "NFS4ERR_NXIO"          },
6124
  { 13, "NFS4ERR_ACCESS"        },
6125
  { 17, "NFS4ERR_EXIST"         },
6126
  { 18, "NFS4ERR_XDEV"          },
6127
  { 19, "NFS4ERR_DQUOT"         },
6128
  { 20, "NFS4ERR_NOTDIR"        },
6129
  { 21, "NFS4ERR_ISDIR"         },
6130
  { 22, "NFS4ERR_INVAL"         },
6131
  { 27, "NFS4ERR_FBIG"          },
6132
  { 28, "NFS4ERR_NOSPC"         },
6133
  { 30, "NFS4ERR_ROFS"          },
6134
  { 31, "NFS4ERR_MLINK"         },
6135
  { 63, "NFS4ERR_NAMETOOLONG"       },
6136
  { 66, "NFS4ERR_NOTEMPTY"        },
6137
  { 69, "NFS4ERR_DQUOT"         },
6138
  { 70, "NFS4ERR_STALE"         },
6139
  { 10001,  "NFS4ERR_BADHANDLE"       },
6140
  { 10003,  "NFS4ERR_BAD_COOKIE"        },
6141
  { 10004,  "NFS4ERR_NOTSUPP"       },
6142
  { 10005,  "NFS4ERR_TOOSMALL"        },
6143
  { 10006,  "NFS4ERR_SERVERFAULT"       },
6144
  { 10007,  "NFS4ERR_BADTYPE"       },
6145
  { 10008,  "NFS4ERR_DELAY"         },
6146
  { 10009,  "NFS4ERR_SAME"          },
6147
  { 10010,  "NFS4ERR_DENIED"        },
6148
  { 10011,  "NFS4ERR_EXPIRED"       },
6149
  { 10012,  "NFS4ERR_LOCKED"        },
6150
  { 10013,  "NFS4ERR_GRACE"         },
6151
  { 10014,  "NFS4ERR_FHEXPIRED"       },
6152
  { 10015,  "NFS4ERR_SHARE_DENIED"        },
6153
  { 10016,  "NFS4ERR_WRONGSEC"        },
6154
  { 10017,  "NFS4ERR_CLID_INUSE"        },
6155
  { 10018,  "NFS4ERR_RESOURCE"        },
6156
  { 10019,  "NFS4ERR_MOVED"         },
6157
  { 10020,  "NFS4ERR_NOFILEHANDLE"        },
6158
  { 10021,  "NFS4ERR_MINOR_VERS_MISMATCH"     },
6159
  { 10022,  "NFS4ERR_STALE_CLIENTID"      },
6160
  { 10023,  "NFS4ERR_STALE_STATEID"       },
6161
  { 10024,  "NFS4ERR_OLD_STATEID"       },
6162
  { 10025,  "NFS4ERR_BAD_STATEID"       },
6163
  { 10026,  "NFS4ERR_BAD_SEQID"       },
6164
  { 10027,  "NFS4ERR_NOT_SAME"        },
6165
  { 10028,  "NFS4ERR_LOCK_RANGE"        },
6166
  { 10029,  "NFS4ERR_SYMLINK"       },
6167
  { 10030,  "NFS4ERR_READDIR_NOSPC"       },
6168
  { 10031,  "NFS4ERR_LEASE_MOVED"       },
6169
  { 10032,  "NFS4ERR_ATTRNOTSUPP"       },
6170
  { 10033,  "NFS4ERR_NO_GRACE"        },
6171
  { 10034,  "NFS4ERR_RECLAIM_BAD"       },
6172
  { 10035,  "NFS4ERR_RECLAIM_CONFLICT"      },
6173
  { 10036,  "NFS4ERR_BADXDR"        },
6174
  { 10037,  "NFS4ERR_LOCKS_HELD"        },
6175
  { 10038,  "NFS4ERR_OPENMODE"        },
6176
  { 10039,  "NFS4ERR_BADOWNER"        },
6177
  { 10040,  "NFS4ERR_BADCHAR"       },
6178
  { 10041,  "NFS4ERR_BADNAME"       },
6179
  { 10042,  "NFS4ERR_BAD_RANGE"       },
6180
  { 10043,  "NFS4ERR_LOCK_NOTSUPP"        },
6181
  { 10044,  "NFS4ERR_OP_ILLEGAL"        },
6182
  { 10045,  "NFS4ERR_DEADLOCK"        },
6183
  { 10046,  "NFS4ERR_FILE_OPEN"       },
6184
  { 10047,  "NFS4ERR_ADMIN_REVOKED"       },
6185
  { 10048,  "NFS4ERR_CB_PATH_DOWN"        },
6186
  { 10049,  "NFS4ERR_BADIOMODE"       },
6187
  { 10050,  "NFS4ERR_BADLAYOUT"       },
6188
  { 10051,  "NFS4ERR_BAD_SESSION_DIGEST"      },
6189
  { 10052,  "NFS4ERR_BADSESSION"        },
6190
  { 10053,  "NFS4ERR_BADSLOT"       },
6191
  { 10054,  "NFS4ERR_COMPLETE_ALREADY"      },
6192
  { 10055,  "NFS4ERR_CONN_NOT_BOUND_TO_SESSION" },
6193
  { 10056,  "NFS4ERR_DELEG_ALREADY_WANTED"      },
6194
  { 10057,  "NFS4ERR_BACK_CHAN_BUSY"      },
6195
  { 10058,  "NFS4ERR_LAYOUTTRYLATER"      },
6196
  { 10059,  "NFS4ERR_LAYOUTUNAVAILABLE"     },
6197
  { 10060,  "NFS4ERR_NOMATCHING_LAYOUT"     },
6198
  { 10061,  "NFS4ERR_RECALLCONFLICT"      },
6199
  { 10062,  "NFS4ERR_UNKNOWN_LAYOUTTYPE"      },
6200
  { 10063,  "NFS4ERR_SEQ_MISORDERED"      },
6201
  { 10064,  "NFS4ERR_SEQUENCE_POS"        },
6202
  { 10065,  "NFS4ERR_REQ_TOO_BIG"       },
6203
  { 10066,  "NFS4ERR_REP_TOO_BIG"       },
6204
  { 10067,  "NFS4ERR_REP_TOO_BIG_TO_CACHE"      },
6205
  { 10068,  "NFS4ERR_RETRY_UNCACHED_REP"      },
6206
  { 10069,  "NFS4ERR_UNSAFE_COMPOUND"     },
6207
  { 10070,  "NFS4ERR_TOO_MANY_OPS"        },
6208
  { 10071,  "NFS4ERR_OP_NOT_IN_SESSION"     },
6209
  { 10072,  "NFS4ERR_HASH_ALG_UNSUPP"     },
6210
  { 10073,  "NFS4ERR_CONN_BINDING_NOT_ENFORCED" },
6211
  { 10074,  "NFS4ERR_CLIENTID_BUSY"       },
6212
  { 10075,  "NFS4ERR_PNFS_IO_HOLE"        },
6213
  { 10076,  "NFS4ERR_SEQ_FALSE_RETRY"     },
6214
  { 10077,  "NFS4ERR_BAD_HIGH_SLOT"       },
6215
  { 10078,  "NFS4ERR_DEADSESSION"       },
6216
  { 10079,  "NFS4ERR_ENCR_ALG_UNSUPP"     },
6217
  { 10080,  "NFS4ERR_PNFS_NO_LAYOUT"      },
6218
  { 10081,  "NFS4ERR_NOT_ONLY_OP"       },
6219
  { 10082,  "NFS4ERR_WRONG_CRED"        },
6220
  { 10083,  "NFS4ERR_WRONG_TYPE"        },
6221
  { 10084,  "NFS4ERR_DIRDELEG_UNAVAIL"      },
6222
  { 10085,  "NFS4ERR_REJECT_DELEG"        },
6223
  { 10086,  "NFS4ERR_RETURNCONFLICT"      },
6224
  { 10087,  "NFS4ERR_DELEG_REVOKED"       },
6225
  { 10088,  "NFS4ERR_PARTNER_NOTSUPP"     },
6226
  { 10089,  "NFS4ERR_PARTNER_NO_AUTH"     },
6227
  { 10090,  "NFS4ERR_UNION_NOTSUPP"       },
6228
  { 10091,  "NFS4ERR_OFFLOAD_DENIED"      },
6229
  { 10092,  "NFS4ERR_WRONG_LFS"       },
6230
  { 10093,  "NFS4ERR_BADLABEL"        },
6231
  { 10094,  "NFS4ERR_OFFLOAD_NO_REQS"     },
6232
  { 10095,  "NFS4ERR_NOXATTR"       },
6233
  { 10096,  "NFS4ERR_XATTR2BIG"       },
6234
  { 0,  NULL }
6235
};
6236
static value_string_ext names_nfs4_status_ext = VALUE_STRING_EXT_INIT(names_nfs4_status);
6237
6238
static const value_string fattr4_names[] = {
6239
0
#define FATTR4_SUPPORTED_ATTRS     0
6240
  { FATTR4_SUPPORTED_ATTRS,    "Supported_Attrs"  },
6241
0
#define FATTR4_TYPE                1
6242
  { FATTR4_TYPE,               "Type"},
6243
0
#define FATTR4_FH_EXPIRE_TYPE      2
6244
  { FATTR4_FH_EXPIRE_TYPE,     "FH_Expire_Type" },
6245
0
#define FATTR4_CHANGE              3
6246
  { FATTR4_CHANGE,             "Change"},
6247
0
#define FATTR4_SIZE                4
6248
  { FATTR4_SIZE,             "Size" },
6249
0
#define FATTR4_LINK_SUPPORT        5
6250
  { FATTR4_LINK_SUPPORT,       "Link_Support" },
6251
0
#define FATTR4_SYMLINK_SUPPORT     6
6252
  { FATTR4_SYMLINK_SUPPORT,    "Symlink_Support"  },
6253
0
#define FATTR4_NAMED_ATTR          7
6254
  { FATTR4_NAMED_ATTR,         "Named_Attr" },
6255
0
#define FATTR4_FSID                8
6256
  { FATTR4_FSID,               "FSID" },
6257
0
#define FATTR4_UNIQUE_HANDLES      9
6258
  { FATTR4_UNIQUE_HANDLES,     "Unique_Handles" },
6259
0
#define FATTR4_LEASE_TIME          10
6260
  { FATTR4_LEASE_TIME,         "Lease_Time" },
6261
0
#define FATTR4_RDATTR_ERROR        11
6262
  { FATTR4_RDATTR_ERROR,       "RDAttr_Error" },
6263
0
#define FATTR4_ACL                 12
6264
  { FATTR4_ACL,                "ACL"  },
6265
0
#define FATTR4_ACLSUPPORT          13
6266
  { FATTR4_ACLSUPPORT,         "ACLSupport" },
6267
0
#define FATTR4_ARCHIVE             14
6268
  { FATTR4_ARCHIVE,            "Archive"  },
6269
0
#define FATTR4_CANSETTIME          15
6270
  { FATTR4_CANSETTIME,         "CanSetTime" },
6271
0
#define FATTR4_CASE_INSENSITIVE    16
6272
  { FATTR4_CASE_INSENSITIVE,   "Case_Insensitive" },
6273
0
#define FATTR4_CASE_PRESERVING     17
6274
  { FATTR4_CASE_PRESERVING,    "Case_Preserving"  },
6275
0
#define FATTR4_CHOWN_RESTRICTED    18
6276
  { FATTR4_CHOWN_RESTRICTED,   "Chown_Restricted" },
6277
0
#define FATTR4_FILEHANDLE          19
6278
  { FATTR4_FILEHANDLE,         "Filehandle" },
6279
0
#define FATTR4_FILEID              20
6280
  { FATTR4_FILEID,             "FileId" },
6281
0
#define FATTR4_FILES_AVAIL         21
6282
  { FATTR4_FILES_AVAIL,        "Files_Avail"  },
6283
0
#define FATTR4_FILES_FREE          22
6284
  { FATTR4_FILES_FREE,         "Files_Free" },
6285
0
#define FATTR4_FILES_TOTAL         23
6286
  { FATTR4_FILES_TOTAL,        "Files_Total"  },
6287
0
#define FATTR4_FS_LOCATIONS        24
6288
  { FATTR4_FS_LOCATIONS,       "FS_Locations" },
6289
0
#define FATTR4_HIDDEN              25
6290
  { FATTR4_HIDDEN,             "Hidden" },
6291
0
#define FATTR4_HOMOGENEOUS         26
6292
  { FATTR4_HOMOGENEOUS,        "Homogeneous"  },
6293
0
#define FATTR4_MAXFILESIZE         27
6294
  { FATTR4_MAXFILESIZE,        "MaxFileSize"  },
6295
0
#define FATTR4_MAXLINK             28
6296
  { FATTR4_MAXLINK,            "MaxLink"  },
6297
0
#define FATTR4_MAXNAME             29
6298
  { FATTR4_MAXNAME,            "MaxName"  },
6299
0
#define FATTR4_MAXREAD             30
6300
  { FATTR4_MAXREAD,            "MaxRead"  },
6301
0
#define FATTR4_MAXWRITE            31
6302
  { FATTR4_MAXWRITE,           "MaxWrite" },
6303
0
#define FATTR4_MIMETYPE            32
6304
  { FATTR4_MIMETYPE,           "MimeType" },
6305
0
#define FATTR4_MODE                33
6306
  { FATTR4_MODE,               "Mode" },
6307
0
#define FATTR4_NO_TRUNC            34
6308
  { FATTR4_NO_TRUNC,           "No_Trunc" },
6309
0
#define FATTR4_NUMLINKS            35
6310
  { FATTR4_NUMLINKS,           "NumLinks" },
6311
0
#define FATTR4_OWNER               36
6312
  { FATTR4_OWNER,              "Owner"  },
6313
0
#define FATTR4_OWNER_GROUP         37
6314
  { FATTR4_OWNER_GROUP,        "Owner_Group"  },
6315
0
#define FATTR4_QUOTA_AVAIL_HARD    38
6316
  { FATTR4_QUOTA_AVAIL_HARD,   "Quota_Avail_Hard" },
6317
0
#define FATTR4_QUOTA_AVAIL_SOFT    39
6318
  { FATTR4_QUOTA_AVAIL_SOFT,   "Quota_Avail_Soft" },
6319
0
#define FATTR4_QUOTA_USED          40
6320
  { FATTR4_QUOTA_USED,         "Quota_Used" },
6321
0
#define FATTR4_RAWDEV              41
6322
  { FATTR4_RAWDEV,             "RawDev" },
6323
0
#define FATTR4_SPACE_AVAIL         42
6324
  { FATTR4_SPACE_AVAIL,        "Space_Avail"  },
6325
0
#define FATTR4_SPACE_FREE          43
6326
  { FATTR4_SPACE_FREE,         "Space_Free" },
6327
0
#define FATTR4_SPACE_TOTAL         44
6328
  { FATTR4_SPACE_TOTAL,        "Space_Total"  },
6329
0
#define FATTR4_SPACE_USED          45
6330
  { FATTR4_SPACE_USED,         "Space_Used" },
6331
0
#define FATTR4_SYSTEM              46
6332
  { FATTR4_SYSTEM,             "System" },
6333
0
#define FATTR4_TIME_ACCESS         47
6334
  { FATTR4_TIME_ACCESS,        "Time_Access"  },
6335
0
#define FATTR4_TIME_ACCESS_SET     48
6336
  { FATTR4_TIME_ACCESS_SET,    "Time_Access_Set"  },
6337
0
#define FATTR4_TIME_BACKUP         49
6338
  { FATTR4_TIME_BACKUP,        "Time_Backup"  },
6339
0
#define FATTR4_TIME_CREATE         50
6340
  { FATTR4_TIME_CREATE,        "Time_Create"  },
6341
0
#define FATTR4_TIME_DELTA          51
6342
  { FATTR4_TIME_DELTA,         "Time_Delta" },
6343
0
#define FATTR4_TIME_METADATA       52
6344
  { FATTR4_TIME_METADATA,      "Time_Metadata"  },
6345
0
#define FATTR4_TIME_MODIFY         53
6346
  { FATTR4_TIME_MODIFY,        "Time_Modify"  },
6347
0
#define FATTR4_TIME_MODIFY_SET     54
6348
  { FATTR4_TIME_MODIFY_SET,    "Time_Modify_Set"  },
6349
0
#define FATTR4_MOUNTED_ON_FILEID   55
6350
  { FATTR4_MOUNTED_ON_FILEID,  "Mounted_on_FileId"  },
6351
0
#define FATTR4_DIR_NOTIF_DELAY     56
6352
  { FATTR4_DIR_NOTIF_DELAY,    "Dir_Notif_Delay"  },
6353
0
#define FATTR4_DIRENT_NOTIF_DELAY  57
6354
  { FATTR4_DIRENT_NOTIF_DELAY, "Dirent_Notif_Delay" },
6355
0
#define FATTR4_DACL                58
6356
  { FATTR4_DACL,               "DACL"                },
6357
0
#define FATTR4_SACL                59
6358
  { FATTR4_SACL,               "SACL"                },
6359
#define FATTR4_CHANGE_POLICY       60
6360
  { FATTR4_CHANGE_POLICY,      "Change_Policy"    },
6361
#define FATTR4_FS_STATUS           61
6362
  { FATTR4_FS_STATUS,          "FS_Status"      },
6363
0
#define FATTR4_FS_LAYOUT_TYPE      62
6364
  { FATTR4_FS_LAYOUT_TYPE,     "FS_Layout_Type"   },
6365
#define FATTR4_LAYOUT_HINT         63
6366
  { FATTR4_LAYOUT_HINT,        "Layout_hint"    },
6367
#define FATTR4_LAYOUT_TYPE         64
6368
  { FATTR4_LAYOUT_TYPE,        "Layout_type"    },
6369
0
#define FATTR4_LAYOUT_BLKSIZE      65
6370
  { FATTR4_LAYOUT_BLKSIZE,     "Layout_blksize"   },
6371
#define FATTR4_LAYOUT_ALIGNMENT    66
6372
  { FATTR4_LAYOUT_ALIGNMENT,   "Layout_alignment" },
6373
#define FATTR4_FS_LOCATIONS_INFO   67
6374
  { FATTR4_FS_LOCATIONS_INFO,  "FS_Locations_info"  },
6375
0
#define FATTR4_MDSTHRESHOLD        68
6376
  { FATTR4_MDSTHRESHOLD,       "MDS_Threshold"    },
6377
#define FATTR4_RETENTION_GET       69
6378
  { FATTR4_RETENTION_GET,      "Retention_Get"    },
6379
#define FATTR4_RETENTION_SET       70
6380
  { FATTR4_RETENTION_SET,      "Retention_Set"    },
6381
#define FATTR4_RETENTEVT_GET       71
6382
  { FATTR4_RETENTEVT_GET,      "RetentEvt_Get"    },
6383
#define FATTR4_RETENTEVT_SET       72
6384
  { FATTR4_RETENTEVT_SET,      "RetentEvt_Set"    },
6385
#define FATTR4_RETENTION_HOLD      73
6386
  { FATTR4_RETENTION_HOLD,     "Retention_Hold"   },
6387
#define FATTR4_MODE_SET_MASKED     74
6388
  { FATTR4_MODE_SET_MASKED,    "Mode_Set_Masked"  },
6389
0
#define FATTR4_SUPPATTR_EXCLCREAT  75
6390
  { FATTR4_SUPPATTR_EXCLCREAT, "Suppattr_ExclCreat" },
6391
0
#define FATTR4_FS_CHARSET_CAP      76
6392
  { FATTR4_FS_CHARSET_CAP,     "FS_Charset_Cap"   },
6393
0
#define FATTR4_CLONE_BLOCKSIZE     77
6394
  { FATTR4_CLONE_BLOCKSIZE,    "Clone_Block_Size"   },
6395
0
#define FATTR4_SPACE_FREED         78
6396
  { FATTR4_SPACE_FREED,        "Space_Freed"    },
6397
0
#define FATTR4_CHANGE_ATTR_TYPE    79
6398
  { FATTR4_CHANGE_ATTR_TYPE,   "Change_Attr_Type"   },
6399
0
#define FATTR4_SECURITY_LABEL      80
6400
  { FATTR4_SECURITY_LABEL,     "Security_Label"   },
6401
0
#define FATTR4_MODE_UMASK          81
6402
  { FATTR4_MODE_UMASK,         "Mode_Umask"     },
6403
0
#define FATTR4_XATTR_SUPPORT       82
6404
  { FATTR4_XATTR_SUPPORT,      "Xattr_Support"    },
6405
0
#define FATTR4_OFFLINE             83
6406
  { FATTR4_OFFLINE,            "Offline"                    },
6407
0
#define FATTR4_TIME_DELEG_ACCESS   84
6408
  { FATTR4_TIME_DELEG_ACCESS,  "Time_Deleg_Access"          },
6409
0
#define FATTR4_TIME_DELEG_MODIFY   85
6410
  { FATTR4_TIME_DELEG_MODIFY,  "Time_Deleg_Modify"          },
6411
  { 0,  NULL  }
6412
};
6413
static value_string_ext fattr4_names_ext = VALUE_STRING_EXT_INIT(fattr4_names);
6414
6415
static unsigned
6416
dissect_nfs4_status(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint32_t *status)
6417
0
{
6418
0
  uint32_t      stat;
6419
0
  proto_item *stat_item;
6420
6421
0
  proto_tree_add_item_ret_uint(tree, hf_nfs4_status, tvb, offset+0, 4, ENC_BIG_ENDIAN, &stat);
6422
0
  stat_item = proto_tree_add_uint(tree, hf_nfs_status, tvb, offset+0, 4, stat);
6423
0
  proto_item_set_hidden(stat_item);
6424
6425
0
  if (status)
6426
0
    *status = stat;
6427
6428
0
  return offset + 4;
6429
0
}
6430
6431
6432
static unsigned
6433
dissect_nfs_utf8string(tvbuff_t *tvb, packet_info* pinfo, unsigned offset,
6434
           proto_tree *tree, int hf, const char **string_ret)
6435
0
{
6436
  /* TODO: this dissector is subject to change; do not remove */
6437
0
  return dissect_rpc_string(tvb, pinfo, tree, hf, offset, string_ret);
6438
0
}
6439
6440
6441
/*
6442
 *  Generic function to dissect bitmap4 and optionally its corresponding
6443
 *  opaque data.
6444
 */
6445
static unsigned
6446
dissect_nfs4_bitmap(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree,
6447
  rpc_call_info_value *civ, uint32_t opcode, uint32_t fh_idx,
6448
  nfs4_bitmap_info_t *bitmap_info, nfs4_bitmap_type_t type,
6449
  const char *name)
6450
0
{
6451
0
  unsigned attr_offset;
6452
0
  int hf_item = 0;
6453
0
  uint32_t i, j;
6454
0
  uint32_t count;
6455
0
  uint32_t bitmap;
6456
0
  uint32_t bit_num;
6457
0
  uint32_t bit_set;
6458
0
  uint32_t num_bitmaps;
6459
0
  uint32_t end_offset;
6460
0
  uint32_t mask_offset;
6461
0
  uint32_t opaque_offset;
6462
0
  uint32_t opaque_length = 0;
6463
0
  uint32_t opaque_padding = 0;
6464
0
  bool no_idx = false;
6465
0
  bool first_attr = false;
6466
0
  bool skip_attr_values = false;
6467
6468
0
  header_field_info *hfinfo;
6469
6470
0
  proto_item *name_tree   = tree;
6471
0
  proto_item *bitmap_item = NULL;
6472
0
  proto_tree *bitmap_tree = NULL;
6473
0
  proto_item *attr_item   = NULL;
6474
0
  proto_tree *attr_tree   = NULL;
6475
0
  proto_item *attr_count  = NULL;
6476
6477
  /* Get the number of bitmap masks */
6478
0
  num_bitmaps = tvb_get_ntohl(tvb, offset);
6479
0
  mask_offset = offset + 4;  /* Offset of first bitmap mask */
6480
0
  opaque_offset = mask_offset + 4*num_bitmaps;
6481
6482
0
  if (type == NFS4_BITMAP_VALUES) {
6483
    /* Get the length of opaque including padding */
6484
0
    opaque_length = tvb_get_ntohl(tvb, opaque_offset);
6485
0
    opaque_padding = WS_PADDING_TO_4(opaque_length);
6486
0
    opaque_offset += 4;  /* Starting offset of bitmap values */
6487
0
  }
6488
6489
  /* Offset after the bitmap mask and values regardless of type */
6490
0
  end_offset = opaque_offset + opaque_length + opaque_padding;
6491
6492
0
  if (name != NULL) {
6493
    /* Add subtree if name is given -- all bitmap data will be
6494
     * under this main tree */
6495
0
    name_tree = proto_tree_add_subtree(tree, tvb, offset, end_offset - offset,
6496
0
              ett_nfs4_bitmap, NULL, name);
6497
0
  }
6498
6499
0
  if (num_bitmaps > MAX_BITMAPS) {
6500
0
    proto_tree_add_uint(name_tree, hf_nfs4_huge_bitmap_length, tvb, offset, 4, num_bitmaps);
6501
0
    expert_add_info(pinfo, name_tree, &ei_nfs_too_many_bitmaps);
6502
0
    return end_offset;
6503
0
  } else if (bitmap_info->hf_mask_count) {
6504
    /* Display the number of bitmap masks if the label is given */
6505
0
    proto_tree_add_uint(name_tree, *bitmap_info->hf_mask_count, tvb, offset, 4, num_bitmaps);
6506
0
  }
6507
6508
  /* Count the number of non-zero masks */
6509
0
  count = 0;
6510
0
  for (i = 0; i < num_bitmaps; i++) {
6511
0
    bitmap = tvb_get_ntohl(tvb, mask_offset + 4*i);
6512
0
    if (bitmap > 0)
6513
0
      count++;
6514
0
  }
6515
6516
  /* If there is only one non-zero bitmap, don't display the bitmap index "[x]". */
6517
0
  if (count <= 1)
6518
0
    no_idx = true;
6519
6520
  /* Set the offset to the first value */
6521
0
  offset = opaque_offset;
6522
6523
  /* set i to num_bitmaps if each bitmap is zero */
6524
0
  for (i = 0; i < num_bitmaps; i++) {
6525
0
    bitmap = tvb_get_ntohl(tvb, mask_offset + 4*i);
6526
0
    if (bitmap)
6527
0
      break;
6528
0
  }
6529
6530
  /* Show mask label when the number of bitmap masks is zero or each bitmap is zero */
6531
0
  if (num_bitmaps == i && name == NULL && name_tree && bitmap_info->hf_mask_label) {
6532
    /* Get header field to add the mask index to the field name */
6533
0
    hfinfo = proto_registrar_get_nth(*bitmap_info->hf_mask_label);
6534
0
    bitmap_tree = proto_tree_add_subtree_format(name_tree, tvb, mask_offset-4, 4 + 4*num_bitmaps,
6535
0
            ett_nfs4_bitmap, NULL, "%s:", hfinfo->name);
6536
0
  }
6537
6538
0
  for (i = 0; i < num_bitmaps; i++) {
6539
0
    bitmap = tvb_get_ntohl(tvb, mask_offset);
6540
6541
0
    if (bitmap) {
6542
0
      if (name_tree && bitmap_info->hf_mask_label) {
6543
0
        if (no_idx) {
6544
0
          bitmap_item = proto_tree_add_uint(name_tree, *bitmap_info->hf_mask_label, tvb,
6545
0
              mask_offset, 4, bitmap);
6546
0
        } else {
6547
          /* Get header field to add the mask index to the field name */
6548
0
          hfinfo = proto_registrar_get_nth(*bitmap_info->hf_mask_label);
6549
0
          bitmap_item = proto_tree_add_uint_format(name_tree, *bitmap_info->hf_mask_label, tvb,
6550
0
              mask_offset, 4, bitmap, "%s[%u]: 0x%08x", hfinfo->name, i, bitmap);
6551
0
        }
6552
0
        bitmap_tree = proto_item_add_subtree(bitmap_item, ett_nfs4_bitmap);
6553
0
        first_attr = true;
6554
6555
0
        if (bitmap_info->hf_item_count) {
6556
          /* Count the number of attribute bits set */
6557
0
          for (j = 0, count = 0; j < 32; j++)
6558
0
            count += ((bitmap >> j) & 1);
6559
0
          hfinfo = proto_registrar_get_nth(*bitmap_info->hf_item_count);
6560
0
          attr_count = proto_tree_add_uint_format(bitmap_tree, *bitmap_info->hf_item_count, tvb, mask_offset,
6561
0
              4, count, "%u %s%s", count, hfinfo->name, plurality(count, "", "s"));
6562
0
          proto_item_set_hidden(attr_count);
6563
0
          proto_item_set_generated(attr_count);
6564
0
        }
6565
0
      }
6566
6567
0
      for (j = 0; j < 32; j++) {
6568
0
        bit_num = 32*i + j;
6569
0
        bit_set = ((bitmap >> j) & 1);
6570
0
        if (bit_set) {
6571
0
          if (bitmap_tree) {
6572
0
            if (bitmap_info->vse_names_ext) {
6573
              /* Append this attribute name to the 'attr mask' header line */
6574
0
              proto_item_append_text(bitmap_tree, (first_attr ? " (%s" : ", %s"),
6575
0
                val_to_str_ext(pinfo->pool, bit_num, bitmap_info->vse_names_ext, "Unknown: %u"));
6576
0
              first_attr = false;
6577
0
            }
6578
6579
            /* Get correct item label */
6580
0
            if (bitmap_info->get_item_label)
6581
0
              hf_item = bitmap_info->get_item_label(bit_num);
6582
0
            else if (bitmap_info->hf_item_label)
6583
0
              hf_item = *bitmap_info->hf_item_label;
6584
6585
0
            if (hf_item > 0) {
6586
              /* Display label */
6587
0
              attr_item = proto_tree_add_uint(bitmap_tree, hf_item, tvb, offset, 0, bit_num);
6588
0
            }
6589
0
          }
6590
6591
0
          attr_offset = offset;
6592
6593
0
          if (skip_attr_values && attr_item) {
6594
            /* Skip dissecting anymore attribute values since
6595
             * a previous attribute value was not dissected */
6596
0
            attr_tree = proto_item_add_subtree(attr_item, ett_nfs4_bitmap);
6597
0
            expert_add_info(pinfo, attr_tree, &ei_nfs_bitmap_skip_value);
6598
0
          } else if (type == NFS4_BITMAP_VALUES && attr_item) {
6599
            /* Display bit value */
6600
0
            attr_tree = proto_item_add_subtree(attr_item, ett_nfs4_bitmap);
6601
0
            if (bitmap_info->dissect_battr)
6602
0
              offset = bitmap_info->dissect_battr(tvb, offset, pinfo, civ, opcode, fh_idx,
6603
0
                  attr_tree, attr_item, bit_num, bitmap_info->battr_data);
6604
0
            if (offset == attr_offset) {
6605
              /* No value was dissected, this attribute is most likely not
6606
               * supported yet so stop dissecting the rest of the bitmap data */
6607
0
              expert_add_info(pinfo, attr_tree, &ei_nfs_bitmap_no_dissector);
6608
0
              skip_attr_values = true;
6609
0
            }
6610
0
          }
6611
6612
0
          if (attr_item)
6613
0
            proto_item_set_len(attr_item, offset - attr_offset);
6614
0
        }
6615
0
      }
6616
6617
0
      if (bitmap_tree && !first_attr)
6618
0
        proto_item_append_text(bitmap_tree, ")");
6619
0
    }
6620
0
    mask_offset += 4;
6621
0
  }
6622
6623
0
  if (type == NFS4_BITMAP_VALUES) {
6624
0
    count = end_offset - offset;
6625
0
    if (bitmap_info->hf_btmap_data && offset == opaque_offset) {
6626
      /* Display opaque data */
6627
0
      offset = dissect_nfsdata(tvb, pinfo, offset-4, name_tree, *bitmap_info->hf_btmap_data);
6628
0
    } else if (count == opaque_padding) {
6629
      /* Everything is good, just consume the padding bytes */
6630
0
      offset += opaque_padding;
6631
0
    } else if (count > 0) {
6632
      /* There are still bytes remaining from the opaque
6633
       * just consume the bytes */
6634
0
      expert_add_info(pinfo, name_tree, &ei_nfs_bitmap_undissected_data);
6635
0
      offset = dissect_rpc_bytes(tvb, pinfo, name_tree, hf_nfs4_bitmap_data, offset, count, false, NULL);
6636
0
    }
6637
0
  }
6638
6639
0
  return offset;
6640
0
}
6641
6642
6643
/*
6644
 * When using RPC-over-RDMA, certain opaque data are eligible for DDP
6645
 * (direct data placement), so these must be reduced by sending just
6646
 * the opaque length with the rest of the NFS packet and the opaque
6647
 * data is sent separately using RDMA (RFC 8267).
6648
 */
6649
static unsigned
6650
dissect_nfsdata_reduced(rdma_reduce_type_t rtype, tvbuff_t *tvb, packet_info* pinfo, unsigned offset,
6651
      proto_tree *tree, int hf, const char **name)
6652
0
{
6653
0
  if (rpcrdma_is_reduced()) {
6654
    /*
6655
     * The opaque data is reduced so just increment the offset
6656
     * since there is no actual data yet.
6657
     */
6658
0
    offset += 4;
6659
    /* Add offset (from the end) where the opaque data should be */
6660
0
    rpcrdma_insert_offset(tvb_reported_length_remaining(tvb, offset));
6661
0
    if (name) {
6662
      /* Return non-NULL string */
6663
0
      *name = "";
6664
0
    }
6665
0
  } else {
6666
    /* No data reduction, dissect the opaque data */
6667
0
    switch (rtype) {
6668
0
      case R_UTF8STRING:
6669
0
        offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf, name);
6670
0
        break;
6671
0
      case R_NFS2_PATH:
6672
0
        offset = dissect_path(tvb, pinfo, offset, tree, hf, name);
6673
0
        break;
6674
0
      case R_NFS3_PATH:
6675
0
        offset = dissect_nfs3_path(tvb, pinfo, offset, tree, hf, name);
6676
0
        break;
6677
0
      case R_NFSDATA:
6678
0
        offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf);
6679
0
        break;
6680
0
    }
6681
0
  }
6682
0
  return offset;
6683
0
}
6684
6685
6686
static unsigned
6687
dissect_nfs4_deviceid(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
6688
0
{
6689
0
  proto_tree_add_item(tree, hf_nfs4_deviceid, tvb, offset, 16, ENC_NA);
6690
0
  offset += 16;
6691
0
  return offset;
6692
0
}
6693
6694
6695
static unsigned
6696
dissect_nfs4_sessionid(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
6697
0
{
6698
0
  proto_tree_add_item(tree, hf_nfs4_sessionid, tvb, offset, 16, ENC_NA);
6699
0
  offset += 16;
6700
0
  return offset;
6701
0
}
6702
6703
6704
static unsigned
6705
dissect_nfs4_specdata(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
6706
0
{
6707
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_specdata1, offset);
6708
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_specdata2, offset);
6709
0
  return offset;
6710
0
}
6711
6712
static const value_string names_ftype4[] = {
6713
  { NF4REG,   "NF4REG"  },
6714
  { NF4DIR,   "NF4DIR"  },
6715
  { NF4BLK,   "NF4BLK"  },
6716
  { NF4CHR,   "NF4CHR"  },
6717
  { NF4LNK,   "NF4LNK"  },
6718
  { NF4SOCK,  "NF4SOCK" },
6719
  { NF4FIFO,  "NF4FIFO" },
6720
  { NF4ATTRDIR, "NF4ATTRDIR"  },
6721
  { NF4NAMEDATTR, "NF4NAMEDATTR"  },
6722
  { 0,  NULL }
6723
};
6724
6725
6726
static unsigned
6727
dissect_nfs4_lock_owner(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
6728
0
{
6729
0
  proto_tree *newftree;
6730
6731
0
  newftree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_nfs4_lock_owner, NULL, "Owner");
6732
0
  offset   = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
6733
0
  offset   = dissect_nfsdata(tvb, pinfo, offset, newftree, hf_nfs4_lock_owner);
6734
6735
0
  return offset;
6736
0
}
6737
6738
6739
static unsigned
6740
dissect_nfs4_pathname(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
6741
0
{
6742
0
  uint32_t      comp_count, i;
6743
0
  proto_item *fitem;
6744
0
  proto_tree *newftree;
6745
6746
0
  fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_pathname_components, tvb, offset, 4, ENC_BIG_ENDIAN, &comp_count);
6747
0
  offset += 4;
6748
6749
0
  newftree = proto_item_add_subtree(fitem, ett_nfs4_pathname);
6750
6751
0
  for (i = 0; i < comp_count; i++)
6752
0
    offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, NULL);
6753
0
  return offset;
6754
0
}
6755
6756
6757
static unsigned
6758
dissect_nfs4_nfstime(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
6759
0
{
6760
0
  nstime_t ts;
6761
0
  proto_item *item;
6762
6763
0
  ts.secs = tvb_get_ntoh64(tvb, offset+0);
6764
0
  ts.nsecs = tvb_get_ntohl(tvb, offset+8);
6765
0
  item = proto_tree_add_time(tree, hf_nfs4_time, tvb, offset, 12, &ts);
6766
0
  tree = proto_item_add_subtree(item, ett_nfs4_nfstime);
6767
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_time_seconds, offset);
6768
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_time_nseconds, offset);
6769
6770
0
  return offset;
6771
0
}
6772
6773
static const value_string names_time_how4[] = {
6774
#define SET_TO_SERVER_TIME4 0
6775
  { SET_TO_SERVER_TIME4,  "SET_TO_SERVER_TIME4" },
6776
0
#define SET_TO_CLIENT_TIME4 1
6777
  { SET_TO_CLIENT_TIME4,  "SET_TO_CLIENT_TIME4" },
6778
  { 0,  NULL  }
6779
};
6780
6781
static unsigned
6782
dissect_nfs4_settime(tvbuff_t *tvb, unsigned offset,
6783
         proto_tree *tree, const char *name _U_)
6784
0
{
6785
0
  uint32_t set_it;
6786
6787
0
  proto_tree_add_item_ret_uint(tree, hf_nfs4_time_how4, tvb, offset+0, 4, ENC_BIG_ENDIAN, &set_it);
6788
0
  offset += 4;
6789
6790
0
  if (set_it == SET_TO_CLIENT_TIME4)
6791
0
    offset = dissect_nfs4_nfstime(tvb, offset, tree);
6792
6793
0
  return offset;
6794
0
}
6795
6796
static unsigned
6797
dissect_nfs4_fsid(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
6798
0
{
6799
0
  proto_tree *newftree;
6800
6801
0
  newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_fsid, NULL, name);
6802
0
  offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_fsid_major, offset);
6803
0
  offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_fsid_minor, offset);
6804
0
  return offset;
6805
0
}
6806
6807
/* ACE type values  */
6808
static const value_string names_acetype4[] = {
6809
#define ACE4_TYPE_ACCESS_ALLOWED  0x00000000
6810
  { ACE4_TYPE_ACCESS_ALLOWED, "Access_Allowed"  },
6811
#define ACE4_TYPE_ACCESS_DENIED   0x00000001
6812
  { ACE4_TYPE_ACCESS_DENIED,  "access_denied" },
6813
#define ACE4_TYPE_SYSTEM_AUDIT    0x00000002
6814
  { ACE4_TYPE_SYSTEM_AUDIT,   "system_audit" },
6815
#define ACE4_TYPE_SYSTEM_ALARM    0x00000003
6816
  { ACE4_TYPE_SYSTEM_ALARM,   "system_alarm" },
6817
  { 0,  NULL }
6818
};
6819
6820
/* ACE flag values */
6821
16
#define ACE4_FLAG_FILE_INHERIT             0x00000001
6822
16
#define ACE4_FLAG_DIRECTORY_INHERIT        0x00000002
6823
16
#define ACE4_FLAG_NO_PROPAGATE_INHERIT     0x00000004
6824
16
#define ACE4_FLAG_INHERIT_ONLY             0x00000008
6825
16
#define ACE4_FLAG_SUCCESSFUL_ACCESS        0x00000010
6826
16
#define ACE4_FLAG_FAILED_ACCESS            0x00000020
6827
16
#define ACE4_FLAG_IDENTIFIER_GROUP         0x00000040
6828
16
#define ACE4_FLAG_INHERITED_ACE            0x00000080
6829
6830
static unsigned
6831
dissect_nfs_aceflags4(tvbuff_t *tvb, unsigned offset, packet_info *pinfo _U_, proto_tree *ace_tree)
6832
0
{
6833
0
    static int * const flags[] = {
6834
0
        &hf_nfs4_aceflag_file_inherit,
6835
0
        &hf_nfs4_aceflag_dir_inherit,
6836
0
        &hf_nfs4_aceflag_no_prop_inherit,
6837
0
        &hf_nfs4_aceflag_inherit_only,
6838
0
        &hf_nfs4_aceflag_successful_access,
6839
0
        &hf_nfs4_aceflag_failed_access,
6840
0
        &hf_nfs4_aceflag_id_group,
6841
0
        &hf_nfs4_aceflag_inherited_ace,
6842
0
        NULL
6843
0
    };
6844
6845
0
    proto_tree_add_bitmask(ace_tree, tvb, offset, hf_nfs4_aceflags, ett_nfs4_aceflag, flags, ENC_BIG_ENDIAN);
6846
6847
0
    offset += 4;
6848
0
    return offset;
6849
0
}
6850
6851
6852
/* ACE4 permissions for files */
6853
static const value_string  acemask4_perms_file[] = {
6854
#define ACE4_READ_DATA             0x00000001
6855
  { ACE4_READ_DATA,            "Read_Data"  },
6856
#define ACE4_WRITE_DATA            0x00000002
6857
  { ACE4_WRITE_DATA,           "Write_Data" },
6858
#define ACE4_APPEND_DATA           0x00000004
6859
  { ACE4_APPEND_DATA,          "Append_Data"  },
6860
  { 0, NULL }
6861
};
6862
/* Abbreviated ACE4 permissions for files */
6863
static const value_string  acemask4_abbrev_perms_file[] = {
6864
  { ACE4_READ_DATA,            "RdData"  },
6865
  { ACE4_WRITE_DATA,           "WrData" },
6866
  { ACE4_APPEND_DATA,          "AppData"  },
6867
  { 0, NULL }
6868
};
6869
6870
/* ACE4 permissions for dirs */
6871
static const value_string  acemask4_perms_dir[] = {
6872
#define ACE4_LIST_DIRECTORY        0x00000001
6873
  { ACE4_LIST_DIRECTORY,       "List_Dir" },
6874
#define ACE4_ADD_FILE              0x00000002
6875
  { ACE4_ADD_FILE,             "Add_File" },
6876
#define ACE4_ADD_SUBDIRECTORY      0x00000004
6877
  { ACE4_ADD_SUBDIRECTORY,     "Add_Subdir" },
6878
  { 0, NULL }
6879
};
6880
/* Abbreviated ACE4 permissions for dirs */
6881
static const value_string  acemask4_abbrev_perms_dir[] = {
6882
  { ACE4_LIST_DIRECTORY,       "LstDir" },
6883
  { ACE4_ADD_FILE,             "AddFile" },
6884
  { ACE4_ADD_SUBDIRECTORY,     "AddSubD" },
6885
  { 0, NULL }
6886
};
6887
6888
/* ACE4 permissions for objects of unknown type */
6889
static const value_string  acemask4_perms_unkwn[] = {
6890
  { ACE4_READ_DATA,            "Read_Data / List_Dir" },
6891
  { ACE4_WRITE_DATA,           "Write_Data / Add_File" },
6892
  { ACE4_APPEND_DATA,          "Append_Data / Add_SubDir" },
6893
  { 0, NULL }
6894
};
6895
/* Abbreviated ACE4 permissions for objects of unknown type */
6896
static const value_string  acemask4_abbrev_perms_unkwn[] = {
6897
  { ACE4_READ_DATA,            "RdData/LstDir" },
6898
  { ACE4_WRITE_DATA,           "WrData/AddFile" },
6899
  { ACE4_APPEND_DATA,          "AppData/AddSubD" },
6900
  { 0, NULL }
6901
};
6902
6903
/* ACE4 permissions for object types 0x8 and above */
6904
static const value_string  acemask4_perms_8_and_above[] = {
6905
#define ACE4_READ_NAMED_ATTRS      0x00000008
6906
  { ACE4_READ_NAMED_ATTRS,     "Read_Named_Attrs" },
6907
#define ACE4_WRITE_NAMED_ATTRS     0x00000010
6908
  { ACE4_WRITE_NAMED_ATTRS,    "Write_Named_Attrs" },
6909
#define ACE4_EXECUTE               0x00000020
6910
  { ACE4_EXECUTE,              "Execute" },
6911
#define ACE4_DELETE_CHILD          0x00000040
6912
  { ACE4_DELETE_CHILD,         "Delete_Child" },
6913
#define ACE4_READ_ATTRIBUTES       0x00000080
6914
  { ACE4_READ_ATTRIBUTES,      "Read_Attributes" },
6915
#define ACE4_WRITE_ATTRIBUTES      0x00000100
6916
  { ACE4_WRITE_ATTRIBUTES,     "Write_Attributes" },
6917
#define ACE4_WRITE_RETENTION       0x00000200
6918
  { ACE4_WRITE_RETENTION,      "Write_Retention" },
6919
#define ACE4_WRITE_RETENTION_HOLD  0x00000400
6920
  { ACE4_WRITE_RETENTION_HOLD, "Write_Retention_Hold" },
6921
#define ACE4_DELETE                0x00010000
6922
  { ACE4_DELETE,               "Delete" },
6923
#define ACE4_READ_ACL              0x00020000
6924
  { ACE4_READ_ACL,             "Read_ACL" },
6925
#define ACE4_WRITE_ACL             0x00040000
6926
  { ACE4_WRITE_ACL,            "Write_ACL" },
6927
#define ACE4_WRITE_OWNER           0x00080000
6928
  { ACE4_WRITE_OWNER,          "Write_Owner" },
6929
0
#define ACE4_SYNCHRONIZE           0x00100000
6930
  { ACE4_SYNCHRONIZE,          "Synchronize" },
6931
  { 0, NULL }
6932
};
6933
static value_string_ext acemask4_perms_8_and_above_ext = VALUE_STRING_EXT_INIT(acemask4_perms_8_and_above);
6934
6935
/* Abbreviated ACE4 permissions for object types 0x8 and above */
6936
static const value_string  acemask4_abbrev_perms_8_and_above[] = {
6937
  { ACE4_READ_NAMED_ATTRS,     "RdNamAt" },
6938
  { ACE4_WRITE_NAMED_ATTRS,    "WrNamAt" },
6939
  { ACE4_EXECUTE,              "Exec" },
6940
  { ACE4_DELETE_CHILD,         "DelChld" },
6941
  { ACE4_READ_ATTRIBUTES,      "RdAttrs" },
6942
  { ACE4_WRITE_ATTRIBUTES,     "WrAttrs" },
6943
  { ACE4_WRITE_RETENTION,      "WrRet" },
6944
  { ACE4_WRITE_RETENTION_HOLD, "WrRetHld" },
6945
  { ACE4_DELETE,               "Del" },
6946
  { ACE4_READ_ACL,             "RdACL" },
6947
  { ACE4_WRITE_ACL,            "WrACL" },
6948
  { ACE4_WRITE_OWNER,          "WrOwn" },
6949
  { ACE4_SYNCHRONIZE,          "Sync" },
6950
  { 0, NULL }
6951
};
6952
static value_string_ext acemask4_abbrev_perms_8_and_above_ext = VALUE_STRING_EXT_INIT(acemask4_abbrev_perms_8_and_above);
6953
6954
static unsigned
6955
dissect_nfs4_acemask(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *ace_tree, uint32_t acetype4, uint32_t obj_type)
6956
0
{
6957
0
  const char *type   = NULL;
6958
0
  const char *atype  = NULL;
6959
0
  uint32_t       acemask   = tvb_get_ntohl(tvb, offset);
6960
0
  uint32_t       acemask_bit = 1;
6961
0
  bool         first_perm  = true;
6962
0
  proto_item  *acemask_item;
6963
0
  proto_tree  *acemask_tree;
6964
6965
0
  acemask_item = proto_tree_add_uint(ace_tree, hf_nfs4_acemask, tvb, offset, 4, acemask);
6966
0
  acemask_tree = proto_item_add_subtree(acemask_item, ett_nfs4_acemask);
6967
0
  proto_item_append_text(acemask_item, "  (");
6968
6969
0
  while (acemask_bit <= ACE4_SYNCHRONIZE)
6970
0
  {
6971
0
    if (acemask_bit & acemask) {
6972
0
      if (acemask_bit <= 0x4) {
6973
0
        if (obj_type) {
6974
0
          if  (obj_type == NF4REG) {
6975
0
            type = val_to_str(pinfo->pool, acemask_bit, acemask4_perms_file, "Unknown: %u");
6976
0
            atype = val_to_str(pinfo->pool, acemask_bit, acemask4_abbrev_perms_file, "Unknown: %u");
6977
0
          } else if (obj_type == NF4DIR) {
6978
0
            type = val_to_str(pinfo->pool, acemask_bit, acemask4_perms_dir, "Unknown: %u");
6979
0
            atype = val_to_str(pinfo->pool, acemask_bit, acemask4_abbrev_perms_dir, "Unknown: %u");
6980
0
          } else {
6981
0
            type = val_to_str(pinfo->pool, acemask_bit, acemask4_perms_unkwn, "Unknown: %u");
6982
0
            atype = val_to_str(pinfo->pool, acemask_bit, acemask4_abbrev_perms_unkwn, "Unknown: %u");
6983
0
          }
6984
0
        } else {
6985
0
          type = val_to_str(pinfo->pool, acemask_bit, acemask4_perms_unkwn, "Unknown: %u");
6986
0
          atype = val_to_str(pinfo->pool, acemask_bit, acemask4_abbrev_perms_unkwn, "Unknown: %u");
6987
0
        }
6988
0
      } else {
6989
0
        type = val_to_str_ext(pinfo->pool, acemask_bit, &acemask4_perms_8_and_above_ext, "Unknown: %u");
6990
0
        atype = val_to_str_ext(pinfo->pool, acemask_bit, &acemask4_abbrev_perms_8_and_above_ext, "Unknown: %u");
6991
0
      }
6992
0
      proto_tree_add_uint_format(acemask_tree, hf_nfs4_ace_permission, tvb, offset, 4,
6993
0
        acemask_bit, "%s: %s (0x%08x)", val_to_str(pinfo->pool, acetype4, names_acetype4, "Unknown: %u"), type, acemask_bit);
6994
0
      proto_item_append_text(acemask_item, first_perm ? "%s" : ", %s", atype);
6995
0
      first_perm = false;
6996
0
    }
6997
0
    acemask_bit <<= 1;
6998
0
  }
6999
0
  proto_item_append_text(acemask_item, ")");
7000
7001
0
  offset += 4;
7002
7003
0
  return offset;
7004
0
}
7005
7006
/* Decode exactly one ACE (type, flags, mask, permissions, and who) */
7007
static unsigned
7008
dissect_nfs4_ace(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, int ace_number,
7009
         uint32_t obj_type)
7010
0
{
7011
0
  uint32_t      acetype4 = 0;
7012
0
  const char *acetype4_str;
7013
0
  proto_tree *ace_tree = NULL;
7014
7015
0
  if (tree) {
7016
0
    proto_item *ace_item = NULL;
7017
7018
0
    acetype4 = tvb_get_ntohl(tvb, offset);
7019
0
    acetype4_str = val_to_str(pinfo->pool, acetype4, names_acetype4, "Unknown: %u");
7020
7021
    /* Display the ACE type and create a subtree for this ACE */
7022
0
    if (ace_number == 0) {
7023
0
      ace_item = proto_tree_add_uint_format(tree, hf_nfs4_acetype, tvb, offset, 4,
7024
0
        acetype4, "ACE Type: %s (%u)", acetype4_str, acetype4);
7025
0
    } else {
7026
0
      ace_item = proto_tree_add_uint_format(tree, hf_nfs4_acetype, tvb, offset, 4,
7027
0
        acetype4, "%u. ACE Type: %s (%u)", ace_number, acetype4_str, acetype4);
7028
0
    }
7029
0
    ace_tree = proto_item_add_subtree(ace_item, ett_nfs4_ace);
7030
0
  }
7031
7032
0
  offset += 4;
7033
7034
0
  if (tree) {
7035
0
    offset = dissect_nfs_aceflags4(tvb, offset, pinfo, ace_tree);
7036
0
    offset = dissect_nfs4_acemask(tvb, pinfo, offset, ace_tree, acetype4, obj_type);
7037
0
  } else {
7038
0
    offset += 8;
7039
0
  }
7040
7041
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, ace_tree, hf_nfs4_who, NULL);
7042
7043
0
  return offset;
7044
0
}
7045
7046
16
#define ACL4_AUTO_INHERIT 0x00000001
7047
16
#define ACL4_PROTECTED    0x00000002
7048
16
#define ACL4_DEFAULTED    0x00000004
7049
7050
static int * const aclflags_fields[] = {
7051
  &hf_nfs4_aclflag_auto_inherit,
7052
  &hf_nfs4_aclflag_protected,
7053
  &hf_nfs4_aclflag_defaulted,
7054
  NULL
7055
};
7056
7057
static unsigned
7058
dissect_nfs4_aclflags(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
7059
0
{
7060
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_aclflags,
7061
0
    ett_nfs4_aclflag, aclflags_fields, ENC_BIG_ENDIAN);
7062
0
  offset += 4;
7063
7064
0
  return offset;
7065
0
}
7066
7067
static unsigned
7068
dissect_nfs4_fattr_acl(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_item *attr_item,
7069
           proto_tree *tree, uint32_t obj_type, uint32_t attr_num)
7070
0
{
7071
0
  uint32_t num_aces;
7072
0
  uint32_t ace_number;
7073
7074
0
  if (attr_num != FATTR4_ACL)
7075
0
    offset = dissect_nfs4_aclflags(tvb, offset, tree);
7076
7077
0
  num_aces = tvb_get_ntohl(tvb, offset);
7078
0
  if (tree && num_aces > 0) {
7079
0
    proto_tree_add_uint(tree, hf_nfs4_num_aces, tvb, offset, 4, num_aces);
7080
0
    proto_item_append_text(attr_item, " (%u ACEs)", num_aces);
7081
0
  }
7082
0
  offset += 4;
7083
7084
  /* Tree or not, this for loop is required due dissect_nfs_utf8string() call */
7085
0
  for (ace_number = 1; ace_number<=num_aces; ace_number++)
7086
0
    offset = dissect_nfs4_ace(tvb, offset, pinfo, tree, ace_number, obj_type);
7087
7088
0
  return offset;
7089
0
}
7090
7091
16
#define ACL4_SUPPORT_ALLOW_ACL  0x00000001
7092
16
#define ACL4_SUPPORT_DENY_ACL 0x00000002
7093
16
#define ACL4_SUPPORT_AUDIT_ACL  0x00000004
7094
16
#define ACL4_SUPPORT_ALARM_ACL  0x00000008
7095
7096
static int * const aclsupport_fields[] = {
7097
  &hf_nfs4_aclsupport_allow_acl,
7098
  &hf_nfs4_aclsupport_deny_acl,
7099
  &hf_nfs4_aclsupport_audit_acl,
7100
  &hf_nfs4_aclsupport_alarm_acl,
7101
  NULL
7102
};
7103
7104
static unsigned
7105
dissect_nfs4_fattr_aclsupport(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
7106
0
{
7107
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_fattr_aclsupport,
7108
0
    ett_nfs4_fattr_aclsupport, aclsupport_fields, ENC_BIG_ENDIAN);
7109
0
  offset += 4;
7110
7111
0
  return offset;
7112
0
}
7113
7114
static unsigned
7115
dissect_nfs4_fh(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
7116
    proto_tree *tree, const char *name,
7117
    uint32_t *hash, int *fh_offset_ptr, int *fh_length_ptr,
7118
    rpc_call_info_value *civ, uint32_t opcode, uint32_t fh_idx)
7119
0
{
7120
0
  int fh_offset, fh_length;
7121
7122
0
  fh_length = tvb_get_ntohl(tvb, offset);
7123
0
  fh_offset = offset+4;
7124
7125
  /* are we snooping fh to filenames ?*/
7126
0
  if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
7127
    /* NFS v4 GETFH, GETATTR and READDIR replies might give us a mapping */
7128
    /* TODO: Matching NFS v4 READDIR name entry with entry filehandle attribute and with READDIR directory name is not supported yet */
7129
0
    if (civ->prog == NFS_PROGRAM && civ->vers == 4 && !civ->request && civ->proc == 1 && (opcode == NFS4_OP_GETFH || opcode == NFS4_OP_GETATTR)) {
7130
0
      nfs_name_snoop_add_fh(((uint64_t)fh_idx << 32) | civ->xid, tvb, fh_offset, fh_length);
7131
0
    }
7132
0
  }
7133
7134
0
  if (fh_offset_ptr)
7135
0
    *fh_offset_ptr = fh_offset;
7136
0
  if (fh_length_ptr)
7137
0
    *fh_length_ptr = fh_length;
7138
7139
0
  return dissect_nfs3_fh(tvb, offset, pinfo, tree, name, hash, civ);
7140
0
}
7141
7142
7143
static int
7144
dissect_nfs4_server(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data _U_)
7145
0
{
7146
0
  return dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_server, NULL);
7147
0
}
7148
7149
7150
static int
7151
dissect_nfs4_fs_location(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data _U_)
7152
0
{
7153
0
  proto_tree *newftree;
7154
7155
0
  newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_fs_location, NULL, "fs_location4");
7156
7157
0
  offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_server, hf_nfs4_servers);
7158
0
  offset = dissect_nfs4_pathname(tvb, pinfo, offset, newftree);
7159
7160
0
  return offset;
7161
0
}
7162
7163
7164
static unsigned
7165
dissect_nfs4_fs_locations(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
7166
        proto_tree *tree, const char *name)
7167
0
{
7168
0
  proto_tree *newftree;
7169
7170
0
  newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_fs_locations, NULL, name);
7171
7172
0
  offset = dissect_nfs4_pathname(tvb, pinfo, offset, newftree);
7173
7174
0
  offset = dissect_rpc_array(tvb, pinfo, newftree, offset,
7175
0
    dissect_nfs4_fs_location, hf_nfs4_fslocation);
7176
7177
0
  return offset;
7178
0
}
7179
7180
/* RFC5661 - '14.4. UTF-8 Capabilities' */
7181
16
#define FSCHARSET_CAP4_CONTAINS_NON_UTF8  0x00000001
7182
16
#define FSCHARSET_CAP4_ALLOWS_ONLY_UTF8   0x00000002
7183
7184
static unsigned
7185
dissect_nfs4_fattr_fs_charset_cap(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
7186
0
{
7187
0
  int * const fs_charset_cap_fields[] = {
7188
0
    &hf_nfs4_fs_charset_cap_nonutf8,
7189
0
    &hf_nfs4_fs_charset_cap_utf8,
7190
0
    NULL
7191
0
  };
7192
7193
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_fattr_fs_charset_cap,
7194
0
    ett_nfs4_fattr_fs_charset_cap, fs_charset_cap_fields, ENC_BIG_ENDIAN);
7195
0
  offset += 4;
7196
7197
0
  return offset;
7198
0
}
7199
7200
static unsigned
7201
dissect_nfs4_mode(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
7202
0
{
7203
0
  static int * const modes[] = {
7204
0
    &hf_nfs2_mode_set_user_id,
7205
0
    &hf_nfs2_mode_set_group_id,
7206
0
    &hf_nfs2_mode_save_swap_text,
7207
0
    &hf_nfs2_mode_read_owner,
7208
0
    &hf_nfs2_mode_write_owner,
7209
0
    &hf_nfs2_mode_exec_owner,
7210
0
    &hf_nfs2_mode_read_group,
7211
0
    &hf_nfs2_mode_write_group,
7212
0
    &hf_nfs2_mode_exec_group,
7213
0
    &hf_nfs2_mode_read_other,
7214
0
    &hf_nfs2_mode_write_other,
7215
0
    &hf_nfs2_mode_exec_other,
7216
0
    NULL
7217
0
  };
7218
7219
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_nfs2_mode, ett_nfs2_mode, modes, ENC_BIG_ENDIAN);
7220
7221
0
  offset += 4;
7222
0
  return offset;
7223
0
}
7224
7225
0
#define FH4_PERSISTENT         0x00000000
7226
16
#define FH4_NOEXPIRE_WITH_OPEN 0x00000001
7227
16
#define FH4_VOLATILE_ANY       0x00000002
7228
16
#define FH4_VOL_MIGRATION      0x00000004
7229
16
#define FH4_VOL_RENAME         0x00000008
7230
7231
static const value_string nfs4_fattr4_fh_expire_type_names[] = {
7232
  { FH4_PERSISTENT, "FH4_PERSISTENT" },
7233
  { 0, NULL }
7234
};
7235
7236
static int * const nfs4_fattr_fh_expire_type_fields[] = {
7237
  &hf_nfs4_fattr_fh_expiry_noexpire_with_open,
7238
  &hf_nfs4_fattr_fh_expiry_volatile_any,
7239
  &hf_nfs4_fattr_fh_expiry_vol_migration,
7240
  &hf_nfs4_fattr_fh_expiry_vol_rename,
7241
  NULL
7242
};
7243
7244
static unsigned
7245
dissect_nfs4_fattr_fh_expire_type(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
7246
0
{
7247
0
  uint32_t    expire_type;
7248
7249
0
  expire_type = tvb_get_ntohl(tvb, offset + 0);
7250
7251
0
  if (expire_type == FH4_PERSISTENT)
7252
0
    proto_tree_add_item(tree, hf_nfs4_fattr_fh_expire_type, tvb, offset, 4, ENC_BIG_ENDIAN);
7253
0
  else
7254
0
    proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_fattr_fh_expire_type,
7255
0
      ett_nfs4_fattr_fh_expire_type, nfs4_fattr_fh_expire_type_fields,
7256
0
      ENC_BIG_ENDIAN);
7257
7258
0
  offset += 4;
7259
7260
0
  return offset;
7261
0
}
7262
7263
7264
static unsigned
7265
dissect_nfs_fs_layout_type(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
7266
0
{
7267
0
  unsigned count, i;
7268
7269
0
  count = tvb_get_ntohl(tvb, offset);
7270
0
  offset += 4;
7271
7272
0
  for (i = 0; i < count; i++)
7273
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
7274
7275
0
  return offset;
7276
0
}
7277
7278
7279
static const value_string th4_names_file[] = {
7280
0
#define TH4_READ_SIZE             0
7281
  { TH4_READ_SIZE,    "Read_Size"   },
7282
0
#define TH4_WRITE_SIZE            1
7283
  { TH4_WRITE_SIZE,   "Write_Size"    },
7284
0
#define TH4_READ_IOSIZE           2
7285
  { TH4_READ_IOSIZE,  "Read_IO_Size"    },
7286
0
#define TH4_WRITE_IOSIZE          3
7287
  { TH4_WRITE_IOSIZE, "Write_IO_Size"   },
7288
  { 0,  NULL  }
7289
};
7290
static value_string_ext th4_names_ext_file = VALUE_STRING_EXT_INIT(th4_names_file);
7291
7292
7293
/* Dissect the threshold_item4 bit attribute for the files layout type */
7294
static unsigned
7295
dissect_nfs4_threshold_item_file(tvbuff_t *tvb, unsigned offset, packet_info *pinfo _U_,
7296
    rpc_call_info_value *civ _U_, uint32_t opcode _U_, uint32_t fh_idx _U_,
7297
    proto_tree *attr_tree, proto_item *attr_item _U_,
7298
    uint32_t bit_num, void *battr_data _U_)
7299
0
{
7300
0
  uint64_t size;
7301
7302
0
  switch (bit_num) {
7303
0
    case TH4_READ_SIZE:
7304
0
    case TH4_WRITE_SIZE:
7305
0
    case TH4_READ_IOSIZE:
7306
0
    case TH4_WRITE_IOSIZE:
7307
0
      size = tvb_get_ntoh64(tvb, offset);
7308
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_length, offset);
7309
0
      proto_item_append_text(attr_tree, " = %" PRIu64, size);
7310
0
      break;
7311
0
  }
7312
0
  return offset;
7313
0
}
7314
7315
7316
/* Dissect the threshold_item4 structure */
7317
static int
7318
dissect_nfs4_threshold_item(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data)
7319
0
{
7320
0
  uint32_t layout_type;
7321
0
  static nfs4_bitmap_info_t *bitmap_info_p;
7322
7323
  /* Bitmap info for the files layout type */
7324
0
  static nfs4_bitmap_info_t bitmap_info_files = {
7325
0
    .vse_names_ext = &th4_names_ext_file,
7326
0
    .dissect_battr = dissect_nfs4_threshold_item_file,
7327
0
    .hf_mask_label = &hf_nfs4_mdsthreshold_hint_mask,
7328
0
    .hf_item_label = &hf_nfs4_mdsthreshold_hint_file,
7329
0
    .hf_item_count = &hf_nfs4_mdsthreshold_hint_count,
7330
0
    .hf_mask_count = &hf_nfs4_mdsthreshold_mask_count
7331
0
  };
7332
7333
  /* Bitmap info for an unsupported layout type,
7334
   * just display the bitmap mask and its data */
7335
0
  static nfs4_bitmap_info_t bitmap_info_default = {
7336
0
    .hf_mask_label = &hf_nfs4_mdsthreshold_hint_mask,
7337
0
    .hf_mask_count = &hf_nfs4_mdsthreshold_mask_count,
7338
0
    .hf_btmap_data = &hf_nfs4_bitmap_data,
7339
0
  };
7340
7341
  /* Get layout type */
7342
0
  layout_type = tvb_get_ntohl(tvb, offset);
7343
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
7344
7345
0
  switch (layout_type) {
7346
0
    case LAYOUT4_NFSV4_1_FILES:
7347
0
      bitmap_info_p = &bitmap_info_files;
7348
0
      break;
7349
0
    default:
7350
0
      bitmap_info_p = &bitmap_info_default;
7351
0
      break;
7352
0
  }
7353
0
  return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, (rpc_call_info_value *)data, -1, -1, bitmap_info_p, NFS4_BITMAP_VALUES, NULL);
7354
0
}
7355
7356
7357
/* Dissect the fattr4_mdsthreshold structure */
7358
static unsigned
7359
dissect_nfs4_mdsthreshold(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, proto_tree *tree)
7360
0
{
7361
0
  int mds_offset = offset;
7362
7363
0
  offset = dissect_rpc_array(tvb, pinfo, tree, offset,
7364
0
    dissect_nfs4_threshold_item, hf_nfs4_mdsthreshold_item);
7365
0
  proto_item_set_len(tree, offset - mds_offset);
7366
7367
0
  return offset;
7368
0
}
7369
7370
7371
static unsigned
7372
dissect_nfs4_security_label(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset)
7373
0
{
7374
7375
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_security_label_lfs, offset);
7376
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_security_label_pi, offset);
7377
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree,
7378
0
    hf_nfs4_fattr_security_label_context, NULL);
7379
7380
0
  return offset;
7381
0
}
7382
7383
static unsigned
7384
dissect_nfs4_mode_umask(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
7385
0
{
7386
0
  offset = dissect_nfs4_mode(tvb, offset, tree);
7387
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_umask_mask, offset);
7388
0
  return offset;
7389
0
}
7390
7391
0
#define FATTR4_BITMAP_ONLY 0
7392
0
#define FATTR4_DISSECT_VALUES 1
7393
7394
#define CHANGE_TYPE_IS_MONOTONIC_INCR 0
7395
#define CHANGE_TYPE_IS_VERSION_COUNTER 1
7396
#define CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS 2
7397
#define CHANGE_TYPE_IS_TIME_METADATA 3
7398
#define CHANGE_TYPE_IS_UNDEFINED 4
7399
7400
static const value_string names_nfs_change_attr_types[] =
7401
{
7402
  { CHANGE_TYPE_IS_MONOTONIC_INCR,  "CHANGE_TYPE_IS_MONOTONIC_INCR" },
7403
  { CHANGE_TYPE_IS_VERSION_COUNTER, "CHANGE_TYPE_IS_VERSION_COUNTER"  },
7404
  { CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS,  "CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS" },
7405
  { CHANGE_TYPE_IS_TIME_METADATA, "CHANGE_TYPE_IS_TIME_METADATA"  },
7406
  { CHANGE_TYPE_IS_UNDEFINED, "CHANGE_TYPE_IS_UNDEFINED"  },
7407
  { 0,  NULL  }
7408
};
7409
7410
static unsigned
7411
dissect_nfs4_fattrs(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, int type, rpc_call_info_value *civ, uint32_t opcode, uint32_t fh_idx);
7412
7413
/* Display attribute as either required or recommended */
7414
static unsigned
7415
nfs4_fattr_item_label(uint32_t attr_num)
7416
0
{
7417
0
  return (attr_num <= FATTR4_RDATTR_ERROR ||
7418
0
    attr_num == FATTR4_FILEHANDLE ||
7419
0
    attr_num == FATTR4_SUPPATTR_EXCLCREAT) ?
7420
0
    hf_nfs4_reqd_attr: hf_nfs4_reco_attr;
7421
7422
0
}
7423
7424
/* Dissect the value of the attribute given by attr_num */
7425
static unsigned
7426
dissect_nfs4_fattr_value(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
7427
    rpc_call_info_value *civ, uint32_t opcode, uint32_t fh_idx,
7428
    proto_tree *attr_tree,
7429
    proto_item *attr_item, uint32_t attr_num, void *battr_data)
7430
0
{
7431
0
  uint32_t *fattr_obj_type_p = (uint32_t *)battr_data;
7432
0
  switch (attr_num) {
7433
0
    case FATTR4_SUPPORTED_ATTRS:
7434
0
    case FATTR4_SUPPATTR_EXCLCREAT:
7435
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, attr_tree, FATTR4_BITMAP_ONLY, civ, opcode, fh_idx);
7436
0
      break;
7437
7438
0
    case FATTR4_TYPE:
7439
0
      *fattr_obj_type_p = tvb_get_ntohl(tvb, offset);
7440
0
      if (attr_tree)
7441
0
        proto_tree_add_item(attr_tree, hf_nfs4_ftype, tvb, offset, 4,
7442
0
          ENC_BIG_ENDIAN);
7443
0
      offset += 4;
7444
0
      break;
7445
7446
0
    case FATTR4_FH_EXPIRE_TYPE:
7447
0
      offset = dissect_nfs4_fattr_fh_expire_type(tvb, offset, attr_tree);
7448
0
      break;
7449
7450
0
    case FATTR4_CHANGE:
7451
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_changeid, offset);
7452
0
      break;
7453
7454
0
    case FATTR4_SIZE:
7455
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_size, offset);
7456
0
      break;
7457
7458
0
    case FATTR4_LINK_SUPPORT:
7459
0
      offset = dissect_rpc_bool(tvb,
7460
0
        attr_tree, hf_nfs4_fattr_link_support, offset);
7461
0
      break;
7462
7463
0
    case FATTR4_SYMLINK_SUPPORT:
7464
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_symlink_support, offset);
7465
0
      break;
7466
7467
0
    case FATTR4_NAMED_ATTR:
7468
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_named_attr, offset);
7469
0
      break;
7470
7471
0
    case FATTR4_FSID:
7472
0
      offset = dissect_nfs4_fsid(tvb, offset, attr_tree, "fattr4_fsid");
7473
0
      break;
7474
7475
0
    case FATTR4_UNIQUE_HANDLES:
7476
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_unique_handles, offset);
7477
0
      break;
7478
7479
0
    case FATTR4_LEASE_TIME:
7480
0
      offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_lease_time, offset);
7481
0
      break;
7482
7483
0
    case FATTR4_RDATTR_ERROR:
7484
0
      offset = dissect_nfs4_status(tvb, offset, attr_tree, NULL);
7485
0
      break;
7486
7487
0
    case FATTR4_ACL:
7488
0
    case FATTR4_DACL:
7489
0
    case FATTR4_SACL:
7490
0
      offset = dissect_nfs4_fattr_acl(tvb, offset, pinfo, attr_item, attr_tree,
7491
0
        *fattr_obj_type_p, attr_num);
7492
0
      break;
7493
7494
0
    case FATTR4_ACLSUPPORT:
7495
0
      offset = dissect_nfs4_fattr_aclsupport(tvb, offset, attr_tree);
7496
0
      break;
7497
7498
0
    case FATTR4_ARCHIVE:
7499
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_archive, offset);
7500
0
      break;
7501
7502
0
    case FATTR4_CANSETTIME:
7503
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_cansettime, offset);
7504
0
      break;
7505
7506
0
    case FATTR4_CASE_INSENSITIVE:
7507
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_case_insensitive, offset);
7508
0
      break;
7509
7510
0
    case FATTR4_CASE_PRESERVING:
7511
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_case_preserving, offset);
7512
0
      break;
7513
7514
0
    case FATTR4_CHOWN_RESTRICTED:
7515
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_chown_restricted, offset);
7516
0
      break;
7517
7518
0
    case FATTR4_FILEID:
7519
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_fileid, offset);
7520
0
      break;
7521
7522
0
    case FATTR4_FILES_AVAIL:
7523
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_files_avail, offset);
7524
0
      break;
7525
7526
0
    case FATTR4_FILEHANDLE:
7527
0
      offset = dissect_nfs4_fh(tvb, offset, pinfo, attr_tree, "fattr4_filehandle", NULL, NULL, NULL, civ, opcode, fh_idx);
7528
0
      break;
7529
7530
0
    case FATTR4_FILES_FREE:
7531
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_files_free, offset);
7532
0
      break;
7533
7534
0
    case FATTR4_FILES_TOTAL:
7535
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_files_total, offset);
7536
0
      break;
7537
7538
0
    case FATTR4_FS_LOCATIONS:
7539
0
      offset = dissect_nfs4_fs_locations(tvb, pinfo, offset, attr_tree,
7540
0
        "fattr4_fs_locations");
7541
0
      break;
7542
7543
0
    case FATTR4_HIDDEN:
7544
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_hidden, offset);
7545
0
      break;
7546
7547
0
    case FATTR4_HOMOGENEOUS:
7548
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_homogeneous, offset);
7549
0
      break;
7550
7551
0
    case FATTR4_MAXFILESIZE:
7552
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_maxfilesize, offset);
7553
0
      break;
7554
7555
0
    case FATTR4_MAXLINK:
7556
0
      offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_maxlink, offset);
7557
0
      break;
7558
7559
0
    case FATTR4_MAXNAME:
7560
0
      offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_maxname, offset);
7561
0
      break;
7562
7563
0
    case FATTR4_MAXREAD:
7564
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_maxread, offset);
7565
0
      break;
7566
7567
0
    case FATTR4_MAXWRITE:
7568
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_maxwrite, offset);
7569
0
      break;
7570
7571
0
    case FATTR4_MIMETYPE:
7572
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, attr_tree,  hf_nfs4_fattr_mimetype,
7573
0
        NULL);
7574
0
      break;
7575
7576
0
    case FATTR4_MODE:
7577
0
      offset = dissect_nfs4_mode(tvb, offset, attr_tree);
7578
0
      break;
7579
7580
0
    case FATTR4_NO_TRUNC:
7581
0
      offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_no_trunc, offset);
7582
0
      break;
7583
7584
0
    case FATTR4_NUMLINKS:
7585
0
      offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_numlinks, offset);
7586
0
      break;
7587
7588
0
    case FATTR4_OWNER:
7589
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, attr_tree,  hf_nfs4_fattr_owner,
7590
0
        NULL);
7591
0
      break;
7592
7593
0
    case FATTR4_OWNER_GROUP:
7594
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, attr_tree,
7595
0
        hf_nfs4_fattr_owner_group, NULL);
7596
0
      break;
7597
7598
0
    case FATTR4_QUOTA_AVAIL_HARD:
7599
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_quota_hard, offset);
7600
0
      break;
7601
7602
0
    case FATTR4_QUOTA_AVAIL_SOFT:
7603
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_quota_soft, offset);
7604
0
      break;
7605
7606
0
    case FATTR4_QUOTA_USED:
7607
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_quota_used, offset);
7608
0
      break;
7609
7610
0
    case FATTR4_RAWDEV:
7611
0
      offset = dissect_nfs4_specdata(tvb, offset, attr_tree);
7612
0
      break;
7613
7614
0
    case FATTR4_SPACE_AVAIL:
7615
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_avail, offset);
7616
0
      break;
7617
7618
0
    case FATTR4_SPACE_FREE:
7619
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_free, offset);
7620
0
      break;
7621
7622
0
    case FATTR4_SPACE_TOTAL:
7623
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_total, offset);
7624
0
      break;
7625
7626
0
    case FATTR4_SPACE_USED:
7627
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_used, offset);
7628
0
      break;
7629
7630
0
    case FATTR4_SYSTEM:
7631
0
      if (attr_tree)
7632
0
        dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_system, offset);
7633
0
      offset += 4;
7634
0
      break;
7635
7636
0
    case FATTR4_TIME_ACCESS:
7637
0
    case FATTR4_TIME_BACKUP:
7638
0
    case FATTR4_TIME_CREATE:
7639
0
    case FATTR4_TIME_DELTA:
7640
0
    case FATTR4_TIME_METADATA:
7641
0
    case FATTR4_TIME_MODIFY:
7642
0
    case FATTR4_DIR_NOTIF_DELAY:
7643
0
    case FATTR4_DIRENT_NOTIF_DELAY:
7644
0
    case FATTR4_TIME_DELEG_ACCESS:
7645
0
    case FATTR4_TIME_DELEG_MODIFY:
7646
0
      if (attr_tree)
7647
0
        dissect_nfs4_nfstime(tvb, offset, attr_tree);
7648
0
      offset += 12;
7649
0
      break;
7650
7651
0
    case FATTR4_TIME_ACCESS_SET:
7652
0
    case FATTR4_TIME_MODIFY_SET:
7653
0
      offset = dissect_nfs4_settime(tvb, offset, attr_tree, "settime4");
7654
0
      break;
7655
7656
0
    case FATTR4_MOUNTED_ON_FILEID:
7657
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_mounted_on_fileid,
7658
0
             offset);
7659
0
      break;
7660
7661
0
    case FATTR4_FS_LAYOUT_TYPE:
7662
0
      offset = dissect_nfs_fs_layout_type(tvb, attr_tree, offset);
7663
0
      break;
7664
7665
0
    case FATTR4_LAYOUT_BLKSIZE:
7666
0
      offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_layout_blksize,
7667
0
            offset);
7668
0
      break;
7669
7670
0
    case FATTR4_MDSTHRESHOLD:
7671
0
      offset = dissect_nfs4_mdsthreshold(tvb, pinfo, offset, attr_tree);
7672
0
      break;
7673
7674
0
    case FATTR4_CLONE_BLOCKSIZE:
7675
0
      offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_clone_blocksize,
7676
0
            offset);
7677
0
      break;
7678
7679
0
    case FATTR4_SPACE_FREED:
7680
0
      offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_freed,
7681
0
            offset);
7682
0
      break;
7683
7684
0
    case FATTR4_CHANGE_ATTR_TYPE:
7685
0
      offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_change_attr_type,
7686
0
            offset);
7687
0
      break;
7688
7689
0
    case FATTR4_SECURITY_LABEL:
7690
0
      offset = dissect_nfs4_security_label(tvb, pinfo, attr_tree, offset);
7691
0
      break;
7692
7693
0
    case FATTR4_MODE_UMASK:
7694
0
      offset = dissect_nfs4_mode_umask(tvb, attr_tree, offset);
7695
0
      break;
7696
7697
0
    case FATTR4_XATTR_SUPPORT:
7698
0
      offset = dissect_rpc_bool(tvb,
7699
0
        attr_tree, hf_nfs4_fattr_xattr_support, offset);
7700
0
      break;
7701
7702
0
    case FATTR4_OFFLINE:
7703
0
      offset = dissect_rpc_bool(tvb,
7704
0
        attr_tree, hf_nfs4_fattr_offline, offset);
7705
0
      break;
7706
7707
0
    case FATTR4_FS_CHARSET_CAP:
7708
0
      offset = dissect_nfs4_fattr_fs_charset_cap(tvb, offset, attr_tree);
7709
0
      break;
7710
7711
0
    default:
7712
0
      break;
7713
0
  }
7714
7715
0
  return offset;
7716
0
}
7717
7718
/* Display each attrmask bitmap and optionally dissect the value. */
7719
static unsigned
7720
dissect_nfs4_fattrs(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, int type, rpc_call_info_value *civ, uint32_t opcode, uint32_t fh_idx)
7721
0
{
7722
0
  static uint32_t fattr_obj_type = 0;
7723
0
  nfs4_bitmap_type_t bitmap_type;
7724
0
  static nfs4_bitmap_info_t bitmap_info = {
7725
0
    .vse_names_ext  = &fattr4_names_ext,
7726
0
    .dissect_battr  = dissect_nfs4_fattr_value,
7727
0
    .battr_data     = &fattr_obj_type,
7728
0
    .hf_mask_label  = &hf_nfs4_attr_mask,
7729
0
    .hf_item_count  = &hf_nfs4_attr_count,
7730
0
    .get_item_label = nfs4_fattr_item_label
7731
0
  };
7732
7733
0
  fattr_obj_type = 0;
7734
0
  bitmap_type = (type == FATTR4_BITMAP_ONLY) ? NFS4_BITMAP_MASK : NFS4_BITMAP_VALUES;
7735
7736
0
  return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, civ, opcode, fh_idx, &bitmap_info, bitmap_type, NULL);
7737
0
}
7738
7739
static const value_string names_open4_share_access[] = {
7740
#define  OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE     0x0000
7741
  { OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE, "OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE" },
7742
#define OPEN4_SHARE_ACCESS_READ 0x00000001
7743
  { OPEN4_SHARE_ACCESS_READ, "OPEN4_SHARE_ACCESS_READ" },
7744
#define OPEN4_SHARE_ACCESS_WRITE 0x00000002
7745
  { OPEN4_SHARE_ACCESS_WRITE, "OPEN4_SHARE_ACCESS_WRITE" },
7746
#define OPEN4_SHARE_ACCESS_BOTH 0x00000003
7747
  { OPEN4_SHARE_ACCESS_BOTH, "OPEN4_SHARE_ACCESS_BOTH" },
7748
#define  OPEN4_SHARE_ACCESS_WANT_READ_DELEG        0x0100
7749
  { OPEN4_SHARE_ACCESS_WANT_READ_DELEG, "OPEN4_SHARE_ACCESS_WANT_READ_DELEG" },
7750
#define  OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG       0x0200
7751
  { OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG, "OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG" },
7752
#define  OPEN4_SHARE_ACCESS_WANT_ANY_DELEG         0x0300
7753
  { OPEN4_SHARE_ACCESS_WANT_ANY_DELEG, "OPEN4_SHARE_ACCESS_WANT_ANY_DELEG" },
7754
#define  OPEN4_SHARE_ACCESS_WANT_NO_DELEG          0x0400
7755
  { OPEN4_SHARE_ACCESS_WANT_NO_DELEG, "OPEN4_SHARE_ACCESS_WANT_NO_DELEG" },
7756
#define  OPEN4_SHARE_ACCESS_WANT_CANCEL            0x0500
7757
  { OPEN4_SHARE_ACCESS_WANT_CANCEL, "OPEN4_SHARE_ACCESS_WANT_CANCEL" },
7758
16
#define OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x00010000
7759
  { OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL,
7760
    "OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL"},
7761
16
#define OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED  0x00020000
7762
  { OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED,
7763
   "OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED"},
7764
16
#define OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS 0x00100000
7765
  {OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS,
7766
   "OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS"},
7767
  { 0, NULL }
7768
};
7769
static value_string_ext names_open4_share_access_ext = VALUE_STRING_EXT_INIT(names_open4_share_access);
7770
7771
static unsigned
7772
dissect_nfs4_open_share_access(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
7773
0
{
7774
0
  proto_item *notify_item;
7775
0
  proto_tree *notify_tree;
7776
0
  unsigned      share_access;
7777
0
  unsigned      want_flags;
7778
0
  unsigned      want_notify_flags;
7779
7780
0
  want_notify_flags = tvb_get_ntohl(tvb, offset);
7781
0
  share_access = want_notify_flags & 0x3;
7782
0
  want_flags = want_notify_flags & 0xff00;
7783
0
  want_notify_flags &= 0x130000;
7784
0
  proto_tree_add_uint(tree, hf_nfs4_open_share_access, tvb, offset, 4, share_access);
7785
0
  if (want_flags)
7786
0
    proto_tree_add_uint(tree, hf_nfs4_want_flags, tvb, offset, 4, want_flags);
7787
0
  if (want_notify_flags) {
7788
0
    notify_item = proto_tree_add_uint(tree, hf_nfs4_want_notify_flags, tvb, offset, 4, want_notify_flags);
7789
7790
0
    notify_tree = proto_item_add_subtree(notify_item, ett_nfs4_want_notify_flags);
7791
0
    proto_tree_add_item(notify_tree, hf_nfs4_want_signal_deleg_when_resrc_avail, tvb, offset, 4, ENC_BIG_ENDIAN);
7792
0
    proto_tree_add_item(notify_tree, hf_nfs4_want_push_deleg_when_uncontended, tvb, offset, 4, ENC_BIG_ENDIAN);
7793
0
  }
7794
0
  offset += 4;
7795
7796
0
  return offset;
7797
0
}
7798
7799
static const value_string names_open4_share_deny[] = {
7800
#define OPEN4_SHARE_DENY_NONE 0x00000000
7801
  { OPEN4_SHARE_DENY_NONE, "OPEN4_SHARE_DENY_NONE" },
7802
#define OPEN4_SHARE_DENY_READ 0x00000001
7803
  { OPEN4_SHARE_DENY_READ, "OPEN4_SHARE_DENY_READ" },
7804
#define OPEN4_SHARE_DENY_WRITE 0x00000002
7805
  { OPEN4_SHARE_DENY_WRITE, "OPEN4_SHARE_DENY_WRITE" },
7806
#define OPEN4_SHARE_DENY_BOTH 0x00000003
7807
  { OPEN4_SHARE_DENY_BOTH, "OPEN4_SHARE_DENY_BOTH" },
7808
  { 0, NULL }
7809
};
7810
7811
7812
static unsigned
7813
dissect_nfs4_open_share_deny(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
7814
0
{
7815
0
  proto_tree_add_item(tree, hf_nfs4_open_share_deny, tvb, offset, 4, ENC_BIG_ENDIAN);
7816
0
  offset += 4;
7817
7818
0
  return offset;
7819
0
}
7820
7821
7822
static unsigned
7823
dissect_nfs4_open_owner(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
7824
0
{
7825
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_clientid, offset);
7826
0
  offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs4_open_owner);
7827
7828
0
  return offset;
7829
0
}
7830
7831
7832
static unsigned
7833
dissect_nfs4_open_claim_delegate_cur(tvbuff_t *tvb, packet_info* pinfo, unsigned offset,
7834
             proto_tree *tree)
7835
0
{
7836
0
  offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
7837
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_component, NULL);
7838
7839
0
  return offset;
7840
0
}
7841
7842
0
#define CLAIM_NULL    0
7843
0
#define CLAIM_PREVIOUS    1
7844
0
#define CLAIM_DELEGATE_CUR  2
7845
0
#define CLAIM_DELEGATE_PREV 3
7846
#define CLAIM_FH    4
7847
#define CLAIM_DELEG_CUR_FH  5
7848
#define CLAIM_DELEG_CUR_PREV_FH 6
7849
7850
static const value_string names_claim_type4[] = {
7851
  { CLAIM_NULL,    "CLAIM_NULL"  },
7852
  { CLAIM_PREVIOUS,    "CLAIM_PREVIOUS" },
7853
  { CLAIM_DELEGATE_CUR,  "CLAIM_DELEGATE_CUR" },
7854
  { CLAIM_DELEGATE_PREV,   "CLAIM_DELEGATE_PREV" },
7855
  { CLAIM_FH,    "CLAIM_FH" },
7856
  { CLAIM_DELEG_CUR_FH,  "CLAIM_DELEG_CUR_FH"},
7857
  { CLAIM_DELEG_CUR_PREV_FH, "CLAIN_DELEG_CUR_PREV_FH"},
7858
  { 0, NULL }
7859
};
7860
7861
/* XXX - need a better place to populate name than here, maybe? */
7862
static unsigned
7863
dissect_nfs4_open_claim(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
7864
  proto_tree *tree, const char **name,
7865
  int current_fh_offset, int current_fh_length,
7866
  rpc_call_info_value *civ, uint32_t fh_idx)
7867
0
{
7868
0
  unsigned      open_claim_type4;
7869
0
  proto_item *fitem;
7870
0
  proto_tree *newftree = NULL;
7871
0
  uint32_t      name_offset, name_len;
7872
7873
0
  if (name)
7874
0
    *name = NULL; /* will be filled later for CLAIM_NULL */
7875
7876
0
  open_claim_type4 = tvb_get_ntohl(tvb, offset);
7877
0
  fitem = proto_tree_add_uint(tree, hf_nfs4_open_claim_type, tvb,
7878
0
            offset+0, 4, open_claim_type4);
7879
0
  offset += 4;
7880
7881
0
  newftree = proto_item_add_subtree(fitem, ett_nfs4_open_claim);
7882
7883
0
  switch (open_claim_type4)
7884
0
  {
7885
0
    case CLAIM_NULL:
7886
0
      if (nfs_file_name_snooping) {
7887
0
        name_offset = offset+4;
7888
0
        name_len = tvb_get_ntohl(tvb, offset);
7889
0
        nfs_name_snoop_add_name(((uint64_t)fh_idx << 32) | civ->xid, tvb,
7890
0
          name_offset, name_len, current_fh_offset, current_fh_length, NULL);
7891
0
      }
7892
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, name);
7893
0
      break;
7894
7895
0
    case CLAIM_PREVIOUS:
7896
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_delegate_type, offset);
7897
0
      break;
7898
7899
0
    case CLAIM_DELEGATE_CUR:
7900
0
      offset = dissect_nfs4_open_claim_delegate_cur(tvb, pinfo, offset, newftree);
7901
0
      break;
7902
7903
0
    case CLAIM_DELEGATE_PREV:
7904
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, NULL);
7905
0
      break;
7906
7907
0
    default:
7908
0
      break;
7909
0
  }
7910
7911
0
  return offset;
7912
0
}
7913
7914
static const value_string names_createmode4[] = {
7915
  { UNCHECKED4, "UNCHECKED4" },
7916
  { GUARDED4, "GUARDED4" },
7917
  { EXCLUSIVE4, "EXCLUSIVE4" },
7918
  { EXCLUSIVE4_1, "EXCLUSIVE4_1" },
7919
  { 0, NULL }
7920
};
7921
7922
7923
static unsigned
7924
dissect_nfs4_createhow(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
7925
           proto_tree *tree, rpc_call_info_value *civ)
7926
0
{
7927
0
  unsigned mode;
7928
7929
0
  mode = tvb_get_ntohl(tvb, offset);
7930
0
  proto_tree_add_uint(tree, hf_nfs4_createmode, tvb, offset, 4, mode);
7931
0
  offset += 4;
7932
7933
0
  switch (mode)
7934
0
  {
7935
0
  case UNCHECKED4:
7936
0
  case GUARDED4:
7937
0
    offset = dissect_nfs4_fattrs(tvb, offset, pinfo, tree, FATTR4_DISSECT_VALUES, civ, -1, -1);
7938
0
    break;
7939
7940
0
  case EXCLUSIVE4:
7941
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
7942
0
    break;
7943
7944
0
  case EXCLUSIVE4_1:
7945
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
7946
0
    offset = dissect_nfs4_fattrs(tvb, offset, pinfo, tree, FATTR4_DISSECT_VALUES, civ, -1, -1);
7947
0
    break;
7948
7949
0
  default:
7950
0
    break;
7951
0
  }
7952
7953
0
  return offset;
7954
0
}
7955
7956
7957
#define OPEN4_NOCREATE        0
7958
0
#define OPEN4_CREATE        1
7959
static const value_string names_opentype4[] = {
7960
  { OPEN4_NOCREATE, "OPEN4_NOCREATE"  },
7961
  { OPEN4_CREATE, "OPEN4_CREATE" },
7962
  { 0, NULL }
7963
};
7964
7965
static unsigned
7966
dissect_nfs4_openflag(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
7967
  proto_tree *tree, rpc_call_info_value *civ)
7968
0
{
7969
0
  unsigned      opentype4;
7970
0
  proto_item *fitem;
7971
0
  proto_tree *newftree;
7972
7973
0
  opentype4 = tvb_get_ntohl(tvb, offset);
7974
0
  fitem = proto_tree_add_uint(tree, hf_nfs4_opentype, tvb,
7975
0
    offset+0, 4, opentype4);
7976
0
  offset += 4;
7977
7978
0
  newftree = proto_item_add_subtree(fitem, ett_nfs4_opentype);
7979
7980
0
  switch (opentype4)
7981
0
  {
7982
0
    case OPEN4_CREATE:
7983
0
      offset = dissect_nfs4_createhow(tvb, offset, pinfo, newftree, civ);
7984
0
      break;
7985
7986
0
    default:
7987
0
      break;
7988
0
  }
7989
7990
0
  return offset;
7991
0
}
7992
7993
7994
static unsigned
7995
dissect_nfs4_clientaddr(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
7996
0
{
7997
0
  const char *universal_ip_address = NULL;
7998
0
  const char *protocol     = NULL;
7999
0
  unsigned  b1, b2, b3, b4, b5, b6, b7, b8, b9, b10;
8000
0
  uint16_t port;
8001
0
  int addr_offset;
8002
0
  uint32_t ipv4;
8003
0
  ws_in6_addr ipv6;
8004
0
  address addr;
8005
0
  proto_item* ti;
8006
8007
0
  offset = dissect_rpc_string(tvb, pinfo, tree, hf_nfs4_r_netid, offset, &protocol);
8008
0
  addr_offset = offset;
8009
0
  offset = dissect_rpc_string(tvb, pinfo, tree, hf_nfs4_r_addr, offset, &universal_ip_address);
8010
8011
0
  if (strlen(protocol) == 3 && strncmp(protocol, "tcp", 3) == 0) {
8012
0
    if (universal_ip_address && sscanf(universal_ip_address, "%u.%u.%u.%u.%u.%u",
8013
0
               &b1, &b2, &b3, &b4, &b5, &b6) == 6) {
8014
      /* IPv4: h1.h2.h3.h4.p1.p2 */
8015
0
      port = (b5<<8) | b6;
8016
0
      ipv4 = g_htonl((b1<<24) | (b2<<16) | (b3<<8) | b4);
8017
0
      set_address(&addr, AT_IPv4, 4, &ipv4);
8018
0
      ti = proto_tree_add_ipv4_format(tree, hf_nfs4_universal_address_ipv4, tvb, addr_offset, offset-addr_offset, ipv4, "IPv4 address %s, protocol=%s, port=%u",
8019
0
        address_to_str(pinfo->pool, &addr), protocol, port);
8020
0
      proto_item_set_generated(ti);
8021
0
    } else if (universal_ip_address && sscanf(universal_ip_address, "%u.%u",
8022
0
               &b1, &b2) == 2) {
8023
      /* Some clients (linux) sometimes send only the port. */
8024
0
      port = (b1<<8) | b2;
8025
0
      ti = proto_tree_add_ipv4_format(tree, hf_nfs4_universal_address_ipv4, tvb, addr_offset, offset-addr_offset, 0, "ip address NOT SPECIFIED, protocol=%s, port=%u", protocol, port);
8026
0
      proto_item_set_generated(ti);
8027
0
    } else if (universal_ip_address && sscanf(universal_ip_address,
8028
0
            "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x.%u.%u",
8029
0
            &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &b9, &b10) == 10) {
8030
0
      port = (b9<<8) | b10;
8031
0
      memset(&ipv6, 0, sizeof(ipv6));
8032
0
      ipv6.bytes[0] = b1; ipv6.bytes[1] = b2; ipv6.bytes[2] = b3; ipv6.bytes[3] = b4;
8033
0
      ipv6.bytes[4] = b5; ipv6.bytes[5] = b6; ipv6.bytes[6] = b7; ipv6.bytes[7] = b8;
8034
0
      set_address(&addr, AT_IPv6, 16, &ipv6);
8035
0
      ti = proto_tree_add_ipv6_format(tree, hf_nfs4_universal_address_ipv6, tvb, addr_offset, offset-addr_offset, &ipv6, "IPv6 address %s, protocol=%s, port=%u",
8036
0
        address_to_str(pinfo->pool, &addr), protocol, port);
8037
0
      proto_item_set_generated(ti);
8038
0
    } else {
8039
0
      ti = proto_tree_add_ipv4_format(tree, hf_nfs4_universal_address_ipv4, tvb, addr_offset, offset-addr_offset, 0, "Invalid address");
8040
0
      proto_item_set_generated(ti);
8041
0
    }
8042
0
  }
8043
0
  return offset;
8044
0
}
8045
8046
8047
static unsigned
8048
dissect_nfs4_cb_client4(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
8049
0
{
8050
0
  proto_tree *cb_location;
8051
0
  proto_item *fitem;
8052
0
  unsigned    old_offset;
8053
8054
0
  nfs4_cb_register_prog(tvb, offset);
8055
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_cb_program, offset);
8056
0
  old_offset = offset;
8057
0
  cb_location = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "cb_location");
8058
8059
0
  offset = dissect_nfs4_clientaddr(tvb, pinfo, offset, cb_location);
8060
0
  proto_item_set_len(fitem, offset - old_offset);
8061
8062
0
  return offset;
8063
0
}
8064
8065
8066
static const value_string names_stable_how4[] = {
8067
#define UNSTABLE4 0
8068
  { UNSTABLE4,  "UNSTABLE4" },
8069
#define DATA_SYNC4 1
8070
  { DATA_SYNC4, "DATA_SYNC4"  },
8071
#define FILE_SYNC4 2
8072
  { FILE_SYNC4, "FILE_SYNC4"  },
8073
  { 0,  NULL  }
8074
};
8075
8076
static unsigned
8077
dissect_nfs4_stable_how(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree, const char *name)
8078
0
{
8079
0
  unsigned stable_how4;
8080
8081
0
  stable_how4 = tvb_get_ntohl(tvb, offset);
8082
0
  proto_tree_add_uint_format(tree, hf_nfs4_stable_how, tvb,
8083
0
      offset+0, 4, stable_how4, "%s: %s (%u)", name,
8084
0
      val_to_str(pinfo->pool, stable_how4, names_stable_how4, "%u"), stable_how4);
8085
0
  offset += 4;
8086
8087
0
  return offset;
8088
0
}
8089
8090
static const value_string names_data_content[] = {
8091
  { 0,  "DATA"  },
8092
  { 1,  "HOLE"  },
8093
  { 0, NULL }
8094
};
8095
8096
static const value_string names_setxattr_options[] = {
8097
  { 0,  "EITHER"  },
8098
  { 1,  "CREATE"  },
8099
  { 2,  "REPLACE"  },
8100
  { 0, NULL }
8101
};
8102
8103
static unsigned
8104
dissect_nfs4_listxattr_names(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
8105
0
{
8106
0
  uint32_t      comp_count, i;
8107
0
  proto_item *fitem;
8108
0
  proto_tree *newftree;
8109
8110
0
  fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_listxattr_names_len, tvb, offset, 4, ENC_BIG_ENDIAN, &comp_count);
8111
0
  offset += 4;
8112
8113
0
  newftree = proto_item_add_subtree(fitem, ett_nfs4_listxattr_names);
8114
8115
0
  for (i = 0; i < comp_count; i++)
8116
0
    offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_xattrkey, NULL);
8117
0
  return offset;
8118
0
}
8119
8120
static unsigned
8121
dissect_nfs4_gdd_time(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int hfindex)
8122
0
{
8123
0
  proto_item *item;
8124
0
  proto_tree *subtree;
8125
8126
0
  item = proto_tree_add_item(tree, hfindex, tvb, offset, 12, ENC_NA);
8127
0
  subtree = proto_item_add_subtree(item, ett_nfs4_notify_delay);
8128
0
  return dissect_nfs4_nfstime(tvb, offset, subtree);
8129
0
}
8130
8131
static unsigned
8132
dissect_nfs4_gdd_fattrs(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, int type,
8133
      rpc_call_info_value *civ, int hfindex, uint32_t opcode, uint32_t fh_idx)
8134
0
{
8135
0
  proto_item *item;
8136
0
  proto_tree *subtree;
8137
0
  int len;
8138
8139
0
  len = tvb_get_ntohl(tvb, offset);
8140
8141
0
  item = proto_tree_add_item(tree, hfindex, tvb, offset, len * 4, ENC_NA);
8142
0
  subtree = proto_item_add_subtree(item, ett_nfs4_notify_attrs);
8143
0
  return dissect_nfs4_fattrs(tvb, offset, pinfo, subtree, type, civ, opcode, fh_idx);
8144
0
}
8145
8146
/* NFSv4 Operations  */
8147
static const value_string names_nfs4_operation[] = {
8148
  { NFS4_OP_ACCESS,                "ACCESS"  },
8149
  { NFS4_OP_CLOSE,                 "CLOSE"  },
8150
  { NFS4_OP_COMMIT,                "COMMIT"  },
8151
  { NFS4_OP_CREATE,                "CREATE"  },
8152
  { NFS4_OP_DELEGPURGE,            "DELEGPURGE"  },
8153
  { NFS4_OP_DELEGRETURN,           "DELEGRETURN"  },
8154
  { NFS4_OP_GETATTR,               "GETATTR"  },
8155
  { NFS4_OP_GETFH,                 "GETFH"  },
8156
  { NFS4_OP_LINK,                  "LINK"  },
8157
  { NFS4_OP_LOCK,                  "LOCK"  },
8158
  { NFS4_OP_LOCKT,                 "LOCKT"  },
8159
  { NFS4_OP_LOCKU,                 "LOCKU"  },
8160
  { NFS4_OP_LOOKUP,                "LOOKUP"  },
8161
  { NFS4_OP_LOOKUPP,               "LOOKUPP"  },
8162
  { NFS4_OP_NVERIFY,               "NVERIFY"  },
8163
  { NFS4_OP_OPEN,                  "OPEN"  },
8164
  { NFS4_OP_OPENATTR,              "OPENATTR"  },
8165
  { NFS4_OP_OPEN_CONFIRM,          "OPEN_CONFIRM"  },
8166
  { NFS4_OP_OPEN_DOWNGRADE,        "OPEN_DOWNGRADE"  },
8167
  { NFS4_OP_PUTFH,                 "PUTFH"  },
8168
  { NFS4_OP_PUTPUBFH,              "PUTPUBFH"  },
8169
  { NFS4_OP_PUTROOTFH,             "PUTROOTFH"  },
8170
  { NFS4_OP_READ,                  "READ"  },
8171
  { NFS4_OP_READDIR,               "READDIR"  },
8172
  { NFS4_OP_READLINK,              "READLINK"  },
8173
  { NFS4_OP_REMOVE,                "REMOVE"  },
8174
  { NFS4_OP_RENAME,                "RENAME"  },
8175
  { NFS4_OP_RENEW,                 "RENEW"  },
8176
  { NFS4_OP_RESTOREFH,             "RESTOREFH"  },
8177
  { NFS4_OP_SAVEFH,                "SAVEFH"  },
8178
  { NFS4_OP_SECINFO,               "SECINFO"  },
8179
  { NFS4_OP_SETATTR,               "SETATTR"  },
8180
  { NFS4_OP_SETCLIENTID,           "SETCLIENTID"  },
8181
  { NFS4_OP_SETCLIENTID_CONFIRM,   "SETCLIENTID_CONFIRM"  },
8182
  { NFS4_OP_VERIFY,                "VERIFY"  },
8183
  { NFS4_OP_WRITE,                 "WRITE"  },
8184
  { NFS4_OP_RELEASE_LOCKOWNER,     "RELEASE_LOCKOWNER"  },
8185
  { NFS4_OP_BACKCHANNEL_CTL,       "BACKCHANNEL_CTL"  },
8186
  { NFS4_OP_BIND_CONN_TO_SESSION,  "BIND_CONN_TO_SESSION"  },
8187
  { NFS4_OP_EXCHANGE_ID,           "EXCHANGE_ID"  },
8188
  { NFS4_OP_CREATE_SESSION,        "CREATE_SESSION"  },
8189
  { NFS4_OP_DESTROY_SESSION,       "DESTROY_SESSION"  },
8190
  { NFS4_OP_FREE_STATEID,          "FREE_STATEID"  },
8191
  { NFS4_OP_GET_DIR_DELEGATION,    "GET_DIR_DELEGATION"  },
8192
  { NFS4_OP_GETDEVINFO,            "GETDEVINFO"  },
8193
  { NFS4_OP_GETDEVLIST,            "GETDEVLIST"  },
8194
  { NFS4_OP_LAYOUTCOMMIT,          "LAYOUTCOMMIT"  },
8195
  { NFS4_OP_LAYOUTGET,             "LAYOUTGET"  },
8196
  { NFS4_OP_LAYOUTRETURN,          "LAYOUTRETURN"  },
8197
  { NFS4_OP_SECINFO_NO_NAME,       "SECINFO_NO_NAME"  },
8198
  { NFS4_OP_SEQUENCE,              "SEQUENCE"  },
8199
  { NFS4_OP_SET_SSV,               "SET_SSV"  },
8200
  { NFS4_OP_TEST_STATEID,          "TEST_STATEID"  },
8201
  { NFS4_OP_WANT_DELEGATION,       "WANT_DELEG"  },
8202
  { NFS4_OP_DESTROY_CLIENTID,      "DESTROY_CLIENTID"  },
8203
  { NFS4_OP_RECLAIM_COMPLETE,      "RECLAIM_COMPLETE"  },
8204
  { NFS4_OP_ALLOCATE,              "ALLOCATE"  },
8205
  { NFS4_OP_COPY,                  "COPY"  },
8206
  { NFS4_OP_COPY_NOTIFY,           "COPY_NOTIFY"  },
8207
  { NFS4_OP_DEALLOCATE,            "DEALLOCATE"  },
8208
  { NFS4_OP_IO_ADVISE,             "IO_ADVISE"  },
8209
  { NFS4_OP_LAYOUTERROR,           "LAYOUTERROR"  },
8210
  { NFS4_OP_LAYOUTSTATS,           "LAYOUTSTATS"  },
8211
  { NFS4_OP_OFFLOAD_CANCEL,        "OFFLOAD_CANCEL"  },
8212
  { NFS4_OP_OFFLOAD_STATUS,        "OFFLOAD_STATUS"  },
8213
  { NFS4_OP_READ_PLUS,             "READ_PLUS"  },
8214
  { NFS4_OP_SEEK,                  "SEEK"  },
8215
  { NFS4_OP_WRITE_SAME,            "WRITE_SAME"  },
8216
  { NFS4_OP_CLONE,                 "CLONE"  },
8217
  { NFS4_OP_GETXATTR,              "GETXATTR"  },
8218
  { NFS4_OP_SETXATTR,              "SETXATTR"  },
8219
  { NFS4_OP_LISTXATTRS,            "LISTXATTRS"  },
8220
  { NFS4_OP_REMOVEXATTR,           "REMOVEXATTR"  },
8221
  { NFS4_OP_ILLEGAL,               "ILLEGAL"  },
8222
  { 0, NULL  }
8223
};
8224
8225
static value_string_ext names_nfs4_operation_ext = VALUE_STRING_EXT_INIT(names_nfs4_operation);
8226
8227
/* Each subtree number in this array corresponds to the associated item in the above
8228
*  'names_nfs4_operation array[]' array. */
8229
static int *nfs4_operation_ett[] =
8230
{
8231
   &ett_nfs4_access ,
8232
   &ett_nfs4_close ,
8233
   &ett_nfs4_commit ,
8234
   &ett_nfs4_create ,
8235
   &ett_nfs4_delegpurge ,
8236
   &ett_nfs4_delegreturn ,
8237
   &ett_nfs4_getattr ,
8238
   &ett_nfs4_getfh ,
8239
   &ett_nfs4_link ,
8240
   &ett_nfs4_lock ,
8241
   &ett_nfs4_lockt ,
8242
   &ett_nfs4_locku ,
8243
   &ett_nfs4_lookup ,
8244
   &ett_nfs4_lookupp ,
8245
   &ett_nfs4_nverify ,
8246
   &ett_nfs4_open ,
8247
   &ett_nfs4_openattr ,
8248
   &ett_nfs4_open_confirm ,
8249
   &ett_nfs4_open_downgrade ,
8250
   &ett_nfs4_putfh ,
8251
   &ett_nfs4_putpubfh ,
8252
   &ett_nfs4_putrootfh ,
8253
   &ett_nfs4_read ,
8254
   &ett_nfs4_readdir ,
8255
   &ett_nfs4_readlink ,
8256
   &ett_nfs4_remove ,
8257
   &ett_nfs4_rename ,
8258
   &ett_nfs4_renew ,
8259
   &ett_nfs4_restorefh ,
8260
   &ett_nfs4_savefh ,
8261
   &ett_nfs4_secinfo ,
8262
   &ett_nfs4_setattr ,
8263
   &ett_nfs4_setclientid ,
8264
   &ett_nfs4_setclientid_confirm ,
8265
   &ett_nfs4_verify ,
8266
   &ett_nfs4_write,
8267
   &ett_nfs4_release_lockowner,
8268
   &ett_nfs4_backchannel_ctl,
8269
   &ett_nfs4_bind_conn_to_session,
8270
   &ett_nfs4_exchange_id,
8271
   &ett_nfs4_create_session,
8272
   &ett_nfs4_destroy_session,
8273
   &ett_nfs4_free_stateid,
8274
   &ett_nfs4_get_dir_delegation,
8275
   &ett_nfs4_getdevinfo,
8276
   &ett_nfs4_getdevlist,
8277
   &ett_nfs4_layoutcommit,
8278
   &ett_nfs4_layoutget,
8279
   &ett_nfs4_layoutreturn,
8280
   &ett_nfs4_secinfo_no_name,
8281
   &ett_nfs4_sequence,
8282
   NULL, /* set ssv */
8283
   &ett_nfs4_test_stateid,
8284
   NULL, /* want delegation */
8285
   &ett_nfs4_destroy_clientid,
8286
   &ett_nfs4_reclaim_complete,
8287
   &ett_nfs4_allocate,
8288
   &ett_nfs4_copy,
8289
   &ett_nfs4_copy_notify,
8290
   &ett_nfs4_deallocate,
8291
   &ett_nfs4_io_advise,
8292
   &ett_nfs4_layouterror,
8293
   &ett_nfs4_layoutstats,
8294
   &ett_nfs4_offload_cancel,
8295
   &ett_nfs4_offload_status,
8296
   &ett_nfs4_read_plus,
8297
   &ett_nfs4_seek,
8298
   &ett_nfs4_write_same,
8299
   &ett_nfs4_clone,
8300
   &ett_nfs4_getxattr,
8301
   &ett_nfs4_setxattr,
8302
   &ett_nfs4_listxattr,
8303
   &ett_nfs4_removexattr,
8304
};
8305
8306
8307
static unsigned
8308
dissect_nfs4_dirlist(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
8309
         proto_tree *tree, rpc_call_info_value *civ, uint32_t opcode, uint32_t fh_idx)
8310
0
{
8311
0
  uint32_t      val_follows;
8312
0
  uint32_t      name_len;
8313
0
  char     *name;
8314
0
  proto_tree *dirlist_tree;
8315
0
  proto_item *eitem;
8316
0
  proto_tree *entry_tree;
8317
8318
0
  dirlist_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_dirlist, NULL, "Directory Listing");
8319
8320
0
  while (1)
8321
0
  {
8322
0
    val_follows = tvb_get_ntohl(tvb, offset);
8323
0
    if (val_follows) {
8324
0
      int start_off = offset;
8325
8326
      /* Make sure we have 16 bytes (value follows + cookie + name length) */
8327
0
      name_len = tvb_get_ntohl(tvb, offset + 12);
8328
0
      tvb_ensure_bytes_exist(tvb, offset, 16 + name_len);
8329
      /*
8330
      * Get the entry name and create subtree of field nfs.name
8331
      */
8332
0
      name = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset + 16, name_len, ENC_UTF_8);
8333
8334
0
      eitem = proto_tree_add_string_format(
8335
0
        dirlist_tree, hf_nfs_name, tvb, offset, -1, name, "Entry: %s", name);
8336
0
      entry_tree = proto_item_add_subtree(eitem, ett_nfs4_dir_entry);
8337
8338
      /* Value Follows: <Yes|No> */
8339
0
      proto_tree_add_boolean(entry_tree, hf_nfs4_value_follows, tvb, offset, 4, val_follows);
8340
0
      offset += 4;
8341
8342
      /* Directory entry cookie */
8343
0
      if (entry_tree)
8344
0
        dissect_rpc_uint64(tvb, entry_tree, hf_nfs4_cookie, offset);
8345
0
      offset += 8;
8346
8347
      /* Directory entry name (nfs.entry_name) */
8348
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, entry_tree, hf_nfs4_dir_entry_name, NULL);
8349
8350
      /* Attrmask(s) */
8351
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, entry_tree, FATTR4_DISSECT_VALUES, civ, opcode, fh_idx);
8352
0
      proto_item_set_len(eitem, offset - start_off);
8353
0
    } else {
8354
0
      break;
8355
0
    }
8356
0
  }
8357
0
  if (dirlist_tree) {
8358
0
    proto_tree_add_boolean(dirlist_tree, hf_nfs4_value_follows, tvb, offset, 4, val_follows);
8359
0
    offset += 4;
8360
    /* The last entry in this packet has been reached but do more follow? */
8361
0
    offset = dissect_rpc_bool(tvb, dirlist_tree, hf_nfs4_dirlist_eof, offset);
8362
0
  } else {
8363
0
    offset += 8;
8364
0
  }
8365
0
  return offset;
8366
0
}
8367
8368
static unsigned
8369
dissect_nfs4_change_info(tvbuff_t *tvb, unsigned offset,
8370
       proto_tree *tree, const char *name)
8371
0
{
8372
0
  proto_tree *newftree;
8373
0
  proto_tree *fitem;
8374
0
  int         old_offset = offset;
8375
8376
0
  newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_change_info, &fitem, name);
8377
8378
0
  offset = dissect_rpc_bool(  tvb, newftree, hf_nfs4_change_info_atomic, offset);
8379
0
  offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_changeid_before,    offset);
8380
0
  offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_changeid_after,     offset);
8381
0
  proto_item_set_len(fitem, offset - old_offset);
8382
8383
0
  return offset;
8384
0
}
8385
8386
8387
static const value_string names_nfs_lock_type4[] =
8388
{
8389
#define READ_LT 1
8390
  { READ_LT,  "READ_LT" },
8391
#define WRITE_LT 2
8392
  { WRITE_LT, "WRITE_LT"  },
8393
#define READW_LT 3
8394
  { READW_LT, "READW_LT"  },
8395
#define WRITEW_LT 4
8396
  { WRITEW_LT,  "WRITEW_LT" },
8397
#define RELEASE_STATE 5
8398
  { RELEASE_STATE,  "RELEASE_STATE" },
8399
  { 0,  NULL  }
8400
};
8401
8402
static unsigned
8403
dissect_nfs4_lockdenied(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
8404
0
{
8405
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8406
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
8407
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_lock_type, offset);
8408
0
  offset = dissect_nfs4_lock_owner(tvb, pinfo, offset, tree);
8409
0
  return offset;
8410
0
}
8411
8412
8413
16
#define OPEN4_RESULT_CONFIRM    0x00000002
8414
16
#define OPEN4_RESULT_LOCKTYPE_POSIX 0x00000004
8415
16
#define OPEN4_RESULT_PRESERVE_UNLINKED  0x00000008
8416
16
#define OPEN4_RESULT_MAY_NOTIFY_LOCK  0x00000020
8417
8418
static int * const open4_result_flag_fields[] = {
8419
  &hf_nfs4_open_rflags_confirm,
8420
  &hf_nfs4_open_rflags_locktype_posix,
8421
  &hf_nfs4_open_rflags_preserve_unlinked,
8422
  &hf_nfs4_open_rflags_may_notify_lock,
8423
  NULL
8424
};
8425
8426
static unsigned
8427
dissect_nfs4_open_rflags(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
8428
0
{
8429
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_open_rflags,
8430
0
      ett_nfs4_open_result_flags, open4_result_flag_fields, ENC_BIG_ENDIAN);
8431
0
  offset += 4;
8432
8433
0
  return offset;
8434
0
}
8435
8436
8437
static unsigned
8438
dissect_nfs4_stateid(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint16_t *hash)
8439
0
{
8440
0
  uint16_t     stateid_hash;
8441
0
  uint32_t     other_hash;
8442
0
  proto_item  *sitem, *hitem, *oth_item;
8443
0
  proto_tree  *stateid_tree;
8444
0
  int    old_offset = offset;
8445
8446
0
  sitem = proto_tree_add_bytes_format(tree, hf_nfs4_stateid, tvb, offset, 16, NULL, "StateID");
8447
0
  stateid_tree = proto_item_add_subtree(sitem, ett_nfs4_stateid);
8448
8449
0
  stateid_hash = crc16_ccitt_tvb_offset(tvb, offset, 16);
8450
0
  hitem = proto_tree_add_uint(stateid_tree, hf_nfs4_stateid_hash, tvb, offset, 16, stateid_hash);
8451
0
  proto_item_set_generated(hitem);
8452
8453
0
  offset = dissect_rpc_uint32(tvb, sitem, hf_nfs4_seqid_stateid, offset);
8454
8455
0
  proto_tree_add_item(stateid_tree, hf_nfs4_stateid_other, tvb, offset, 12, ENC_NA);
8456
8457
0
  other_hash = crc32_ccitt_tvb_offset(tvb, offset, 12);
8458
0
  oth_item = proto_tree_add_uint(stateid_tree, hf_nfs4_stateid_other_hash, tvb, offset, 12, other_hash);
8459
0
  proto_item_set_generated(oth_item);
8460
0
  offset+=12;
8461
8462
0
  if (hash)
8463
0
    *hash = stateid_hash;
8464
8465
0
  proto_item_set_len(sitem, offset - old_offset);
8466
8467
0
  return offset;
8468
0
}
8469
8470
8471
static unsigned
8472
dissect_nfs4_open_read_delegation(tvbuff_t *tvb, unsigned offset,
8473
      packet_info *pinfo, proto_tree *tree)
8474
0
{
8475
0
  offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8476
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_recall4, offset);
8477
0
  offset = dissect_nfs4_ace(tvb, offset, pinfo, tree, 0, 0);
8478
8479
0
  return offset;
8480
0
}
8481
8482
8483
static unsigned
8484
dissect_nfs4_modified_limit(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
8485
0
{
8486
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_num_blocks, offset);
8487
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_bytes_per_block, offset);
8488
8489
0
  return offset;
8490
0
}
8491
8492
8493
static unsigned
8494
dissect_nfs4_state_protect_bitmap(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
8495
        proto_tree *tree, const char *name)
8496
0
{
8497
0
  static nfs4_bitmap_info_t bitmap_info = {
8498
0
    .vse_names_ext = &names_nfs4_operation_ext,
8499
0
    .hf_mask_label = &hf_nfs4_op_mask,
8500
0
    .hf_item_label = &hf_nfs4_op
8501
0
  };
8502
8503
0
  return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, -1, -1, &bitmap_info, NFS4_BITMAP_MASK, name);
8504
0
}
8505
8506
0
#define SP4_NONE                                0
8507
0
#define SP4_MACH_CRED                           1
8508
0
#define SP4_SSV                                 2
8509
static const value_string names_state_protect_how4[] = {
8510
  { SP4_NONE, "SP4_NONE"  },
8511
  { SP4_MACH_CRED,  "SP4_MACH_CRED" },
8512
  { SP4_SSV,  "SP4_SSV" },
8513
  { 0,    NULL }
8514
};
8515
8516
static unsigned
8517
dissect_nfs4_state_protect_ops(tvbuff_t *tvb, unsigned offset,
8518
    packet_info *pinfo, proto_tree *tree)
8519
0
{
8520
0
  offset = dissect_nfs4_state_protect_bitmap(tvb, offset, pinfo, tree, "spo_must_enforce");
8521
0
  offset = dissect_nfs4_state_protect_bitmap(tvb, offset, pinfo, tree, "spo_must_allow");
8522
0
  return offset;
8523
0
}
8524
8525
8526
static int
8527
dissect_oid(tvbuff_t *tvb, unsigned int offset, packet_info *pinfo _U_, proto_tree* tree, void* data _U_)
8528
0
{
8529
0
  int length = tvb_reported_length(tvb);
8530
0
  proto_tree_add_item(tree, hf_nfs4_sec_oid, tvb, 0, length, ENC_NA);
8531
0
  return offset + 4 + length + (4 - length%4) % 4;
8532
0
}
8533
8534
static int
8535
dissect_nfs4_sec_oid(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data _U_)
8536
0
{
8537
0
  return dissect_rpc_opaque_data(tvb, offset, tree, pinfo,
8538
0
        hf_nfs4_sec_oid, false, 0, false, NULL, dissect_oid);
8539
0
}
8540
8541
static unsigned
8542
dissect_nfs4_ssv_sp_parms(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
8543
0
{
8544
0
  offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8545
0
  offset = dissect_rpc_array(tvb, pinfo, tree, offset, dissect_nfs4_sec_oid, hf_nfs4_sp_parms_hash_algs);
8546
0
  offset = dissect_rpc_array(tvb, pinfo, tree, offset, dissect_nfs4_sec_oid, hf_nfs4_sp_parms_encr_algs);
8547
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_state_protect_window, offset);
8548
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_state_protect_num_gss_handles, offset);
8549
0
  return offset;
8550
0
}
8551
8552
8553
static unsigned
8554
dissect_nfs4_ssv_prot_info(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
8555
0
{
8556
0
  offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8557
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_hash_alg, offset);
8558
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_encr_alg, offset);
8559
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_svv_length, offset);
8560
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_spi_window, offset);
8561
0
  offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs4_gsshandle);
8562
0
  return offset;
8563
0
}
8564
8565
8566
static unsigned
8567
dissect_nfs4_state_protect_a(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
8568
0
{
8569
0
  unsigned stateprotect;
8570
8571
0
  proto_tree_add_item_ret_uint(tree, hf_nfs4_state_protect_how, tvb, offset+0, 4, ENC_BIG_ENDIAN, &stateprotect);
8572
0
  offset += 4;
8573
8574
0
  switch (stateprotect) {
8575
0
    case SP4_NONE:
8576
0
      break;
8577
0
    case SP4_MACH_CRED:
8578
0
      offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8579
0
      break;
8580
0
    case SP4_SSV:
8581
0
      offset = dissect_nfs4_ssv_sp_parms(tvb, offset, pinfo, tree);
8582
0
      break;
8583
0
    default:
8584
0
      break;
8585
0
  }
8586
0
  return offset;
8587
0
}
8588
8589
8590
static unsigned
8591
dissect_nfs4_state_protect_r(tvbuff_t *tvb, unsigned offset,
8592
    packet_info *pinfo, proto_tree *tree)
8593
0
{
8594
0
  unsigned stateprotect;
8595
8596
0
  proto_tree_add_item_ret_uint(tree, hf_nfs4_state_protect_how, tvb, offset+0, 4,
8597
0
          ENC_BIG_ENDIAN, &stateprotect);
8598
0
  offset += 4;
8599
8600
0
  switch (stateprotect) {
8601
0
    case SP4_NONE:
8602
0
      break;
8603
0
    case SP4_MACH_CRED:
8604
0
      offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8605
0
      break;
8606
0
    case SP4_SSV:
8607
0
      offset = dissect_nfs4_ssv_prot_info(tvb, offset, pinfo, tree);
8608
0
      break;
8609
0
    default:
8610
0
      break;
8611
0
  }
8612
0
  return offset;
8613
0
}
8614
8615
8616
0
#define NFS_LIMIT_SIZE            1
8617
0
#define NFS_LIMIT_BLOCKS          2
8618
static const value_string names_limit_by4[] = {
8619
  { NFS_LIMIT_SIZE,   "NFS_LIMIT_SIZE"  },
8620
  { NFS_LIMIT_BLOCKS, "NFS_LIMIT_BLOCKS" },
8621
  { 0,      NULL }
8622
};
8623
8624
static unsigned
8625
dissect_nfs4_space_limit(tvbuff_t *tvb, unsigned offset,
8626
       proto_tree *tree)
8627
0
{
8628
0
  unsigned limitby;
8629
8630
0
  proto_tree_add_item_ret_uint(tree, hf_nfs4_limit_by, tvb, offset+0, 4, ENC_BIG_ENDIAN, &limitby);
8631
0
  offset += 4;
8632
8633
0
  switch (limitby)
8634
0
  {
8635
0
  case NFS_LIMIT_SIZE:
8636
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_filesize,
8637
0
      offset);
8638
0
    break;
8639
8640
0
  case NFS_LIMIT_BLOCKS:
8641
0
    offset = dissect_nfs4_modified_limit(tvb, offset, tree);
8642
0
    break;
8643
8644
0
  default:
8645
0
    break;
8646
0
  }
8647
8648
0
  return offset;
8649
0
}
8650
8651
8652
static unsigned
8653
dissect_nfs4_open_write_delegation(tvbuff_t *tvb, unsigned offset,
8654
  packet_info *pinfo, proto_tree *tree)
8655
0
{
8656
0
  offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8657
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_recall, offset);
8658
0
  offset = dissect_nfs4_space_limit(tvb, offset, tree);
8659
0
  offset = dissect_nfs4_ace(tvb, offset, pinfo, tree, 0, 0);
8660
8661
0
  return offset;
8662
0
}
8663
8664
8665
0
#define OPEN_DELEGATE_NONE 0
8666
0
#define OPEN_DELEGATE_READ 1
8667
0
#define OPEN_DELEGATE_WRITE 2
8668
0
#define OPEN_DELEGATE_NONE_EXT 3 /* new to v4.1 */
8669
0
#define OPEN_DELEGATE_READ_ATTRS_DELEG 4  /* New to V4.2 */
8670
0
#define OPEN_DELEGATE_WRITE_ATTRS_DELEG 5
8671
static const value_string names_open_delegation_type4[] = {
8672
  { OPEN_DELEGATE_NONE, "OPEN_DELEGATE_NONE" },
8673
  { OPEN_DELEGATE_READ, "OPEN_DELEGATE_READ" },
8674
  { OPEN_DELEGATE_WRITE,  "OPEN_DELEGATE_WRITE" },
8675
  { OPEN_DELEGATE_NONE_EXT, "OPEN_DELEGATE_NONE_EXT"},
8676
  { OPEN_DELEGATE_READ_ATTRS_DELEG, "OPEN_DELEGATE_READ_ATTRS_DELEG"},
8677
  { OPEN_DELEGATE_WRITE_ATTRS_DELEG, "OPEN_DELEGATE_WRITE_ATTRS_DELEG"},
8678
  { 0,  NULL }
8679
};
8680
8681
#define WND4_NOT_WANTED 0
8682
0
#define WND4_CONTENTION 1
8683
0
#define WND4_RESOURCE 2
8684
#define WND4_NOT_SUPP_FTYPE 3
8685
#define WND4_WRITE_DELEG_NOT_SUPP_FTYPE 4
8686
#define WND4_NOT_SUPP_UPGRADE 5
8687
#define WND4_NOT_SUPP_DOWNGRADE 6
8688
#define WND4_CANCELLED 7
8689
#define WND4_IS_DIR 8
8690
static const value_string names_why_no_delegation4[] = {
8691
  { WND4_NOT_WANTED,     "WND4_NOT_WANTED" },
8692
  { WND4_CONTENTION,     "WND4_CONTENTION" },
8693
  { WND4_RESOURCE,       "WND4_RESOURCE" },
8694
  { WND4_NOT_SUPP_FTYPE,     "WND4_NOT_SUPP_FTYPE" },
8695
  { WND4_WRITE_DELEG_NOT_SUPP_FTYPE, "WND4_WRITE_DELEG_NOT_SUPP_FTYPE" },
8696
  { WND4_NOT_SUPP_UPGRADE,     "WND4_NOT_SUPP_UPGRADE" },
8697
  { WND4_NOT_SUPP_DOWNGRADE,   "WND4_NOT_SUPP_DOWNGRADE" },
8698
  { WND4_CANCELLED,      "WND4_CANCELLED" },
8699
  { WND4_IS_DIR,       "WND4_IS_DIR" },
8700
  { 0,        NULL }
8701
};
8702
8703
static unsigned
8704
dissect_nfs4_open_delegation(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
8705
  proto_tree *tree)
8706
0
{
8707
0
  unsigned delegation_type;
8708
0
  proto_tree *newftree, *wndftree;
8709
0
  proto_item *fitem, *wnditem;
8710
0
  uint32_t ond_why;
8711
8712
0
  fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_open_delegation_type, tvb,
8713
0
    offset+0, 4, ENC_BIG_ENDIAN, &delegation_type);
8714
0
  newftree = proto_item_add_subtree(fitem, ett_nfs4_open_delegation);
8715
0
  offset += 4;
8716
8717
0
  switch (delegation_type)
8718
0
  {
8719
0
    case OPEN_DELEGATE_NONE:
8720
0
      break;
8721
8722
0
    case OPEN_DELEGATE_READ:
8723
0
    case OPEN_DELEGATE_READ_ATTRS_DELEG:
8724
0
      offset = dissect_nfs4_open_read_delegation(tvb, offset, pinfo, newftree);
8725
0
      break;
8726
8727
0
    case OPEN_DELEGATE_WRITE:
8728
0
    case OPEN_DELEGATE_WRITE_ATTRS_DELEG:
8729
0
      offset = dissect_nfs4_open_write_delegation(tvb, offset, pinfo, newftree);
8730
0
      break;
8731
0
    case OPEN_DELEGATE_NONE_EXT:
8732
0
      wnditem = proto_tree_add_item_ret_uint(newftree, hf_nfs4_why_no_delegation, tvb, offset, 4, ENC_BIG_ENDIAN, &ond_why);
8733
0
      offset += 4;
8734
0
      switch (ond_why) {
8735
0
      case WND4_CONTENTION:
8736
0
        wndftree = proto_item_add_subtree(wnditem, ett_nfs4_open_why_no_deleg);
8737
0
        offset = dissect_rpc_bool(tvb, wndftree, hf_nfs4_ond_server_will_push_deleg, offset);
8738
0
        break;
8739
0
      case WND4_RESOURCE:
8740
0
        wndftree = proto_item_add_subtree(wnditem, ett_nfs4_open_why_no_deleg);
8741
0
        offset = dissect_rpc_bool(tvb, wndftree, hf_nfs4_ond_server_will_signal_avail, offset);
8742
0
        break;
8743
0
      default:
8744
0
        break;
8745
0
      }
8746
0
      break;
8747
0
    default:
8748
0
      break;
8749
0
  }
8750
8751
0
  return offset;
8752
0
}
8753
8754
8755
static unsigned
8756
dissect_nfs_rpcsec_gss_info(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, proto_tree *tree)
8757
0
{
8758
0
  offset = dissect_nfs4_sec_oid(tvb, offset, pinfo, tree, NULL);
8759
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_qop, offset);
8760
0
  offset = dissect_rpc_uint32(tvb, tree,
8761
0
    hf_nfs4_secinfo_rpcsec_gss_info_service, offset);
8762
8763
0
  return offset;
8764
0
}
8765
8766
8767
static unsigned
8768
dissect_nfs4_open_to_lock_owner(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
8769
0
{
8770
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_seqid, offset);
8771
0
  offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8772
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_lock_seqid, offset);
8773
0
  offset = dissect_nfs4_lock_owner(tvb, pinfo, offset, tree);
8774
8775
0
  return offset;
8776
0
}
8777
8778
8779
static unsigned
8780
dissect_nfs4_exist_lock_owner(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
8781
0
{
8782
0
  offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8783
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_lock_seqid, offset);
8784
8785
0
  return offset;
8786
0
}
8787
8788
8789
static unsigned
8790
dissect_nfs4_locker(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
8791
0
{
8792
0
  unsigned new_lock_owner;
8793
8794
0
  new_lock_owner = tvb_get_ntohl(tvb, offset);
8795
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_new_lock_owner, offset);
8796
8797
0
  if (new_lock_owner)
8798
0
    offset = dissect_nfs4_open_to_lock_owner(tvb, pinfo, offset, tree);
8799
0
  else
8800
0
    offset = dissect_nfs4_exist_lock_owner(tvb, offset, tree);
8801
8802
0
  return offset;
8803
0
}
8804
8805
static const value_string read_plus_content_names[] = {
8806
0
#define NFS4_CONTENT_DATA                 0
8807
  { NFS4_CONTENT_DATA,    "Data"  },
8808
0
#define NFS4_CONTENT_HOLE             1
8809
  { NFS4_CONTENT_HOLE,    "Hole"  },
8810
  { 0,  NULL  }
8811
};
8812
static value_string_ext read_plus_content_names_ext = VALUE_STRING_EXT_INIT(read_plus_content_names);
8813
8814
static int
8815
dissect_nfs4_read_plus_content(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data _U_)
8816
0
{
8817
0
  proto_tree *ss_tree;
8818
0
  proto_item *ss_fitem;
8819
0
  unsigned    type;
8820
8821
0
  ss_fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_read_plus_content_type,
8822
0
            tvb, offset, 4, ENC_BIG_ENDIAN, &type);
8823
0
  ss_tree = proto_item_add_subtree(ss_fitem, ett_nfs4_read_plus_content_sub);
8824
0
  offset += 4;
8825
8826
0
  switch (type) {
8827
0
    case NFS4_CONTENT_DATA:
8828
0
      offset = dissect_rpc_uint64(tvb, ss_tree, hf_nfs4_offset, offset);
8829
0
      dissect_rpc_uint32(tvb, ss_tree, hf_nfs4_read_data_length, offset); /* don't change offset */
8830
0
      offset = dissect_nfsdata(tvb, pinfo, offset, ss_tree, hf_nfs_data);
8831
0
      break;
8832
0
    case NFS4_CONTENT_HOLE:
8833
0
      offset = dissect_rpc_uint64(tvb, ss_tree, hf_nfs4_offset, offset);
8834
0
      offset = dissect_rpc_uint64(tvb, ss_tree, hf_nfs4_length, offset);
8835
0
      break;
8836
0
    default:
8837
0
      break;
8838
0
  }
8839
8840
0
  return offset;
8841
0
}
8842
8843
static unsigned
8844
dissect_nfs4_client_id(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
8845
0
{
8846
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
8847
0
  offset = dissect_rpc_data(tvb, pinfo, tree, hf_nfs4_client_id, offset);
8848
8849
0
  return offset;
8850
0
}
8851
8852
8853
static unsigned
8854
dissect_nfs4_newtime(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
8855
0
{
8856
0
  unsigned new_time;
8857
8858
0
  new_time = tvb_get_ntohl(tvb, offset);
8859
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_newtime, offset);
8860
8861
0
  if (new_time) {
8862
0
    offset = dissect_nfs4_nfstime(tvb, offset, tree);
8863
0
  }
8864
8865
0
  return offset;
8866
0
}
8867
8868
8869
static unsigned
8870
dissect_nfs4_newsize(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
8871
0
{
8872
0
  unsigned new_size;
8873
8874
0
  new_size = tvb_get_ntohl(tvb, offset);
8875
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_newsize, offset);
8876
8877
0
  if (new_size) {
8878
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
8879
0
  }
8880
8881
0
  return offset;
8882
0
}
8883
8884
8885
static unsigned
8886
dissect_nfs4_newoffset(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
8887
0
{
8888
0
  unsigned new_offset;
8889
8890
0
  new_offset = tvb_get_ntohl(tvb, offset);
8891
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_newoffset, offset);
8892
8893
0
  if (new_offset) {
8894
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8895
0
  }
8896
8897
0
  return offset;
8898
0
}
8899
8900
static const value_string io_advise_names[] = {
8901
#define IO_ADVISE4_NORMAL                 0
8902
  { IO_ADVISE4_NORMAL,    "Normal"  },
8903
#define IO_ADVISE4_SEQUENTIAL             1
8904
  { IO_ADVISE4_SEQUENTIAL,    "Sequential"  },
8905
#define IO_ADVISE4_SEQUENTIAL_BACKWARDS   2
8906
  { IO_ADVISE4_SEQUENTIAL_BACKWARDS,    "Sequential Backwards"  },
8907
#define IO_ADVISE4_RANDOM                 3
8908
  { IO_ADVISE4_RANDOM,    "Random"  },
8909
#define IO_ADVISE4_WILLNEED               4
8910
  { IO_ADVISE4_WILLNEED,    "Will Need" },
8911
#define IO_ADVISE4_WILLNEED_OPPORTUNISTIC 5
8912
  { IO_ADVISE4_WILLNEED_OPPORTUNISTIC,    "Will Need Opportunistic" },
8913
#define IO_ADVISE4_DONTNEED               6
8914
  { IO_ADVISE4_DONTNEED,    "Don't Need"  },
8915
#define IO_ADVISE4_NOREUSE                7
8916
  { IO_ADVISE4_NOREUSE,    "No Reuse" },
8917
#define IO_ADVISE4_READ                   8
8918
  { IO_ADVISE4_READ,    "Read"  },
8919
#define IO_ADVISE4_WRITE                  9
8920
  { IO_ADVISE4_WRITE,    "Write"  },
8921
#define IO_ADVISE4_INIT_PROXIMITY         10
8922
  { IO_ADVISE4_INIT_PROXIMITY,    "Init Proximity"  },
8923
  { 0,  NULL  }
8924
};
8925
static value_string_ext io_advise_names_ext = VALUE_STRING_EXT_INIT(io_advise_names);
8926
8927
static unsigned
8928
dissect_nfs4_io_hints(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
8929
0
{
8930
0
  static nfs4_bitmap_info_t bitmap_info = {
8931
0
    .vse_names_ext = &io_advise_names_ext,
8932
0
    .hf_mask_label = &hf_nfs4_io_hints_mask,
8933
0
    .hf_item_label = &hf_nfs4_io_advise_hint,
8934
0
    .hf_item_count = &hf_nfs4_io_hint_count,
8935
0
  };
8936
8937
0
  return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, -1, -1, &bitmap_info, NFS4_BITMAP_MASK, NULL);
8938
0
}
8939
8940
static const value_string cb_recall_any_names[] = {
8941
/* RFC 5661 Network File System (NFS) Version 4 Minor Version 1 Protocol */
8942
#define RCA4_TYPE_MASK_RDATA_DLG    0
8943
  { RCA4_TYPE_MASK_RDATA_DLG,   "Read Delegation" },
8944
#define RCA4_TYPE_MASK_WDATA_DLG    1
8945
  { RCA4_TYPE_MASK_WDATA_DLG,   "Write Delegation"  },
8946
#define RCA4_TYPE_MASK_DIR_DLG      2
8947
  { RCA4_TYPE_MASK_DIR_DLG,     "Directory Delegation"  },
8948
#define RCA4_TYPE_MASK_FILE_LAYOUT    3
8949
  { RCA4_TYPE_MASK_FILE_LAYOUT,   "File Layout" },
8950
#define RCA4_TYPE_MASK_BLK_LAYOUT   4
8951
  { RCA4_TYPE_MASK_BLK_LAYOUT,    "Block Layout"  },
8952
#define RCA4_TYPE_MASK_OBJ_LAYOUT_MIN   8
8953
  { RCA4_TYPE_MASK_OBJ_LAYOUT_MIN,    "Object Layout Min" },
8954
#define RCA4_TYPE_MASK_OBJ_LAYOUT_MAX   9
8955
  { RCA4_TYPE_MASK_OBJ_LAYOUT_MAX,    "Object Layout Max" },
8956
#define RCA4_TYPE_MASK_OTHER_LAYOUT_MIN   12
8957
  { RCA4_TYPE_MASK_OTHER_LAYOUT_MIN,  "Other Layout Min"  },
8958
#define RCA4_TYPE_MASK_OTHER_LAYOUT_MAX   15
8959
  { RCA4_TYPE_MASK_OTHER_LAYOUT_MAX,  "Other Layout Max"  },
8960
8961
/* RFC 8435 Parallel NFS (pNFS) Flexible File Layout */
8962
#define RCA4_TYPE_MASK_FF_LAYOUT_MIN    16
8963
  { RCA4_TYPE_MASK_FF_LAYOUT_MIN,   "Flexible File Layout Min"  },
8964
#define RCA4_TYPE_MASK_FF_LAYOUT_MAX    17
8965
  { RCA4_TYPE_MASK_FF_LAYOUT_MAX,   "Flexible File Layout Max"  },
8966
  { 0,  NULL  }
8967
};
8968
static value_string_ext cb_recall_any_names_ext = VALUE_STRING_EXT_INIT(cb_recall_any_names);
8969
8970
static unsigned
8971
dissect_nfs4_cb_recall_any_mask(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
8972
0
{
8973
0
  static nfs4_bitmap_info_t bitmap_info = {
8974
0
    .vse_names_ext = &cb_recall_any_names_ext,
8975
0
    .hf_mask_count = &hf_nfs4_cb_recall_any_count,
8976
0
    .hf_mask_label = &hf_nfs4_cb_recall_any_mask,
8977
0
    .hf_item_label = &hf_nfs4_cb_recall_any_item,
8978
0
  };
8979
8980
0
  return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, -1, -1, &bitmap_info, NFS4_BITMAP_MASK, NULL);
8981
0
}
8982
8983
static unsigned
8984
dissect_nfs4_app_data_block(tvbuff_t *tvb, unsigned offset, proto_tree *tree, uint32_t *hash)
8985
0
{
8986
0
  proto_item *fitem;
8987
8988
0
  uint32_t    pattern_hash;
8989
0
  unsigned    pattern_len;
8990
8991
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8992
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_block_size, offset);
8993
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_block_count, offset);
8994
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_reloff_blocknum, offset);
8995
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_blocknum, offset);
8996
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_reloff_pattern, offset);
8997
8998
0
  pattern_len = tvb_get_ntohl(tvb, offset);
8999
0
  offset += 4;
9000
9001
0
  pattern_hash = crc32_ccitt_tvb_offset(tvb, offset, pattern_len);
9002
0
  fitem = proto_tree_add_uint(tree, hf_nfs4_pattern_hash, tvb, offset, pattern_len, pattern_hash);
9003
0
  proto_item_set_generated(fitem);
9004
0
  proto_item_set_len(fitem, pattern_len);
9005
9006
0
  offset += pattern_len;
9007
9008
0
  if (hash)
9009
0
    *hash = pattern_hash;
9010
9011
0
  return offset;
9012
0
}
9013
9014
static unsigned
9015
dissect_nfs4_io_time(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *timer_mode)
9016
0
{
9017
0
  proto_tree *newtree;
9018
9019
0
  newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_time, NULL, "%s", timer_mode);
9020
0
  offset = dissect_nfs4_nfstime(tvb, offset, newtree);
9021
9022
0
  return offset;
9023
0
}
9024
9025
static unsigned
9026
dissect_nfs4_io_latency(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *io_mode)
9027
0
{
9028
0
  proto_tree *newtree;
9029
9030
0
  newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_latency, NULL, "%s Latency", io_mode);
9031
9032
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_requested, offset);
9033
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_requested, offset);
9034
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_completed, offset);
9035
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_completed, offset);
9036
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_not_delivered, offset);
9037
9038
0
  offset = dissect_nfs4_io_time(tvb, offset, newtree, "Busy time");
9039
0
  offset = dissect_nfs4_io_time(tvb, offset, newtree, "Completion time");
9040
9041
0
  return offset;
9042
0
}
9043
9044
static unsigned
9045
dissect_nfs4_io_info(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *io_mode)
9046
0
{
9047
0
  proto_tree *newtree;
9048
9049
0
  newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_info, NULL, "%s Info", io_mode);
9050
9051
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_count, offset);
9052
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_bytes, offset);
9053
9054
0
  return offset;
9055
0
}
9056
9057
static unsigned
9058
dissect_nfs4_layoutstats(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ, bool has_layout_type)
9059
0
{
9060
0
  unsigned      layout_type = LAYOUT4_NO_LAYOUT_TYPE;
9061
0
  proto_tree *netaddr;
9062
0
  proto_item *fitem;
9063
0
  unsigned    old_offset;
9064
0
  uint32_t      last_fh_hash    = 0;
9065
9066
  /* FIXME: Are these here or in the caller? Check for layoutcommit */
9067
0
  offset = dissect_nfs4_io_info(tvb, offset, tree, "Read");
9068
0
  offset = dissect_nfs4_io_info(tvb, offset, tree, "Write");
9069
0
  offset = dissect_nfs4_deviceid(tvb, offset, tree);
9070
9071
0
  if (has_layout_type) {
9072
0
    layout_type = tvb_get_ntohl(tvb, offset);
9073
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
9074
0
  }
9075
9076
  /* If not flex files layout type eat the rest and move on.. */
9077
0
  if (!has_layout_type || layout_type == LAYOUT4_FLEX_FILES) {
9078
9079
    /* NFS Flex Files */
9080
0
    if (has_layout_type)
9081
0
      offset += 4; /* Skip past opaque count */
9082
9083
    /* The netaddr */
9084
0
    old_offset = offset;
9085
0
    netaddr = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "DS address");
9086
9087
0
    offset = dissect_nfs4_clientaddr(tvb, pinfo, offset, netaddr);
9088
0
    proto_item_set_len(fitem, offset - old_offset);
9089
9090
    /* The file handle */
9091
0
    offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "Filehandle", &last_fh_hash, NULL, NULL, civ, -1, -1);
9092
9093
    /* Read Latency */
9094
0
    offset = dissect_nfs4_io_latency(tvb, offset, tree, "Read");
9095
9096
    /* Write Latency */
9097
0
    offset = dissect_nfs4_io_latency(tvb, offset, tree, "Write");
9098
9099
    /* Duration */
9100
0
    offset = dissect_nfs4_io_time(tvb, offset, tree, "Duration");
9101
9102
    /* Local? */
9103
0
    offset = dissect_rpc_bool(tvb, tree, hf_nfs4_ff_local, offset);
9104
0
  } else {
9105
0
    offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs4_layoutstats);
9106
0
  }
9107
9108
0
  return offset;
9109
0
}
9110
9111
static unsigned
9112
dissect_nfs4_ff_io_stats(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
9113
0
{
9114
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
9115
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
9116
0
  offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
9117
9118
  /* Note that we've already determined that we are in the Flex File Layout Type */
9119
0
  offset = dissect_nfs4_layoutstats(tvb, offset, pinfo, tree, civ, false);
9120
9121
0
  return offset;
9122
0
}
9123
9124
static unsigned
9125
dissect_nfs4_device_errors(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
9126
0
{
9127
0
  proto_item *sub_fitem;
9128
0
  proto_tree *ss_tree;
9129
0
  proto_tree *subtree;
9130
0
  proto_item *ss_fitem;
9131
0
  unsigned    i;
9132
0
  unsigned    count;
9133
9134
0
  unsigned      opcode;
9135
9136
0
  count = tvb_get_ntohl(tvb, offset);
9137
0
  sub_fitem = proto_tree_add_item(tree, hf_nfs4_device_error_count,
9138
0
          tvb, offset, 4, ENC_BIG_ENDIAN);
9139
0
  offset += 4;
9140
9141
0
  subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_device_errors_sub);
9142
0
  for (i = 0; i < count; i++) {
9143
0
    ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_device_errors_index,
9144
0
              tvb, offset+0, 4, i, "Error [%u]", i);
9145
0
    ss_tree = proto_item_add_subtree(ss_fitem,
9146
0
             ett_nfs4_device_errors_sub);
9147
0
    offset = dissect_nfs4_deviceid(tvb, offset, ss_tree);
9148
0
    offset = dissect_nfs4_status(tvb, offset, ss_tree, NULL);
9149
9150
0
    opcode = tvb_get_ntohl(tvb, offset);
9151
0
    proto_tree_add_uint(ss_tree, hf_nfs4_io_error_op, tvb, offset, 4, opcode);
9152
0
    offset += 4;
9153
0
  }
9154
9155
0
  return offset;
9156
0
}
9157
9158
static unsigned
9159
dissect_nfs4_ff_io_error(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
9160
0
{
9161
0
  proto_tree *newtree;
9162
9163
  /* FIXME */
9164
0
  newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_latency, NULL, "IO errors");
9165
9166
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ioerrs_offset, offset);
9167
0
  offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ioerrs_length, offset);
9168
0
  offset = dissect_nfs4_stateid(tvb, offset, newtree, NULL);
9169
9170
0
  offset = dissect_nfs4_device_errors(tvb, offset, newtree);
9171
9172
0
  return offset;
9173
0
}
9174
9175
static unsigned
9176
dissect_nfs4_layoutreturn(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
9177
0
{
9178
0
  unsigned returntype;
9179
0
  unsigned layout_type;
9180
9181
0
  proto_item *sub_fitem;
9182
0
  proto_tree *ss_tree;
9183
0
  proto_tree *subtree;
9184
0
  proto_item *ss_fitem;
9185
0
  unsigned    i;
9186
0
  unsigned    count;
9187
9188
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_reclaim, offset);
9189
9190
0
  layout_type = tvb_get_ntohl(tvb, offset);
9191
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
9192
9193
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_iomode, offset);
9194
9195
0
  returntype = tvb_get_ntohl(tvb, offset);
9196
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_return_type, offset);
9197
0
  if (returntype == 1) { /* RETURN_FILE */
9198
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
9199
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
9200
0
    offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
9201
9202
    /* If not flex files layout type eat the rest and move on.. */
9203
0
    if (layout_type == LAYOUT4_FLEX_FILES) {
9204
0
      offset += 4; /* Skip past opaque count */
9205
9206
      /* Get the errors */
9207
0
      count = tvb_get_ntohl(tvb, offset);
9208
0
      sub_fitem = proto_tree_add_item(tree, hf_nfs4_ff_ioerrs_count,
9209
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
9210
0
      offset += 4;
9211
9212
0
      subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_ff_ioerrs_sub);
9213
0
      for (i = 0; i < count; i++) {
9214
0
        ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_ff_ioerrs_index,
9215
0
                  tvb, offset+0, 4, i, "IO Error [%u]", i);
9216
0
        ss_tree = proto_item_add_subtree(ss_fitem,
9217
0
                 ett_nfs4_ff_ioerrs_sub);
9218
9219
0
        offset = dissect_nfs4_ff_io_error(tvb, offset, ss_tree);
9220
0
      }
9221
9222
      /* Get the stats */
9223
0
      count = tvb_get_ntohl(tvb, offset);
9224
0
      sub_fitem = proto_tree_add_item(tree, hf_nfs4_ff_iostats_count,
9225
0
              tvb, offset, 4, ENC_BIG_ENDIAN);
9226
0
      offset += 4;
9227
9228
0
      subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_ff_iostats_sub);
9229
0
      for (i = 0; i < count; i++) {
9230
0
        ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_ff_iostats_index,
9231
0
                  tvb, offset+0, 4, i, "IO Stat [%u]", i);
9232
0
        ss_tree = proto_item_add_subtree(ss_fitem,
9233
0
                 ett_nfs4_ff_iostats_sub);
9234
9235
0
        offset = dissect_nfs4_ff_io_stats(tvb, offset, pinfo, ss_tree, civ);
9236
0
      }
9237
9238
0
    } else {
9239
0
      offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs4_lrf_body_content);
9240
0
    }
9241
0
  }
9242
9243
0
  return offset;
9244
0
}
9245
9246
static unsigned
9247
dissect_nfs_layoutreturn_stateid(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
9248
0
{
9249
0
  unsigned lrs_present;
9250
9251
0
  lrs_present = tvb_get_ntohl(tvb, offset);
9252
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_lrs_present, offset);
9253
9254
0
  if (lrs_present) {
9255
0
    offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
9256
0
  }
9257
9258
0
  return offset;
9259
0
}
9260
9261
static const value_string notify_type4[] = {
9262
#define NOTIFY4_CHANGE_CHILD_ATTRS  0
9263
  { NOTIFY4_CHANGE_CHILD_ATTRS, "Change Child Attrs" },
9264
#define NOTIFY4_CHANGE_DIR_ATTRS  1
9265
  { NOTIFY4_CHANGE_DIR_ATTRS, "Change Dir Attrs" },
9266
#define NOTIFY4_REMOVE_ENTRY    2
9267
  { NOTIFY4_REMOVE_ENTRY, "Remove Entry" },
9268
#define NOTIFY4_ADD_ENTRY   3
9269
  { NOTIFY4_ADD_ENTRY, "Add Entry" },
9270
#define NOTIFY4_RENAME_ENTRY    4
9271
  { NOTIFY4_RENAME_ENTRY, "Rename Entry" },
9272
#define NOTIFY4_CHANGE_COOKIE_VERIFIER  5
9273
  { NOTIFY4_CHANGE_COOKIE_VERIFIER, "Change Cookie Verifier" },
9274
  /*
9275
   * Added in NFSv4.1 bis document
9276
   */
9277
#define NOTIFY4_GFLAG_EXTEND    6
9278
  { NOTIFY4_GFLAG_EXTEND, "RFC8881bis Extensions Supported" },
9279
#define NOTIFY4_AUFLAG_VALID    7
9280
  { NOTIFY4_AUFLAG_VALID, "Lookup Authorization Flags Valid" },
9281
#define NOTIFY4_AUFLAG_OWNER  8
9282
  { NOTIFY4_AUFLAG_OWNER, "Owner LOOKUP Authorized" },
9283
#define NOTIFY4_AUFLAG_GROUP    9
9284
  { NOTIFY4_AUFLAG_GROUP, "Group LOOKUP Authorized" },
9285
#define NOTIFY4_AUFLAG_OTHER    10
9286
  { NOTIFY4_AUFLAG_OTHER, "Other LOOKUP Authorized" },
9287
#define NOTIFY4_CHANGE_AUTH   11
9288
  { NOTIFY4_CHANGE_AUTH, "LOOKUP Authorization Change" },
9289
#define NOTIFY4_CFLAG_ORDER   12
9290
  { NOTIFY4_CFLAG_ORDER, "Directory Ordering Info Requested" },
9291
#define NOTIFY4_AUFLAG_GANOW    13
9292
  { NOTIFY4_AUFLAG_GANOW, "GETATTRs Require No Access Checks" },
9293
#define NOTIFY4_AUFLAG_GALATER    14
9294
  { NOTIFY4_AUFLAG_GALATER, "GETATTRs Require Access Checks" },
9295
#define NOTIFY4_CHANGE_GA   15
9296
  { NOTIFY4_CHANGE_GA, "GETATTR Authorization Change" },
9297
#define NOTIFY4_CHANGE_AMASK    16
9298
  { NOTIFY4_CHANGE_AMASK, "Update to Change Notification Mask" },
9299
  { 0,  NULL  }
9300
};
9301
static value_string_ext notify_type4_ext = VALUE_STRING_EXT_INIT(notify_type4);
9302
9303
static unsigned
9304
dissect_nfs4_notify_type4_bitmap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset, uint32_t opcode, uint32_t fh_idx)
9305
0
{
9306
0
  static nfs4_bitmap_info_t bitmap_info = {
9307
0
    .vse_names_ext = &notify_type4_ext,
9308
0
    .hf_mask_label = &hf_nfs4_notify_mask,
9309
0
    .hf_item_label = &hf_nfs4_notify_type,
9310
0
  };
9311
9312
0
  return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, opcode, fh_idx, &bitmap_info, NFS4_BITMAP_MASK,
9313
0
           NULL);
9314
0
}
9315
9316
static const value_string notify_deviceid_type4[] = {
9317
#define NOTIFY_DEVICEID4_CHANGE      1
9318
  { NOTIFY_DEVICEID4_CHANGE, "Change" },
9319
#define NOTIFY_DEVICEID4_DELETE      2
9320
  { NOTIFY_DEVICEID4_DELETE, "Delete" },
9321
  { 0,  NULL  }
9322
};
9323
static value_string_ext notify_deviceid_type4_ext = VALUE_STRING_EXT_INIT(notify_deviceid_type4);
9324
9325
9326
static unsigned
9327
dissect_nfs4_notify_deviceid_bitmap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, unsigned offset)
9328
0
{
9329
0
  static nfs4_bitmap_info_t bitmap_info = {
9330
0
    .vse_names_ext = &notify_deviceid_type4_ext,
9331
0
    .hf_mask_label = &hf_nfs4_notify_deviceid_mask,
9332
0
    .hf_item_label = &hf_nfs4_notify_deviceid_type,
9333
0
  };
9334
9335
0
  return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, -1, -1, &bitmap_info, NFS4_BITMAP_MASK, NULL);
9336
0
}
9337
9338
9339
static unsigned
9340
dissect_nfs4_devices_file(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
9341
0
{
9342
0
  unsigned i, j;
9343
0
  uint32_t num_indices, num_multipath, num_addr;
9344
9345
  /* dissect indices */
9346
0
  num_indices = tvb_get_ntohl(tvb, offset);
9347
0
  offset += 4;
9348
0
  for (i = 0; i < num_indices; i++) {
9349
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_deviceidx, offset);
9350
0
  }
9351
9352
0
  num_multipath = tvb_get_ntohl(tvb, offset);
9353
0
  offset += 4;
9354
0
  for (i = 0; i < num_multipath; i++) {
9355
0
    num_addr = tvb_get_ntohl(tvb, offset);
9356
0
    offset += 4;
9357
0
    for (j = 0; j < num_addr; j++) {
9358
0
      offset = dissect_rpc_string(tvb, pinfo, tree, hf_nfs4_r_netid, offset, NULL);
9359
0
      offset = dissect_rpc_string(tvb, pinfo, tree, hf_nfs4_r_addr, offset, NULL);
9360
0
    }
9361
0
  }
9362
9363
0
  return offset;
9364
0
}
9365
9366
static unsigned
9367
dissect_nfs4_devices_flexfile(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
9368
0
{
9369
0
  unsigned i;
9370
0
  uint32_t num_addr;
9371
0
  uint32_t num_vers;
9372
9373
  /* dissect indices */
9374
0
  num_addr = tvb_get_ntohl(tvb, offset);
9375
0
  offset += 4;
9376
0
  for (i = 0; i < num_addr; i++) {
9377
0
    offset = dissect_rpc_string(tvb, pinfo, tree, hf_nfs4_r_netid, offset,
9378
0
              NULL);
9379
0
    offset = dissect_rpc_string(tvb, pinfo, tree, hf_nfs4_r_addr, offset,
9380
0
              NULL);
9381
0
  }
9382
9383
0
  num_vers = tvb_get_ntohl(tvb, offset);
9384
0
  offset += 4;
9385
9386
0
  for (i = 0; i < num_vers; i++) {
9387
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_version, offset);
9388
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_minorversion,
9389
0
            offset);
9390
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_rsize,
9391
0
            offset);
9392
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_wsize,
9393
0
            offset);
9394
0
    offset = dissect_rpc_bool(tvb, tree, hf_nfs4_ff_tightly_coupled,
9395
0
          offset);
9396
0
  }
9397
9398
0
  return offset;
9399
0
}
9400
9401
static const value_string scsi_vol_type_names[] = {
9402
0
#define PNFS_SCSI_VOLUME_SLICE  1
9403
  { PNFS_SCSI_VOLUME_SLICE,   "Slice" },
9404
0
#define PNFS_SCSI_VOLUME_CONCAT 2
9405
  { PNFS_SCSI_VOLUME_CONCAT,  "Concat" },
9406
0
#define PNFS_SCSI_VOLUME_STRIPE 3
9407
  { PNFS_SCSI_VOLUME_STRIPE,  "Stripe" },
9408
0
#define PNFS_SCSI_VOLUME_BASE 4
9409
  { PNFS_SCSI_VOLUME_BASE,    "Base" },
9410
  { 0,  NULL }
9411
};
9412
9413
static const value_string scsi_vpd_designator_type_names[] = {
9414
#define PS_DESIGNATOR_T10 1
9415
  { PS_DESIGNATOR_T10,  "T10" },
9416
#define PS_DESIGNATOR_EUI64 2
9417
  { PS_DESIGNATOR_EUI64,  "EUI64" },
9418
#define PS_DESIGNATOR_NAA 3
9419
  { PS_DESIGNATOR_NAA,  "NAA" },
9420
#define PS_DESIGNATOR_NAME  8
9421
  { PS_DESIGNATOR_NAME, "Name" },
9422
  { 0,  NULL }
9423
};
9424
9425
static const value_string scsi_vpd_code_set_names[] = {
9426
#define PS_CODE_SET_BINARY  1
9427
  { PS_CODE_SET_BINARY, "binary" },
9428
#define PS_CODE_SET_ASCII 2
9429
  { PS_CODE_SET_ASCII,  "ASCII" },
9430
#define PS_CODE_SET_UTF8  3
9431
  { PS_CODE_SET_UTF8, "UTF8" },
9432
  { 0,  NULL }
9433
};
9434
9435
static const value_string scsi_extent_state_names[] = {
9436
#define PNFS_SCSI_EXT_READ_WRITE_DATA    0
9437
  { PNFS_SCSI_EXT_READ_WRITE_DATA,  "READ_WRITE_DATA" },
9438
#define PNFS_SCSI_EXT_READ_DATA      1
9439
  { PNFS_SCSI_EXT_READ_DATA,  "READ_DATA" },
9440
#define PNFS_SCSI_EXT_INVALID_DATA     2
9441
  { PNFS_SCSI_EXT_INVALID_DATA, "INVALID_DATA" },
9442
#define PNFS_SCSI_EXT_NONE_DATA      3
9443
  { PNFS_SCSI_EXT_NONE_DATA,  "NONE_DATA" },
9444
  { 0,  NULL }
9445
};
9446
9447
static unsigned
9448
dissect_nfs4_devices_scsi_base_volume(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
9449
0
{
9450
0
  uint32_t desig_len;
9451
9452
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_devaddr_scsi_vpd_code_set, offset);
9453
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_devaddr_scsi_vpd_designator_type, offset);
9454
9455
0
  desig_len = tvb_get_ntohl(tvb, offset);
9456
0
  offset += 4;
9457
0
  proto_tree_add_item(tree, hf_nfs4_devaddr_scsi_vpd_designator,
9458
0
    tvb, offset, desig_len, ENC_NA);
9459
0
  offset += desig_len;
9460
9461
0
  proto_tree_add_item(tree, hf_nfs4_devaddr_scsi_private_key,
9462
0
    tvb, offset, 8, ENC_NA);
9463
0
  offset += 8;
9464
9465
0
  return offset;
9466
0
}
9467
9468
static unsigned
9469
dissect_nfs4_vol_indices(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
9470
0
{
9471
0
  unsigned i;
9472
0
  uint32_t num_vols;
9473
0
  proto_item *indices_item;
9474
0
  proto_tree *indices_tree;
9475
9476
0
  num_vols = tvb_get_ntohl(tvb, offset);
9477
0
  offset += 4;
9478
0
  if (num_vols == 0)
9479
0
    return offset;
9480
9481
0
  indices_tree = proto_tree_add_subtree_format(tree, tvb, offset, 0,
9482
0
        ett_nfs4_scsi_layout_vol_indices, &indices_item,
9483
0
        "volume indices");
9484
0
  for (i = 0; i < num_vols; i++) {
9485
0
    proto_tree_add_item(indices_tree, hf_nfs4_devaddr_scsi_vol_ref_index,
9486
0
        tvb, offset, 4, ENC_BIG_ENDIAN);
9487
0
    offset += 4;
9488
0
  }
9489
0
  return offset;
9490
0
}
9491
9492
static unsigned
9493
dissect_nfs4_devices_scsi(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
9494
0
{
9495
0
  unsigned i;
9496
0
  proto_item *vol_item;
9497
0
  proto_tree *vol_tree;
9498
0
  int old_offset = offset;
9499
0
  uint32_t num_vols;
9500
0
  uint32_t vol_type;
9501
9502
0
  num_vols = tvb_get_ntohl(tvb, offset);
9503
0
  offset += 4;
9504
9505
0
  for (i = 0; i < num_vols; i++) {
9506
9507
0
    vol_item = proto_tree_add_item_ret_uint(tree, hf_nfs4_devaddr_scsi_vol_type, tvb, offset, 4, ENC_BIG_ENDIAN, &vol_type);
9508
0
    vol_tree = proto_item_add_subtree(vol_item, ett_nfs4_scsi_layout_vol);
9509
0
    offset += 4;
9510
0
    proto_tree_add_uint(vol_tree, hf_nfs4_devaddr_scsi_vol_index, tvb, offset, 0, i);
9511
0
    switch (vol_type)
9512
0
    {
9513
0
    case PNFS_SCSI_VOLUME_SLICE:
9514
0
      proto_tree_add_item(vol_tree, hf_nfs4_devaddr_ssv_start, tvb, offset, 8, ENC_BIG_ENDIAN);
9515
0
      proto_tree_add_item(vol_tree, hf_nfs4_devaddr_ssv_length, tvb, offset + 8, 8, ENC_BIG_ENDIAN);
9516
0
      proto_tree_add_item(vol_tree, hf_nfs4_devaddr_scsi_vol_ref_index, tvb, offset + 16, 4, ENC_BIG_ENDIAN);
9517
0
      offset += 20;
9518
0
      break;
9519
0
    case PNFS_SCSI_VOLUME_CONCAT:
9520
0
      offset = dissect_nfs4_vol_indices(tvb, offset, vol_tree);
9521
0
      break;
9522
0
    case PNFS_SCSI_VOLUME_STRIPE:
9523
0
      proto_tree_add_item(vol_tree, hf_nfs4_devaddr_ssv_stripe_unit, tvb, offset, 8, ENC_BIG_ENDIAN);
9524
0
      offset += 8;
9525
0
      offset = dissect_nfs4_vol_indices(tvb, offset, vol_tree);
9526
0
      break;
9527
0
    case PNFS_SCSI_VOLUME_BASE:
9528
0
      offset = dissect_nfs4_devices_scsi_base_volume(tvb, offset, vol_tree);
9529
0
      break;
9530
0
    }
9531
9532
0
    proto_item_set_len(vol_item, offset - old_offset);
9533
0
    old_offset = offset;
9534
0
  }
9535
9536
0
  return offset;
9537
0
}
9538
9539
9540
static int
9541
dissect_nfs4_test_stateid_arg(tvbuff_t *tvb, unsigned offset, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
9542
0
{
9543
0
  return dissect_nfs4_stateid(tvb, offset, tree, NULL);
9544
0
}
9545
9546
9547
static int
9548
dissect_nfs4_test_stateid_res(tvbuff_t *tvb, unsigned offset, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
9549
0
{
9550
0
  return dissect_nfs4_status(tvb, offset, tree, NULL);
9551
0
}
9552
9553
static unsigned
9554
dissect_nfs4_netloc(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
9555
0
{
9556
0
  unsigned netloc_type;
9557
0
  proto_tree *netaddr;
9558
0
  int old_offset;
9559
0
  proto_item *fitem;
9560
9561
  /* netloc type */
9562
0
  netloc_type = tvb_get_ntohl(tvb, offset);
9563
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_netloc_type, offset);
9564
9565
0
  switch (netloc_type) {
9566
0
  case NL4_NAME:
9567
0
    offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_nl_name, NULL);
9568
0
    break;
9569
0
  case NL4_URL:
9570
0
    offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_nl_url, NULL);
9571
0
    break;
9572
0
  case NL4_NETADDR:
9573
0
    old_offset = offset;
9574
0
    netaddr = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "netaddr");
9575
9576
0
    offset = dissect_nfs4_clientaddr(tvb, pinfo, offset, netaddr);
9577
0
    proto_item_set_len(fitem, offset - old_offset);
9578
0
    break;
9579
0
  default:
9580
    /* back up to re-read the length field when treating as
9581
     * opaque */
9582
0
    offset -= 4;
9583
0
    offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs4_netloc);
9584
0
    break;
9585
0
  }
9586
9587
0
  return offset;
9588
0
}
9589
9590
static unsigned
9591
dissect_nfs4_copy_reqs(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
9592
0
{
9593
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_consecutive, offset);
9594
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_synchronous, offset);
9595
9596
0
  return offset;
9597
0
}
9598
9599
static unsigned
9600
dissect_nfs4_write_response(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
9601
0
{
9602
0
  proto_item *sub_fitem;
9603
0
  proto_tree *ss_tree;
9604
0
  proto_tree *subtree;
9605
0
  proto_item *ss_fitem;
9606
0
  unsigned    i;
9607
0
  uint32_t      count;
9608
9609
  /* Number of callback stateids */
9610
0
  sub_fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_callback_stateids,
9611
0
      tvb, offset, 4, ENC_BIG_ENDIAN, &count);
9612
0
  offset += 4;
9613
9614
0
  subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_callback_stateids_sub);
9615
0
  for (i = 0; i < count; i++) {
9616
0
    ss_fitem = proto_tree_add_uint(subtree,
9617
0
        hf_nfs4_callback_stateids_index,
9618
0
        tvb, offset, 4, i);
9619
9620
0
    ss_tree = proto_item_add_subtree(ss_fitem,
9621
0
        ett_nfs4_callback_stateids_sub);
9622
0
    offset = dissect_nfs4_stateid(tvb, offset, ss_tree, NULL);
9623
0
  }
9624
9625
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
9626
0
  offset = dissect_nfs4_stable_how(tvb, pinfo, offset, tree, "committed");
9627
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
9628
9629
0
  return offset;
9630
0
}
9631
9632
static unsigned
9633
dissect_nfs4_source_servers(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
9634
0
{
9635
0
  proto_item *sub_fitem;
9636
0
  proto_tree *ss_tree;
9637
0
  proto_tree *subtree;
9638
0
  proto_item *ss_fitem;
9639
0
  unsigned    i;
9640
0
  uint32_t      source_servers;
9641
9642
  /* Number of source servers */
9643
0
  sub_fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_source_servers,
9644
0
      tvb, offset, 4, ENC_BIG_ENDIAN, &source_servers);
9645
0
  offset += 4;
9646
9647
0
  subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_source_servers_sub);
9648
0
  for (i = 0; i < source_servers; i++) {
9649
0
    ss_fitem = proto_tree_add_uint(subtree,
9650
0
        hf_nfs4_source_server_index,
9651
0
        tvb, offset, 4, i);
9652
9653
0
    ss_tree = proto_item_add_subtree(ss_fitem,
9654
0
        ett_nfs4_source_servers_sub);
9655
9656
0
    offset = dissect_nfs4_netloc(tvb, pinfo, offset, ss_tree);
9657
0
  }
9658
9659
0
  return offset;
9660
0
}
9661
9662
static unsigned
9663
dissect_nfs4_deviceaddr(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
9664
0
{
9665
0
  unsigned layout_type;
9666
9667
  /* layout type */
9668
0
  layout_type = tvb_get_ntohl(tvb, offset);
9669
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
9670
9671
  /* skip length */
9672
0
  offset+=4;
9673
9674
0
  switch (layout_type) {
9675
0
  case LAYOUT4_NFSV4_1_FILES:
9676
0
    offset = dissect_nfs4_devices_file(tvb, pinfo, offset, tree);
9677
0
    break;
9678
0
  case LAYOUT4_FLEX_FILES:
9679
0
    offset = dissect_nfs4_devices_flexfile(tvb, pinfo, offset, tree);
9680
0
    break;
9681
0
  case LAYOUT4_SCSI:
9682
0
    offset = dissect_nfs4_devices_scsi(tvb, offset, tree);
9683
0
  break;
9684
0
  default:
9685
    /* back up to re-read the length field when treating as
9686
     * opaque */
9687
0
    offset -= 4;
9688
0
    offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs4_getdevinfo);
9689
0
    break;
9690
0
  }
9691
9692
0
  return offset;
9693
0
}
9694
9695
9696
static unsigned
9697
dissect_nfs4_devicelist(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
9698
0
{
9699
0
  unsigned count;
9700
0
  unsigned i;
9701
9702
0
  count = tvb_get_ntohl(tvb, offset);
9703
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_devicenum, offset);
9704
0
  for (i = 0; i < count; i++)
9705
0
    offset = dissect_nfs4_deviceid(tvb, offset, tree);
9706
9707
0
  return offset;
9708
0
}
9709
9710
9711
static unsigned
9712
dissect_rpc_serverowner4(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree)
9713
0
{
9714
0
  offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_minorid, offset);
9715
0
  offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs4_majorid);
9716
0
  return offset;
9717
0
}
9718
9719
9720
static unsigned
9721
dissect_rpc_chanattrs4(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *name)
9722
0
{
9723
0
  proto_tree *chan_attrs_tree;
9724
0
  unsigned i, count, rdma_ird_len;
9725
9726
0
  rdma_ird_len = tvb_get_ntohl(tvb, offset + 24);
9727
0
  count = 28 + rdma_ird_len * 4;
9728
9729
0
  chan_attrs_tree = proto_tree_add_subtree(tree, tvb, offset, count, ett_nfs4_chan_attrs, NULL, name);
9730
9731
0
  offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_padsize, offset);
9732
0
  offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxreqsize, offset);
9733
0
  offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxrespsize, offset);
9734
0
  offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxrespsizecached, offset);
9735
0
  offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxops, offset);
9736
0
  offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxreqs, offset);
9737
0
  offset += 4;
9738
0
  for (i = 0; i < rdma_ird_len; i++) {
9739
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_rdmachanattrs, offset);
9740
0
  }
9741
0
  return offset;
9742
0
}
9743
9744
9745
static unsigned
9746
dissect_rpc_nfs_impl_id4(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *tree, const char *name)
9747
0
{
9748
0
  proto_tree *impl_id_tree;
9749
0
  unsigned i, count;
9750
9751
0
  count = tvb_get_ntohl(tvb, offset);
9752
0
  impl_id_tree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_nfs4_clientowner, NULL, name);
9753
0
  offset += 4;
9754
9755
0
  for (i = 0; i < count; i++) {
9756
0
    proto_tree *date_tree;
9757
9758
0
    offset = dissect_nfs_utf8string(tvb, pinfo, offset, impl_id_tree, hf_nfs4_nii_domain, NULL);
9759
0
    offset = dissect_nfs_utf8string(tvb, pinfo, offset, impl_id_tree, hf_nfs4_nii_name, NULL);
9760
9761
0
    date_tree = proto_tree_add_subtree(impl_id_tree, tvb, offset, 12, ett_nfs4_clientowner, NULL, "Build timestamp(nii_date)");
9762
0
    offset = dissect_nfs4_nfstime(tvb, offset, date_tree);
9763
0
  }
9764
0
  return offset;
9765
0
}
9766
9767
9768
static unsigned
9769
dissect_rpc_secparms4(tvbuff_t *tvb, packet_info* pinfo, unsigned offset, proto_tree *parent_tree)
9770
0
{
9771
0
  unsigned count, i;
9772
0
  int array_offset;
9773
0
  proto_tree *array_tree;
9774
0
  proto_item *array_item;
9775
9776
0
  array_offset = offset;
9777
0
  array_tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0, ett_nfs4_sec_parms_array, &array_item, "cb_sec_parms");
9778
9779
0
  count = tvb_get_ntohl(tvb, offset);
9780
0
  offset += 4;
9781
9782
0
  for (i = 0; i < count; i++) {
9783
0
    proto_item *item;
9784
0
    int item_offset = offset;
9785
0
    proto_tree *tree = proto_tree_add_subtree(array_tree, tvb, offset, 0, ett_nfs4_sec_parms_item, &item, "entry");
9786
0
    unsigned j, flavor = tvb_get_ntohl(tvb, offset);
9787
0
    offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_flavor, offset);
9788
9789
0
    switch (flavor) {
9790
0
    case AUTH_NULL:
9791
0
      break;
9792
0
    case AUTH_UNIX: {
9793
0
      unsigned count2;
9794
0
      proto_tree *tree2;
9795
0
      offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_stamp, offset);
9796
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_machinename, NULL);
9797
0
      offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_uid, offset);
9798
0
      offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_gid, offset);
9799
0
      count2 = tvb_get_ntohl(tvb, offset);
9800
0
      tree2 = proto_tree_add_subtree_format(tree, tvb, offset,
9801
0
          4+count2*4, ett_nfs4_gids, NULL, "auxiliary gids (%u)", count2);
9802
0
      offset += 4;
9803
0
      for (j = 0; j < count2; j++) {
9804
0
        offset = dissect_rpc_uint32(tvb, tree2, hf_nfs4_gid, offset);
9805
0
      }
9806
0
      break;
9807
0
    }
9808
0
    case RPCSEC_GSS:
9809
0
      offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_service, offset);
9810
0
      proto_item_append_text(tree, ", Handle from server");
9811
0
      offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs_data);
9812
0
      proto_item_append_text(tree, ", Handle from client");
9813
0
      offset = dissect_nfsdata(tvb, pinfo, offset, tree, hf_nfs_data);
9814
0
      break;
9815
0
    default:
9816
      /* Report fatal error as it is not possible to figure out item length and therefore
9817
       * not possible to continue parsing next item or continue parsing next packet. */
9818
0
      THROW(ReportedBoundsError);
9819
0
    }
9820
9821
0
    proto_item_set_len(item, offset - item_offset);
9822
0
  }
9823
9824
0
  proto_item_set_len(array_item, offset - array_offset);
9825
9826
0
  return offset;
9827
0
}
9828
9829
static unsigned
9830
dissect_nfs4_layoutget(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
9831
0
{
9832
0
  unsigned      layout_type;
9833
0
  unsigned      sub_num;
9834
0
  unsigned      nfl_util;
9835
0
  unsigned      lo_seg_count;
9836
0
  unsigned      i, j, k, lo_seg;
9837
0
  proto_tree *newtree;
9838
0
  proto_item *sub_fitem;
9839
0
  proto_tree *subtree;
9840
0
  proto_tree *nfl_item;
9841
0
  proto_tree *nfl_tree;
9842
9843
0
  static int * const layout_flags[] = {
9844
0
    &hf_nfs4_ff_layout_flags_no_layoutcommit,
9845
0
    &hf_nfs4_ff_layout_flags_no_io_thru_mds,
9846
0
    &hf_nfs4_ff_layout_flags_no_read_io,
9847
0
    NULL
9848
0
  };
9849
9850
0
  lo_seg_count = tvb_get_ntohl(tvb, offset);
9851
9852
0
  newtree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_nfs4_layoutseg, NULL,
9853
0
                      "Layout Segment (count: %u)", lo_seg_count);
9854
0
  offset += 4;
9855
9856
0
  for (lo_seg = 0; lo_seg < lo_seg_count; lo_seg++) {
9857
0
    offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_offset, offset);
9858
0
    offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_length, offset);
9859
9860
0
    offset = dissect_rpc_uint32(tvb, newtree, hf_nfs4_iomode, offset);
9861
9862
0
    layout_type = tvb_get_ntohl(tvb, offset);
9863
0
    offset = dissect_rpc_uint32(tvb, newtree, hf_nfs4_layout_type, offset);
9864
9865
    /* If not files layout type eat the rest and move on.. */
9866
0
    if (layout_type == LAYOUT4_NFSV4_1_FILES) {
9867
      /* NFS Files */
9868
0
      offset += 4; /* Skip past opaque count */
9869
9870
0
      offset = dissect_nfs4_deviceid(tvb, offset, newtree);
9871
9872
      /* Get nfl_util and break it down into its components */
9873
0
      nfl_util = tvb_get_ntohl(tvb, offset);
9874
0
      nfl_item = proto_tree_add_uint(newtree, hf_nfs4_nfl_util, tvb, offset, 4, nfl_util);
9875
0
      nfl_tree = proto_item_add_subtree(nfl_item, ett_nfs4_nfl_util);
9876
0
      proto_tree_add_uint(nfl_tree, hf_nfs4_nfl_util_stripe_size, tvb, offset, 4, nfl_util&NFL4_UFLG_STRIPE_UNIT_SIZE_MASK);
9877
0
      proto_tree_add_uint(nfl_tree, hf_nfs4_nfl_util_commit_thru_mds, tvb, offset+3, 1, (nfl_util&NFL4_UFLG_COMMIT_THRU_MDS?1:0));
9878
0
      proto_tree_add_uint(nfl_tree, hf_nfs4_nfl_util_dense, tvb, offset+3, 1, (nfl_util&NFL4_UFLG_DENSE?1:0));
9879
0
      offset += 4;
9880
9881
0
      offset = dissect_rpc_uint32(tvb, newtree,
9882
0
          hf_nfs4_nfl_first_stripe_index, offset);
9883
0
      offset = dissect_rpc_uint64(tvb, newtree,
9884
0
          hf_nfs4_offset, offset);
9885
9886
0
      sub_num = tvb_get_ntohl(tvb, offset); /* Len of FH list */
9887
9888
0
      sub_fitem = proto_tree_add_item(newtree, hf_nfs4_nfl_fhs,
9889
0
          tvb, offset, 4, ENC_BIG_ENDIAN);
9890
0
      offset += 4;
9891
9892
0
      subtree = proto_item_add_subtree(sub_fitem,
9893
0
          ett_nfs4_layoutseg_sub);
9894
0
      for (i = 0; i < sub_num; i++)
9895
0
        offset = dissect_nfs4_fh(tvb, offset, pinfo,
9896
0
            subtree, "lo_filehandle",
9897
0
            NULL, NULL, NULL,
9898
0
            civ, -1, -1);
9899
0
    } else if (layout_type == LAYOUT4_FLEX_FILES) {
9900
0
      unsigned  ds_count, fh_count;
9901
0
      proto_item *ds_item, *mirrors_item, *subitem;
9902
0
      proto_tree *ds_tree, *mirrors_tree;
9903
0
      unsigned end_offset = offset;
9904
0
      unsigned mirror_start_offset, ds_start_offset;
9905
9906
      /* NFS Flex Files */
9907
0
      end_offset += tvb_get_ntohl(tvb, offset) + 4;
9908
0
      offset += 4; /* Skip past opaque count */
9909
9910
      /* stripe unit */
9911
0
      offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_stripeunit, offset);
9912
9913
      /* Len of mirror list */
9914
0
      sub_num = tvb_get_ntohl(tvb, offset);
9915
0
      mirrors_item = proto_tree_add_uint_format(newtree, hf_nfs4_nfl_mirrors,
9916
0
        tvb, offset, 4, sub_num, "Mirrors (%u)", sub_num);
9917
0
      offset += 4;
9918
9919
0
      mirrors_tree = proto_item_add_subtree(mirrors_item, ett_nfs4_layoutseg_sub);
9920
9921
0
      for (i = 0; i < sub_num; i++) {
9922
9923
0
        mirror_start_offset = offset;
9924
0
        subtree = proto_tree_add_subtree_format(mirrors_tree, tvb, offset, -1,
9925
0
            ett_nfs4_layoutseg_sub, &subitem,
9926
0
            "Mirror: %u", i);
9927
9928
        /* data server count */
9929
0
        ds_count = tvb_get_ntohl(tvb, offset);
9930
0
        offset += 4;
9931
9932
0
        for (j = 0; j < ds_count; j++) {
9933
0
          ds_start_offset = offset;
9934
0
          ds_tree = proto_tree_add_subtree_format(subtree, tvb, offset, -1,
9935
0
              ett_nfs4_layoutseg_sub, &ds_item,
9936
0
              "Data Server: %u", j);
9937
9938
0
          offset = dissect_nfs4_deviceid(tvb, offset,
9939
0
              ds_tree);
9940
0
          offset = dissect_rpc_uint32(tvb, ds_tree,
9941
0
              hf_nfs4_mirror_eff, offset);
9942
0
          offset = dissect_nfs4_stateid(tvb, offset,
9943
0
              ds_tree, NULL);
9944
9945
0
          fh_count = tvb_get_ntohl(tvb, offset);
9946
0
          offset += 4;
9947
9948
0
          for (k = 0; k < fh_count; k++)
9949
0
            offset = dissect_nfs4_fh(tvb, offset,
9950
0
              pinfo, ds_tree, "fh", NULL, NULL, NULL, civ, -1, -1);
9951
9952
0
          offset = dissect_nfs_utf8string(tvb, pinfo, offset,
9953
0
              ds_tree, hf_nfs4_ff_synthetic_owner,
9954
0
              NULL);
9955
0
          offset = dissect_nfs_utf8string(tvb, pinfo, offset,
9956
0
              ds_tree, hf_nfs4_ff_synthetic_owner_group,
9957
0
              NULL);
9958
9959
0
          proto_item_set_len(ds_item, offset - ds_start_offset);
9960
0
        }
9961
9962
0
        proto_item_set_len(subitem, offset - mirror_start_offset);
9963
0
      }
9964
9965
0
      proto_tree_add_bitmask(newtree, tvb, offset, hf_nfs4_ff_layout_flags,
9966
0
            ett_nfs4_ff_layout_flags, layout_flags, ENC_BIG_ENDIAN);
9967
0
      offset += 4;
9968
9969
0
      if (offset + 4 <= end_offset)
9970
0
        offset = dissect_rpc_uint32(tvb, newtree,
9971
0
            hf_nfs4_ff_stats_collect_hint,
9972
0
            offset);
9973
0
    } else if (layout_type == LAYOUT4_SCSI) {
9974
0
      unsigned  ext_count;
9975
0
      proto_tree *ext_tree;
9976
9977
0
      offset += 4; /* Skip past opaque count */
9978
9979
0
      ext_count = tvb_get_ntohl(tvb, offset);
9980
9981
0
      subtree = proto_tree_add_subtree_format(newtree, tvb, offset, 4,
9982
0
            ett_nfs4_layoutseg_sub, NULL, "SCSI Extents (count: %u)",
9983
0
            ext_count);
9984
0
      offset +=4;
9985
9986
0
      for (i = 0; i < ext_count; i++) {
9987
0
        ext_tree = proto_tree_add_subtree_format(subtree, tvb, offset, 4,
9988
0
              ett_nfs4_layoutseg_sub, NULL, "extent %u", i);
9989
0
        offset = dissect_nfs4_deviceid(tvb, offset, ext_tree);
9990
0
        offset = dissect_rpc_uint64(tvb, ext_tree,
9991
0
              hf_nfs4_scsil_ext_file_offset, offset);
9992
0
        offset = dissect_rpc_uint64(tvb, ext_tree,
9993
0
              hf_nfs4_scsil_ext_length, offset);
9994
0
        offset = dissect_rpc_uint64(tvb, ext_tree,
9995
0
              hf_nfs4_scsil_ext_vol_offset, offset);
9996
0
        offset = dissect_rpc_uint32(tvb, ext_tree,
9997
0
              hf_nfs4_scsil_ext_state, offset);
9998
0
      }
9999
0
    } else {
10000
0
      offset = dissect_nfsdata(tvb, pinfo, offset, newtree, hf_nfs4_layout);
10001
0
      continue;
10002
0
    }
10003
0
  }
10004
0
  return offset;
10005
0
}
10006
10007
10008
static unsigned
10009
dissect_nfs_create_session_flags(tvbuff_t *tvb, unsigned offset, proto_tree *tree, int hf_csa)
10010
0
{
10011
0
  int * const flags[] = {
10012
0
    &hf_nfs4_create_session_flags_persist,
10013
0
    &hf_nfs4_create_session_flags_conn_back_chan,
10014
0
    &hf_nfs4_create_session_flags_conn_rdma,
10015
0
    NULL
10016
0
  };
10017
10018
0
  proto_tree_add_bitmask(tree, tvb, offset, hf_csa, ett_nfs4_create_session_flags, flags, ENC_BIG_ENDIAN);
10019
0
  offset += 4;
10020
10021
0
  return offset;
10022
0
}
10023
10024
10025
enum channel_dir_from_client4 {
10026
  CDFC4_FORE = 0x1,
10027
  CDFC4_BACK = 0x2,
10028
  CDFC4_FORE_OR_BOTH = 0x3,
10029
  CDFC4_BACK_OR_BOTH = 0x7
10030
};
10031
10032
static const value_string names_channel_dir_from_client[] = {
10033
  { CDFC4_FORE,   "CDFC4_FORE" },
10034
  { CDFC4_BACK,   "CDFC4_BACK" },
10035
  { CDFC4_FORE_OR_BOTH, "CDFC4_FORE_OR_BOTH" },
10036
  { CDFC4_BACK_OR_BOTH, "CDFC4_BACK_OR_BOTH" },
10037
  { 0, NULL }
10038
};
10039
10040
enum channel_dir_from_server4 {
10041
  CDFS4_FORE = 0x1,
10042
  CDFS4_BACK = 0x2,
10043
  CDFS4_BOTH = 0x3
10044
};
10045
10046
static const value_string names_channel_dir_from_server[] = {
10047
  { CDFS4_FORE, "CDFS4_FORE" },
10048
  { CDFS4_BACK, "CDFS4_BACK" },
10049
  { CDFS4_BOTH, "CDFS4_BOTH" },
10050
  { 0, NULL }
10051
};
10052
10053
#define SECINFO_STYLE4_CURRENT_FH 0
10054
#define SECINFO_STYLE4_PARENT 1
10055
static const value_string names_secinfo_style4[] = {
10056
  { SECINFO_STYLE4_CURRENT_FH,  "SECINFO_STYLE4_CURRENT_FH" },
10057
  { SECINFO_STYLE4_PARENT,  "SECINFO_STYLE4_PARENT"     },
10058
  { 0, NULL }
10059
};
10060
10061
typedef struct _nfs4_operation_summary {
10062
    uint32_t         opcode;
10063
    bool           iserror;
10064
    wmem_strbuf_t *optext;
10065
} nfs4_operation_summary;
10066
10067
10068
/*
10069
 To try to determine which NFSv4 operations are most important in a
10070
  request, we categorize the operations into different "tiers".
10071
10072
 All operations falling into the highest tier (where 1 is highest, 5
10073
  is lowest) are considered to be the "most significant" operations.
10074
  This information is useful for display purposes, filtering, and for
10075
  response time calculations.
10076
10077
 For example, virtually all NFSv4 requests include a GETATTR.  But in
10078
  a request with PUTFH; CLOSE; GETATTR operations, CLOSE is the
10079
  significant operation.
10080
10081
 In a request with PUTFH; GETATTR operations, GETATTR is the
10082
  significant operation.  CLOSE has higher tier than GETATTR, which is
10083
  in a higher tier than PUTFH.
10084
10085
 In practice this seems to be a very reliable method of determining
10086
  the most significant operation(s).
10087
 */
10088
10089
static const int nfs4_operation_tiers[] = {
10090
     1 /* 0 */ ,
10091
     1 /* 1 */ ,
10092
     1 /* 2 */ ,
10093
     2 /* 3, NFS4_OP_ACCESS */ ,
10094
     1 /* 4, NFS4_OP_CLOSE */,
10095
     1 /* 5, NFS4_OP_COMMIT */,
10096
     1 /* 6, NFS4_OP_CREATE */,
10097
     1 /* 7, NFS4_OP_DELEGPURGE */,
10098
     1 /* 8, NFS4_OP_DELEGRETURN */,
10099
     3 /* 9, NFS4_OP_GETATTR */,
10100
     4 /* 10, NFS4_OP_GETFH */,
10101
     1 /* 11, NFS4_OP_LINK  */,
10102
     1 /* 12, NFS4_OP_LOCK */,
10103
     1 /* 13, NFS4_OP_LOCKT */,
10104
     1 /* 14, NFS4_OP_LOCKU */,
10105
     1 /* 15, NFS4_OP_LOOKUP */,
10106
     1 /* 16, NFS4_OP_LOOKUPP */,
10107
     2 /* 17, NFS4_OP_NVERIFY */,
10108
     1 /* 18, NFS4_OP_OPEN */,
10109
     1 /* 19, NFS4_OP_OPENATTR */,
10110
     1 /* 20, NFS4_OP_OPEN_CONFIRM */,
10111
     1 /* 21, NFS4_OP_OPEN_DOWNGRADE */,
10112
     4 /* 22, NFS4_OP_PUTFH */,
10113
     3 /* 23, NFS4_OP_PUTPUBFH  */,
10114
     3 /* 24, NFS4_OP_PUTROOTFH */,
10115
     1 /* 25, NFS4_OP_READ  */,
10116
     1 /* 26, NFS4_OP_READDIR */,
10117
     1 /* 27, NFS4_OP_READLINK  */,
10118
     1 /* 28, NFS4_OP_REMOVE */,
10119
     1 /* 29, NFS4_OP_RENAME */,
10120
     1 /* 30, NFS4_OP_RENEW */,
10121
     4 /* 31, NFS4_OP_RESTOREFH */,
10122
     4 /* 32, NFS4_OP_SAVEFH */,
10123
     1 /* 33, NFS4_OP_SECINFO */,
10124
     1 /* 34, NFS4_OP_SETATTR */,
10125
     1 /* 35, NFS4_OP_SETCLIENTID */,
10126
     1 /* 36, NFS4_OP_SETCLIENTID_CONFIRM */,
10127
     1 /* 37, NFS4_OP_VERIFY */,
10128
     1 /* 38, NFS4_OP_WRITE */,
10129
     1 /* 39, NFS4_OP_RELEASE_LOCKOWNER */,
10130
      /* Minor version 1 */
10131
     1 /* 40, NFS4_OP_BACKCHANNEL_CTL */,
10132
     1 /* 41, NFS4_OP_BIND_CONN_TO_SESSION */,
10133
     1 /* 42, NFS4_OP_EXCHANGE_ID */,
10134
     1 /* 43, NFS4_OP_CREATE_SESSION */,
10135
     1 /* 44, NFS4_OP_DESTROY_SESSION */,
10136
     1 /* 45, NFS4_OP_FREE_STATEID */,
10137
     1 /* 46, NFS4_OP_GET_DIR_DELEGATION */,
10138
     1 /* 47, NFS4_OP_GETDEVINFO */,
10139
     1 /* 48, NFS4_OP_GETDEVLIST */,
10140
     1 /* 49, NFS4_OP_LAYOUTCOMMIT */,
10141
     1 /* 50, NFS4_OP_LAYOUTGET */,
10142
     1 /* 51, NFS4_OP_LAYOUTRETURN */,
10143
     1 /* 52, NFS4_OP_SECINFO_NO_NAME */,
10144
     4 /* 53, NFS4_OP_SEQUENCE */,
10145
     1 /* 54, NFS4_OP_SET_SSV */,
10146
     1 /* 55, NFS4_OP_TEST_STATEID */,
10147
     1 /* 56, NFS4_OP_WANT_DELEGATION  */,
10148
     1 /* 57, NFS4_OP_DESTROY_CLIENTID  */,
10149
     1 /* 58, NFS4_OP_RECLAIM_COMPLETE */,
10150
      /* Minor version 2 */
10151
     1 /* 59, NFS4_OP_ALLOCATE */,
10152
     1 /* 60, NFS4_OP_COPY */,
10153
     1 /* 61, NFS4_OP_COPY_NOTIFY */,
10154
     1 /* 62, NFS4_OP_DEALLOCATE */,
10155
     1 /* 63, NFS4_OP_IO_ADVISE */,
10156
     1 /* 64, NFS4_OP_LAYOUTERROR */,
10157
     1 /* 65, NFS4_OP_LAYOUTSTATS */,
10158
     1 /* 66, NFS4_OP_OFFLOAD_CANCEL */,
10159
     1 /* 67, NFS4_OP_OFFLOAD_STATUS */,
10160
     1 /* 68, NFS4_OP_READ_PLUS */,
10161
     1 /* 69, NFS4_OP_SEEK */,
10162
     1 /* 70, NFS4_OP_WRITE_SAME */,
10163
     1 /* 71, NFS4_OP_CLONE */,
10164
     1 /* 72, NFS4_OP_GETXATTR */,
10165
     1 /* 73, NFS4_OP_SETXATTR */,
10166
     1 /* 74, NFS4_OP_LISTXATTRS */,
10167
     1 /* 75, NFS4_OP_REMOVEXATTR */,
10168
};
10169
10170
#define NFS4_OPERATION_TIER(op) \
10171
0
  ((op) < G_N_ELEMENTS(nfs4_operation_tiers) ? nfs4_operation_tiers[(op)] : 0)
10172
10173
static int * const nfs4_exchid_flags[] = {
10174
  &hf_nfs4_exchid_flags_confirmed_r,
10175
  &hf_nfs4_exchid_flags_upd_conf_rec_a,
10176
  &hf_nfs4_exchid_flags_pnfs_ds,
10177
  &hf_nfs4_exchid_flags_pnfs_mds,
10178
  &hf_nfs4_exchid_flags_non_pnfs,
10179
  &hf_nfs4_exchid_flags_bind_princ,
10180
  &hf_nfs4_exchid_flags_moved_migr,
10181
  &hf_nfs4_exchid_flags_moved_refer,
10182
  NULL
10183
};
10184
10185
typedef struct nfs4_tap_data {
10186
10187
  uint32_t    ops_counter;
10188
  nfs4_operation_summary *op_summary;
10189
  unsigned highest_tier;
10190
} nfs4_tap_data_t;
10191
10192
static unsigned
10193
dissect_nfs4_request_op(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
10194
0
{
10195
0
  const char *name      = NULL;
10196
0
  const char *source_name     = NULL;
10197
0
  const char *dest_name     = NULL;
10198
0
  const char *opname      = NULL;
10199
0
  unsigned      opcode;
10200
0
  unsigned      highest_tier    = 5;
10201
0
  unsigned      current_tier    = 5;
10202
0
  unsigned      first_operation = 1;
10203
  /*unsigned name_offset = 0;*/
10204
0
  uint16_t      sid_hash;
10205
0
  uint64_t      clientid        = 0;
10206
0
  uint32_t      ops;
10207
0
  uint32_t      ops_counter;
10208
0
  uint32_t      summary_counter;
10209
0
  uint32_t      string_length;
10210
0
  int       last_fh_offset  = 0;
10211
0
  int       last_fh_length  = 0;
10212
0
  uint32_t      last_fh_hash    = 0;
10213
0
  uint32_t      saved_fh_hash   = 0;
10214
0
  int       saved_fh_offset = 0;
10215
0
  int       saved_fh_length = 0;
10216
0
  uint32_t      length;
10217
0
  uint32_t      hash;
10218
0
  uint64_t      length64;
10219
0
  uint64_t      file_offset;
10220
0
  proto_item *fitem;
10221
0
  proto_tree *ftree;
10222
0
  proto_tree *newftree      = NULL;
10223
0
  nfs4_operation_summary *op_summary;
10224
0
  uint16_t    dst_sid_hash;
10225
0
  uint64_t    dst_file_offset;
10226
10227
0
  ops = tvb_get_ntohl(tvb, offset+0);
10228
10229
0
  fitem = proto_tree_add_uint_format(tree, hf_nfs4_ops_count, tvb, offset+0, 4, ops,
10230
0
    "Operations (count: %u)", ops);
10231
0
  offset += 4;
10232
10233
0
#define MAX_NFSV4_OPS 128
10234
0
  if (ops > MAX_NFSV4_OPS) {
10235
    /*  Limit the number of operations to something "reasonable."
10236
     *  This is an arbitrary number to keep us from attempting to
10237
     *  allocate too much memory below.
10238
     */
10239
0
    expert_add_info(pinfo, fitem, &ei_nfs_too_many_ops);
10240
0
    ops = MAX_NFSV4_OPS;
10241
0
  }
10242
10243
0
  op_summary = wmem_alloc0_array(pinfo->pool, nfs4_operation_summary, ops);
10244
10245
0
  ftree = proto_item_add_subtree(fitem, ett_nfs4_request_op);
10246
10247
0
  if (ops)
10248
0
    proto_item_append_text(proto_tree_get_parent(tree), ", Ops(%u):", ops);
10249
10250
0
  for (ops_counter=0; ops_counter<ops; ops_counter++)
10251
0
  {
10252
0
    op_summary[ops_counter].optext = wmem_strbuf_new(pinfo->pool, "");
10253
0
    opcode = tvb_get_ntohl(tvb, offset);
10254
0
    op_summary[ops_counter].opcode = opcode;
10255
10256
0
    fitem = proto_tree_add_uint(ftree, hf_nfs4_op, tvb, offset, 4, opcode);
10257
10258
    /* the opcodes are not contiguous */
10259
0
    if ((opcode < NFS4_OP_ACCESS || opcode > NFS4_LAST_OP)
10260
0
    &&  opcode != NFS4_OP_ILLEGAL)
10261
0
      break;
10262
10263
    /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
10264
0
    if (opcode == NFS4_OP_ILLEGAL) {
10265
0
      newftree = proto_item_add_subtree(fitem, ett_nfs4_illegal);
10266
0
    } else if (nfs4_operation_ett[opcode - 3]) {
10267
0
      newftree = proto_item_add_subtree(fitem, *nfs4_operation_ett[opcode - 3]);
10268
0
    } else {
10269
0
      break;
10270
0
    }
10271
10272
0
    opname = val_to_str_ext_const(opcode, &names_nfs4_operation_ext, "Unknown");
10273
0
    offset += 4;
10274
10275
0
    wmem_strbuf_append_printf(op_summary[ops_counter].optext, "%s", opname);
10276
10277
0
    proto_item_append_text(proto_tree_get_parent(tree),
10278
0
      "%s%s", ops_counter ? ", " : " ", opname);
10279
0
    proto_item_append_text(proto_tree_get_parent(ftree),
10280
0
      "%s%s", ops_counter ? ", " : ": ", opname);
10281
10282
0
    switch (opcode)
10283
0
    {
10284
0
    case NFS4_OP_ACCESS:
10285
0
      {
10286
0
        uint32_t *acc_request, amask;
10287
10288
        /* Get access mask to check and save it for comparison in the reply. */
10289
0
        amask = tvb_get_ntohl(tvb, offset);
10290
0
        acc_request = (uint32_t *)wmem_memdup(wmem_file_scope(),  &amask, sizeof(uint32_t));
10291
0
        civ->private_data = acc_request;
10292
10293
0
        if (last_fh_hash != 0)
10294
0
          wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10295
0
        display_access_items(tvb, offset, pinfo, fitem, amask, amask, 'C', 4,
10296
0
          op_summary[ops_counter].optext, "Check") ;
10297
0
        offset+=4;
10298
0
      }
10299
0
      break;
10300
10301
0
    case NFS4_OP_CLOSE:
10302
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10303
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10304
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
10305
0
      break;
10306
10307
0
    case NFS4_OP_COMMIT:
10308
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10309
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10310
0
      length = tvb_get_ntohl(tvb, offset);
10311
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
10312
0
      if (last_fh_hash != 0)
10313
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10314
0
          " FH: 0x%08x Offset: %"PRIu64" Len: %u",
10315
0
          last_fh_hash, file_offset, length);
10316
10317
0
      break;
10318
10319
0
    case NFS4_OP_CREATE:
10320
0
      {
10321
0
        unsigned create_type;
10322
10323
0
        create_type = tvb_get_ntohl(tvb, offset);
10324
0
        offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_ftype, offset);
10325
10326
0
        switch (create_type)
10327
0
        {
10328
0
        case NF4LNK:
10329
0
          offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_linktext, NULL);
10330
0
          break;
10331
10332
0
        case NF4BLK:
10333
0
        case NF4CHR:
10334
0
          offset = dissect_nfs4_specdata(tvb, offset, newftree);
10335
0
          break;
10336
10337
0
        case NF4SOCK:
10338
0
        case NF4FIFO:
10339
0
        case NF4DIR:
10340
0
          break;
10341
10342
0
        default:
10343
0
          break;
10344
0
        }
10345
10346
0
        offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, &name);
10347
0
        offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ, opcode, -1);
10348
10349
0
        if (nfs_file_name_snooping) {
10350
0
          nfs_name_snoop_add_name(((uint64_t)ops_counter << 32) | civ->xid, tvb, -1, (int)strlen(name), last_fh_offset, last_fh_length, name);
10351
0
        }
10352
0
      }
10353
0
      break;
10354
10355
0
    case NFS4_OP_DELEGPURGE:
10356
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10357
0
      break;
10358
10359
0
    case NFS4_OP_DELEGRETURN:
10360
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10361
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
10362
0
      break;
10363
10364
0
    case NFS4_OP_GETATTR:
10365
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ, opcode, -1);
10366
10367
0
      if (last_fh_hash != 0)
10368
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10369
10370
0
      break;
10371
10372
0
    case NFS4_OP_GETFH:
10373
0
      break;
10374
10375
0
    case NFS4_OP_LINK:
10376
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, NULL);
10377
0
      break;
10378
10379
0
    case NFS4_OP_LOCK:
10380
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_lock_type, offset);
10381
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_lock_reclaim, offset);
10382
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10383
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10384
0
      length64 = tvb_get_ntoh64(tvb, offset);
10385
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10386
0
      offset = dissect_nfs4_locker(tvb, pinfo, offset, newftree);
10387
0
      if (last_fh_hash != 0)
10388
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10389
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " Offset: %"PRIu64, file_offset);
10390
0
      if (length64 == UINT64_C(0xffffffffffffffff))
10391
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " Length: <End of File>");
10392
0
      else
10393
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " Length: %"PRIu64, length64);
10394
0
      break;
10395
10396
0
    case NFS4_OP_LOCKT:
10397
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_lock_type, offset);
10398
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10399
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10400
0
      offset = dissect_nfs4_lock_owner(tvb, pinfo, offset, newftree);
10401
0
      break;
10402
10403
0
    case NFS4_OP_LOCKU:
10404
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_lock_type, offset);
10405
0
      offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_seqid, offset);
10406
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10407
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10408
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10409
0
      length64 = tvb_get_ntoh64(tvb, offset);
10410
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10411
0
      if (last_fh_hash != 0)
10412
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10413
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " Offset: %"PRIu64, file_offset);
10414
0
      if (length64 == UINT64_C(0xffffffffffffffff))
10415
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " Length: <End of File>");
10416
0
      else
10417
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " Length: %"PRIu64, length64);
10418
0
      break;
10419
10420
0
    case NFS4_OP_LOOKUP:
10421
      /*name_offset = offset;*/
10422
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, &name);
10423
0
      if (nfs_file_name_snooping) {
10424
0
        nfs_name_snoop_add_name(((uint64_t)ops_counter << 32) | civ->xid, tvb, -1, (int)strlen(name), last_fh_offset, last_fh_length, name);
10425
0
      }
10426
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " ");
10427
0
      if (last_fh_hash != 0)
10428
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, "DH: 0x%08x/", last_fh_hash);
10429
0
      if (name != NULL)
10430
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", name);
10431
0
      break;
10432
10433
0
    case NFS4_OP_LOOKUPP:
10434
0
      break;
10435
10436
0
    case NFS4_OP_NVERIFY:
10437
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ, opcode, -1);
10438
0
      if (last_fh_hash != 0)
10439
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10440
0
      break;
10441
10442
0
    case NFS4_OP_OPEN:
10443
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10444
0
      offset = dissect_nfs4_open_share_access(tvb, offset, newftree);
10445
0
      offset = dissect_nfs4_open_share_deny(tvb, offset, newftree);
10446
0
      offset = dissect_nfs4_open_owner(tvb, pinfo, offset, newftree);
10447
0
      offset = dissect_nfs4_openflag(tvb, offset, pinfo, newftree, civ);
10448
0
      offset = dissect_nfs4_open_claim(tvb, offset, pinfo, newftree, &name, last_fh_offset, last_fh_length, civ, ops_counter);
10449
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " ");
10450
0
      if (last_fh_hash != 0) {
10451
0
        if (name != NULL)
10452
0
          wmem_strbuf_append_printf (op_summary[ops_counter].optext, "DH: 0x%08x/", last_fh_hash);
10453
0
        else
10454
0
          wmem_strbuf_append_printf (op_summary[ops_counter].optext, "FH: 0x%08x", last_fh_hash);
10455
0
      }
10456
0
      if (name != NULL)
10457
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", name);
10458
0
      break;
10459
10460
0
    case NFS4_OP_OPENATTR:
10461
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_attr_dir_create, offset);
10462
0
      break;
10463
10464
0
    case NFS4_OP_OPEN_CONFIRM:
10465
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10466
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10467
0
      break;
10468
10469
0
    case NFS4_OP_OPEN_DOWNGRADE:
10470
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10471
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10472
0
      offset = dissect_nfs4_open_share_access(tvb, offset, newftree);
10473
0
      offset = dissect_nfs4_open_share_deny(tvb, offset, newftree);
10474
0
      break;
10475
10476
0
    case NFS4_OP_PUTFH:
10477
0
      offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", &last_fh_hash, &last_fh_offset, &last_fh_length, civ, opcode, -1);
10478
0
      break;
10479
10480
0
    case NFS4_OP_PUTPUBFH:
10481
0
      break;
10482
10483
0
    case NFS4_OP_PUTROOTFH:
10484
0
      if (nfs_file_name_snooping)
10485
0
        nfs_name_snoop_add_name(((uint64_t)ops_counter << 32) | civ->xid, tvb, -1, 1, 0, 0, "/");
10486
0
      break;
10487
10488
0
    case NFS4_OP_READ:
10489
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10490
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10491
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10492
0
      length = tvb_get_ntohl(tvb, offset);
10493
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
10494
0
      if (sid_hash != 0)
10495
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10496
0
          " StateID: 0x%04x Offset: %" PRIu64 " Len: %u",
10497
0
          sid_hash, file_offset, length);
10498
0
      break;
10499
10500
0
    case NFS4_OP_READDIR:
10501
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie, offset);
10502
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie_verf, offset);
10503
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_dircount, offset);
10504
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount, offset);
10505
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ, opcode, -1);
10506
0
      if (last_fh_hash != 0)
10507
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10508
0
      break;
10509
10510
0
    case NFS4_OP_READLINK:
10511
0
      break;
10512
10513
0
    case NFS4_OP_TEST_STATEID:
10514
0
      offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_test_stateid_arg, hf_nfs4_test_stateid_arg);
10515
0
      break;
10516
10517
0
    case NFS4_OP_DESTROY_CLIENTID:
10518
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10519
0
      break;
10520
0
    case NFS4_OP_RECLAIM_COMPLETE:
10521
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_reclaim_one_fs, offset);
10522
0
      break;
10523
10524
0
    case NFS4_OP_REMOVE:
10525
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, &name);
10526
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " ");
10527
0
      if (last_fh_hash != 0)
10528
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, "DH: 0x%08x/", last_fh_hash);
10529
0
      if (name != NULL)
10530
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", name);
10531
0
      break;
10532
10533
0
    case NFS4_OP_RENAME:
10534
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, &source_name);
10535
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_component, &dest_name);
10536
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " From: %s To: %s",
10537
0
        source_name ? source_name : "Unknown", dest_name ? dest_name : "Unknown");
10538
0
      break;
10539
10540
0
    case NFS4_OP_RENEW:
10541
0
      clientid = tvb_get_ntoh64(tvb, offset);
10542
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10543
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " CID: 0x%016"PRIx64, clientid);
10544
10545
0
      break;
10546
10547
0
    case NFS4_OP_RESTOREFH:
10548
0
      last_fh_offset = saved_fh_offset;
10549
0
      last_fh_length = saved_fh_length;
10550
0
      last_fh_hash = saved_fh_hash;
10551
0
      break;
10552
10553
0
    case NFS4_OP_SAVEFH:
10554
0
      saved_fh_offset = last_fh_offset;
10555
0
      saved_fh_length = last_fh_length;
10556
0
      saved_fh_hash = last_fh_hash;
10557
0
      break;
10558
10559
0
    case NFS4_OP_SECINFO:
10560
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree,
10561
0
        hf_nfs4_component, NULL);
10562
0
      break;
10563
10564
0
    case NFS4_OP_SECINFO_NO_NAME:
10565
0
      proto_tree_add_item(newftree, hf_nfs4_secinfo_style, tvb, offset, 4, ENC_BIG_ENDIAN);
10566
0
      offset += 4;
10567
0
      break;
10568
10569
0
    case NFS4_OP_SETATTR:
10570
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10571
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ, opcode, -1);
10572
0
      if (last_fh_hash != 0)
10573
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10574
0
      break;
10575
10576
0
    case NFS4_OP_SETCLIENTID:
10577
0
      {
10578
0
        proto_tree *client_tree = NULL;
10579
0
        proto_tree *callback_tree = NULL;
10580
10581
0
        client_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_client_id, NULL, "client");
10582
10583
0
        offset = dissect_nfs4_client_id(tvb, pinfo, offset, client_tree);
10584
10585
0
        callback_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_cb_client, NULL, "callback");
10586
10587
0
        offset = dissect_nfs4_cb_client4(tvb, pinfo, offset, callback_tree);
10588
10589
0
        offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_callback_ident,
10590
0
          offset);
10591
0
      }
10592
0
      break;
10593
10594
0
    case NFS4_OP_SETCLIENTID_CONFIRM:
10595
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10596
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
10597
0
      break;
10598
10599
0
    case NFS4_OP_VERIFY:
10600
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ, opcode, -1);
10601
0
      break;
10602
10603
0
    case NFS4_OP_WRITE:
10604
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10605
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10606
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10607
0
      offset = dissect_nfs4_stable_how(tvb, pinfo, offset, newftree, "stable");
10608
0
      string_length = tvb_get_ntohl(tvb, offset+0);
10609
0
      dissect_rpc_uint32(tvb, newftree, hf_nfs4_write_data_length, offset); /* don't change offset */
10610
0
      offset = dissect_nfsdata(tvb, pinfo, offset, newftree, hf_nfs_data);
10611
0
      if (sid_hash != 0)
10612
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10613
0
          " StateID: 0x%04x Offset: %"PRIu64" Len: %u",
10614
0
          sid_hash, file_offset, string_length);
10615
0
      break;
10616
10617
0
    case NFS4_OP_RELEASE_LOCKOWNER:
10618
0
      offset = dissect_nfs4_lock_owner(tvb, pinfo, offset, newftree);
10619
0
      break;
10620
10621
      /* Minor Version 1 */
10622
0
    case NFS4_OP_BACKCHANNEL_CTL:
10623
0
      nfs4_cb_register_prog(tvb, offset);
10624
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_cb_program, offset);
10625
0
      offset = dissect_rpc_secparms4(tvb, pinfo, offset, newftree);
10626
0
      break;
10627
0
    case NFS4_OP_BIND_CONN_TO_SESSION:
10628
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10629
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_bctsa_dir, offset);
10630
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_bctsa_use_conn_in_rdma_mode, offset);
10631
0
      break;
10632
10633
0
    case NFS4_OP_EXCHANGE_ID:
10634
0
      {
10635
0
      proto_tree *eia_clientowner_tree;
10636
10637
0
      eia_clientowner_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_clientowner, NULL, "eia_clientowner");
10638
0
      offset = dissect_rpc_uint64(tvb, eia_clientowner_tree, hf_nfs4_verifier, offset);
10639
0
      offset = dissect_nfsdata(tvb, pinfo, offset, eia_clientowner_tree, hf_nfs_data);
10640
10641
0
      proto_tree_add_bitmask(eia_clientowner_tree, tvb, offset, hf_nfs4_exchid_call_flags, ett_nfs4_exchangeid_call_flags, nfs4_exchid_flags, ENC_BIG_ENDIAN);
10642
0
      offset += 4;
10643
10644
0
      offset = dissect_nfs4_state_protect_a(tvb, offset, pinfo, newftree);
10645
0
      offset = dissect_rpc_nfs_impl_id4(tvb, pinfo, offset, newftree, "eia_client_impl_id");
10646
0
      }
10647
0
      break;
10648
10649
0
    case NFS4_OP_CREATE_SESSION:
10650
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10651
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10652
0
      offset = dissect_nfs_create_session_flags(tvb, offset, newftree,
10653
0
        hf_nfs4_create_session_flags_csa);
10654
0
      offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csa_fore_chan_attrs");
10655
0
      offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csa_back_chan_attrs");
10656
0
      nfs4_cb_register_prog(tvb, offset);
10657
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_cb_program, offset);
10658
0
      offset = dissect_rpc_secparms4(tvb, pinfo, offset, newftree);
10659
0
      break;
10660
10661
0
    case NFS4_OP_DESTROY_SESSION:
10662
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10663
0
      break;
10664
0
    case NFS4_OP_FREE_STATEID:
10665
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10666
0
      wmem_strbuf_append_printf(op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
10667
0
      break;
10668
10669
0
    case NFS4_OP_GET_DIR_DELEGATION:
10670
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_gdd_signal_deleg_avail, offset);
10671
0
      offset = dissect_nfs4_notify_type4_bitmap(tvb, newftree, pinfo, offset, opcode, -1);
10672
0
      offset = dissect_nfs4_gdd_time(tvb, offset, newftree, hf_nfs4_gdd_child_attr_delay);
10673
0
      offset = dissect_nfs4_gdd_time(tvb, offset, newftree, hf_nfs4_gdd_dir_attr_delay);
10674
0
      offset = dissect_nfs4_gdd_fattrs(tvb, offset, pinfo, newftree,
10675
0
               FATTR4_BITMAP_ONLY, civ, hf_nfs4_gdd_child_attrs, opcode, -1);
10676
0
      offset = dissect_nfs4_gdd_fattrs(tvb, offset, pinfo, newftree,
10677
0
               FATTR4_BITMAP_ONLY, civ, hf_nfs4_gdd_dir_attrs, opcode, -1);
10678
0
      break;
10679
10680
      /* pNFS */
10681
0
    case NFS4_OP_LAYOUTGET:
10682
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_layout_avail, offset);
10683
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10684
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_iomode, offset);
10685
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10686
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10687
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length_minlength, offset);
10688
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10689
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount,
10690
0
                    offset);
10691
0
      break;
10692
10693
0
    case NFS4_OP_LAYOUTCOMMIT:
10694
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10695
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10696
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_reclaim, offset);
10697
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10698
0
      offset = dissect_nfs4_newoffset(tvb, offset, newftree);
10699
0
      offset = dissect_nfs4_newtime(tvb, offset, newftree);
10700
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10701
0
      offset = dissect_nfsdata(tvb, pinfo, offset, newftree, hf_nfs4_layoutupdate);
10702
0
      break;
10703
10704
0
    case NFS4_OP_LAYOUTRETURN:
10705
0
      offset = dissect_nfs4_layoutreturn(tvb, offset, pinfo, newftree, civ);
10706
0
      break;
10707
10708
0
    case NFS4_OP_GETDEVINFO:
10709
0
      offset = dissect_nfs4_deviceid(tvb, offset, newftree);
10710
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10711
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount, offset);
10712
0
      offset = dissect_nfs4_notify_deviceid_bitmap(tvb, newftree, pinfo, offset);
10713
0
      break;
10714
10715
0
    case NFS4_OP_GETDEVLIST:
10716
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10717
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount, offset);
10718
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie, offset);
10719
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie_verf, offset);
10720
0
      break;
10721
10722
0
    case NFS4_OP_SEQUENCE:
10723
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10724
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10725
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
10726
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
10727
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_cachethis, offset);
10728
0
      break;
10729
10730
0
    case NFS4_OP_ALLOCATE:
10731
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10732
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10733
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10734
0
      length64 = tvb_get_ntoh64(tvb, offset);
10735
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10736
0
      if (sid_hash != 0)
10737
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10738
0
          " StateID: 0x%04x"
10739
0
          " Offset: %" PRIu64
10740
0
          " Len: %" PRIu64,
10741
0
          sid_hash, file_offset, length64);
10742
0
      break;
10743
10744
0
    case NFS4_OP_COPY:
10745
10746
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10747
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &dst_sid_hash);
10748
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10749
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10750
0
      dst_file_offset = tvb_get_ntoh64(tvb, offset);
10751
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10752
0
      length64 = tvb_get_ntoh64(tvb, offset);
10753
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10754
0
      if (sid_hash != 0)
10755
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10756
0
          " Src StateID: 0x%04x"
10757
0
          " Offset: %" PRIu64
10758
0
          " Len: %" PRIu64,
10759
0
          sid_hash, file_offset, length64);
10760
10761
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_consecutive, offset);
10762
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_synchronous, offset);
10763
10764
      /* FIXME: Report consecutive and sync? */
10765
10766
0
      if (dst_sid_hash != 0)
10767
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10768
0
          " Dst StateID: 0x%04x"
10769
0
          " Offset: %" PRIu64,
10770
0
          dst_sid_hash, dst_file_offset);
10771
10772
0
      offset = dissect_nfs4_source_servers(tvb, pinfo, offset, newftree);
10773
0
      break;
10774
10775
0
    case NFS4_OP_COPY_NOTIFY:
10776
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10777
0
      if (sid_hash != 0)
10778
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10779
0
          " StateID: 0x%04x",
10780
0
          sid_hash);
10781
10782
0
      offset = dissect_nfs4_netloc(tvb, pinfo, offset, newftree);
10783
10784
0
      break;
10785
10786
0
    case NFS4_OP_DEALLOCATE:
10787
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10788
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10789
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10790
0
      length64 = tvb_get_ntoh64(tvb, offset);
10791
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10792
0
      if (sid_hash != 0)
10793
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10794
0
          " StateID: 0x%04x"
10795
0
          " Offset: %" PRIu64
10796
0
          " Len: %" PRIu64,
10797
0
          sid_hash, file_offset, length64);
10798
0
      break;
10799
10800
0
    case NFS4_OP_IO_ADVISE:
10801
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10802
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10803
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10804
0
      length64 = tvb_get_ntoh64(tvb, offset);
10805
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10806
0
      if (sid_hash != 0)
10807
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10808
0
          " StateID: 0x%04x"
10809
0
          " Offset: %" PRIu64
10810
0
          " Len: %" PRIu64,
10811
0
          sid_hash, file_offset, length64);
10812
0
      offset = dissect_nfs4_io_hints(tvb, offset, pinfo, newftree);
10813
0
      break;
10814
10815
0
    case NFS4_OP_OFFLOAD_CANCEL:
10816
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10817
0
      if (sid_hash != 0)
10818
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10819
0
          " StateID: 0x%04x",
10820
0
          sid_hash);
10821
0
      break;
10822
10823
0
    case NFS4_OP_OFFLOAD_STATUS:
10824
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10825
0
      if (sid_hash != 0)
10826
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10827
0
          " StateID: 0x%04x",
10828
0
          sid_hash);
10829
0
      break;
10830
10831
0
    case NFS4_OP_READ_PLUS:
10832
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10833
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10834
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10835
0
      length = tvb_get_ntohl(tvb, offset);
10836
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
10837
0
      if (sid_hash != 0)
10838
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10839
0
          " StateID: 0x%04x Offset: %" PRIu64 " Len: %u",
10840
0
          sid_hash, file_offset, length);
10841
0
      break;
10842
10843
0
    case NFS4_OP_LAYOUTERROR:
10844
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10845
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10846
0
      length = tvb_get_ntohl(tvb, offset);
10847
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10848
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10849
0
      if (sid_hash != 0)
10850
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10851
0
          " StateID: 0x%04x Offset: %" PRIu64 " Len: %u",
10852
0
          sid_hash, file_offset, length);
10853
0
      offset = dissect_nfs4_device_errors(tvb, offset, newftree);
10854
0
      break;
10855
10856
0
    case NFS4_OP_LAYOUTSTATS:
10857
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10858
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10859
0
      length = tvb_get_ntohl(tvb, offset);
10860
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10861
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10862
0
      if (sid_hash != 0)
10863
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10864
0
          " StateID: 0x%04x Offset: %" PRIu64 " Len: %u",
10865
0
          sid_hash, file_offset, length);
10866
0
      offset = dissect_nfs4_layoutstats(tvb, offset, pinfo, newftree, civ, true);
10867
0
      break;
10868
10869
0
    case NFS4_OP_SEEK:
10870
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10871
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10872
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10873
0
      proto_tree_add_item(newftree, hf_nfs4_seek_data_content, tvb,
10874
0
            offset, 4, ENC_BIG_ENDIAN);
10875
0
      offset += 4;
10876
0
      if (sid_hash != 0)
10877
0
        wmem_strbuf_append_printf(op_summary[ops_counter].optext,
10878
0
          " StateID: 0x%04x Offset: %" PRIu64,
10879
0
          sid_hash, file_offset);
10880
0
      break;
10881
10882
0
    case NFS4_OP_WRITE_SAME:
10883
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10884
0
      offset = dissect_nfs4_stable_how(tvb, pinfo, offset, newftree, "stable");
10885
0
      offset = dissect_nfs4_app_data_block(tvb, offset, newftree, &hash);
10886
0
      wmem_strbuf_append_printf(op_summary[ops_counter].optext,
10887
0
        "Pattern Hash: 0x%08x", hash);
10888
10889
0
      break;
10890
10891
0
    case NFS4_OP_CLONE:
10892
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10893
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &dst_sid_hash);
10894
0
      file_offset = tvb_get_ntoh64(tvb, offset);
10895
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10896
0
      dst_file_offset = tvb_get_ntoh64(tvb, offset);
10897
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10898
0
      length64 = tvb_get_ntoh64(tvb, offset);
10899
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10900
0
      if (sid_hash != 0)
10901
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10902
0
          " Src StateID: 0x%04x"
10903
0
          " Offset: %" PRIu64
10904
0
          " Len: %" PRIu64,
10905
0
          sid_hash, file_offset, length64);
10906
10907
0
      if (dst_sid_hash != 0)
10908
0
        wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10909
0
          " Dst StateID: 0x%04x"
10910
0
          " Offset: %" PRIu64,
10911
0
          dst_sid_hash, dst_file_offset);
10912
10913
0
      break;
10914
10915
0
    case NFS4_OP_GETXATTR:
10916
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_xattrkey, NULL);
10917
0
      break;
10918
10919
0
    case NFS4_OP_SETXATTR:
10920
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_setxattr_options, offset);
10921
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_xattrkey, NULL);
10922
0
      offset = dissect_nfsdata(tvb, pinfo, offset, newftree, hf_nfs_data);
10923
0
      break;
10924
10925
0
    case NFS4_OP_LISTXATTRS:
10926
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_listxattr_cookie, offset);
10927
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_listxattr_maxcount, offset);
10928
0
      break;
10929
10930
0
    case NFS4_OP_REMOVEXATTR:
10931
0
      offset = dissect_nfs_utf8string(tvb, pinfo, offset, newftree, hf_nfs4_xattrkey, NULL);
10932
0
      break;
10933
10934
    /* In theory, it's possible to get this opcode */
10935
0
    case NFS4_OP_ILLEGAL:
10936
0
      break;
10937
10938
0
    default:
10939
0
      break;
10940
0
    }
10941
0
  }
10942
10943
  /* Detect which tiers are present in this packet */
10944
0
  for (summary_counter=0; summary_counter < ops_counter; summary_counter++)
10945
0
  {
10946
0
    current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
10947
0
    if (current_tier < highest_tier)
10948
0
      highest_tier = current_tier;
10949
0
  }
10950
10951
  /* Display packet summary */
10952
0
  for (summary_counter=0; summary_counter < ops_counter; summary_counter++)
10953
0
  {
10954
0
    unsigned main_opcode;
10955
0
    proto_item *main_op_item = NULL;
10956
10957
0
    main_opcode = op_summary[summary_counter].opcode;
10958
0
    current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
10959
10960
    /* Display summary info only for operations that are "most significant".
10961
       Controlled by a user option. */
10962
0
    if (current_tier == highest_tier || !display_major_nfs4_ops) {
10963
0
      if (current_tier == highest_tier) {
10964
0
        const char *main_opname = NULL;
10965
10966
        /* Display a filterable field of the most significant operations in all cases. */
10967
0
        main_opname = val_to_str_ext_const(main_opcode, &names_nfs4_operation_ext, "Unknown");
10968
0
        main_op_item = proto_tree_add_uint_format_value(tree, hf_nfs4_main_opcode, tvb, 0, 0,
10969
0
                    main_opcode, "%s (%u)", main_opname, main_opcode);
10970
0
        proto_item_set_generated(main_op_item);
10971
0
      }
10972
10973
0
      if (first_operation == 0)
10974
        /* Separator between operation text */
10975
0
        col_append_str(pinfo->cinfo, COL_INFO, " |");
10976
10977
0
      if (wmem_strbuf_get_len(op_summary[summary_counter].optext) > 0)
10978
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10979
0
          wmem_strbuf_get_str(op_summary[summary_counter].optext));
10980
10981
0
      first_operation = 0;
10982
0
    }
10983
0
  }
10984
10985
  /* Copy the information from the call info and store information about
10986
   * the operations here in private data.
10987
   */
10988
0
  rpc_call_info_value *tapdata = wmem_new0(pinfo->pool, rpc_call_info_value);
10989
0
  *tapdata = *civ;
10990
0
  nfs4_tap_data_t *ops_info = wmem_new0(pinfo->pool, nfs4_tap_data_t);
10991
0
  ops_info->op_summary = op_summary;
10992
0
  ops_info->ops_counter = ops_counter;
10993
0
  ops_info->highest_tier = highest_tier;
10994
0
  tapdata->private_data = ops_info;
10995
0
  tap_queue_packet(nfsv4_tap, pinfo, tapdata);
10996
10997
0
  return offset;
10998
0
}
10999
11000
11001
static int
11002
dissect_nfs4_compound_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
11003
0
{
11004
0
  const char *tag = NULL;
11005
0
  unsigned offset = 0;
11006
11007
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_tag, &tag);
11008
  /*
11009
   * Display the NFSv4 tag.  If it is empty, string generator will have returned "<EMPTY>",
11010
   * in which case don't display anything */
11011
0
  if (nfs_display_v4_tag && strncmp(tag, "<EMPTY>", 7) != 0)
11012
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
11013
11014
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_minorversion, offset);
11015
0
  offset = dissect_nfs4_request_op(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
11016
11017
0
  return offset;
11018
0
}
11019
11020
11021
static int
11022
dissect_nfs4_secinfo_res(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void *data _U_)
11023
0
{
11024
0
  unsigned flavor;
11025
0
  proto_item *fitem;
11026
0
  proto_tree *secftree;
11027
11028
0
  fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_secinfo_flavor, tvb, offset, 4,
11029
0
    ENC_BIG_ENDIAN, &flavor);
11030
0
  offset += 4;
11031
11032
0
  switch (flavor)
11033
0
  {
11034
0
    case RPCSEC_GSS:
11035
0
      secftree = proto_item_add_subtree(fitem, ett_nfs4_secinfo_flavor_info);
11036
0
      offset = dissect_nfs_rpcsec_gss_info(tvb, pinfo, offset, secftree);
11037
0
      break;
11038
11039
0
    default:
11040
0
      break;
11041
0
  }
11042
11043
0
  return offset;
11044
0
}
11045
11046
11047
static unsigned
11048
dissect_nfs4_offload_status_res(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
11049
0
{
11050
0
  proto_item *sub_fitem;
11051
0
  proto_tree *ss_tree;
11052
0
  proto_tree *subtree;
11053
0
  proto_item *ss_fitem;
11054
0
  unsigned    i;
11055
0
  uint32_t      count;
11056
11057
  /* Number of osr_complete status */
11058
0
  sub_fitem = proto_tree_add_item_ret_uint(tree,
11059
0
      hf_nfs4_num_offload_status, tvb, offset, 4,
11060
0
      ENC_BIG_ENDIAN, &count);
11061
0
  offset += 4;
11062
11063
0
  subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_osr_complete_sub);
11064
0
  for (i = 0; i < count; i++) {
11065
0
    ss_fitem = proto_tree_add_item(subtree,
11066
0
        hf_nfs4_offload_status_index,
11067
0
        tvb, offset, 4, ENC_BIG_ENDIAN);
11068
11069
0
    ss_tree = proto_item_add_subtree(ss_fitem,
11070
0
        ett_nfs4_osr_complete_sub);
11071
11072
0
    offset = dissect_rpc_uint32(tvb, ss_tree, hf_nfs4_status, offset);
11073
0
  }
11074
11075
0
  return offset;
11076
0
}
11077
11078
static unsigned
11079
dissect_nfs4_response_op(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
11080
0
{
11081
0
  unsigned      highest_tier    = 5;
11082
0
  unsigned      current_tier    = 5;
11083
0
  unsigned      first_operation = 1;
11084
0
  uint16_t      sid_hash      = 0;
11085
0
  uint32_t      last_fh_idx     = -1;
11086
0
  uint32_t      saved_fh_idx    = -1;
11087
0
  uint32_t      ops, ops_counter;
11088
0
  uint32_t      summary_counter;
11089
0
  uint32_t      opcode, status, nfstatus;
11090
0
  const char *opname;
11091
0
  proto_item *fitem, *ti;
11092
0
  proto_tree *ftree     = NULL;
11093
0
  proto_tree *newftree      = NULL;
11094
0
  nfs4_operation_summary *op_summary;
11095
11096
0
  ops = tvb_get_ntohl(tvb, offset+0);
11097
11098
0
  fitem = proto_tree_add_uint_format(tree, hf_nfs4_ops_count, tvb, offset+0, 4, ops,
11099
0
    "Operations (count: %u)", ops);
11100
0
  offset += 4;
11101
11102
0
  if (ops > MAX_NFSV4_OPS) {
11103
0
    expert_add_info(pinfo, fitem, &ei_nfs_too_many_ops);
11104
0
    ops = MAX_NFSV4_OPS;
11105
0
  }
11106
11107
0
  op_summary = wmem_alloc0_array(pinfo->pool, nfs4_operation_summary, ops);
11108
11109
0
  ftree = proto_item_add_subtree(fitem, ett_nfs4_response_op);
11110
11111
0
  proto_item_append_text(tree, ", Ops(%u):", ops);
11112
11113
0
  for (ops_counter = 0; ops_counter < ops; ops_counter++)
11114
0
  {
11115
0
    op_summary[ops_counter].optext = wmem_strbuf_new(pinfo->pool, "");
11116
0
    opcode = tvb_get_ntohl(tvb, offset);
11117
0
    op_summary[ops_counter].iserror = false;
11118
0
    op_summary[ops_counter].opcode = opcode;
11119
11120
    /* sanity check for bogus packets */
11121
0
    if ((opcode < NFS4_OP_ACCESS || opcode > NFS4_LAST_OP) &&
11122
0
      (opcode != NFS4_OP_ILLEGAL))
11123
0
      break;
11124
11125
0
    fitem = proto_tree_add_uint(ftree, hf_nfs4_op, tvb, offset, 4, opcode);
11126
11127
    /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
11128
0
    if (opcode == NFS4_OP_ILLEGAL) {
11129
0
      newftree = proto_item_add_subtree(fitem, ett_nfs4_illegal);
11130
0
    } else if (nfs4_operation_ett[opcode - 3]) {
11131
0
      newftree = proto_item_add_subtree(fitem, *nfs4_operation_ett[opcode - 3]);
11132
0
    } else {
11133
0
      break;
11134
0
    }
11135
11136
0
    opname = val_to_str_ext_const(opcode, &names_nfs4_operation_ext, "Unknown");
11137
0
    offset += 4;
11138
0
    wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", opname);
11139
11140
0
    offset = dissect_nfs4_status(tvb, offset, newftree, &status);
11141
0
    if (status != NFS4_OK) {
11142
0
      proto_item_append_text(tree, " %s(%s)", opname,
11143
0
        val_to_str_ext(pinfo->pool, status, &names_nfs4_status_ext, "Unknown error: %u"));
11144
0
    } else {
11145
0
      proto_item_append_text(tree, " %s", opname);
11146
0
    }
11147
11148
    /*
11149
     * With the exception of NFS4_OP_LOCK, NFS4_OP_LOCKT,
11150
     * NFS4_OP_SETATTR, NFS4_OP_SETCLIENTID, and NFS4_OP_COPY, all other
11151
     * ops do *not* return data with the failed status code.
11152
     */
11153
0
    if (status != NFS4_OK
11154
0
    && opcode != NFS4_OP_LOCK
11155
0
    && opcode != NFS4_OP_LOCKT
11156
0
    && opcode != NFS4_OP_SETATTR
11157
0
    && opcode != NFS4_OP_SETCLIENTID
11158
0
    && opcode != NFS4_OP_COPY) {
11159
0
      op_summary[ops_counter].iserror = true;
11160
0
      continue;
11161
0
    }
11162
11163
    /* These parsing routines are only executed if the status is NFS4_OK */
11164
0
    switch (opcode)
11165
0
    {
11166
0
    case NFS4_OP_ACCESS:
11167
0
      offset = dissect_access_reply(tvb, offset, pinfo, fitem, 4, op_summary[ops_counter].optext, civ);
11168
0
      break;
11169
11170
0
    case NFS4_OP_CLOSE:
11171
0
      ti = proto_tree_add_item(newftree, hf_nfs4_stateid, tvb, offset, 16, ENC_NA);
11172
      /*
11173
       * RFC8881 18.2.4. CLOSE IMPLEMENTATION: The server SHOULD return the invalid special stateid
11174
       * (the "other" value is zero and the "seqid" field is NFS4_UINT32_MAX).
11175
       */
11176
0
      if (memcmp(tvb_get_ptr(tvb, offset, 16), "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) != 0)
11177
0
        expert_add_info(pinfo, ti, &ei_nfs4_stateid_deprecated);
11178
0
      offset += 16;
11179
0
      break;
11180
11181
0
    case NFS4_OP_COMMIT:
11182
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
11183
0
      break;
11184
11185
0
    case NFS4_OP_CREATE:
11186
0
      last_fh_idx = ops_counter;
11187
0
      offset = dissect_nfs4_change_info(tvb, offset, newftree, "change_info");
11188
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ, opcode, last_fh_idx);
11189
0
      break;
11190
11191
0
    case NFS4_OP_GETATTR:
11192
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ, opcode, last_fh_idx);
11193
0
      break;
11194
11195
0
    case NFS4_OP_GETFH:
11196
0
      offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "Filehandle", NULL, NULL, NULL, civ, opcode, last_fh_idx);
11197
0
      break;
11198
11199
0
    case NFS4_OP_LINK:
11200
0
      offset = dissect_nfs4_change_info(tvb, offset, newftree, "change_info");
11201
0
      break;
11202
11203
0
    case NFS4_OP_LOOKUP:
11204
0
    case NFS4_OP_LOOKUPP:
11205
0
      last_fh_idx = ops_counter;
11206
0
      break;
11207
11208
0
    case NFS4_OP_LOCK:
11209
0
    case NFS4_OP_LOCKT:
11210
0
      if (status == NFS4_OK)
11211
0
      {
11212
0
        if (opcode == NFS4_OP_LOCK)
11213
0
          offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
11214
0
      }
11215
0
      else
11216
0
      if (status == NFS4ERR_DENIED)
11217
0
        offset = dissect_nfs4_lockdenied(tvb, pinfo, offset, newftree);
11218
0
      break;
11219
11220
0
    case NFS4_OP_LOCKU:
11221
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
11222
0
      break;
11223
11224
0
    case NFS4_OP_OPEN:
11225
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
11226
0
      offset = dissect_nfs4_change_info(tvb, offset, newftree,
11227
0
        "change_info");
11228
0
      offset = dissect_nfs4_open_rflags(tvb, offset, newftree);
11229
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ, opcode, -1);
11230
0
      offset = dissect_nfs4_open_delegation(tvb, offset, pinfo, newftree);
11231
0
      wmem_strbuf_append_printf (op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
11232
0
      break;
11233
11234
0
    case NFS4_OP_OPEN_CONFIRM:
11235
0
    case NFS4_OP_OPEN_DOWNGRADE:
11236
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
11237
0
      break;
11238
11239
0
    case NFS4_OP_PUTFH:
11240
0
    case NFS4_OP_PUTPUBFH:
11241
0
    case NFS4_OP_PUTROOTFH:
11242
0
      last_fh_idx = ops_counter;
11243
0
      break;
11244
11245
0
    case NFS4_OP_READ:
11246
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
11247
0
      dissect_rpc_uint32(tvb, newftree, hf_nfs4_read_data_length, offset); /* don't change offset */
11248
0
      offset = dissect_nfsdata_reduced(R_NFSDATA, tvb, pinfo, offset, newftree, hf_nfs_data, NULL);
11249
0
      break;
11250
11251
0
    case NFS4_OP_READDIR:
11252
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
11253
0
      offset = dissect_nfs4_dirlist(tvb, offset, pinfo, newftree, civ, opcode, -1);
11254
0
      break;
11255
11256
0
    case NFS4_OP_READLINK:
11257
0
      offset = dissect_nfsdata_reduced(R_UTF8STRING, tvb, pinfo, offset, newftree, hf_nfs4_linktext, NULL);
11258
0
      break;
11259
11260
0
    case NFS4_OP_RECLAIM_COMPLETE:
11261
0
      break;
11262
11263
0
    case NFS4_OP_REMOVE:
11264
0
      offset = dissect_nfs4_change_info(tvb, offset, newftree, "change_info");
11265
0
      break;
11266
11267
0
    case NFS4_OP_RENAME:
11268
0
      offset = dissect_nfs4_change_info(tvb, offset, newftree, "source_cinfo");
11269
0
      offset = dissect_nfs4_change_info(tvb, offset, newftree, "target_cinfo");
11270
0
      break;
11271
11272
0
    case NFS4_OP_RESTOREFH:
11273
0
      last_fh_idx = saved_fh_idx;
11274
0
      break;
11275
11276
0
    case NFS4_OP_SAVEFH:
11277
0
      saved_fh_idx = last_fh_idx;
11278
0
      break;
11279
11280
0
    case NFS4_OP_SECINFO:
11281
0
    case NFS4_OP_SECINFO_NO_NAME:
11282
0
      offset = dissect_rpc_array(tvb, pinfo, newftree, offset,
11283
0
        dissect_nfs4_secinfo_res, hf_nfs4_secinfo_arr);
11284
0
      break;
11285
11286
0
    case NFS4_OP_SETATTR:
11287
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ, opcode, -1);
11288
0
      break;
11289
11290
0
    case NFS4_OP_SETCLIENTID:
11291
0
      if (status == NFS4_OK) {
11292
0
        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid,
11293
0
          offset);
11294
0
        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier,
11295
0
          offset);
11296
0
      } else if (status == NFS4ERR_CLID_INUSE)
11297
        /*
11298
         * XXX: below function actually assumes
11299
         * this is for a callback.  Fix:
11300
         */
11301
0
        offset = dissect_nfs4_clientaddr(tvb, pinfo, offset, newftree);
11302
0
      break;
11303
11304
0
    case NFS4_OP_WRITE:
11305
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
11306
0
      offset = dissect_nfs4_stable_how(tvb, pinfo, offset, newftree,  "committed");
11307
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
11308
0
      break;
11309
11310
      /* Minor Version 1 */
11311
0
    case NFS4_OP_BIND_CONN_TO_SESSION:
11312
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
11313
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_bctsr_dir, offset);
11314
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_bctsr_use_conn_in_rdma_mode, offset);
11315
0
      break;
11316
11317
0
    case NFS4_OP_EXCHANGE_ID: {
11318
0
        proto_tree *eir_server_owner_tree = NULL;
11319
11320
0
        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
11321
0
        offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
11322
11323
0
        proto_tree_add_bitmask(newftree, tvb, offset, hf_nfs4_exchid_reply_flags, ett_nfs4_exchangeid_reply_flags, nfs4_exchid_flags, ENC_BIG_ENDIAN);
11324
0
        offset += 4;
11325
11326
0
        offset = dissect_nfs4_state_protect_r(tvb, offset, pinfo, newftree);
11327
11328
0
        eir_server_owner_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_server_owner, NULL, "eir_server_owner");
11329
0
        offset = dissect_rpc_serverowner4(tvb, pinfo, offset, eir_server_owner_tree);
11330
0
        offset = dissect_nfsdata(tvb, pinfo, offset, newftree, hf_nfs4_serverscope4);
11331
0
        offset = dissect_rpc_nfs_impl_id4(tvb, pinfo, offset, newftree, "eir_server_impl_id");
11332
0
      }
11333
0
      break;
11334
0
    case NFS4_OP_CREATE_SESSION:
11335
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
11336
0
      offset = dissect_rpc_uint32(tvb, newftree,
11337
0
          hf_nfs4_seqid, offset);
11338
0
      offset = dissect_nfs_create_session_flags(tvb, offset, newftree,
11339
0
        hf_nfs4_create_session_flags_csr);
11340
0
      offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csr_fore_chan_attrs");
11341
0
      offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csr_back_chan_attrs");
11342
0
      break;
11343
11344
0
    case NFS4_OP_DESTROY_SESSION:
11345
0
      break;
11346
0
    case NFS4_OP_FREE_STATEID:
11347
0
      break;
11348
0
    case NFS4_OP_TEST_STATEID:
11349
0
      offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_test_stateid_res, hf_nfs4_test_stateid_res);
11350
0
      break;
11351
11352
0
    case NFS4_OP_GET_DIR_DELEGATION:
11353
0
      nfstatus = tvb_get_ntohl(tvb, offset);
11354
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_gdd_non_fatal_status, offset);
11355
0
      if (nfstatus == GDD4_OK) {
11356
0
        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
11357
0
        offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
11358
0
        offset = dissect_nfs4_notify_type4_bitmap(tvb, newftree, pinfo, offset, opcode, -1);
11359
0
        offset = dissect_nfs4_gdd_fattrs(tvb, offset, pinfo, newftree,
11360
0
               FATTR4_BITMAP_ONLY, civ, hf_nfs4_gdd_child_attrs, opcode, -1);
11361
0
        offset = dissect_nfs4_gdd_fattrs(tvb, offset, pinfo, newftree,
11362
0
               FATTR4_BITMAP_ONLY, civ, hf_nfs4_gdd_dir_attrs, opcode, -1);
11363
0
      } else if (nfstatus == GDD4_UNAVAIL) {
11364
0
        offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_gdd_signal_deleg_avail, offset);
11365
0
      }
11366
0
      break;
11367
11368
0
    case NFS4_OP_LAYOUTGET:
11369
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_return_on_close,
11370
0
                    offset);
11371
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
11372
0
      offset = dissect_nfs4_layoutget(tvb, offset, pinfo, newftree, civ);
11373
0
      break;
11374
11375
0
    case NFS4_OP_LAYOUTCOMMIT:
11376
0
      offset = dissect_nfs4_newsize(tvb, offset, newftree);
11377
0
      break;
11378
11379
0
    case NFS4_OP_LAYOUTRETURN:
11380
0
      offset = dissect_nfs_layoutreturn_stateid(tvb, newftree, offset);
11381
0
      break;
11382
11383
0
    case NFS4_OP_GETDEVINFO:
11384
0
      offset = dissect_nfs4_deviceaddr(tvb, pinfo, offset, newftree);
11385
0
      offset = dissect_nfs4_notify_deviceid_bitmap(tvb, newftree, pinfo, offset);
11386
0
      break;
11387
11388
0
    case NFS4_OP_GETDEVLIST:
11389
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie, offset);
11390
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie_verf, offset);
11391
0
      offset = dissect_nfs4_devicelist(tvb, offset, newftree);
11392
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
11393
0
      break;
11394
11395
0
    case NFS4_OP_SEQUENCE:
11396
0
      {
11397
0
      static int * const sequence_flags[] = {
11398
0
        &hf_nfs4_sequence_status_flags_cb_path_down,
11399
0
        &hf_nfs4_sequence_status_flags_cb_gss_contexts_expiring,
11400
0
        &hf_nfs4_sequence_status_flags_cb_gss_contexts_expired,
11401
0
        &hf_nfs4_sequence_status_flags_expired_all_state_revoked,
11402
0
        &hf_nfs4_sequence_status_flags_expired_some_state_revoked,
11403
0
        &hf_nfs4_sequence_status_flags_admin_state_revoked,
11404
0
        &hf_nfs4_sequence_status_flags_recallable_state_revoked,
11405
0
        &hf_nfs4_sequence_status_flags_lease_moved,
11406
0
        &hf_nfs4_sequence_status_flags_restart_reclaim_needed,
11407
0
        &hf_nfs4_sequence_status_flags_cb_path_down_session,
11408
0
        &hf_nfs4_sequence_status_flags_backchannel_fault,
11409
0
        &hf_nfs4_sequence_status_flags_devid_changed,
11410
0
        &hf_nfs4_sequence_status_flags_devid_deleted,
11411
0
        NULL
11412
0
      };
11413
11414
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
11415
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
11416
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
11417
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
11418
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_target_high_slotid, offset);
11419
0
      proto_tree_add_bitmask(newftree, tvb, offset, hf_nfs4_sequence_status_flags, ett_nfs4_sequence_status_flags, sequence_flags, ENC_BIG_ENDIAN);
11420
0
      offset += 4;
11421
0
      }
11422
0
      break;
11423
11424
0
    case NFS4_OP_ALLOCATE:
11425
0
      break;
11426
11427
0
    case NFS4_OP_COPY:
11428
11429
0
      if (status == NFS4_OK) {
11430
0
        offset = dissect_nfs4_write_response(tvb, pinfo, offset, newftree);
11431
0
        offset = dissect_nfs4_copy_reqs(tvb, offset, newftree);
11432
0
      } else if (status == NFS4ERR_OFFLOAD_NO_REQS)
11433
0
        offset = dissect_nfs4_copy_reqs(tvb, offset, newftree);
11434
11435
0
      break;
11436
11437
0
    case NFS4_OP_COPY_NOTIFY:
11438
11439
0
      offset = dissect_nfs4_nfstime(tvb, offset, newftree);
11440
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
11441
0
      offset = dissect_nfs4_source_servers(tvb, pinfo, offset, newftree);
11442
11443
0
      break;
11444
11445
0
    case NFS4_OP_DEALLOCATE:
11446
0
      break;
11447
11448
0
    case NFS4_OP_OFFLOAD_CANCEL:
11449
0
      break;
11450
11451
0
    case NFS4_OP_IO_ADVISE:
11452
0
      offset = dissect_nfs4_io_hints(tvb, offset, pinfo, newftree);
11453
0
      break;
11454
11455
0
    case NFS4_OP_OFFLOAD_STATUS:
11456
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
11457
0
      offset = dissect_nfs4_offload_status_res(tvb, offset, newftree);
11458
0
      break;
11459
11460
0
    case NFS4_OP_READ_PLUS:
11461
0
      if (status == NFS4_OK) {
11462
0
        offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
11463
0
        offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_read_plus_content, hf_nfs4_read_plus_contents);
11464
0
      }
11465
0
      break;
11466
11467
0
    case NFS4_OP_LAYOUTERROR:
11468
0
      break;
11469
11470
0
    case NFS4_OP_LAYOUTSTATS:
11471
0
      break;
11472
11473
0
    case NFS4_OP_SEEK:
11474
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
11475
0
      offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
11476
0
      break;
11477
11478
0
    case NFS4_OP_WRITE_SAME:
11479
0
      if (status == NFS4_OK) {
11480
0
        offset = dissect_nfs4_write_response(tvb, pinfo, offset, newftree);
11481
0
      }
11482
0
      break;
11483
11484
0
    case NFS4_OP_CLONE:
11485
0
      break;
11486
11487
0
    case NFS4_OP_GETXATTR:
11488
0
      if (status == NFS4_OK) {
11489
0
        offset = dissect_nfsdata(tvb, pinfo, offset, newftree, hf_nfs_data);
11490
0
      }
11491
0
      break;
11492
11493
0
    case NFS4_OP_SETXATTR:
11494
0
      if (status == NFS4_OK) {
11495
0
        offset = dissect_nfs4_change_info(tvb, offset, newftree, "cinfo");
11496
0
      }
11497
0
      break;
11498
11499
0
    case NFS4_OP_LISTXATTRS:
11500
0
      if (status == NFS4_OK) {
11501
0
        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_listxattr_cookie, offset);
11502
0
        offset = dissect_nfs4_listxattr_names(tvb, pinfo, offset, newftree);
11503
0
        offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_listxattr_eof, offset);
11504
0
      }
11505
0
      break;
11506
11507
0
    case NFS4_OP_REMOVEXATTR:
11508
0
      if (status == NFS4_OK) {
11509
0
        offset = dissect_nfs4_change_info(tvb, offset, newftree, "cinfo");
11510
0
      }
11511
0
      break;
11512
11513
0
    default:
11514
0
      break;
11515
0
    }
11516
0
  }
11517
11518
  /* Detect which tiers are present in this packet */
11519
0
  for (summary_counter = 0; summary_counter < ops_counter; summary_counter++)
11520
0
  {
11521
0
    current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
11522
0
    if (current_tier < highest_tier)
11523
0
      highest_tier = current_tier;
11524
0
  }
11525
11526
  /* Display packet summary */
11527
0
  for (summary_counter = 0; summary_counter < ops_counter; summary_counter++)
11528
0
  {
11529
0
    unsigned main_opcode;
11530
0
    proto_item *main_op_item = NULL;
11531
11532
0
    main_opcode = op_summary[summary_counter].opcode;
11533
0
    current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
11534
11535
    /* Display summary info only for operations that are "most significant".
11536
     Controlled by a user option.
11537
     Display summary info for operations that return an error as well.  */
11538
0
    if (current_tier == highest_tier
11539
0
    || !display_major_nfs4_ops
11540
0
    || op_summary[summary_counter].iserror == true)
11541
0
    {
11542
0
      if (current_tier == highest_tier) {
11543
0
        const char *main_opname = NULL;
11544
11545
        /* Display a filterable field of the most significant operations in all cases. */
11546
0
        main_opname = val_to_str_ext_const(main_opcode, &names_nfs4_operation_ext, "Unknown");
11547
0
        main_op_item = proto_tree_add_uint_format_value(tree, hf_nfs4_main_opcode, tvb, 0, 0,
11548
0
                  main_opcode, "%s (%u)", main_opname, main_opcode);
11549
0
        proto_item_set_generated(main_op_item);
11550
0
      }
11551
11552
0
      if (first_operation == 0)
11553
        /* Separator between operation text */
11554
0
        col_append_str(pinfo->cinfo, COL_INFO, " |");
11555
11556
0
      if (wmem_strbuf_get_len(op_summary[summary_counter].optext) > 0)
11557
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11558
0
          wmem_strbuf_get_str(op_summary[summary_counter].optext));
11559
0
      first_operation = 0;
11560
0
    }
11561
0
  }
11562
11563
  /* Copy the information from the call info and store information about
11564
   * the operations here in private data.
11565
   */
11566
0
  rpc_call_info_value *tapdata = wmem_new0(pinfo->pool, rpc_call_info_value);
11567
0
  *tapdata = *civ;
11568
0
  nfs4_tap_data_t *ops_info = wmem_new0(pinfo->pool, nfs4_tap_data_t);
11569
0
  ops_info->op_summary = op_summary;
11570
0
  ops_info->ops_counter = ops_counter;
11571
0
  ops_info->highest_tier = highest_tier;
11572
0
  tapdata->private_data = ops_info;
11573
0
  tap_queue_packet(nfsv4_tap, pinfo, tapdata);
11574
11575
0
  return offset;
11576
0
}
11577
11578
11579
static int
11580
dissect_nfs4_compound_reply(tvbuff_t *tvb, packet_info *pinfo,  proto_tree *tree, void *data)
11581
0
{
11582
0
  uint32_t      status;
11583
0
  const char *tag = NULL;
11584
0
  unsigned offset = 0;
11585
11586
0
  offset = dissect_nfs4_status(tvb, offset, tree, &status);
11587
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_tag, &tag);
11588
  /*
11589
  * Display the NFSv4 tag. If it is empty, string generator will have returned "<EMPTY>", in
11590
  * which case don't display anything */
11591
0
  if (nfs_display_v4_tag && strncmp(tag, "<EMPTY>", 7) != 0)
11592
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
11593
11594
0
  offset = dissect_nfs4_response_op(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
11595
11596
0
  if (status != NFS4_OK)
11597
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " Status: %s",
11598
0
        val_to_str_ext(pinfo->pool, status, &names_nfs4_status_ext, "Unknown error: %u"));
11599
11600
0
  return offset;
11601
0
}
11602
11603
11604
/* proc number, "proc name", dissect_request, dissect_reply */
11605
static const vsff nfs3_proc[] = {
11606
  { 0,  "NULL",   /* OK */
11607
  dissect_nfs3_null_call,   dissect_nfs3_null_reply },
11608
  { 1,  "GETATTR",  /* OK */
11609
  dissect_nfs3_getattr_call,  dissect_nfs3_getattr_reply },
11610
  { 2,  "SETATTR",  /* OK */
11611
  dissect_nfs3_setattr_call,  dissect_nfs3_setattr_reply },
11612
  { 3,  "LOOKUP", /* OK */
11613
  dissect_nfs3_lookup_call, dissect_nfs3_lookup_reply },
11614
  { 4,  "ACCESS", /* OK */
11615
  dissect_nfs3_access_call, dissect_nfs3_access_reply },
11616
  { 5,  "READLINK", /* OK */
11617
  dissect_nfs3_readlink_call, dissect_nfs3_readlink_reply },
11618
  { 6,  "READ",   /* OK */
11619
  dissect_nfs3_read_call,   dissect_nfs3_read_reply },
11620
  { 7,  "WRITE",  /* OK */
11621
  dissect_nfs3_write_call,  dissect_nfs3_write_reply },
11622
  { 8,  "CREATE", /* OK */
11623
  dissect_nfs3_create_call, dissect_nfs3_create_reply },
11624
  { 9,  "MKDIR",  /* OK */
11625
  dissect_nfs3_mkdir_call,  dissect_nfs3_mkdir_reply },
11626
  { 10, "SYMLINK",  /* OK */
11627
  dissect_nfs3_symlink_call,  dissect_nfs3_symlink_reply },
11628
  { 11, "MKNOD",  /* OK */
11629
  dissect_nfs3_mknod_call,  dissect_nfs3_mknod_reply },
11630
  { 12, "REMOVE", /* OK */
11631
  dissect_nfs3_remove_call, dissect_nfs3_remove_reply },
11632
  { 13, "RMDIR",  /* OK */
11633
  dissect_nfs3_rmdir_call,  dissect_nfs3_rmdir_reply },
11634
  { 14, "RENAME", /* OK */
11635
  dissect_nfs3_rename_call, dissect_nfs3_rename_reply },
11636
  { 15, "LINK",   /* OK */
11637
  dissect_nfs3_link_call,   dissect_nfs3_link_reply },
11638
  { 16, "READDIR",  /* OK */
11639
  dissect_nfs3_readdir_call,  dissect_nfs3_readdir_reply },
11640
  { 17, "READDIRPLUS",  /* OK */
11641
  dissect_nfs3_readdirplus_call,  dissect_nfs3_readdirplus_reply },
11642
  { 18, "FSSTAT", /* OK */
11643
  dissect_nfs3_fsstat_call, dissect_nfs3_fsstat_reply },
11644
  { 19, "FSINFO", /* OK */
11645
  dissect_nfs3_fsinfo_call, dissect_nfs3_fsinfo_reply },
11646
  { 20, "PATHCONF", /* OK */
11647
  dissect_nfs3_pathconf_call, dissect_nfs3_pathconf_reply },
11648
  { 21, "COMMIT", /* OK */
11649
  dissect_nfs3_commit_call, dissect_nfs3_commit_reply },
11650
  { 0,  NULL, NULL, NULL }
11651
};
11652
11653
static const value_string nfs3_proc_vals[] = {
11654
  { 0,  "NULL" },
11655
  { 1,  "GETATTR" },
11656
  { 2,  "SETATTR" },
11657
  { 3,  "LOOKUP" },
11658
  { 4,  "ACCESS" },
11659
  { 5,  "READLINK" },
11660
  { 6,  "READ" },
11661
  { 7,  "WRITE" },
11662
  { 8,  "CREATE" },
11663
  { 9,  "MKDIR" },
11664
  { 10, "SYMLINK" },
11665
  { 11, "MKNOD" },
11666
  { 12, "REMOVE" },
11667
  { 13, "RMDIR" },
11668
  { 14, "RENAME" },
11669
  { 15, "LINK" },
11670
  { 16, "READDIR" },
11671
  { 17, "READDIRPLUS" },
11672
  { 18, "FSSTAT" },
11673
  { 19, "FSINFO" },
11674
  { 20, "PATHCONF" },
11675
  { 21, "COMMIT" },
11676
  { 0,  NULL }
11677
};
11678
static value_string_ext nfs3_proc_vals_ext = VALUE_STRING_EXT_INIT(nfs3_proc_vals);
11679
11680
/* End of NFS Version 3 */
11681
11682
11683
/* the call to dissect_nfs3_null_call & dissect_nfs3_null_reply is
11684
 * intentional.  The V4 NULLPROC is the same as V3.
11685
 */
11686
static const vsff nfs4_proc[] = {
11687
  { 0, "NULL",
11688
  dissect_nfs3_null_call,   dissect_nfs3_null_reply },
11689
  { 1, "COMPOUND",
11690
  dissect_nfs4_compound_call, dissect_nfs4_compound_reply },
11691
  { 0, NULL, NULL, NULL }
11692
};
11693
11694
static const value_string nfs4_proc_vals[] = {
11695
  { 0, "NULL" },
11696
  { 1, "COMPOUND" },
11697
  { 0, NULL }
11698
};
11699
11700
static const rpc_prog_vers_info nfs_vers_info[] = {
11701
  { 2, nfs2_proc, &hf_nfs2_procedure },
11702
  { 3, nfs3_proc, &hf_nfs3_procedure },
11703
  { 4, nfs4_proc, &hf_nfs4_procedure },
11704
};
11705
11706
/*
11707
 * Union of the NFSv2, NFSv3, and NFSv4 status codes.
11708
 * Used for the "nfs.status" hidden field and in packet-nfsacl.c.
11709
 */
11710
static const value_string names_nfs_nfsstat[] = {
11711
  {    0,  "OK"            },
11712
  {    1,  "ERR_PERM"          },
11713
  {    2,  "ERR_NOENT"           },
11714
  {    5,  "ERR_IO"          },
11715
  {    6,  "ERR_NXIO"          },
11716
  {    11, "ERR_EAGAIN"          },
11717
  {    13, "ERR_ACCESS"          },
11718
  {    17, "ERR_EXIST"           },
11719
  {    18, "ERR_XDEV"          },
11720
  {    19, "ERR_NODEV"           },
11721
  {    20, "ERR_NOTDIR"          },
11722
  {    21, "ERR_ISDIR"           },
11723
  {    22, "ERR_INVAL"           },
11724
  {    26, "ERR_TXTBSY"          },
11725
  {    27, "ERR_FBIG"          },
11726
  {    28, "ERR_NOSPC"           },
11727
  {    30, "ERR_ROFS"          },
11728
  {    31, "ERR_MLINK"           },
11729
  {    45, "ERR_OPNOTSUPP"         },
11730
  {    63, "ERR_NAMETOOLONG"         },
11731
  {    66, "ERR_NOTEMPTY"          },
11732
  {    69, "ERR_DQUOT"           },
11733
  {    70, "ERR_STALE"           },
11734
  {    71, "ERR_REMOTE"          },
11735
  {    99, "ERR_WFLUSH"          },
11736
  { 10001, "ERR_BADHANDLE"         },
11737
  { 10002, "ERR_NOT_SYNC"          },
11738
  { 10003, "ERR_BAD_COOKIE"        },
11739
  { 10004, "ERR_NOTSUPP"           },
11740
  { 10005, "ERR_TOOSMALL"          },
11741
  { 10006, "ERR_SERVERFAULT"         },
11742
  { 10007, "ERR_BADTYPE"           },
11743
  { 10008, "ERR_DELAY"           },
11744
  { 10009, "ERR_SAME"          },
11745
  { 10010, "ERR_DENIED"          },
11746
  { 10011, "ERR_EXPIRED"           },
11747
  { 10012, "ERR_LOCKED"          },
11748
  { 10013, "ERR_GRACE"           },
11749
  { 10014, "ERR_FHEXPIRED"         },
11750
  { 10015, "ERR_SHARE_DENIED"        },
11751
  { 10016, "ERR_WRONGSEC"          },
11752
  { 10017, "ERR_CLID_INUSE"        },
11753
  { 10018, "ERR_RESOURCE"          },
11754
  { 10019, "ERR_MOVED"           },
11755
  { 10020, "ERR_NOFILEHANDLE"        },
11756
  { 10021, "ERR_MINOR_VERS_MISMATCH"       },
11757
  { 10022, "ERR_STALE_CLIENTID"        },
11758
  { 10023, "ERR_STALE_STATEID"         },
11759
  { 10024, "ERR_OLD_STATEID"         },
11760
  { 10025, "ERR_BAD_STATEID"         },
11761
  { 10026, "ERR_BAD_SEQID"         },
11762
  { 10027, "ERR_NOT_SAME"          },
11763
  { 10028, "ERR_LOCK_RANGE"        },
11764
  { 10029, "ERR_SYMLINK"           },
11765
  { 10030, "ERR_READDIR_NOSPC"         },
11766
  { 10031, "ERR_LEASE_MOVED"         },
11767
  { 10032, "ERR_ATTRNOTSUPP"         },
11768
  { 10033, "ERR_NO_GRACE"          },
11769
  { 10034, "ERR_RECLAIM_BAD"         },
11770
  { 10035, "ERR_RECLAIM_CONFLICT"        },
11771
  { 10036, "ERR_BADXDR"          },
11772
  { 10037, "ERR_LOCKS_HELD"        },
11773
  { 10038, "ERR_OPENMODE"          },
11774
  { 10039, "ERR_BADOWNER"          },
11775
  { 10040, "ERR_BADCHAR"           },
11776
  { 10041, "ERR_BADNAME"           },
11777
  { 10042, "ERR_BAD_RANGE"         },
11778
  { 10043, "ERR_LOCK_NOTSUPP"        },
11779
  { 10044, "ERR_OP_ILLEGAL"        },
11780
  { 10045, "ERR_DEADLOCK"          },
11781
  { 10046, "ERR_FILE_OPEN"         },
11782
  { 10047, "ERR_ADMIN_REVOKED"         },
11783
  { 10048, "ERR_CB_PATH_DOWN"        },
11784
  { 10049, "ERR_REPLAY_ME_or_BADIOMODE"      },
11785
  { 10050, "ERR_BADLAYOUT"         },
11786
  { 10051, "ERR_BAD_SESSION_DIGEST"      },
11787
  { 10052, "ERR_BADSESSION"        },
11788
  { 10053, "ERR_BADSLOT"           },
11789
  { 10054, "ERR_COMPLETE_ALREADY"        },
11790
  { 10055, "ERR_CONN_NOT_BOUND_TO_SESSION"     },
11791
  { 10056, "ERR_DELEG_ALREADY_WANTED"      },
11792
  { 10057, "ERR_BACK_CHAN_BUSY"        },
11793
  { 10058, "ERR_LAYOUTTRYLATER"        },
11794
  { 10059, "ERR_LAYOUTUNAVAILABLE"       },
11795
  { 10060, "ERR_NOMATCHING_LAYOUT"       },
11796
  { 10061, "ERR_RECALLCONFLICT"        },
11797
  { 10062, "ERR_UNKNOWN_LAYOUTTYPE"      },
11798
  { 10063, "ERR_SEQ_MISORDERED"        },
11799
  { 10064, "ERR_SEQUENCE_POS"        },
11800
  { 10065, "ERR_REQ_TOO_BIG"         },
11801
  { 10066, "ERR_REP_TOO_BIG"         },
11802
  { 10067, "ERR_REP_TOO_BIG_TO_CACHE"      },
11803
  { 10068, "ERR_RETRY_UNCACHED_REP"      },
11804
  { 10069, "ERR_UNSAFE_COMPOUND"         },
11805
  { 10070, "ERR_TOO_MANY_OPS"        },
11806
  { 10071, "ERR_OP_NOT_IN_SESSION"       },
11807
  { 10072, "ERR_HASH_ALG_UNSUPP"         },
11808
  { 10073, "NFS4ERR_CONN_BINDING_NOT_ENFORCED" },
11809
  { 10074, "ERR_CLIENTID_BUSY"         },
11810
  { 10075, "ERR_PNFS_IO_HOLE"        },
11811
  { 10076, "ERR_SEQ_FALSE_RETRY"         },
11812
  { 10077, "ERR_BAD_HIGH_SLOT"         },
11813
  { 10078, "ERR_DEADSESSION"         },
11814
  { 10079, "ERR_ENCR_ALG_UNSUPP"         },
11815
  { 10080, "ERR_PNFS_NO_LAYOUT"        },
11816
  { 10081, "ERR_NOT_ONLY_OP"         },
11817
  { 10082, "ERR_WRONG_CRED"        },
11818
  { 10083, "ERR_WRONG_TYPE"        },
11819
  { 10084, "ERR_DIRDELEG_UNAVAIL"        },
11820
  { 10085, "ERR_REJECT_DELEG"        },
11821
  { 10086, "ERR_RETURNCONFLICT"        },
11822
  { 10087, "ERR_DELEG_REVOKED"         },
11823
  { 10088, "ERR_PARTNER_NOTSUPP"         },
11824
  { 10089, "ERR_PARTNER_NO_AUTH"         },
11825
  { 10090, "ERR_UNION_NOTSUPP"         },
11826
  { 10091, "ERR_OFFLOAD_DENIED"        },
11827
  { 10092, "ERR_WRONG_LFS"         },
11828
  { 10093, "ERR_BADLABEL"          },
11829
  { 10094, "ERR_OFFLOAD_NO_REQS"         },
11830
  { 0,  NULL }
11831
};
11832
static value_string_ext names_nfs_nfsstat_ext = VALUE_STRING_EXT_INIT(names_nfs_nfsstat);
11833
11834
static const value_string iomode_names[] = {
11835
  { 1, "IOMODE_READ" },
11836
  { 2, "IOMODE_RW"   },
11837
  { 3, "IOMODE_ANY"  },
11838
  { 0, NULL }
11839
};
11840
11841
#if 0
11842
static const value_string stripetype_names[] = {
11843
  { 1, "STRIPE_SPARSE" },
11844
  { 2, "STRIPE_DENSE"  },
11845
  { 0, NULL }
11846
};
11847
#endif
11848
11849
static const value_string netloctype_names[] = {
11850
  { NL4_NAME, "NL4_NAME" },
11851
  { NL4_URL, "NL4_URL"  },
11852
  { NL4_NETADDR, "NL4_NETADDR"  },
11853
  { 0, NULL }
11854
};
11855
11856
static const value_string layouttype_names[] = {
11857
  { 1, "LAYOUT4_NFSV4_1_FILES" },
11858
  { 2, "LAYOUT4_OSD2_OBJECTS"  },
11859
  { 3, "LAYOUT4_BLOCK_VOLUME"  },
11860
  { 4, "LAYOUT4_FLEX_FILES"  },
11861
  { 5, "LAYOUT4_SCSI"  },
11862
  { 0, NULL }
11863
};
11864
11865
static const value_string layoutreturn_names[] = {
11866
  { 1, "RETURN_FILE" },
11867
  { 2, "RETURN_FSID" },
11868
  { 3, "RETURN_ALL"  },
11869
  { 0, NULL }
11870
};
11871
11872
static const value_string gdd_non_fatal_status_names[] = {
11873
  { 0,  "GDD4_OK"  },
11874
  { 1,  "GDD4_UNAVAIL"  },
11875
  { 0, NULL }
11876
};
11877
11878
static const value_string nfs_fh_obj_id[] = {
11879
  { 1, "NF4REG"      },
11880
  { 2, "NF4DIR"      },
11881
  { 3, "NF4BLK"      },
11882
  { 4, "NF4CHR"      },
11883
  { 5, "NF4LNK"      },
11884
  { 6, "NF4SOCK"     },
11885
  { 7, "NF4FIFO"     },
11886
  { 8, "NF4ATTRDIR"  },
11887
  { 9, "NF4NAMEDATTR"},
11888
  { 0, NULL }
11889
};
11890
11891
static const true_false_string nfs4_ro_boolean = {
11892
  "object is read only",
11893
  "object is *not* read-only"
11894
};
11895
11896
static const value_string layoutrecall_names[] = {
11897
  { 1, "RECALL_FILE" },
11898
  { 2, "RECALL_FSID" },
11899
  { 3, "RECALL_ALL"  },
11900
  { 0, NULL }
11901
};
11902
11903
/* NFS Callback */
11904
static int hf_nfs4_cb_procedure;
11905
static int hf_nfs4_cb_op;
11906
static int hf_nfs4_cb_truncate;
11907
static int hf_nfs4_cb_layoutrecall_type;
11908
static int hf_nfs4_cb_clorachanged;
11909
11910
static int ett_nfs4_cb_request_op;
11911
static int ett_nfs4_cb_resop;
11912
static int ett_nfs4_cb_getattr;
11913
static int ett_nfs4_cb_recall;
11914
static int ett_nfs4_cb_layoutrecall;
11915
static int ett_nfs4_cb_pushdeleg;
11916
static int ett_nfs4_cb_recallany;
11917
static int ett_nfs4_cb_recallableobjavail;
11918
static int ett_nfs4_cb_recallslot;
11919
static int ett_nfs4_cb_sequence;
11920
static int ett_nfs4_cb_wantscancelled;
11921
static int ett_nfs4_cb_notifylock;
11922
static int ett_nfs4_cb_notifydeviceid;
11923
static int ett_nfs4_cb_notify;
11924
static int ett_nfs4_cb_reflists;
11925
static int ett_nfs4_cb_refcalls;
11926
static int ett_nfs4_cb_illegal;
11927
11928
static const value_string names_nfs_cb_operation[] = {
11929
  { NFS4_OP_CB_GETATTR,      "CB_GETATTR" },
11930
  { NFS4_OP_CB_RECALL,       "CB_RECALL"  },
11931
  { NFS4_OP_CB_LAYOUTRECALL,     "CB_LAYOUTRECALL" },
11932
  { NFS4_OP_CB_NOTIFY,       "CB_NOTIFY" },
11933
  { NFS4_OP_CB_PUSH_DELEG,     "CB_PUSH_DELEG" },
11934
  { NFS4_OP_CB_RECALL_ANY,     "CB_RECALL_ANY" },
11935
  { NFS4_OP_CB_RECALLABLE_OBJ_AVAIL, "CB_RECALLABLE_OBJ_AVAIL" },
11936
  { NFS4_OP_CB_RECALL_SLOT,    "CB_RECALL_SLOT"},
11937
  { NFS4_OP_CB_SEQUENCE,       "CB_SEQUENCE" },
11938
  { NFS4_OP_CB_WANTS_CANCELLED,    "CB_WANTS_CANCELLED" },
11939
  { NFS4_OP_CB_NOTIFY_LOCK,    "CB_NOTIFY_LOCK" },
11940
  { NFS4_OP_CB_NOTIFY_DEVICEID,    "CB_NOTIFY_DEVICEID" },
11941
  { NFS4_OP_CB_OFFLOAD,      "CB_OFFLOAD" },
11942
  { NFS4_OP_CB_ILLEGAL,      "CB_ILLEGAL"},
11943
  { 0,  NULL }
11944
};
11945
static value_string_ext names_nfs_cb_operation_ext = VALUE_STRING_EXT_INIT(names_nfs_cb_operation);
11946
11947
static int *nfs4_cb_operation_ett[] =
11948
{
11949
  &ett_nfs4_cb_getattr,
11950
  &ett_nfs4_cb_recall,
11951
  &ett_nfs4_cb_layoutrecall,
11952
  &ett_nfs4_cb_notify,
11953
  &ett_nfs4_cb_pushdeleg,
11954
  &ett_nfs4_cb_recallany,
11955
  &ett_nfs4_cb_recallableobjavail,
11956
  &ett_nfs4_cb_recallslot,
11957
  &ett_nfs4_cb_sequence,
11958
  &ett_nfs4_cb_wantscancelled,
11959
  &ett_nfs4_cb_notifylock,
11960
  &ett_nfs4_cb_notifydeviceid,
11961
  &ett_nfs4_cb_illegal
11962
};
11963
11964
static unsigned
11965
dissect_nfs4_cb_referring_calls(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
11966
0
{
11967
0
  unsigned      num_reflists, num_refcalls, i, j;
11968
0
  proto_tree *rl_tree, *rc_tree;
11969
11970
0
  num_reflists = tvb_get_ntohl(tvb, offset);
11971
0
  rl_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4,
11972
0
      ett_nfs4_cb_reflists, NULL, "referring call lists (count: %u)", num_reflists);
11973
0
  offset += 4;
11974
11975
0
  for (i = 0; i < num_reflists; i++) {
11976
0
    offset = dissect_nfs4_sessionid(tvb, offset, rl_tree);
11977
0
    num_refcalls = tvb_get_ntohl(tvb, offset);
11978
0
    rc_tree = proto_tree_add_subtree_format(rl_tree, tvb, offset, 4,
11979
0
        ett_nfs4_cb_refcalls, NULL, "referring calls (count: %u)", num_refcalls);
11980
0
    offset += 4;
11981
0
    for (j = 0; j < num_refcalls; j++) {
11982
0
      offset = dissect_rpc_uint32(tvb, rc_tree, hf_nfs4_seqid, offset);
11983
0
      offset = dissect_rpc_uint32(tvb, rc_tree, hf_nfs4_slotid, offset);
11984
0
    }
11985
0
  }
11986
11987
0
  return offset;
11988
0
}
11989
11990
static unsigned
11991
dissect_nfs4_cb_layoutrecall(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo, rpc_call_info_value *civ)
11992
0
{
11993
0
  unsigned recall_type;
11994
11995
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
11996
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_iomode, offset);
11997
0
  offset = dissect_rpc_bool(tvb, tree, hf_nfs4_cb_clorachanged, offset);
11998
11999
0
  recall_type = tvb_get_ntohl(tvb, offset);
12000
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_cb_layoutrecall_type, offset);
12001
12002
0
  if (recall_type == 1) { /* RECALL_FILE */
12003
0
    offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "FileHandle", NULL, NULL, NULL, civ, -1, -1);
12004
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
12005
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
12006
0
    offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
12007
0
  } else if (recall_type == 2) { /* RECALL_FSID */
12008
0
    offset = dissect_nfs4_fsid(tvb, offset, tree, "fsid");
12009
0
  }
12010
12011
0
  return offset;
12012
0
}
12013
12014
0
#define BIT(__n)  (1 << __n)
12015
12016
static unsigned
12017
dissect_notify_entry4(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo,
12018
          rpc_call_info_value *civ)
12019
0
{
12020
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_component, NULL);
12021
0
  return dissect_nfs4_fattrs(tvb, offset, pinfo, tree, FATTR4_DISSECT_VALUES, civ, -1, -1);
12022
0
}
12023
12024
static unsigned
12025
dissect_notify_remove4(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo,
12026
           rpc_call_info_value *civ)
12027
0
{
12028
0
  offset = dissect_notify_entry4(tvb, offset, tree, pinfo, civ);
12029
0
  return dissect_rpc_uint64(tvb, tree, hf_nfs4_cookie, offset);
12030
0
}
12031
12032
static inline int
12033
dissect_prev_entry4(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo,
12034
        rpc_call_info_value *civ)
12035
0
{
12036
0
  return dissect_notify_remove4(tvb, offset, tree, pinfo, civ);
12037
0
}
12038
12039
static unsigned
12040
dissect_notify_attr4(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo,
12041
           rpc_call_info_value *civ)
12042
0
{
12043
0
  return dissect_notify_entry4(tvb, offset, tree, pinfo, civ);
12044
0
}
12045
12046
static unsigned
12047
dissect_notify_add4(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo,
12048
           rpc_call_info_value *civ)
12049
0
{
12050
0
  uint32_t count;
12051
12052
  /* nad_old_entry */
12053
0
  count = tvb_get_ntohl(tvb, offset);
12054
0
  offset += 4;
12055
0
  if (count)
12056
0
    offset = dissect_notify_remove4(tvb, offset, tree, pinfo, civ);
12057
12058
  /* nad_new_entry */
12059
0
  offset = dissect_notify_entry4(tvb, offset, tree, pinfo, civ);
12060
12061
  /* nad_new_entry_cookie */
12062
0
  count = tvb_get_ntohl(tvb, offset);
12063
0
  offset += 4;
12064
0
  if (count)
12065
0
    offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_cookie, offset);
12066
12067
  /* nad_prev_entry */
12068
0
  count = tvb_get_ntohl(tvb, offset);
12069
0
  offset += 4;
12070
0
  if (count)
12071
0
    offset = dissect_prev_entry4(tvb, offset, tree, pinfo, civ);
12072
12073
0
  return dissect_rpc_bool(tvb, tree, hf_nfs4_nad_last_entry, offset);
12074
0
}
12075
12076
static unsigned
12077
dissect_notify_rename4(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo,
12078
           rpc_call_info_value *civ)
12079
0
{
12080
0
  offset = dissect_notify_remove4(tvb, offset, tree, pinfo, civ);
12081
0
  return dissect_notify_add4(tvb, offset, tree, pinfo, civ);
12082
0
}
12083
12084
static unsigned
12085
dissect_nfs4_cb_notify_args(tvbuff_t *tvb, unsigned offset, proto_tree *tree, packet_info *pinfo, rpc_call_info_value *civ)
12086
0
{
12087
0
  proto_tree *ctree;
12088
0
  uint32_t changes;
12089
0
  uint32_t i;
12090
12091
0
  offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
12092
0
  offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "FileHandle", NULL, NULL, NULL, civ, -1, -1);
12093
12094
0
  changes = tvb_get_ntohl(tvb, offset);
12095
0
  ctree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_nfs4_cb_notify_changes,
12096
0
                NULL, "Changes (count: %u)", changes);
12097
0
  offset += 4;
12098
0
  for (i = 0; i < changes; ++i) {
12099
0
    uint32_t len, mask = 0;
12100
0
    proto_tree *ntree;
12101
12102
    /*
12103
     * Grab the first word of the bitmap. This will need to be modified if
12104
     * it ever spills into multiple words (unlikely).
12105
     */
12106
0
    len = tvb_get_ntohl(tvb, offset);
12107
0
    if (len)
12108
0
      mask = tvb_get_ntohl(tvb, offset + 4);
12109
0
    offset = dissect_nfs4_notify_type4_bitmap(tvb, ctree, pinfo, offset, -1, -1);
12110
12111
0
    len = tvb_get_ntohl(tvb, offset);
12112
0
    ntree = proto_tree_add_subtree_format(ctree, tvb, offset, 4,
12113
0
                  ett_nfs4_cb_notify_list_entries,
12114
0
                  NULL, "notify_vals (len: %u)", len);
12115
0
    offset += 4;
12116
12117
0
    if (mask & BIT(NOTIFY4_CHANGE_CHILD_ATTRS)) {
12118
0
      proto_tree *rtree;
12119
12120
0
      rtree = proto_tree_add_subtree(ntree, tvb, offset, 4,
12121
0
                   ett_nfs4_cb_notify_attr4_child,
12122
0
                   NULL, "Child Attr Change");
12123
0
      offset = dissect_notify_attr4(tvb, offset, rtree, pinfo, civ);
12124
0
    }
12125
0
    if (mask & BIT(NOTIFY4_CHANGE_DIR_ATTRS)) {
12126
0
      proto_tree *rtree;
12127
12128
0
      rtree = proto_tree_add_subtree(ntree, tvb, offset, 4,
12129
0
                   ett_nfs4_cb_notify_attr4_dir,
12130
0
                   NULL, "Dir Attr Change");
12131
0
      offset = dissect_notify_attr4(tvb, offset, rtree, pinfo, civ);
12132
0
    }
12133
0
    if (mask & BIT(NOTIFY4_REMOVE_ENTRY)) {
12134
0
      proto_tree *rtree;
12135
12136
0
      rtree = proto_tree_add_subtree(ntree, tvb, offset, 4,
12137
0
                   ett_nfs4_cb_notify_remove4,
12138
0
                   NULL, "Remove Entry");
12139
0
      offset = dissect_notify_remove4(tvb, offset, rtree, pinfo, civ);
12140
0
    }
12141
12142
0
    if (mask & BIT(NOTIFY4_ADD_ENTRY)) {
12143
0
      proto_tree *atree;
12144
12145
0
      atree = proto_tree_add_subtree(ntree, tvb, offset, 4,
12146
0
                   ett_nfs4_cb_notify_add4,
12147
0
                   NULL, "Add Entry");
12148
0
      offset = dissect_notify_add4(tvb, offset, atree, pinfo, civ);
12149
0
    }
12150
12151
0
    if (mask & BIT(NOTIFY4_RENAME_ENTRY)) {
12152
0
      proto_tree *rtree;
12153
12154
0
      rtree = proto_tree_add_subtree(ntree, tvb, offset, 4,
12155
0
                   ett_nfs4_cb_notify_rename4,
12156
0
                   NULL, "Rename Entry");
12157
0
      offset = dissect_notify_rename4(tvb, offset, rtree, pinfo, civ);
12158
0
    }
12159
    /* FIXME: NOTIFY4_CHANGE_COOKIE_VERIFIER */
12160
0
  }
12161
0
  return offset;
12162
0
}
12163
12164
static unsigned
12165
dissect_nfs4_cb_request(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
12166
0
{
12167
0
  uint32_t      ops, ops_counter;
12168
0
  uint32_t      status;
12169
0
  unsigned      opcode;
12170
0
  proto_item *fitem;
12171
0
  proto_tree *ftree;
12172
0
  proto_tree *newftree = NULL;
12173
0
  nfs4_operation_summary *op_summary;
12174
12175
0
  ops = tvb_get_ntohl(tvb, offset+0);
12176
12177
0
  ftree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_nfs4_cb_request_op, NULL, "Operations (count: %u)", ops);
12178
0
  offset += 4;
12179
12180
0
  if (ops > MAX_NFSV4_OPS) {
12181
0
    expert_add_info(pinfo, ftree, &ei_nfs_too_many_ops);
12182
0
    ops = MAX_NFSV4_OPS;
12183
0
  }
12184
12185
0
  op_summary = wmem_alloc0_array(pinfo->pool, nfs4_operation_summary, ops);
12186
12187
0
  for (ops_counter=0; ops_counter<ops; ops_counter++)
12188
0
  {
12189
0
    opcode = tvb_get_ntohl(tvb, offset);
12190
0
    op_summary[ops_counter].iserror = false;
12191
0
    op_summary[ops_counter].opcode = opcode;
12192
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "%c%s", ops_counter == 0?' ':';',
12193
0
        val_to_str_ext_const(opcode, &names_nfs_cb_operation_ext, "Unknown"));
12194
12195
0
    fitem = proto_tree_add_uint(ftree, hf_nfs4_cb_op, tvb, offset, 4, opcode);
12196
0
    offset += 4;
12197
12198
  /* the opcodes are not contiguous */
12199
0
    if ((opcode < NFS4_OP_CB_GETATTR || opcode > NFS4_OP_CB_OFFLOAD) &&
12200
0
        (opcode != NFS4_OP_CB_ILLEGAL))
12201
0
      break;
12202
12203
  /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
12204
0
    if (opcode == NFS4_OP_CB_ILLEGAL)
12205
0
      newftree = proto_item_add_subtree(fitem, ett_nfs4_cb_illegal);
12206
0
    else if (nfs4_cb_operation_ett[opcode - 3])
12207
0
      newftree = proto_item_add_subtree(fitem, *nfs4_cb_operation_ett[opcode - 3]);
12208
0
    else
12209
0
      break;
12210
12211
0
    switch (opcode)
12212
0
    {
12213
0
    case NFS4_OP_CB_RECALL:
12214
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
12215
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_cb_truncate, offset);
12216
0
      offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", NULL, NULL, NULL, civ, opcode, -1);
12217
0
      break;
12218
0
    case NFS4_OP_CB_GETATTR:
12219
0
      offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "FileHandle", NULL, NULL, NULL, civ, opcode, -1);
12220
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, tree, FATTR4_BITMAP_ONLY, civ, opcode, -1);
12221
0
      break;
12222
0
    case NFS4_OP_CB_LAYOUTRECALL:
12223
0
      offset = dissect_nfs4_cb_layoutrecall(tvb, offset, newftree, pinfo, civ);
12224
0
      break;
12225
0
    case NFS4_OP_CB_RECALL_ANY:
12226
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_cb_recall_any_objs, offset);
12227
0
      offset = dissect_nfs4_cb_recall_any_mask(tvb, offset, pinfo, newftree);
12228
0
      break;
12229
0
    case NFS4_OP_CB_NOTIFY:
12230
0
      offset = dissect_nfs4_cb_notify_args(tvb, offset, newftree, pinfo, civ);
12231
0
      break;
12232
0
    case NFS4_OP_CB_PUSH_DELEG:
12233
0
    case NFS4_OP_CB_RECALLABLE_OBJ_AVAIL:
12234
0
    case NFS4_OP_CB_RECALL_SLOT:
12235
0
      break;
12236
0
    case NFS4_OP_CB_SEQUENCE:
12237
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
12238
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
12239
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
12240
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
12241
0
      offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_cachethis, offset);
12242
0
      offset = dissect_nfs4_cb_referring_calls(tvb, offset, newftree);
12243
0
      break;
12244
0
    case NFS4_OP_CB_WANTS_CANCELLED:
12245
0
      break;
12246
0
    case NFS4_OP_CB_NOTIFY_LOCK:
12247
0
      offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", NULL, NULL, NULL, civ, opcode, -1);
12248
0
      offset = dissect_nfs4_lock_owner(tvb, pinfo, offset, newftree);
12249
0
      break;
12250
0
    case NFS4_OP_CB_NOTIFY_DEVICEID:
12251
0
      break;
12252
0
    case NFS4_OP_CB_OFFLOAD:
12253
0
      offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", NULL, NULL, NULL, civ, opcode, -1);
12254
0
      offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
12255
0
      offset = dissect_nfs4_status(tvb, offset, newftree, &status);
12256
0
      if (status == NFS4_OK) {
12257
0
        offset = dissect_nfs4_write_response(tvb, pinfo, offset, newftree);
12258
0
      } else {
12259
0
        offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_bytes_copied, offset);
12260
0
      }
12261
0
      break;
12262
0
    case NFS4_OP_ILLEGAL:
12263
0
      break;
12264
0
    default:
12265
0
      break;
12266
0
    }
12267
0
  }
12268
12269
  /* Copy the information from the call info and store information about
12270
   * the operations here in private data.
12271
   */
12272
0
  rpc_call_info_value *tapdata = wmem_new0(pinfo->pool, rpc_call_info_value);
12273
0
  *tapdata = *civ;
12274
0
  nfs4_tap_data_t *ops_info = wmem_new0(pinfo->pool, nfs4_tap_data_t);
12275
0
  ops_info->op_summary = op_summary;
12276
0
  ops_info->ops_counter = ops_counter;
12277
0
  ops_info->highest_tier = 0;
12278
0
  tapdata->private_data = ops_info;
12279
0
  tap_queue_packet(nfsv4_tap, pinfo, tapdata);
12280
12281
0
  return offset;
12282
0
}
12283
12284
12285
static int
12286
dissect_nfs4_cb_compound_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
12287
0
{
12288
0
  const char *tag = NULL;
12289
0
  unsigned offset = 0;
12290
12291
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_tag, &tag);
12292
12293
0
  col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
12294
12295
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_minorversion, offset);
12296
0
  offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_callback_ident, offset);
12297
0
  offset = dissect_nfs4_cb_request(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
12298
12299
0
  return offset;
12300
0
}
12301
12302
12303
static unsigned
12304
dissect_nfs4_cb_resp_op(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
12305
0
{
12306
0
  uint32_t      ops, ops_counter;
12307
0
  uint32_t      opcode;
12308
0
  proto_item *fitem;
12309
0
  proto_tree *ftree;
12310
0
  proto_tree *newftree = NULL;
12311
0
  uint32_t      status;
12312
0
  nfs4_operation_summary *op_summary;
12313
12314
0
  ops   = tvb_get_ntohl(tvb, offset+0);
12315
0
  ftree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_nfs4_cb_resop, NULL, "Operations (count: %u)", ops);
12316
0
  offset += 4;
12317
12318
0
  if (ops > MAX_NFSV4_OPS) {
12319
0
    expert_add_info(pinfo, ftree, &ei_nfs_too_many_ops);
12320
0
    ops = MAX_NFSV4_OPS;
12321
0
  }
12322
12323
0
  op_summary = wmem_alloc0_array(pinfo->pool, nfs4_operation_summary, ops);
12324
12325
0
  for (ops_counter = 0; ops_counter < ops; ops_counter++)
12326
0
  {
12327
0
    opcode = tvb_get_ntohl(tvb, offset);
12328
0
    op_summary[ops_counter].iserror = false;
12329
0
    op_summary[ops_counter].opcode = opcode;
12330
12331
    /* sanity check for bogus packets */
12332
0
    if ((opcode < NFS4_OP_CB_GETATTR || opcode > NFS4_OP_CB_OFFLOAD) &&
12333
0
      (opcode != NFS4_OP_ILLEGAL))
12334
0
      break;
12335
12336
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "%c%s", ops_counter == 0 ? ' ' : ';',
12337
0
        val_to_str_ext_const(opcode, &names_nfs_cb_operation_ext, "Unknown"));
12338
12339
0
    fitem = proto_tree_add_uint(ftree, hf_nfs4_cb_op, tvb, offset, 4, opcode);
12340
0
    offset += 4;
12341
12342
    /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
12343
0
    if (opcode == NFS4_OP_ILLEGAL)
12344
0
      newftree = proto_item_add_subtree(fitem, ett_nfs4_illegal);
12345
0
    else if (nfs4_cb_operation_ett[opcode - 3])
12346
0
      newftree = proto_item_add_subtree(fitem, *nfs4_cb_operation_ett[opcode - 3]);
12347
0
    else
12348
0
      break;
12349
12350
0
    offset = dissect_nfs4_status(tvb, offset, newftree, &status);
12351
12352
    /* are there any ops that return data with a failure (?) */
12353
0
    if (status != NFS4_OK) {
12354
0
      op_summary[ops_counter].iserror = true;
12355
0
      continue;
12356
0
    }
12357
12358
    /* These parsing routines are only executed if the status is NFS4_OK */
12359
0
    switch (opcode)
12360
0
    {
12361
0
    case NFS4_OP_CB_RECALL:
12362
0
      break;
12363
0
    case NFS4_OP_CB_GETATTR:
12364
0
      offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ, opcode, -1);
12365
0
      break;
12366
0
    case NFS4_OP_CB_LAYOUTRECALL:
12367
0
      break;
12368
0
    case NFS4_OP_CB_NOTIFY:
12369
0
    case NFS4_OP_CB_PUSH_DELEG:
12370
0
    case NFS4_OP_CB_RECALL_ANY:
12371
0
    case NFS4_OP_CB_RECALLABLE_OBJ_AVAIL:
12372
0
    case NFS4_OP_CB_RECALL_SLOT:
12373
0
      break;
12374
0
    case NFS4_OP_CB_SEQUENCE:
12375
0
      offset = dissect_nfs4_sessionid(tvb, offset, newftree);
12376
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
12377
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
12378
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
12379
0
      offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_target_high_slotid, offset);
12380
0
      break;
12381
0
    case NFS4_OP_CB_WANTS_CANCELLED:
12382
0
    case NFS4_OP_CB_NOTIFY_LOCK:
12383
0
    case NFS4_OP_CB_NOTIFY_DEVICEID:
12384
0
    case NFS4_OP_CB_OFFLOAD:
12385
0
      break;
12386
0
    case NFS4_OP_ILLEGAL:
12387
0
      break;
12388
0
    default:
12389
0
      break;
12390
0
    }
12391
0
  }
12392
12393
  /* Copy the information from the call info and store information about
12394
   * the operations here in private data.
12395
   */
12396
0
  rpc_call_info_value *tapdata = wmem_new0(pinfo->pool, rpc_call_info_value);
12397
0
  *tapdata = *civ;
12398
0
  nfs4_tap_data_t *ops_info = wmem_new0(pinfo->pool, nfs4_tap_data_t);
12399
0
  ops_info->op_summary = op_summary;
12400
0
  ops_info->ops_counter = ops_counter;
12401
0
  ops_info->highest_tier = 0;
12402
0
  tapdata->private_data = ops_info;
12403
0
  tap_queue_packet(nfsv4_tap, pinfo, tapdata);
12404
12405
0
  return offset;
12406
0
}
12407
12408
12409
static int
12410
dissect_nfs4_cb_compound_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
12411
0
{
12412
0
  uint32_t      status;
12413
0
  const char *tag = NULL;
12414
0
  unsigned offset = 0;
12415
12416
0
  offset = dissect_nfs4_status(tvb, offset, tree, &status);
12417
0
  offset = dissect_nfs_utf8string(tvb, pinfo, offset, tree, hf_nfs4_tag, &tag);
12418
0
  col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
12419
12420
0
  offset = dissect_nfs4_cb_resp_op(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
12421
12422
0
  return offset;
12423
0
}
12424
12425
12426
static const vsff nfs_cb_proc[] = {
12427
  { 0, "CB_NULL",
12428
    dissect_nfs3_null_call, dissect_nfs3_null_reply },
12429
  { 1, "CB_COMPOUND",
12430
    dissect_nfs4_cb_compound_call, dissect_nfs4_cb_compound_reply },
12431
  { 0, NULL, NULL, NULL }
12432
};
12433
12434
static const value_string nfs_cb_proc_vals[] = {
12435
  { 0, "CB_NULL" },
12436
  { 1, "CB_COMPOUND" },
12437
  { 0, NULL }
12438
};
12439
12440
/*
12441
 * NFS Callback version 1 is used by NFSv4.0 protocol and
12442
 * NFS Callback version 4 is used by NFSv4.1 and NFSv4.2 protocols.
12443
 * Other versions (including 2 and 3) are not defined nor used yet.
12444
 */
12445
static const rpc_prog_vers_info nfs_cb_vers_info[] = {
12446
  { 1, nfs_cb_proc, &hf_nfs4_cb_procedure },
12447
  { 4, nfs_cb_proc, &hf_nfs4_cb_procedure },
12448
};
12449
12450
#define NFS4_SRT_TABLE_INDEX 0
12451
#define NFS4_MAIN_OP_SRT_TABLE_INDEX 1
12452
#define NFS4_CB_SRT_TABLE_INDEX 2
12453
12454
typedef struct nfsv4_tap_data {
12455
12456
  uint32_t    ops_counter;
12457
  nfs4_operation_summary *op_summary;
12458
  uint32_t program;
12459
  uint32_t version;
12460
  uint32_t operation;
12461
  uint32_t xid;
12462
  bool request;
12463
  nstime_t req_time;
12464
} nfsv4_tap_data_t;
12465
12466
static void
12467
nfsstat_init(struct register_srt* srt _U_, GArray* srt_array)
12468
0
{
12469
0
  srt_stat_table *nfs_srt_table, *nfs_main_op_srt_table;
12470
12471
0
  nfs_srt_table = init_srt_table("NFSv4 Operations", NULL, srt_array, NFS4_LAST_OP + 1, "Operations", "nfs.opcode", NULL);
12472
0
  nfs_main_op_srt_table = init_srt_table("NFSv4 Main Operation", NULL, srt_array, NFS4_LAST_OP + 1, "Operations", "nfs.main_opcode", NULL);
12473
0
  for (uint32_t i = 0; i <= NFS4_LAST_OP; i++) {
12474
0
    init_srt_table_row(nfs_srt_table, i,
12475
0
      val_to_str_ext_const(i, &names_nfs4_operation_ext, "Unknown"));
12476
0
    init_srt_table_row(nfs_main_op_srt_table, i,
12477
0
      val_to_str_ext_const(i, &names_nfs4_operation_ext, "Unknown"));
12478
0
  }
12479
12480
0
  nfs_srt_table = init_srt_table("NFSv4 Callback Operations", NULL, srt_array, NFS4_OP_CB_OFFLOAD + 1, "Operations", "nfs.cb.operation", NULL);
12481
12482
0
  for (uint32_t i = 0; i <= NFS4_OP_CB_OFFLOAD; i++) {
12483
0
    init_srt_table_row(nfs_srt_table, i,
12484
0
      val_to_str_ext_const(i, &names_nfs4_operation_ext, "Unknown"));
12485
0
  }
12486
0
}
12487
12488
/* Hash table with NFS4 CB program numbers */
12489
static GHashTable *nfs4_cb_progs;
12490
12491
static void
12492
nfs4_cb_init(void)
12493
16
{
12494
16
  nfs4_cb_progs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
12495
16
}
12496
12497
static void
12498
nfs4_cb_cleanup(void)
12499
0
{
12500
0
  g_hash_table_destroy(nfs4_cb_progs);
12501
0
}
12502
12503
static void
12504
nfs4_cb_register_prog(tvbuff_t *tvb, int offset)
12505
0
{
12506
0
  uint32_t prog = tvb_get_ntohl(tvb, offset);
12507
12508
0
  if (g_hash_table_lookup(nfs4_cb_progs, GUINT_TO_POINTER(prog)) != NULL)
12509
0
    return;
12510
12511
0
  g_hash_table_insert(nfs4_cb_progs, GUINT_TO_POINTER(prog), GUINT_TO_POINTER(1));
12512
12513
  /* Register the CB protocol as RPC */
12514
0
  rpc_init_prog(proto_nfs_cb, prog, ett_nfs, G_N_ELEMENTS(nfs_cb_vers_info), nfs_cb_vers_info);
12515
0
}
12516
12517
static tap_packet_status
12518
nfsstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv, tap_flags_t flags _U_)
12519
0
{
12520
0
  srt_stat_table *nfs_srt_table, *nfs_main_op_srt_table;
12521
0
  srt_data_t *data = (srt_data_t *)pss;
12522
0
  const rpc_call_info_value *ri = (const rpc_call_info_value *)prv;
12523
0
  const nfs4_tap_data_t *ops_info = (const nfs4_tap_data_t *)ri->private_data;
12524
0
  uint32_t opcode;
12525
0
  unsigned current_tier;
12526
12527
  /* we are only interested in response packets */
12528
0
  if (ri->request) {
12529
0
    return TAP_PACKET_DONT_REDRAW;
12530
0
  }
12531
12532
0
  if (ri->prog == NFS_PROGRAM) {
12533
0
    nfs_srt_table = g_array_index(data->srt_array, srt_stat_table*, NFS4_SRT_TABLE_INDEX);
12534
0
    nfs_main_op_srt_table = g_array_index(data->srt_array, srt_stat_table*, NFS4_MAIN_OP_SRT_TABLE_INDEX);
12535
0
  } else if (g_hash_table_lookup(nfs4_cb_progs, GUINT_TO_POINTER(ri->prog)) != NULL) {
12536
0
    nfs_srt_table = g_array_index(data->srt_array, srt_stat_table*, NFS4_CB_SRT_TABLE_INDEX);
12537
0
    nfs_main_op_srt_table = NULL;
12538
0
  } else {
12539
0
    return TAP_PACKET_DONT_REDRAW;
12540
0
  }
12541
12542
  /* Add each of the operations seen to the table. Add operations
12543
   * considered the "main opcode" (in the highest tier in the
12544
   * compound procedure) to another table.
12545
   */
12546
0
  for (uint32_t ops = 0; ops < ops_info->ops_counter; ops++) {
12547
0
    opcode = ops_info->op_summary[ops].opcode;
12548
0
    if (opcode == NFS4_OP_ILLEGAL) {
12549
      /* Ignore the illegal opcode, it would create
12550
       * 10,000 empty SRT rows.
12551
       * Note NFS4_OP_CB_ILLEGAL is the same value;
12552
       * actually testing for it makes some compilers
12553
       * warn about a useless duplicate logical test.
12554
       */
12555
0
      continue;
12556
0
    }
12557
0
    add_srt_table_data(nfs_srt_table, opcode, &ri->req_time, pinfo);
12558
0
    if (nfs_main_op_srt_table) {
12559
0
      current_tier = NFS4_OPERATION_TIER(opcode);
12560
0
      if (current_tier == ops_info->highest_tier) {
12561
0
        add_srt_table_data(nfs_main_op_srt_table, opcode, &ri->req_time, pinfo);
12562
0
      }
12563
0
    }
12564
0
  }
12565
12566
0
  return TAP_PACKET_REDRAW;
12567
0
}
12568
12569
void
12570
proto_register_nfs(void)
12571
16
{
12572
16
  static hf_register_info hf[] = {
12573
16
    { &hf_nfs2_procedure, {
12574
16
      "V2 Procedure", "nfs.procedure_v2", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
12575
16
      &nfs2_proc_vals_ext, 0, NULL, HFILL }},
12576
16
    { &hf_nfs3_procedure, {
12577
16
      "V3 Procedure", "nfs.procedure_v3", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
12578
16
      &nfs3_proc_vals_ext, 0, NULL, HFILL }},
12579
16
    { &hf_nfs4_procedure, {
12580
16
      "V4 Procedure", "nfs.procedure_v4", FT_UINT32, BASE_DEC,
12581
16
      VALS(nfs4_proc_vals), 0, NULL, HFILL }},
12582
#if 0
12583
    { &hf_nfs4_impl_id_len, {
12584
      "Implementation ID length", "nfs.impl_id4.length", FT_UINT32, BASE_DEC,
12585
      NULL, 0, NULL, HFILL }},
12586
#endif
12587
16
    { &hf_nfs_fh_length, {
12588
16
      "length", "nfs.fh.length", FT_UINT32, BASE_DEC,
12589
16
      NULL, 0, "file handle length", HFILL }},
12590
16
    { &hf_nfs_fh_hash, {
12591
16
      "hash (CRC-32)", "nfs.fh.hash", FT_UINT32, BASE_HEX,
12592
16
      NULL, 0, "file handle hash", HFILL }},
12593
12594
12595
16
    { &hf_nfs_fh_mount_fileid, {
12596
16
      "fileid", "nfs.fh.mount.fileid", FT_UINT32, BASE_DEC,
12597
16
      NULL, 0, "mount point fileid", HFILL }},
12598
16
    { &hf_nfs_fh_mount_generation, {
12599
16
      "generation", "nfs.fh.mount.generation", FT_UINT32, BASE_HEX,
12600
16
      NULL, 0, "mount point generation", HFILL }},
12601
16
    { &hf_nfs_fh_flags, {
12602
16
      "Flags", "nfs.fh.flags", FT_UINT16, BASE_HEX,
12603
16
      NULL, 0, "file handle flags", HFILL }},
12604
16
    { &hf_nfs_fh_snapid, {
12605
16
      "snapid", "nfs.fh.snapid", FT_UINT8, BASE_DEC,
12606
16
      NULL, 0, "snapshot ID", HFILL }},
12607
16
    { &hf_nfs_fh_unused, {
12608
16
      "unused", "nfs.fh.unused", FT_UINT8, BASE_DEC,
12609
16
      NULL, 0, NULL, HFILL }},
12610
16
    { &hf_nfs_fh_fileid, {
12611
16
      "fileid", "nfs.fh.fileid", FT_UINT32, BASE_DEC,
12612
16
      NULL, 0, "file ID", HFILL }},
12613
16
    { &hf_nfs_fh_generation, {
12614
16
      "generation", "nfs.fh.generation", FT_UINT32, BASE_HEX,
12615
16
      NULL, 0, "inode generation", HFILL }},
12616
16
    { &hf_nfs_fh_fsid, {
12617
16
      "file system ID", "nfs.fh.fsid", FT_UINT32, BASE_CUSTOM,
12618
16
      CF_FUNC(nfs_fmt_fsid), 0, NULL, HFILL }},
12619
16
    { &hf_nfs_fh_export_fileid, {
12620
16
      "fileid", "nfs.fh.export.fileid", FT_UINT32, BASE_DEC,
12621
16
      NULL, 0, "export point fileid", HFILL }},
12622
16
    { &hf_nfs_fh_export_generation, {
12623
16
      "generation", "nfs.fh.export.generation", FT_UINT32, BASE_HEX,
12624
16
      NULL, 0, "export point generation", HFILL }},
12625
16
    { &hf_nfs_fh_export_snapid, {
12626
16
      "snapid", "nfs.fh.export.snapid", FT_UINT8, BASE_DEC,
12627
16
      NULL, 0, "export point snapid", HFILL }},
12628
16
    { &hf_nfs_fh_exportid, {
12629
16
      "exportid", "nfs.fh.exportid", FT_GUID, BASE_NONE,
12630
16
      NULL, 0, "Gluster/NFS exportid", HFILL }},
12631
16
    { &hf_nfs_fh_handle_type, {
12632
16
      "Handle type", "nfs.fh.handletype", FT_UINT32, BASE_DEC,
12633
16
      VALS(handle_type_strings), 0, "v4 handle type", HFILL }},
12634
16
    { &hf_nfs_fh_file_flag_mntpoint, {
12635
16
      "mount point", "nfs.fh.file.flag.mntpoint", FT_BOOLEAN, 16,
12636
16
      TFS(&tfs_set_notset), 0x0001, "file flag: mountpoint", HFILL }},
12637
16
    { &hf_nfs_fh_file_flag_snapdir, {
12638
16
      "snapdir", "nfs.fh.file.flag.snapdir", FT_BOOLEAN, 16,
12639
16
      TFS(&tfs_set_notset), 0x0002, "file flag: snapdir", HFILL }},
12640
16
    { &hf_nfs_fh_file_flag_snapdir_ent, {
12641
16
      "snapdir_ent", "nfs.fh.file.flag.snadir_ent", FT_BOOLEAN, 16,
12642
16
      TFS(&tfs_set_notset), 0x0004, "file flag: snapdir_ent", HFILL }},
12643
16
    { &hf_nfs_fh_file_flag_empty, {
12644
16
      "empty", "nfs.fh.file.flag.empty", FT_BOOLEAN, 16,
12645
16
      TFS(&tfs_set_notset), 0x0008, "file flag: empty", HFILL }},
12646
16
    { &hf_nfs_fh_file_flag_vbn_access, {
12647
16
      "vbn_access", "nfs.fh.file.flag.vbn_access", FT_BOOLEAN, 16,
12648
16
      TFS(&tfs_set_notset), 0x0010, "file flag: vbn_access", HFILL }},
12649
16
    { &hf_nfs_fh_file_flag_multivolume, {
12650
16
      "multivolume", "nfs.fh.file.flag.multivolume", FT_BOOLEAN, 16,
12651
16
      TFS(&tfs_set_notset), 0x0020, "file flag: multivolume", HFILL }},
12652
16
    { &hf_nfs_fh_file_flag_metadata, {
12653
16
      "metadata", "nfs.fh.file.flag.metadata", FT_BOOLEAN, 16,
12654
16
      TFS(&tfs_set_notset), 0x0040, "file flag: metadata", HFILL }},
12655
16
    { &hf_nfs_fh_file_flag_orphan, {
12656
16
      "orphan", "nfs.fh.file.flag.orphan", FT_BOOLEAN, 16,
12657
16
      TFS(&tfs_set_notset), 0x0080, "file flag: orphan", HFILL }},
12658
16
    { &hf_nfs_fh_file_flag_foster, {
12659
16
      "foster", "nfs.fh.file.flag.foster", FT_BOOLEAN, 16,
12660
16
      TFS(&tfs_set_notset), 0x0100, "file flag: foster", HFILL }},
12661
16
    { &hf_nfs_fh_file_flag_named_attr, {
12662
16
      "named_attr", "nfs.fh.file.flag.named_attr", FT_BOOLEAN, 16,
12663
16
      TFS(&tfs_set_notset), 0x0200, "file flag: named_attr", HFILL }},
12664
16
    { &hf_nfs_fh_file_flag_exp_snapdir, {
12665
16
      "exp_snapdir", "nfs.fh.file.flag.exp_snapdir", FT_BOOLEAN, 16,
12666
16
      TFS(&tfs_set_notset), 0x0400, "file flag: exp_snapdir", HFILL }},
12667
16
    { &hf_nfs_fh_file_flag_vfiler, {
12668
16
      "vfiler", "nfs.fh.file.flag.vfiler", FT_BOOLEAN, 16,
12669
16
      TFS(&tfs_set_notset), 0x0800, "file flag: vfiler", HFILL }},
12670
16
    { &hf_nfs_fh_file_flag_aggr, {
12671
16
      "aggr", "nfs.fh.file.flag.aggr", FT_BOOLEAN, 16,
12672
16
      TFS(&tfs_set_notset), 0x1000, "file flag: aggr", HFILL }},
12673
16
    { &hf_nfs_fh_file_flag_striped, {
12674
16
      "striped", "nfs.fh.file.flag.striped", FT_BOOLEAN, 16,
12675
16
      TFS(&tfs_set_notset), 0x2000, "file flag: striped", HFILL }},
12676
16
    { &hf_nfs_fh_file_flag_private, {
12677
16
      "private", "nfs.fh.file.flag.private", FT_BOOLEAN, 16,
12678
16
      TFS(&tfs_set_notset), 0x4000, "file flag: private", HFILL }},
12679
16
    { &hf_nfs_fh_file_flag_next_gen, {
12680
16
      "next_gen", "nfs.fh.file.flag.next_gen", FT_BOOLEAN, 16,
12681
16
      TFS(&tfs_set_notset), 0x8000, "file flag: next_gen", HFILL }},
12682
16
    { &hf_nfs_fh_fsid_major16_mask, {
12683
16
      "major", "nfs.fh.fsid.major", FT_UINT16, BASE_DEC,
12684
16
      NULL, 0xFF00, "major file system ID", HFILL }},
12685
16
    { &hf_nfs_fh_fsid_minor16_mask, {
12686
16
      "minor", "nfs.fh.fsid.minor", FT_UINT16, BASE_DEC,
12687
16
      NULL, 0x00FF, "minor file system ID", HFILL }},
12688
16
    { &hf_nfs_fh_fsid_major16, {
12689
16
      "major", "nfs.fh.fsid.major", FT_UINT16, BASE_DEC,
12690
16
      NULL, 0x0, "major file system ID", HFILL }},
12691
16
    { &hf_nfs_fh_fsid_minor16, {
12692
16
      "minor", "nfs.fh.fsid.minor", FT_UINT16, BASE_DEC,
12693
16
      NULL, 0x0, "minor file system ID", HFILL }},
12694
16
    { &hf_nfs_fh_fsid_major32, {
12695
16
      "major", "nfs.fh.fsid.major", FT_UINT32, BASE_DEC,
12696
16
      NULL, 0xfffc0000, "major file system ID", HFILL }},
12697
16
    { &hf_nfs_fh_fsid_minor32, {
12698
16
      "minor", "nfs.fh.fsid.minor", FT_UINT32, BASE_DEC,
12699
16
      NULL, 0x0003ffff, "minor file system ID", HFILL }},
12700
16
    { &hf_nfs_fh_fsid_inode, {
12701
16
      "inode", "nfs.fh.fsid.inode", FT_UINT32, BASE_DEC,
12702
16
      NULL, 0, "file system inode", HFILL }},
12703
16
    { &hf_nfs_fh_gfid, {
12704
16
      "gfid", "nfs.fh.gfid", FT_GUID, BASE_NONE,
12705
16
      NULL, 0, "Gluster/NFS GFID", HFILL }},
12706
16
    { &hf_nfs_fh_xfsid_major, {
12707
16
      "exported major", "nfs.fh.xfsid.major", FT_UINT16, BASE_DEC,
12708
16
      NULL, 0xFF00, "exported major file system ID", HFILL }},
12709
16
    { &hf_nfs_fh_xfsid_minor, {
12710
16
      "exported minor", "nfs.fh.xfsid.minor", FT_UINT16, BASE_DEC,
12711
16
      NULL, 0x00FF, "exported minor file system ID", HFILL }},
12712
16
    { &hf_nfs_fh_fstype, {
12713
16
      "file system type", "nfs.fh.fstype", FT_UINT32, BASE_DEC,
12714
16
      NULL, 0, NULL, HFILL }},
12715
16
    { &hf_nfs_fh_fn, {
12716
16
      "file number", "nfs.fh.fn", FT_UINT32, BASE_DEC,
12717
16
      NULL, 0, NULL, HFILL }},
12718
16
    { &hf_nfs_fh_fn_len, {
12719
16
      "length", "nfs.fh.fn.len", FT_UINT32, BASE_DEC,
12720
16
      NULL, 0, "file number length", HFILL }},
12721
16
    { &hf_nfs_fh_fn_inode, {
12722
16
      "inode", "nfs.fh.fn.inode", FT_UINT32, BASE_DEC,
12723
16
      NULL, 0, "file number inode", HFILL }},
12724
16
    { &hf_nfs_fh_fn_generation, {
12725
16
      "generation", "nfs.fh.fn.generation", FT_UINT32, BASE_DEC,
12726
16
      NULL, 0, "file number generation", HFILL }},
12727
16
    { &hf_nfs_fh_xfn, {
12728
16
      "exported file number", "nfs.fh.xfn", FT_UINT32, BASE_DEC,
12729
16
      NULL, 0, NULL, HFILL }},
12730
16
    { &hf_nfs_fh_xfn_len, {
12731
16
      "length", "nfs.fh.xfn.len", FT_UINT32, BASE_DEC,
12732
16
      NULL, 0, "exported file number length", HFILL }},
12733
16
    { &hf_nfs_fh_xfn_inode, {
12734
16
      "exported inode", "nfs.fh.xfn.inode", FT_UINT32, BASE_DEC,
12735
16
      NULL, 0, "exported file number inode", HFILL }},
12736
16
    { &hf_nfs_fh_xfn_generation, {
12737
16
      "generation", "nfs.fh.xfn.generation", FT_UINT32, BASE_DEC,
12738
16
      NULL, 0, "exported file number generation", HFILL }},
12739
16
    { &hf_nfs_fh_dentry, {
12740
16
      "dentry", "nfs.fh.dentry", FT_UINT32, BASE_HEX,
12741
16
      NULL, 0, "dentry (cookie)", HFILL }},
12742
#if 0
12743
    { &hf_nfs_fh_dev, {
12744
      "device", "nfs.fh.dev", FT_UINT32, BASE_DEC,
12745
      NULL, 0, NULL, HFILL }},
12746
#endif
12747
#if 0
12748
    { &hf_nfs_fh_xdev, {
12749
      "exported device", "nfs.fh.xdev", FT_UINT32, BASE_DEC,
12750
      NULL, 0, NULL, HFILL }},
12751
#endif
12752
16
    { &hf_nfs_fh_dirinode, {
12753
16
      "directory inode", "nfs.fh.dirinode", FT_UINT32, BASE_DEC,
12754
16
      NULL, 0, NULL, HFILL }},
12755
16
    { &hf_nfs_fh_pinode, {
12756
16
      "pseudo inode", "nfs.fh.pinode", FT_UINT32, BASE_HEX,
12757
16
      NULL, 0, NULL, HFILL }},
12758
16
    { &hf_nfs_fh_hp_len, {
12759
16
      "length", "nfs.fh.hp.len", FT_UINT32, BASE_DEC,
12760
16
      NULL, 0, "hash path length", HFILL }},
12761
16
    { &hf_nfs_fh_hp_key, {
12762
16
      "key", "nfs.fh.hp.key", FT_BYTES, BASE_NONE,
12763
16
      NULL, 0, NULL, HFILL }},
12764
16
    { &hf_nfs_fh_version, {
12765
16
      "version", "nfs.fh.version", FT_UINT8, BASE_DEC,
12766
16
      NULL, 0, "file handle layout version", HFILL }},
12767
16
    { &hf_nfs_fh_auth_type, {
12768
16
      "auth_type", "nfs.fh.auth_type", FT_UINT8, BASE_DEC,
12769
16
      VALS(auth_type_names), 0, "authentication type", HFILL }},
12770
16
    { &hf_nfs_fh_fsid_type, {
12771
16
      "fsid_type", "nfs.fh.fsid_type", FT_UINT8, BASE_DEC,
12772
16
      VALS(fsid_type_names), 0, "file system ID type", HFILL }},
12773
16
    { &hf_nfs_fh_fileid_type, {
12774
16
      "fileid_type", "nfs.fh.fileid_type", FT_UINT8, BASE_DEC,
12775
16
      VALS(fileid_type_names), 0, "file ID type", HFILL }},
12776
16
    { &hf_nfs_fh_obj_id, {
12777
16
      "Object type", "nfs.fh.obj.id", FT_UINT32, BASE_DEC,
12778
16
      VALS(nfs_fh_obj_id), 0, "Object ID", HFILL }},
12779
16
    { &hf_nfs_fh_ro_node, {
12780
16
      "RO_node", "nfs.fh.ro.node", FT_BOOLEAN, BASE_NONE,
12781
16
      TFS(&nfs4_ro_boolean), 0, "Read Only Node", HFILL }},
12782
16
    { &hf_nfs_fh_obj, {
12783
16
      "Object info", "nfs.fh.obj.info", FT_BYTES, BASE_NONE,
12784
16
      NULL, 0, "File/Dir/Object Info", HFILL }},
12785
16
    { &hf_nfs_fh_obj_fsid, {
12786
16
      "obj_fsid", "nfs.fh.obj.fsid", FT_UINT32, BASE_DEC,
12787
16
      NULL, 0, "File system ID of the object", HFILL }},
12788
16
    { &hf_nfs_fh_obj_kindid, {
12789
16
      "obj_kindid", "nfs.fh.obj.kindid", FT_UINT16, BASE_DEC,
12790
16
      NULL, 0, "KindID of the object", HFILL }},
12791
16
    { &hf_nfs_fh_obj_treeid, {
12792
16
      "obj_treeid", "nfs.fh.obj.treeid", FT_UINT16, BASE_DEC,
12793
16
      NULL, 0, "TreeID of the object", HFILL }},
12794
16
    { &hf_nfs_fh_obj_inode, {
12795
16
      "obj_inode", "nfs.fh.obj.inode", FT_UINT32, BASE_DEC,
12796
16
      NULL, 0, "Inode of the object", HFILL }},
12797
16
    { &hf_nfs_fh_obj_gen, {
12798
16
      "obj_gen", "nfs.fh.obj.gen", FT_UINT32, BASE_DEC,
12799
16
      NULL, 0, "Generation ID of the object", HFILL }},
12800
16
    { &hf_nfs_fh_ex, {
12801
16
      "Export info", "nfs.fh.ex.info", FT_BYTES, BASE_NONE,
12802
16
      NULL, 0, "Export Info (16 bytes)", HFILL }},
12803
16
    { &hf_nfs_fh_ex_fsid, {
12804
16
      "ex_fsid", "nfs.fh.ex.fsid", FT_UINT32, BASE_DEC,
12805
16
      NULL, 0, "File system ID of the object", HFILL }},
12806
16
    { &hf_nfs_fh_ex_kindid, {
12807
16
      "ex_kindid", "nfs.fh.ex.kindid", FT_UINT16, BASE_DEC,
12808
16
      NULL, 0, "KindID of the object", HFILL }},
12809
16
    { &hf_nfs_fh_ex_treeid, {
12810
16
      "ex_treeid", "nfs.fh.ex.treeid", FT_UINT16, BASE_DEC,
12811
16
      NULL, 0, "TreeID of the object", HFILL }},
12812
16
    { &hf_nfs_fh_ex_inode, {
12813
16
      "ex_inode", "nfs.fh.ex.inode", FT_UINT32, BASE_DEC,
12814
16
      NULL, 0, "Inode of the object", HFILL }},
12815
16
    { &hf_nfs_fh_ex_gen, {
12816
16
      "ex_gen", "nfs.fh.ex.gen", FT_UINT32, BASE_DEC,
12817
16
      NULL, 0, "Generation ID of the object", HFILL }},
12818
16
    { &hf_nfs_fh_flag, {
12819
16
      "flag", "nfs.fh.flag", FT_UINT32, BASE_HEX,
12820
16
      NULL, 0, "file handle flag", HFILL }},
12821
16
    { &hf_nfs_fh_endianness, {
12822
16
      "endianness", "nfs.fh.endianness", FT_BOOLEAN, BASE_NONE,
12823
16
      TFS(&tfs_endianness), 0x0, "server native endianness", HFILL }},
12824
16
    { &hf_nfs_fh_dc_opaque, {
12825
16
      "fh opaque data", "nfs.fh.dc.opaque", FT_BYTES, BASE_NONE,
12826
16
      NULL, 0, NULL, HFILL }},
12827
16
    { &hf_nfs_fh_dc_exportid, {
12828
16
      "export_id", "nfs.fh.dc.exportid", FT_UINT32, BASE_HEX,
12829
16
      NULL, 0, NULL, HFILL }},
12830
16
    { &hf_nfs_fh_dc_handle_type, {
12831
16
      "fh type", "nfs.fh.dc.type", FT_UINT8, BASE_DEC,
12832
16
      VALS(dcache_handle_types), 0, NULL, HFILL }},
12833
16
    { &hf_nfs4_fh_pd_share, {
12834
16
      "shareid", "nfs.fh.pd.shareid", FT_UINT32, BASE_DEC,
12835
16
      NULL, 0, NULL, HFILL }},
12836
16
    { &hf_nfs4_fh_pd_flags, {
12837
16
      "flags", "nfs.fh.pd.flags", FT_UINT32, BASE_HEX,
12838
16
      NULL, 0, NULL, HFILL }},
12839
16
    { &hf_nfs4_fh_pd_flags_reserved, {
12840
16
      "reserved", "nfs.fh.pd.flags.reserved", FT_UINT32, BASE_HEX,
12841
16
      NULL, PD_RESERVED_MASK, NULL, HFILL }},
12842
16
    { &hf_nfs4_fh_pd_flags_version, {
12843
16
      "version", "nfs.fh.pd.flags.version", FT_UINT32, BASE_DEC,
12844
16
      NULL, PD_VERSION_MASK, NULL, HFILL }},
12845
16
    { &hf_nfs4_fh_pd_sites, {
12846
16
      "sites", "nfs.fh.pd.sites", FT_UINT64, BASE_HEX,
12847
16
      NULL, 0, NULL, HFILL }},
12848
16
    { &hf_nfs4_fh_pd_sites_inum, {
12849
16
      "inum", "nfs.fh.pd.sites.inum", FT_UINT64, BASE_HEX,
12850
16
      NULL, PD_INUM_MASK, NULL, HFILL }},
12851
16
    { &hf_nfs4_fh_pd_sites_siteid, {
12852
16
      "siteid", "nfs.fh.pd.sites.siteid", FT_UINT16, BASE_DEC,
12853
16
      NULL, PD_SITEID_MASK, NULL, HFILL }},
12854
16
    { &hf_nfs4_fh_pd_spaces, {
12855
16
      "spaces", "nfs.fh.pd.spaces", FT_UINT64, BASE_HEX,
12856
16
      NULL, 0, NULL, HFILL }},
12857
16
    { &hf_nfs4_fh_pd_spaces_snapid, {
12858
16
      "snapid", "nfs.fh.pd.spaces.snapid", FT_UINT16, BASE_HEX,
12859
16
      NULL, PD_SNAPID_MASK, NULL, HFILL }},
12860
16
    { &hf_nfs4_fh_pd_spaces_container, {
12861
16
      "container", "nfs.fh.pd.spaces.container", FT_UINT64, BASE_DEC,
12862
16
      NULL, PD_CONTAINER_MASK, NULL, HFILL }},
12863
16
    { &hf_nfs4_fh_pd_container, {
12864
16
      "container", "nfs.fh.pd.container", FT_UINT64, BASE_DEC,
12865
16
      NULL, 0, NULL, HFILL }},
12866
16
    { &hf_nfs4_fh_pd_inum, {
12867
16
      "inum", "nfs.fh.pd.inum", FT_UINT64, BASE_DEC,
12868
16
      NULL, 0, NULL, HFILL }},
12869
16
    { &hf_nfs2_status, {
12870
16
      "Status", "nfs.status2", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12871
16
      &names_nfs2_stat_ext, 0, "Reply status", HFILL }},
12872
16
    { &hf_nfs_full_name, {
12873
16
      "Full Name", "nfs.full_name", FT_STRING, BASE_NONE,
12874
16
      NULL, 0, NULL, HFILL }},
12875
16
    { &hf_nfs_name, {
12876
16
      "Name", "nfs.name", FT_STRING, BASE_NONE,
12877
16
      NULL, 0, NULL, HFILL }},
12878
16
    { &hf_nfs2_readlink_data, {
12879
16
      "Data", "nfs.readlink.data", FT_STRING, BASE_NONE,
12880
16
      NULL, 0, "Symbolic Link Data", HFILL }},
12881
16
    { &hf_nfs2_read_offset, {
12882
16
      "Offset", "nfs.read.offset", FT_UINT32, BASE_DEC,
12883
16
      NULL, 0, "Read Offset", HFILL }},
12884
16
    { &hf_nfs2_read_count, {
12885
16
      "Count", "nfs.read.count", FT_UINT32, BASE_DEC,
12886
16
      NULL, 0, "Read Count", HFILL }},
12887
16
    { &hf_nfs2_read_totalcount, {
12888
16
      "Total Count", "nfs.read.totalcount", FT_UINT32, BASE_DEC,
12889
16
      NULL, 0, "Total Count (obsolete)", HFILL }},
12890
16
    { &hf_nfs_data, {
12891
16
      "Data", "nfs.data", FT_BYTES, BASE_NONE,
12892
16
      NULL, 0, NULL, HFILL }},
12893
16
    { &hf_nfs4_read_data_length, {
12894
16
      "Read length", "nfs.read.data_length", FT_UINT32, BASE_DEC,
12895
16
      NULL, 0, "Length of read response", HFILL }},
12896
16
    { &hf_nfs4_write_data_length, {
12897
16
      "Write length", "nfs.write.data_length", FT_UINT32, BASE_DEC,
12898
16
      NULL, 0, "Length of write request", HFILL }},
12899
16
    { &hf_nfs2_write_beginoffset, {
12900
16
      "Begin Offset", "nfs.write.beginoffset", FT_UINT32, BASE_DEC,
12901
16
      NULL, 0, "Begin offset (obsolete)", HFILL }},
12902
16
    { &hf_nfs2_write_offset, {
12903
16
      "Offset", "nfs.write.offset", FT_UINT32, BASE_DEC,
12904
16
      NULL, 0, NULL, HFILL }},
12905
16
    { &hf_nfs2_write_totalcount, {
12906
16
      "Total Count", "nfs.write.totalcount", FT_UINT32, BASE_DEC,
12907
16
      NULL, 0, "Total Count (obsolete)", HFILL }},
12908
16
    { &hf_nfs_symlink_to, {
12909
16
      "To", "nfs.symlink.to", FT_STRING, BASE_NONE,
12910
16
      NULL, 0, "Symbolic link destination name", HFILL }},
12911
16
    { &hf_nfs2_readdir_cookie, {
12912
16
      "Cookie", "nfs.readdir.cookie", FT_UINT32, BASE_DEC,
12913
16
      NULL, 0, "Directory Cookie", HFILL }},
12914
16
    { &hf_nfs2_readdir_count, {
12915
16
      "Count", "nfs.readdir.count", FT_UINT32, BASE_DEC,
12916
16
      NULL, 0, "Directory Count", HFILL }},
12917
12918
16
    { &hf_nfs_readdir_entry, {
12919
16
      "Entry", "nfs.readdir.entry", FT_NONE, BASE_NONE,
12920
16
      NULL, 0, "Directory Entry", HFILL }},
12921
12922
16
    { &hf_nfs2_readdir_entry_fileid, {
12923
16
      "File ID", "nfs.readdir.entry.fileid", FT_UINT32, BASE_DEC,
12924
16
      NULL, 0, NULL, HFILL }},
12925
12926
16
    { &hf_nfs2_readdir_entry_name, {
12927
16
      "Name", "nfs.readdir.entry.name", FT_STRING, BASE_NONE,
12928
16
      NULL, 0, NULL, HFILL }},
12929
12930
16
    { &hf_nfs2_readdir_entry_cookie, {
12931
16
      "Cookie", "nfs.readdir.entry.cookie", FT_UINT32, BASE_DEC,
12932
16
      NULL, 0, "Directory Cookie", HFILL }},
12933
12934
16
    { &hf_nfs3_readdir_entry_fileid, {
12935
16
      "File ID", "nfs.readdir.entry3.fileid", FT_UINT64, BASE_DEC,
12936
16
      NULL, 0, NULL, HFILL }},
12937
12938
16
    { &hf_nfs3_readdir_entry_name, {
12939
16
      "Name", "nfs.readdir.entry3.name", FT_STRING, BASE_NONE,
12940
16
      NULL, 0, NULL, HFILL }},
12941
12942
16
    { &hf_nfs3_readdir_entry_cookie, {
12943
16
      "Cookie", "nfs.readdir.entry3.cookie", FT_UINT64, BASE_DEC,
12944
16
      NULL, 0, "Directory Cookie", HFILL }},
12945
12946
16
    { &hf_nfs3_readdirplus_entry_fileid, {
12947
16
      "File ID", "nfs.readdirplus.entry.fileid", FT_UINT64, BASE_DEC,
12948
16
      NULL, 0, NULL, HFILL }},
12949
12950
16
    { &hf_nfs3_readdirplus_entry_name, {
12951
16
      "Name", "nfs.readdirplus.entry.name", FT_STRING, BASE_NONE,
12952
16
      NULL, 0, NULL, HFILL }},
12953
12954
16
    { &hf_nfs3_readdirplus_entry_cookie, {
12955
16
      "Cookie", "nfs.readdirplus.entry.cookie", FT_UINT64, BASE_DEC,
12956
16
      NULL, 0, "Directory Cookie", HFILL }},
12957
12958
16
    { &hf_nfs_readdir_eof, {
12959
16
      "EOF", "nfs.readdir.eof", FT_UINT32, BASE_DEC,
12960
16
      NULL, 0, NULL, HFILL }},
12961
12962
16
    { &hf_nfs2_statfs_tsize, {
12963
16
      "Transfer Size", "nfs.statfs.tsize", FT_UINT32, BASE_DEC,
12964
16
      NULL, 0, NULL, HFILL }},
12965
16
    { &hf_nfs2_statfs_bsize, {
12966
16
      "Block Size", "nfs.statfs.bsize", FT_UINT32, BASE_DEC,
12967
16
      NULL, 0, NULL, HFILL }},
12968
16
    { &hf_nfs2_statfs_blocks, {
12969
16
      "Total Blocks", "nfs.statfs.blocks", FT_UINT32, BASE_DEC,
12970
16
      NULL, 0, NULL, HFILL }},
12971
16
    { &hf_nfs2_statfs_bfree, {
12972
16
      "Free Blocks", "nfs.statfs.bfree", FT_UINT32, BASE_DEC,
12973
16
      NULL, 0, NULL, HFILL }},
12974
16
    { &hf_nfs2_statfs_bavail, {
12975
16
      "Available Blocks", "nfs.statfs.bavail", FT_UINT32, BASE_DEC,
12976
16
      NULL, 0, NULL, HFILL }},
12977
16
    { &hf_nfs3_ftype, {
12978
16
      "Type", "nfs.type", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12979
16
      &names_nfs_ftype3_ext, 0, "File Type", HFILL }},
12980
16
    { &hf_nfs3_status, {
12981
16
      "Status", "nfs.status3", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12982
16
      &names_nfs3_status_ext, 0, "Reply status", HFILL }},
12983
16
    { &hf_nfs3_read_eof, {
12984
16
      "EOF", "nfs.read.eof", FT_BOOLEAN, BASE_NONE,
12985
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12986
16
    { &hf_nfs3_write_stable, {
12987
16
      "Stable", "nfs.write.stable", FT_UINT32, BASE_DEC,
12988
16
      VALS(names_stable_how), 0, NULL, HFILL }},
12989
16
    { &hf_nfs3_write_committed, {
12990
16
      "Committed", "nfs.write.committed", FT_UINT32, BASE_DEC,
12991
16
      VALS(names_stable_how), 0, NULL, HFILL }},
12992
16
    { &hf_nfs3_createmode, {
12993
16
      "Create Mode", "nfs.createmode", FT_UINT32, BASE_DEC,
12994
16
      VALS(names_createmode3), 0, NULL, HFILL }},
12995
16
    { &hf_nfs3_fsstat_invarsec, {
12996
16
      "invarsec", "nfs.fsstat.invarsec", FT_UINT32, BASE_DEC,
12997
16
      NULL, 0, "probable number of seconds of file system invariance", HFILL }},
12998
16
    { &hf_nfs3_fsinfo_rtmax, {
12999
16
      "rtmax", "nfs.fsinfo.rtmax", FT_UINT32, BASE_DEC,
13000
16
      NULL, 0, "maximum READ request", HFILL }},
13001
16
    { &hf_nfs3_fsinfo_rtpref, {
13002
16
      "rtpref", "nfs.fsinfo.rtpref", FT_UINT32, BASE_DEC,
13003
16
      NULL, 0, "Preferred READ request size", HFILL }},
13004
16
    { &hf_nfs3_fsinfo_rtmult, {
13005
16
      "rtmult", "nfs.fsinfo.rtmult", FT_UINT32, BASE_DEC,
13006
16
      NULL, 0, "Suggested READ multiple", HFILL }},
13007
16
    { &hf_nfs3_fsinfo_wtmax, {
13008
16
      "wtmax", "nfs.fsinfo.wtmax", FT_UINT32, BASE_DEC,
13009
16
      NULL, 0, "Maximum WRITE request size", HFILL }},
13010
16
    { &hf_nfs3_fsinfo_wtpref, {
13011
16
      "wtpref", "nfs.fsinfo.wtpref", FT_UINT32, BASE_DEC,
13012
16
      NULL, 0, "Preferred WRITE request size", HFILL }},
13013
16
    { &hf_nfs3_fsinfo_wtmult, {
13014
16
      "wtmult", "nfs.fsinfo.wtmult", FT_UINT32, BASE_DEC,
13015
16
      NULL, 0, "Suggested WRITE multiple", HFILL }},
13016
16
    { &hf_nfs3_fsinfo_dtpref, {
13017
16
      "dtpref", "nfs.fsinfo.dtpref", FT_UINT32, BASE_DEC,
13018
16
      NULL, 0, "Preferred READDIR request", HFILL }},
13019
16
    { &hf_nfs3_fsinfo_maxfilesize, {
13020
16
      "maxfilesize", "nfs.fsinfo.maxfilesize", FT_UINT64, BASE_DEC,
13021
16
      NULL, 0, "Maximum file size", HFILL }},
13022
16
    { &hf_nfs3_fsinfo_properties, {
13023
16
      "Properties", "nfs.fsinfo.properties", FT_UINT32, BASE_HEX,
13024
16
      NULL, 0, "File System Properties", HFILL }},
13025
16
    { &hf_nfs3_fsinfo_properties_setattr, {
13026
16
      "SETATTR can set time on server", "nfs.fsinfo.properties.setattr", FT_BOOLEAN, 32,
13027
16
      TFS(&tfs_yes_no), FSF3_CANSETTIME, NULL, HFILL }},
13028
16
    { &hf_nfs3_fsinfo_properties_pathconf, {
13029
16
      "PATHCONF", "nfs.fsinfo.properties.pathconf", FT_BOOLEAN, 32,
13030
16
      TFS(&tfs_nfs_pathconf), FSF3_HOMOGENEOUS, NULL, HFILL }},
13031
16
    { &hf_nfs3_fsinfo_properties_symlinks, {
13032
16
      "File System supports symbolic links", "nfs.fsinfo.properties.symlinks", FT_BOOLEAN, 32,
13033
16
      TFS(&tfs_yes_no), FSF3_SYMLINK, NULL, HFILL }},
13034
16
    { &hf_nfs3_fsinfo_properties_hardlinks, {
13035
16
      "File System supports hard links", "nfs.fsinfo.properties.hardlinks", FT_BOOLEAN, 32,
13036
16
      TFS(&tfs_yes_no), FSF3_LINK, NULL, HFILL }},
13037
16
    { &hf_nfs3_pathconf_linkmax, {
13038
16
      "linkmax", "nfs.pathconf.linkmax", FT_UINT32, BASE_DEC,
13039
16
      NULL, 0, "Maximum number of hard links", HFILL }},
13040
16
    { &hf_nfs3_pathconf_name_max, {
13041
16
      "name_max", "nfs.pathconf.name_max", FT_UINT32, BASE_DEC,
13042
16
      NULL, 0, "Maximum file name length", HFILL }},
13043
16
    { &hf_nfs3_pathconf_no_trunc, {
13044
16
      "no_trunc", "nfs.pathconf.no_trunc", FT_BOOLEAN, BASE_NONE,
13045
16
      TFS(&tfs_yes_no), 0x0, "No long file name truncation", HFILL }},
13046
16
    { &hf_nfs3_pathconf_chown_restricted, {
13047
16
      "chown_restricted", "nfs.pathconf.chown_restricted", FT_BOOLEAN, BASE_NONE,
13048
16
      TFS(&tfs_yes_no), 0x0, "chown is restricted to root", HFILL }},
13049
16
    { &hf_nfs3_pathconf_case_insensitive, {
13050
16
      "case_insensitive", "nfs.pathconf.case_insensitive", FT_BOOLEAN, BASE_NONE,
13051
16
      TFS(&tfs_yes_no), 0x0, "file names are treated case insensitive", HFILL }},
13052
16
    { &hf_nfs3_pathconf_case_preserving, {
13053
16
      "case_preserving", "nfs.pathconf.case_preserving", FT_BOOLEAN, BASE_NONE,
13054
16
      TFS(&tfs_yes_no), 0x0, "file name cases are preserved", HFILL }},
13055
13056
#if 0
13057
    { &hf_nfs2_fattr_type, {
13058
      "type", "nfs.fattr.type", FT_UINT32, BASE_DEC,
13059
      NULL, 0, NULL, HFILL }},
13060
#endif
13061
13062
16
    { &hf_nfs2_fattr_nlink, {
13063
16
      "nlink", "nfs.fattr.nlink", FT_UINT32, BASE_DEC,
13064
16
      NULL, 0, NULL, HFILL }},
13065
13066
16
    { &hf_nfs2_fattr_uid, {
13067
16
      "uid", "nfs.fattr.uid", FT_UINT32, BASE_DEC,
13068
16
      NULL, 0, NULL, HFILL }},
13069
13070
16
    { &hf_nfs2_fattr_gid, {
13071
16
      "gid", "nfs.fattr.gid", FT_UINT32, BASE_DEC,
13072
16
      NULL, 0, NULL, HFILL }},
13073
13074
16
    { &hf_nfs2_fattr_size, {
13075
16
      "size", "nfs.fattr.size", FT_UINT32, BASE_DEC,
13076
16
      NULL, 0, NULL, HFILL }},
13077
13078
16
    { &hf_nfs2_fattr_blocksize, {
13079
16
      "blocksize", "nfs.fattr.blocksize", FT_UINT32, BASE_DEC,
13080
16
      NULL, 0, NULL, HFILL }},
13081
13082
16
    { &hf_nfs2_fattr_rdev, {
13083
16
      "rdev", "nfs.fattr.rdev", FT_UINT32, BASE_DEC,
13084
16
      NULL, 0, NULL, HFILL }},
13085
13086
16
    { &hf_nfs2_fattr_blocks, {
13087
16
      "blocks", "nfs.fattr.blocks", FT_UINT32, BASE_DEC,
13088
16
      NULL, 0, NULL, HFILL }},
13089
13090
16
    { &hf_nfs2_fattr_fsid, {
13091
16
      "fsid", "nfs.fattr.fsid", FT_UINT32, BASE_HEX,
13092
16
      NULL, 0, NULL, HFILL }},
13093
13094
16
    { &hf_nfs2_fattr_fileid, {
13095
16
      "fileid", "nfs.fattr.fileid", FT_UINT32, BASE_DEC,
13096
16
      NULL, 0, NULL, HFILL }},
13097
13098
16
    { &hf_nfs3_fattr_type, {
13099
16
      "Type", "nfs.fattr3.type", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
13100
16
      &names_nfs_ftype3_ext, 0, NULL, HFILL }},
13101
13102
16
    { &hf_nfs3_fattr_nlink, {
13103
16
      "nlink", "nfs.fattr3.nlink", FT_UINT32, BASE_DEC,
13104
16
      NULL, 0, NULL, HFILL }},
13105
13106
16
    { &hf_nfs3_fattr_uid, {
13107
16
      "uid", "nfs.fattr3.uid", FT_UINT32, BASE_DEC,
13108
16
      NULL, 0, NULL, HFILL }},
13109
13110
16
    { &hf_nfs3_fattr_gid, {
13111
16
      "gid", "nfs.fattr3.gid", FT_UINT32, BASE_DEC,
13112
16
      NULL, 0, NULL, HFILL }},
13113
13114
16
    { &hf_nfs3_fattr_size, {
13115
16
      "size", "nfs.fattr3.size", FT_UINT64, BASE_DEC,
13116
16
      NULL, 0, NULL, HFILL }},
13117
13118
16
    { &hf_nfs3_fattr_used, {
13119
16
      "used", "nfs.fattr3.used", FT_UINT64, BASE_DEC,
13120
16
      NULL, 0, NULL, HFILL }},
13121
13122
#if 0
13123
    { &hf_nfs3_fattr_rdev, {
13124
      "rdev", "nfs.fattr3.rdev", FT_UINT32, BASE_DEC,
13125
      NULL, 0, NULL, HFILL }},
13126
#endif
13127
13128
16
    { &hf_nfs3_fattr_fsid, {
13129
16
      "fsid", "nfs.fattr3.fsid", FT_UINT64, BASE_HEX_DEC,
13130
16
      NULL, 0, NULL, HFILL }},
13131
13132
16
    { &hf_nfs3_fattr_fileid, {
13133
16
      "fileid", "nfs.fattr3.fileid", FT_UINT64, BASE_DEC,
13134
16
      NULL, 0, NULL, HFILL }},
13135
13136
16
    { &hf_nfs3_wcc_attr_size, {
13137
16
      "size", "nfs.wcc_attr.size", FT_UINT64, BASE_DEC,
13138
16
      NULL, 0, NULL, HFILL }},
13139
13140
16
    { &hf_nfs3_set_size, {
13141
16
      "size", "nfs.set_size", FT_UINT64, BASE_DEC,
13142
16
      NULL, 0, NULL, HFILL }},
13143
13144
16
    { &hf_nfs3_uid, {
13145
16
      "uid", "nfs.uid3", FT_UINT32, BASE_DEC,
13146
16
      NULL, 0, NULL, HFILL }},
13147
13148
16
    { &hf_nfs3_gid, {
13149
16
      "gid", "nfs.gid3", FT_UINT32, BASE_DEC,
13150
16
      NULL, 0, NULL, HFILL }},
13151
13152
16
    { &hf_nfs3_cookie, {
13153
16
      "cookie", "nfs.cookie3", FT_UINT64, BASE_DEC,
13154
16
      NULL, 0, NULL, HFILL }},
13155
13156
16
    { &hf_nfs3_offset, {
13157
16
      "offset", "nfs.offset3", FT_UINT64, BASE_DEC,
13158
16
      NULL, 0, NULL, HFILL }},
13159
13160
16
    { &hf_nfs3_count, {
13161
16
      "count", "nfs.count3", FT_UINT32, BASE_DEC,
13162
16
      NULL, 0, NULL, HFILL }},
13163
13164
16
    { &hf_nfs3_count_maxcount, {
13165
16
      "maxcount", "nfs.count3_maxcount", FT_UINT32, BASE_DEC,
13166
16
      NULL, 0, NULL, HFILL }},
13167
13168
16
    { &hf_nfs3_count_dircount, {
13169
16
      "dircount", "nfs.count3_dircount", FT_UINT32, BASE_DEC,
13170
16
      NULL, 0, NULL, HFILL }},
13171
13172
16
    { &hf_nfs3_fsstat_resok_tbytes, {
13173
16
      "Total bytes", "nfs.fsstat3_resok.tbytes", FT_UINT64, BASE_DEC,
13174
16
      NULL, 0, NULL, HFILL }},
13175
13176
16
    { &hf_nfs3_fsstat_resok_fbytes, {
13177
16
      "Free bytes", "nfs.fsstat3_resok.fbytes", FT_UINT64, BASE_DEC,
13178
16
      NULL, 0, NULL, HFILL }},
13179
13180
16
    { &hf_nfs3_fsstat_resok_abytes, {
13181
16
      "Available free bytes", "nfs.fsstat3_resok.abytes", FT_UINT64, BASE_DEC,
13182
16
      NULL, 0, NULL, HFILL }},
13183
13184
16
    { &hf_nfs3_fsstat_resok_tfiles, {
13185
16
      "Total file slots", "nfs.fsstat3_resok.tfiles", FT_UINT64, BASE_DEC,
13186
16
      NULL, 0, NULL, HFILL }},
13187
13188
16
    { &hf_nfs3_fsstat_resok_ffiles, {
13189
16
      "Free file slots", "nfs.fsstat3_resok.ffiles", FT_UINT64, BASE_DEC,
13190
16
      NULL, 0, NULL, HFILL }},
13191
13192
16
    { &hf_nfs3_fsstat_resok_afiles, {
13193
16
      "Available free file slots", "nfs.fsstat3_resok.afiles", FT_UINT64, BASE_DEC,
13194
16
      NULL, 0, NULL, HFILL }},
13195
13196
    /* NFSv4 */
13197
13198
16
    { &hf_nfs4_status, {
13199
16
      "Status", "nfs.nfsstat4", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
13200
16
      &names_nfs4_status_ext, 0, "Reply status", HFILL }},
13201
13202
16
    { &hf_nfs4_op, {
13203
16
      "Opcode", "nfs.opcode", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
13204
16
      &names_nfs4_operation_ext, 0, NULL, HFILL }},
13205
13206
16
    { &hf_nfs4_op_mask, {
13207
16
      "op_mask", "nfs.op_mask", FT_UINT32, BASE_HEX,
13208
16
      NULL, 0, "Operation Mask", HFILL }},
13209
13210
16
    { &hf_nfs4_main_opcode, {
13211
16
      "Main Opcode", "nfs.main_opcode", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
13212
16
      &names_nfs4_operation_ext, 0, "Main Operation number", HFILL }},
13213
13214
16
    { &hf_nfs4_linktext, {
13215
16
      "Link Contents", "nfs.symlink.linktext", FT_STRING, BASE_NONE,
13216
16
      NULL, 0, "Symbolic link contents", HFILL }},
13217
13218
16
    { &hf_nfs4_dir_entry_name, {
13219
16
      "Name", "nfs.entry_name", FT_STRING, BASE_NONE,
13220
16
      NULL, 0, "Directory entry name", HFILL }},
13221
13222
16
    { &hf_nfs4_pathname_components, {
13223
16
      "pathname components", "nfs.pathname.component.count", FT_UINT32, BASE_DEC,
13224
16
      NULL, 0, "Number of Pathname component", HFILL }},
13225
13226
16
    { &hf_nfs4_component, {
13227
16
      "Name", "nfs.pathname.component", FT_STRING, BASE_NONE,
13228
16
      NULL, 0, "Pathname component", HFILL }},
13229
13230
16
    { &hf_nfs4_tag, {
13231
16
      "Tag", "nfs.tag", FT_STRING, BASE_NONE,
13232
16
      NULL, 0, NULL, HFILL }},
13233
13234
16
    { &hf_nfs4_ops_count, {
13235
16
      "Operations", "nfs.ops.count", FT_UINT32, BASE_DEC,
13236
16
      NULL, 0, "Number of Operations", HFILL }},
13237
13238
16
    { &hf_nfs4_clientid, {
13239
16
      "clientid", "nfs.clientid", FT_UINT64, BASE_HEX,
13240
16
      NULL, 0, "Client ID", HFILL }},
13241
13242
#if 0
13243
    { &hf_nfs4_ace, {
13244
      "ace", "nfs.ace", FT_STRING, BASE_NONE,
13245
      NULL, 0, "Access Control Entry", HFILL }},
13246
#endif
13247
13248
16
    { &hf_nfs4_recall, {
13249
16
      "Recall", "nfs.recall", FT_BOOLEAN, BASE_NONE,
13250
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13251
13252
16
    { &hf_nfs4_open_claim_type, {
13253
16
      "Claim Type", "nfs.open.claim_type", FT_UINT32, BASE_DEC,
13254
16
      VALS(names_claim_type4), 0, NULL, HFILL }},
13255
13256
16
    { &hf_nfs4_opentype, {
13257
16
      "Open Type", "nfs.open.opentype", FT_UINT32, BASE_DEC,
13258
16
      VALS(names_opentype4), 0, NULL, HFILL }},
13259
13260
16
    { &hf_nfs4_state_protect_how, {
13261
16
      "eia_state_protect", "nfs.exchange_id.state_protect", FT_UINT32, BASE_DEC,
13262
16
      VALS(names_state_protect_how4), 0, "State Protect How", HFILL }},
13263
13264
16
    { &hf_nfs4_limit_by, {
13265
16
      "Space Limit", "nfs.open.limit_by", FT_UINT32, BASE_DEC,
13266
16
      VALS(names_limit_by4), 0, "Limit By", HFILL }},
13267
13268
16
    { &hf_nfs4_open_delegation_type, {
13269
16
      "Delegation Type", "nfs.open.delegation_type", FT_UINT32, BASE_DEC,
13270
16
      VALS(names_open_delegation_type4), 0, NULL, HFILL }},
13271
13272
16
    { &hf_nfs4_why_no_delegation, {
13273
16
      "why no delegation", "nfs.open.why_no_delegation", FT_UINT32, BASE_DEC,
13274
16
      VALS(names_why_no_delegation4), 0, NULL, HFILL }},
13275
13276
16
    { &hf_nfs4_secinfo_style, {
13277
16
      "Secinfo Style", "nfs.secinfo.style", FT_UINT32, BASE_DEC,
13278
16
      VALS(names_secinfo_style4), 0, NULL, HFILL }},
13279
13280
16
    { &hf_nfs4_ftype, {
13281
16
      "ftype4", "nfs.nfs_ftype4", FT_UINT32, BASE_DEC,
13282
16
      VALS(names_ftype4), 0, NULL, HFILL }},
13283
13284
16
    { &hf_nfs4_change_info_atomic, {
13285
16
      "Atomic", "nfs.change_info.atomic", FT_BOOLEAN, BASE_NONE,
13286
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13287
13288
16
    { &hf_nfs4_open_share_access, {
13289
16
      "share_access", "nfs.open4.share_access", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
13290
16
      &names_open4_share_access_ext, 0, NULL, HFILL }},
13291
13292
16
    { &hf_nfs4_open_share_deny, {
13293
16
      "share_deny", "nfs.open4.share_deny", FT_UINT32, BASE_DEC,
13294
16
      VALS(names_open4_share_deny), 0, NULL, HFILL }},
13295
13296
16
    { &hf_nfs4_want_flags, {
13297
16
      "wants", "nfs.want", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
13298
16
      &names_open4_share_access_ext, 0, NULL, HFILL }},
13299
13300
16
    { &hf_nfs4_want_notify_flags, {
13301
16
      "want notification", "nfs.want_notification", FT_UINT32, BASE_HEX,
13302
16
      NULL, 0, NULL, HFILL }},
13303
13304
16
    { &hf_nfs4_want_signal_deleg_when_resrc_avail, {
13305
16
      "want_signal_deleg_when_resrc_avail",
13306
16
      "nfs.want_notification.when_resrc_avail", FT_BOOLEAN, 32,
13307
16
      TFS(&tfs_set_notset), OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL, NULL, HFILL }},
13308
13309
16
    { &hf_nfs4_want_push_deleg_when_uncontended, {
13310
16
      "want_push_deleg_when_uncontended",
13311
16
      "nfs.want_push_deleg_when_uncontended", FT_BOOLEAN, 32,
13312
16
      TFS(&tfs_set_notset), OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED, NULL, HFILL }},
13313
13314
16
    { &hf_nfs4_want_deleg_timestamps, {
13315
16
      "want_deleg_timestamps",
13316
16
      "nfs.want_deleg_timestamps", FT_BOOLEAN, 32,
13317
16
      TFS(&tfs_set_notset), OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS, NULL, HFILL }},
13318
13319
16
    { &hf_nfs4_seqid, {
13320
16
      "seqid", "nfs.seqid", FT_UINT32, BASE_HEX,
13321
16
      NULL, 0, "Sequence ID", HFILL }},
13322
13323
16
    { &hf_nfs4_lock_seqid, {
13324
16
      "lock_seqid", "nfs.lock_seqid", FT_UINT32, BASE_HEX,
13325
16
      NULL, 0, "Lock Sequence ID", HFILL }},
13326
13327
16
    { &hf_nfs4_reqd_attr, {
13328
16
      "reqd_attr", "nfs.attr", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
13329
16
      &fattr4_names_ext, 0, "Required Attribute", HFILL }},
13330
13331
16
    { &hf_nfs4_reco_attr, {
13332
16
      "reco_attr", "nfs.attr", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
13333
16
      &fattr4_names_ext, 0, "Recommended Attribute", HFILL }},
13334
13335
16
    { &hf_nfs4_attr_mask, {
13336
16
      "Attr mask", "nfs.attr_mask", FT_UINT32, BASE_HEX,
13337
16
      NULL, 0, "Attribute mask", HFILL }},
13338
13339
16
    { &hf_nfs4_attr_count, {
13340
16
      "Attr count", "nfs.attr_count", FT_UINT32, BASE_DEC,
13341
16
      NULL, 0, NULL, HFILL }},
13342
13343
16
    { &hf_nfs4_set_it_value_follows,  {
13344
16
      "set_it", "nfs.set_it", FT_UINT32, BASE_DEC,
13345
16
      VALS(value_follows), 0, "How To Set Time", HFILL }},
13346
13347
16
    { &hf_nfs4_time_how,  {
13348
16
      "set_it", "nfs.set_it", FT_UINT32, BASE_DEC,
13349
16
      VALS(time_how), 0, "How To Set Time", HFILL }},
13350
13351
16
    { &hf_nfs4_time_how4, {
13352
16
      "set_it", "nfs.set_it", FT_UINT32, BASE_DEC,
13353
16
      VALS(names_time_how4), 0, "How To Set Time", HFILL }},
13354
13355
16
    { &hf_nfs4_fattr_link_support, {
13356
16
      "fattr4_link_support", "nfs.fattr4_link_support", FT_BOOLEAN, BASE_NONE,
13357
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13358
13359
16
    { &hf_nfs4_fattr_symlink_support, {
13360
16
      "fattr4_symlink_support", "nfs.fattr4_symlink_support", FT_BOOLEAN, BASE_NONE,
13361
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13362
13363
16
    { &hf_nfs4_fattr_named_attr, {
13364
16
      "fattr4_named_attr", "nfs.fattr4_named_attr", FT_BOOLEAN, BASE_NONE,
13365
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13366
13367
16
    { &hf_nfs4_fattr_unique_handles, {
13368
16
      "fattr4_unique_handles", "nfs.fattr4_unique_handles", FT_BOOLEAN, BASE_NONE,
13369
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13370
13371
16
    { &hf_nfs4_fattr_archive, {
13372
16
      "fattr4_archive", "nfs.fattr4_archive", FT_BOOLEAN, BASE_NONE,
13373
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13374
13375
16
    { &hf_nfs4_fattr_cansettime, {
13376
16
      "fattr4_cansettime", "nfs.fattr4_cansettime", FT_BOOLEAN, BASE_NONE,
13377
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13378
13379
16
    { &hf_nfs4_fattr_case_insensitive, {
13380
16
      "fattr4_case_insensitive", "nfs.fattr4_case_insensitive", FT_BOOLEAN, BASE_NONE,
13381
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13382
13383
16
    { &hf_nfs4_fattr_case_preserving, {
13384
16
      "fattr4_case_preserving", "nfs.fattr4_case_preserving", FT_BOOLEAN, BASE_NONE,
13385
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13386
13387
16
    { &hf_nfs4_fattr_chown_restricted, {
13388
16
      "fattr4_chown_restricted", "nfs.fattr4_chown_restricted", FT_BOOLEAN, BASE_NONE,
13389
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13390
13391
16
    { &hf_nfs4_fattr_fh_expire_type, {
13392
16
      "fattr4_fh_expire_type", "nfs.fattr4_fh_expire_type", FT_UINT32, BASE_HEX,
13393
16
      VALS(nfs4_fattr4_fh_expire_type_names), 0, NULL, HFILL }},
13394
13395
16
    { &hf_nfs4_fattr_fh_expiry_noexpire_with_open, {
13396
16
      "noexpire_with_open", "nfs.fattr4_fh_expire_type.noexpire_with_open",
13397
16
      FT_BOOLEAN, 32,
13398
16
      NULL, FH4_NOEXPIRE_WITH_OPEN, NULL, HFILL }},
13399
16
    { &hf_nfs4_fattr_fh_expiry_volatile_any, {
13400
16
      "volatile_any", "nfs.fattr4_fh_expire_type.volatile_any",
13401
16
      FT_BOOLEAN, 32,
13402
16
      NULL, FH4_VOLATILE_ANY, NULL, HFILL }},
13403
16
    { &hf_nfs4_fattr_fh_expiry_vol_migration, {
13404
16
      "vol_migration", "nfs.fattr4_fh_expire_type.vol_migration",
13405
16
      FT_BOOLEAN, 32,
13406
16
      NULL, FH4_VOL_MIGRATION, NULL, HFILL }},
13407
16
    { &hf_nfs4_fattr_fh_expiry_vol_rename, {
13408
16
      "vol_rename", "nfs.fattr4_fh_expire_type.vol_rename",
13409
16
      FT_BOOLEAN, 32,
13410
16
      NULL, FH4_VOL_RENAME, NULL, HFILL }},
13411
13412
16
    { &hf_nfs4_fattr_hidden, {
13413
16
      "fattr4_hidden", "nfs.fattr4_hidden", FT_BOOLEAN, BASE_NONE,
13414
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13415
13416
16
    { &hf_nfs4_fattr_homogeneous, {
13417
16
      "fattr4_homogeneous", "nfs.fattr4_homogeneous", FT_BOOLEAN, BASE_NONE,
13418
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13419
13420
16
    { &hf_nfs4_fattr_mimetype, {
13421
16
      "fattr4_mimetype", "nfs.fattr4_mimetype", FT_STRING, BASE_NONE,
13422
16
      NULL, 0, NULL, HFILL }},
13423
13424
16
    { &hf_nfs4_fattr_no_trunc, {
13425
16
      "fattr4_no_trunc", "nfs.fattr4_no_trunc", FT_BOOLEAN, BASE_NONE,
13426
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13427
13428
16
    { &hf_nfs4_fattr_system, {
13429
16
      "fattr4_system", "nfs.fattr4_system", FT_BOOLEAN, BASE_NONE,
13430
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13431
13432
16
    { &hf_nfs4_who, {
13433
16
      "Who", "nfs.who", FT_STRING, BASE_NONE,
13434
16
      NULL, 0, NULL, HFILL }},
13435
13436
16
    { &hf_nfs4_server, {
13437
16
      "server", "nfs.server", FT_STRING, BASE_NONE,
13438
16
      NULL, 0, NULL, HFILL }},
13439
13440
16
    { &hf_nfs4_servers, {
13441
16
      "servers", "nfs.servers", FT_NONE, BASE_NONE,
13442
16
      NULL, 0, NULL, HFILL }},
13443
13444
16
    { &hf_nfs4_fslocation, {
13445
16
      "fs_location4", "nfs.fattr4.fs_location", FT_NONE, BASE_NONE,
13446
16
      NULL, 0, NULL, HFILL }},
13447
13448
16
    { &hf_nfs4_fattr_owner, {
13449
16
      "fattr4_owner", "nfs.fattr4_owner", FT_STRING, BASE_NONE,
13450
16
      NULL, 0, NULL, HFILL }},
13451
13452
16
    { &hf_nfs4_fattr_owner_group, {
13453
16
      "fattr4_owner_group", "nfs.fattr4_owner_group", FT_STRING, BASE_NONE,
13454
16
      NULL, 0, NULL, HFILL }},
13455
13456
16
    { &hf_nfs4_stable_how, {
13457
16
      "stable_how4", "nfs.stable_how4", FT_UINT32, BASE_DEC,
13458
16
      VALS(names_stable_how4), 0, NULL, HFILL }},
13459
13460
16
    { &hf_nfs4_dirlist_eof, {
13461
16
      "EOF", "nfs.dirlist4.eof", FT_BOOLEAN, BASE_NONE,
13462
16
      TFS(&tfs_yes_no), 0x0, "There are no more entries", HFILL }},
13463
13464
    /* StateID */
13465
16
    { &hf_nfs4_stateid,{
13466
16
      "StateID", "nfs.stateid", FT_BYTES, BASE_NONE,
13467
16
      NULL, 0, NULL, HFILL }},
13468
16
    { &hf_nfs4_stateid_hash,{
13469
16
      "StateID Hash", "nfs.stateid.hash", FT_UINT16, BASE_HEX,
13470
16
      NULL, 0, "CRC-16 hash", HFILL }},
13471
16
    { &hf_nfs4_seqid_stateid, {
13472
16
      "StateID seqid", "nfs.stateid.seqid", FT_UINT32, BASE_DEC,
13473
16
      NULL, 0, NULL, HFILL }},
13474
16
    { &hf_nfs4_stateid_other,{
13475
16
      "StateID Other", "nfs.stateid.other", FT_BYTES, BASE_NONE,
13476
16
      NULL, 0, "Unique component of StateID", HFILL }},
13477
16
    { &hf_nfs4_stateid_other_hash,{
13478
16
      "StateID Other hash", "nfs.stateid.other_hash", FT_UINT32, BASE_HEX,
13479
16
      NULL, 0, "CRC-32 hash", HFILL }},
13480
13481
16
    { &hf_nfs4_offset, {
13482
16
      "offset", "nfs.offset4", FT_UINT64, BASE_DEC,
13483
16
      NULL, 0, NULL, HFILL }},
13484
13485
16
    { &hf_nfs4_specdata1, {
13486
16
      "specdata1", "nfs.specdata1", FT_UINT32, BASE_DEC,
13487
16
      NULL, 0, NULL, HFILL }},
13488
13489
16
    { &hf_nfs4_specdata2, {
13490
16
      "specdata2", "nfs.specdata2", FT_UINT32, BASE_DEC,
13491
16
      NULL, 0, NULL, HFILL }},
13492
13493
16
    { &hf_nfs4_lock_type, {
13494
16
      "locktype", "nfs.locktype4", FT_UINT32, BASE_DEC,
13495
16
      VALS(names_nfs_lock_type4), 0, NULL, HFILL }},
13496
13497
16
    { &hf_nfs4_open_rflags, {
13498
16
      "result flags", "nfs.open_rflags", FT_UINT32, BASE_HEX,
13499
16
      NULL, 0, NULL, HFILL }},
13500
13501
16
    { &hf_nfs4_open_rflags_confirm, {
13502
16
      "confirm", "nfs.open_rflags.confirm",
13503
16
      FT_BOOLEAN, 32,
13504
16
      NULL, OPEN4_RESULT_CONFIRM, NULL, HFILL }},
13505
13506
16
    { &hf_nfs4_open_rflags_locktype_posix, {
13507
16
      "locktype posix", "nfs.open_rflags.locktype_posix",
13508
16
      FT_BOOLEAN, 32,
13509
16
      NULL, OPEN4_RESULT_LOCKTYPE_POSIX, NULL, HFILL }},
13510
13511
16
    { &hf_nfs4_open_rflags_preserve_unlinked, {
13512
16
      "preserve unlinked", "nfs.open_rflags.preserve_unlinked",
13513
16
      FT_BOOLEAN, 32,
13514
16
      NULL, OPEN4_RESULT_PRESERVE_UNLINKED, NULL, HFILL }},
13515
13516
16
    { &hf_nfs4_open_rflags_may_notify_lock, {
13517
16
      "may notify lock", "nfs.open_rflags.may_notify_lock",
13518
16
      FT_BOOLEAN, 32,
13519
16
      NULL, OPEN4_RESULT_MAY_NOTIFY_LOCK, NULL, HFILL }},
13520
13521
16
    { &hf_nfs4_reclaim, {
13522
16
      "reclaim", "nfs.reclaim4", FT_BOOLEAN, BASE_NONE,
13523
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13524
13525
16
    { &hf_nfs4_length, {
13526
16
      "length", "nfs.length4", FT_UINT64, BASE_DEC,
13527
16
      NULL, 0, NULL, HFILL }},
13528
13529
16
    { &hf_nfs4_changeid, {
13530
16
      "changeid", "nfs.changeid4", FT_UINT64, BASE_DEC,
13531
16
      NULL, 0, NULL, HFILL }},
13532
13533
16
    { &hf_nfs4_changeid_before, {
13534
16
      "changeid (before)", "nfs.changeid4.before", FT_UINT64, BASE_DEC,
13535
16
      NULL, 0, NULL, HFILL }},
13536
13537
16
    { &hf_nfs4_changeid_after, {
13538
16
      "changeid (after)", "nfs.changeid4.after", FT_UINT64, BASE_DEC,
13539
16
      NULL, 0, NULL, HFILL }},
13540
13541
16
    { &hf_nfs4_time, {
13542
16
      "nfstime4", "nfs.nfstime4", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
13543
16
      NULL, 0, NULL, HFILL }},
13544
13545
16
    { &hf_nfs4_time_seconds, {
13546
16
      "seconds", "nfs.nfstime4.seconds", FT_UINT64, BASE_DEC,
13547
16
      NULL, 0, NULL, HFILL }},
13548
13549
16
    { &hf_nfs4_time_nseconds, {
13550
16
      "nseconds", "nfs.nfstime4.nseconds", FT_UINT32, BASE_DEC,
13551
16
      NULL, 0, NULL, HFILL }},
13552
13553
16
    { &hf_nfs4_fsid_major, {
13554
16
      "fsid4.major", "nfs.fsid4.major", FT_UINT64, BASE_DEC,
13555
16
      NULL, 0, NULL, HFILL }},
13556
13557
16
    { &hf_nfs4_fsid_minor, {
13558
16
      "fsid4.minor", "nfs.fsid4.minor", FT_UINT64, BASE_DEC,
13559
16
      NULL, 0, NULL, HFILL }},
13560
13561
16
    { &hf_nfs4_acetype, {
13562
16
      "acetype", "nfs.acetype4", FT_UINT32, BASE_DEC,
13563
16
      VALS(names_acetype4), 0, NULL, HFILL }},
13564
13565
16
    { &hf_nfs4_aceflags, {
13566
16
      "ACE flags", "nfs.aceflags4", FT_UINT32, BASE_HEX,
13567
16
      NULL, 0, NULL, HFILL }},
13568
13569
16
    { &hf_nfs4_aceflag_file_inherit, {
13570
16
      "File_Inherit", "nfs.aceflag4.file_inherit", FT_BOOLEAN, 32,
13571
16
      TFS(&tfs_yes_no), ACE4_FLAG_FILE_INHERIT, NULL, HFILL }},
13572
13573
16
    { &hf_nfs4_aceflag_dir_inherit, {
13574
16
      "Directory_Inherit", "nfs.aceflag4.dir_inherit", FT_BOOLEAN, 32,
13575
16
      TFS(&tfs_yes_no), ACE4_FLAG_DIRECTORY_INHERIT, NULL, HFILL }},
13576
13577
16
    { &hf_nfs4_aceflag_no_prop_inherit, {
13578
16
      "No_Propagate_Inherit", "nfs.aceflag4.no_prop_inherit", FT_BOOLEAN, 32,
13579
16
      TFS(&tfs_yes_no), ACE4_FLAG_NO_PROPAGATE_INHERIT, NULL, HFILL }},
13580
13581
16
    { &hf_nfs4_aceflag_inherit_only, {
13582
16
      "Inherit_Only", "nfs.aceflag4.inherit_only", FT_BOOLEAN, 32,
13583
16
      TFS(&tfs_yes_no), ACE4_FLAG_INHERIT_ONLY, NULL, HFILL }},
13584
13585
16
    { &hf_nfs4_aceflag_successful_access, {
13586
16
      "Successful_Access", "nfs.aceflag4.successful_access", FT_BOOLEAN, 32,
13587
16
      TFS(&tfs_yes_no), ACE4_FLAG_SUCCESSFUL_ACCESS, NULL, HFILL }},
13588
13589
16
    { &hf_nfs4_aceflag_failed_access, {
13590
16
      "Failed_access", "nfs.aceflag4.failed_access", FT_BOOLEAN, 32,
13591
16
      TFS(&tfs_yes_no), ACE4_FLAG_FAILED_ACCESS, NULL, HFILL }},
13592
13593
16
    { &hf_nfs4_aceflag_id_group, {
13594
16
      "Identifier_Group", "nfs.aceflag4.id_group", FT_BOOLEAN, 32,
13595
16
      TFS(&tfs_yes_no), ACE4_FLAG_IDENTIFIER_GROUP, NULL, HFILL }},
13596
13597
16
    { &hf_nfs4_aceflag_inherited_ace, {
13598
16
      "Inherited_ACE", "nfs.aceflag4.inherited_ace", FT_BOOLEAN, 32,
13599
16
      TFS(&tfs_yes_no), ACE4_FLAG_INHERITED_ACE, NULL, HFILL }},
13600
13601
16
    { &hf_nfs4_acemask, {
13602
16
      "ACE mask", "nfs.acemask4", FT_UINT32, BASE_HEX,
13603
16
      NULL, 0, NULL, HFILL }},
13604
13605
16
    { &hf_nfs4_ace_permission, {
13606
16
      "perm", "nfs.ace_perm4", FT_UINT32, BASE_HEX,
13607
16
      NULL, 0, NULL, HFILL }},
13608
13609
16
    { &hf_nfs4_fattr_size, {
13610
16
      "size", "nfs.fattr4.size", FT_UINT64, BASE_DEC,
13611
16
      NULL, 0, NULL, HFILL }},
13612
13613
16
    { &hf_nfs4_fattr_lease_time, {
13614
16
      "lease_time", "nfs.fattr4.lease_time", FT_UINT32, BASE_DEC,
13615
16
      NULL, 0, "Duration of the lease at server in seconds", HFILL }},
13616
13617
16
    { &hf_nfs4_fattr_aclsupport, {
13618
16
      "aclsupport", "nfs.fattr4.aclsupport", FT_UINT32, BASE_DEC,
13619
16
      NULL, 0, NULL, HFILL }},
13620
13621
16
    { &hf_nfs4_aclsupport_allow_acl, {
13622
16
      "ALLOW", "nfs.fattr4.aclsupport.allow_acl", FT_BOOLEAN, 32,
13623
16
      NULL, ACL4_SUPPORT_ALLOW_ACL, NULL, HFILL }},
13624
13625
16
    { &hf_nfs4_aclsupport_deny_acl, {
13626
16
      "DENY", "nfs.fattr4.aclsupport.deny_acl", FT_BOOLEAN, 32,
13627
16
      NULL, ACL4_SUPPORT_DENY_ACL, NULL, HFILL }},
13628
13629
16
    { &hf_nfs4_aclsupport_audit_acl, {
13630
16
      "AUDIT", "nfs.fattr4.aclsupport.audit_acl", FT_BOOLEAN, 32,
13631
16
      NULL, ACL4_SUPPORT_AUDIT_ACL, NULL, HFILL }},
13632
13633
16
    { &hf_nfs4_aclsupport_alarm_acl, {
13634
16
      "ALARM", "nfs.fattr4.aclsupport.alarm_acl", FT_BOOLEAN, 32,
13635
16
      NULL, ACL4_SUPPORT_ALARM_ACL, NULL, HFILL }},
13636
13637
16
    { &hf_nfs4_fattr_fileid, {
13638
16
      "fileid", "nfs.fattr4.fileid", FT_UINT64, BASE_DEC,
13639
16
      NULL, 0, NULL, HFILL }},
13640
13641
16
    { &hf_nfs4_fattr_files_avail, {
13642
16
      "files_avail", "nfs.fattr4.files_avail", FT_UINT64, BASE_DEC,
13643
16
      NULL, 0, NULL, HFILL }},
13644
13645
16
    { &hf_nfs4_fattr_files_free, {
13646
16
      "files_free", "nfs.fattr4.files_free", FT_UINT64, BASE_DEC,
13647
16
      NULL, 0, NULL, HFILL }},
13648
13649
16
    { &hf_nfs4_fattr_files_total, {
13650
16
      "files_total", "nfs.fattr4.files_total", FT_UINT64, BASE_DEC,
13651
16
      NULL, 0, NULL, HFILL }},
13652
13653
16
    { &hf_nfs4_fattr_maxfilesize, {
13654
16
      "maxfilesize", "nfs.fattr4.maxfilesize", FT_UINT64, BASE_DEC,
13655
16
      NULL, 0, NULL, HFILL }},
13656
13657
16
    { &hf_nfs4_fattr_maxlink, {
13658
16
      "maxlink", "nfs.fattr4.maxlink", FT_UINT32, BASE_DEC,
13659
16
      NULL, 0, NULL, HFILL }},
13660
13661
16
    { &hf_nfs4_fattr_maxname, {
13662
16
      "maxname", "nfs.fattr4.maxname", FT_UINT32, BASE_DEC,
13663
16
      NULL, 0, NULL, HFILL }},
13664
13665
16
    { &hf_nfs4_fattr_numlinks, {
13666
16
      "numlinks", "nfs.fattr4.numlinks", FT_UINT32, BASE_DEC,
13667
16
      NULL, 0, NULL, HFILL }},
13668
13669
16
    { &hf_nfs4_delegate_type, {
13670
16
      "delegate_type", "nfs.delegate_type", FT_UINT32, BASE_DEC,
13671
16
      NULL, 0, NULL, HFILL }},
13672
13673
16
    { &hf_nfs4_secinfo_flavor, {
13674
16
      "flavor", "nfs.secinfo.flavor", FT_UINT32, BASE_DEC,
13675
16
      VALS(rpc_auth_flavor), 0, NULL, HFILL }},
13676
13677
16
    { &hf_nfs4_num_blocks, {
13678
16
      "num_blocks", "nfs.num_blocks", FT_UINT32, BASE_DEC,
13679
16
      NULL, 0, NULL, HFILL }},
13680
13681
16
    { &hf_nfs4_bytes_per_block, {
13682
16
      "bytes_per_block", "nfs.bytes_per_block", FT_UINT32, BASE_DEC,
13683
16
      NULL, 0, NULL, HFILL }},
13684
13685
16
    { &hf_nfs4_eof, {
13686
16
      "eof", "nfs.eof", FT_UINT32, BASE_DEC,
13687
16
      NULL, 0, NULL, HFILL }},
13688
13689
16
    { &hf_nfs4_fattr_maxread, {
13690
16
      "maxread", "nfs.fattr4.maxread", FT_UINT64, BASE_DEC,
13691
16
      NULL, 0, NULL, HFILL }},
13692
13693
16
    { &hf_nfs4_fattr_maxwrite, {
13694
16
      "maxwrite", "nfs.fattr4.maxwrite", FT_UINT64, BASE_DEC,
13695
16
      NULL, 0, NULL, HFILL }},
13696
13697
16
    { &hf_nfs4_fattr_quota_hard, {
13698
16
      "quota_hard", "nfs.fattr4.quota_hard", FT_UINT64, BASE_DEC,
13699
16
      NULL, 0, NULL, HFILL }},
13700
13701
16
    { &hf_nfs4_fattr_quota_soft, {
13702
16
      "quota_soft", "nfs.fattr4.quota_soft", FT_UINT64, BASE_DEC,
13703
16
      NULL, 0, NULL, HFILL }},
13704
13705
16
    { &hf_nfs4_fattr_quota_used, {
13706
16
      "quota_used", "nfs.fattr4.quota_used", FT_UINT64, BASE_DEC,
13707
16
      NULL, 0, NULL, HFILL }},
13708
13709
16
    { &hf_nfs4_fattr_space_avail, {
13710
16
      "space_avail", "nfs.fattr4.space_avail", FT_UINT64, BASE_DEC,
13711
16
      NULL, 0, NULL, HFILL }},
13712
13713
16
    { &hf_nfs4_fattr_space_free, {
13714
16
      "space_free", "nfs.fattr4.space_free", FT_UINT64, BASE_DEC,
13715
16
      NULL, 0, NULL, HFILL }},
13716
13717
16
    { &hf_nfs4_fattr_space_total, {
13718
16
      "space_total", "nfs.fattr4.space_total", FT_UINT64, BASE_DEC,
13719
16
      NULL, 0, NULL, HFILL }},
13720
13721
16
    { &hf_nfs4_fattr_space_used, {
13722
16
      "space_used", "nfs.fattr4.space_used", FT_UINT64, BASE_DEC,
13723
16
      NULL, 0, NULL, HFILL }},
13724
13725
16
    { &hf_nfs4_fattr_mounted_on_fileid, {
13726
16
      "fileid", "nfs.fattr4.mounted_on_fileid", FT_UINT64, BASE_DEC,
13727
16
      NULL, 0, NULL, HFILL }},
13728
13729
16
    { &hf_nfs4_fattr_layout_blksize, {
13730
16
      "blksize", "nfs.fattr4.layout_blksize", FT_UINT32, BASE_DEC,
13731
16
      NULL, 0, NULL, HFILL }},
13732
13733
16
    { &hf_nfs4_mdsthreshold_item, {
13734
16
      "threshold_item4", "nfs.fattr4.threshold_item", FT_NONE, BASE_NONE,
13735
16
      NULL, 0, NULL, HFILL }},
13736
13737
16
    { &hf_nfs4_mdsthreshold_hint_mask, {
13738
16
      "hint mask", "nfs.fattr4.threshold_item.hint_mask", FT_UINT32, BASE_HEX,
13739
16
      NULL, 0, "MDS threshold hint mask", HFILL }},
13740
13741
16
    { &hf_nfs4_mdsthreshold_hint_count, {
13742
16
      "hint", "nfs.fattr4.threshold_item.hint_count", FT_UINT32, BASE_DEC,
13743
16
      NULL, 0, "MDS threshold hint count", HFILL }},
13744
13745
16
    { &hf_nfs4_mdsthreshold_mask_count, {
13746
16
      "number of masks", "nfs.fattr4.threshold_item.mask_count", FT_UINT32, BASE_DEC,
13747
16
      NULL, 0, "MDS threshold hint mask count", HFILL }},
13748
13749
16
    { &hf_nfs4_mdsthreshold_hint_file, {
13750
16
      "hint", "nfs.fattr4.threshold_item.hint", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
13751
16
      &th4_names_ext_file, 0, "MDS threshold hint", HFILL }},
13752
13753
16
    { &hf_nfs4_fattr_security_label_lfs, {
13754
16
      "label_format", "nfs.fattr4.security_label.lfs", FT_UINT32, BASE_DEC,
13755
16
      NULL, 0, NULL, HFILL }},
13756
13757
16
    { &hf_nfs4_fattr_umask_mask, {
13758
16
      "umask", "nfs.fattr4.umask", FT_UINT32, BASE_OCT,
13759
16
      NULL, 0, NULL, HFILL }},
13760
13761
16
    { &hf_nfs4_fattr_xattr_support, {
13762
16
      "fattr4_xattr_support", "nfs.fattr4_xattr_support", FT_BOOLEAN, BASE_NONE,
13763
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13764
13765
16
    { &hf_nfs4_fattr_offline, {
13766
16
      "fattr4_offline", "nfs.fattr4_offline", FT_BOOLEAN, BASE_NONE,
13767
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13768
13769
16
    { &hf_nfs4_fattr_security_label_pi, {
13770
16
      "policy_id", "nfs.fattr4.security_label.pi", FT_UINT32, BASE_DEC,
13771
16
      NULL, 0, NULL, HFILL }},
13772
13773
16
    { &hf_nfs4_fattr_security_label_context, {
13774
16
      "context", "nfs.fattr4.security_label.context", FT_STRING, BASE_NONE,
13775
16
      NULL, 0, NULL, HFILL }},
13776
13777
16
    { &hf_nfs4_fattr_fs_charset_cap, {
13778
16
      "fs_charset_cap", "nfs.fattr4.fs_charset_cap", FT_UINT32, BASE_HEX,
13779
16
      NULL, 0, NULL, HFILL }},
13780
13781
16
    { &hf_nfs4_fs_charset_cap_nonutf8, {
13782
16
      "CONTAINS_NON_UTF8", "nfs.fattr4.fs_charset_cap.nonutf8", FT_BOOLEAN, 32,
13783
16
      NULL, FSCHARSET_CAP4_CONTAINS_NON_UTF8, NULL, HFILL }},
13784
13785
16
    { &hf_nfs4_fs_charset_cap_utf8, {
13786
16
      "ALLOWS_ONLY_UTF8", "nfs.fattr4.fs_charset_cap.utf8", FT_BOOLEAN, 32,
13787
16
      NULL, FSCHARSET_CAP4_ALLOWS_ONLY_UTF8, NULL, HFILL }},
13788
13789
16
    { &hf_nfs4_verifier, {
13790
16
      "verifier", "nfs.verifier4", FT_UINT64, BASE_HEX,
13791
16
      NULL, 0, NULL, HFILL }},
13792
13793
16
    { &hf_nfs4_value_follows, {
13794
16
      "Value Follows", "nfs.value_follows", FT_BOOLEAN, BASE_NONE,
13795
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13796
13797
16
    { &hf_nfs4_cookie, {
13798
16
      "cookie", "nfs.cookie4", FT_UINT64, BASE_DEC,
13799
16
      NULL, 0, NULL, HFILL }},
13800
13801
16
    { &hf_nfs4_cookie_verf, {
13802
16
      "cookie_verf", "nfs.cookie_verf4", FT_UINT64, BASE_DEC,
13803
16
      NULL, 0, NULL, HFILL }},
13804
13805
#if 0
13806
    { &hf_nfs4_cb_location, {
13807
      "cb_location", "nfs.cb_location", FT_UINT32, BASE_DEC,
13808
      NULL, 0, NULL, HFILL }},
13809
#endif
13810
13811
16
    { &hf_nfs4_cb_program, {
13812
16
      "cb_program", "nfs.cb_program", FT_UINT32, BASE_HEX,
13813
16
      NULL, 0, NULL, HFILL }},
13814
13815
16
    { &hf_nfs4_recall4, {
13816
16
      "recall", "nfs.recall4", FT_BOOLEAN, BASE_NONE,
13817
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13818
13819
16
    { &hf_nfs4_filesize, {
13820
16
      "filesize", "nfs.filesize", FT_UINT64, BASE_DEC,
13821
16
      NULL, 0, NULL, HFILL }},
13822
13823
16
    { &hf_nfs4_count, {
13824
16
      "count", "nfs.count4", FT_UINT32, BASE_DEC,
13825
16
      NULL, 0, NULL, HFILL }},
13826
13827
16
    { &hf_nfs4_count_dircount, {
13828
16
      "dircount", "nfs.dircount", FT_UINT32, BASE_DEC,
13829
16
      NULL, 0, NULL, HFILL }},
13830
13831
16
    { &hf_nfs4_count_maxcount, {
13832
16
      "maxcount", "nfs.maxcount", FT_UINT32, BASE_DEC,
13833
16
      NULL, 0, NULL, HFILL }},
13834
13835
16
    { &hf_nfs4_minorversion, {
13836
16
      "minorversion", "nfs.minorversion", FT_UINT32, BASE_DEC,
13837
16
      NULL, 0, NULL, HFILL }},
13838
13839
16
    { &hf_nfs_atime, {
13840
16
      "atime", "nfs.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
13841
16
      NULL, 0, "Access Time", HFILL }},
13842
13843
16
    { &hf_nfs_atime_sec, {
13844
16
      "seconds", "nfs.atime.sec", FT_UINT32, BASE_DEC,
13845
16
      NULL, 0, "Access Time, Seconds", HFILL }},
13846
13847
16
    { &hf_nfs_atime_nsec, {
13848
16
      "nano seconds", "nfs.atime.nsec", FT_UINT32, BASE_DEC,
13849
16
      NULL, 0, "Access Time, Nano-seconds", HFILL }},
13850
13851
16
    { &hf_nfs_atime_usec, {
13852
16
      "micro seconds", "nfs.atime.usec", FT_UINT32, BASE_DEC,
13853
16
      NULL, 0, "Access Time, Micro-seconds", HFILL }},
13854
13855
16
    { &hf_nfs_mtime, {
13856
16
      "mtime", "nfs.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
13857
16
      NULL, 0, "Modify Time", HFILL }},
13858
13859
16
    { &hf_nfs_mtime_sec, {
13860
16
      "seconds", "nfs.mtime.sec", FT_UINT32, BASE_DEC,
13861
16
      NULL, 0, "Modify Seconds", HFILL }},
13862
13863
16
    { &hf_nfs_mtime_nsec, {
13864
16
      "nano seconds", "nfs.mtime.nsec", FT_UINT32, BASE_DEC,
13865
16
      NULL, 0, "Modify Time, Nano-seconds", HFILL }},
13866
13867
16
    { &hf_nfs_mtime_usec, {
13868
16
      "micro seconds", "nfs.mtime.usec", FT_UINT32, BASE_DEC,
13869
16
      NULL, 0, "Modify Time, Micro-seconds", HFILL }},
13870
13871
16
    { &hf_nfs_ctime, {
13872
16
      "ctime", "nfs.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
13873
16
      NULL, 0, "Creation Time", HFILL }},
13874
13875
16
    { &hf_nfs_ctime_sec, {
13876
16
      "seconds", "nfs.ctime.sec", FT_UINT32, BASE_DEC,
13877
16
      NULL, 0, "Creation Time, Seconds", HFILL }},
13878
13879
16
    { &hf_nfs_ctime_nsec, {
13880
16
      "nano seconds", "nfs.ctime.nsec", FT_UINT32, BASE_DEC,
13881
16
      NULL, 0, "Creation Time, Nano-seconds", HFILL }},
13882
13883
16
    { &hf_nfs_ctime_usec, {
13884
16
      "micro seconds", "nfs.ctime.usec", FT_UINT32, BASE_DEC,
13885
16
      NULL, 0, "Creation Time, Micro-seconds", HFILL }},
13886
13887
16
    { &hf_nfs_dtime, {
13888
16
      "time delta", "nfs.dtime", FT_RELATIVE_TIME, BASE_NONE,
13889
16
      NULL, 0, NULL, HFILL }},
13890
13891
16
    { &hf_nfs_dtime_sec, {
13892
16
      "seconds", "nfs.dtime.sec", FT_UINT32, BASE_DEC,
13893
16
      NULL, 0, "Time Delta, Seconds", HFILL }},
13894
13895
16
    { &hf_nfs_dtime_nsec, {
13896
16
      "nano seconds", "nfs.dtime.nsec", FT_UINT32, BASE_DEC,
13897
16
      NULL, 0, "Time Delta, Nano-seconds", HFILL }},
13898
13899
16
    { &hf_nfs4_open_owner, {
13900
16
      "owner", "nfs.open_owner4", FT_BYTES, BASE_NONE,
13901
16
      NULL, 0, NULL, HFILL }},
13902
13903
16
    { &hf_nfs4_lock_owner, {
13904
16
      "owner", "nfs.lock_owner4", FT_BYTES, BASE_NONE,
13905
16
      NULL, 0, NULL, HFILL }},
13906
13907
16
    { &hf_nfs4_createmode, {
13908
16
      "Create Mode", "nfs.createmode4", FT_UINT32, BASE_DEC,
13909
16
      VALS(names_createmode4), 0, NULL, HFILL }},
13910
13911
16
    { &hf_nfs4_secinfo_rpcsec_gss_info_service, {
13912
16
      "service", "nfs.secinfo.rpcsec_gss_info.service", FT_UINT32, BASE_DEC,
13913
16
      VALS(rpc_authgss_svc), 0, NULL, HFILL }},
13914
13915
16
    { &hf_nfs4_attr_dir_create, {
13916
16
      "attribute dir create", "nfs.openattr4.createdir", FT_BOOLEAN, BASE_NONE,
13917
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13918
13919
16
    { &hf_nfs4_new_lock_owner, {
13920
16
      "new lock owner?", "nfs.lock.locker.new_lock_owner", FT_BOOLEAN, BASE_NONE,
13921
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13922
13923
16
    { &hf_nfs4_ond_server_will_push_deleg, {
13924
16
      "server will push deleg?", "nfs.ond.server_will_push_deleg", FT_BOOLEAN, BASE_NONE,
13925
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13926
13927
16
    { &hf_nfs4_ond_server_will_signal_avail, {
13928
16
      "server will signal avail?", "nfs.ond.server_will_signal-avail", FT_BOOLEAN, BASE_NONE,
13929
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13930
13931
16
    { &hf_nfs4_lock_reclaim, {
13932
16
      "reclaim?", "nfs.lock.reclaim", FT_BOOLEAN, BASE_NONE,
13933
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13934
13935
16
    { &hf_nfs4_sec_oid, {
13936
16
      "oid", "nfs.secinfo.flavor_info.rpcsec_gss_info.oid", FT_OID, BASE_NONE,
13937
16
      NULL, 0, NULL, HFILL }},
13938
13939
16
    { &hf_nfs4_qop, {
13940
16
      "qop", "nfs.secinfo.flavor_info.rpcsec_gss_info.qop", FT_UINT32, BASE_DEC,
13941
16
      NULL, 0, NULL, HFILL }},
13942
13943
16
    { &hf_nfs4_client_id, {
13944
16
      "id", "nfs.nfs_client_id4.id", FT_BYTES, BASE_NONE,
13945
16
      NULL, 0, NULL, HFILL }},
13946
13947
16
    { &hf_nfs4_aclflags, {
13948
16
      "ACL flags", "nfs.acl.flags", FT_UINT32, BASE_DEC,
13949
16
      NULL, 0, NULL, HFILL }},
13950
13951
16
    { &hf_nfs4_aclflag_auto_inherit, {
13952
16
      "AUTO_INHERIT", "nfs.acl.flags.auto_inherit", FT_BOOLEAN, 32,
13953
16
      NULL, ACL4_AUTO_INHERIT, NULL, HFILL }},
13954
13955
16
    { &hf_nfs4_aclflag_protected, {
13956
16
      "PROTECTED", "nfs.acl.flags.protected", FT_BOOLEAN, 32,
13957
16
      NULL, ACL4_PROTECTED, NULL, HFILL }},
13958
13959
16
    { &hf_nfs4_aclflag_defaulted, {
13960
16
      "DEFAULTED", "nfs.acl.flags.defaulted", FT_BOOLEAN, 32,
13961
16
      NULL, ACL4_DEFAULTED, NULL, HFILL }},
13962
13963
16
    { &hf_nfs4_num_aces, {
13964
16
      "ACE count", "nfs.num_aces", FT_UINT32, BASE_DEC,
13965
16
      NULL, 0, "Number of ACEs", HFILL }},
13966
13967
16
    { &hf_nfs4_callback_ident, {
13968
16
      "callback_ident", "nfs.callback.ident", FT_UINT32, BASE_HEX,
13969
16
      NULL, 0, "Callback Identifier", HFILL }},
13970
13971
16
    { &hf_nfs4_gsshandle, {
13972
16
      "gsshandle4", "nfs.gsshandle4", FT_BYTES, BASE_NONE,
13973
16
      NULL, 0, NULL, HFILL }},
13974
13975
16
    { &hf_nfs4_r_netid, {
13976
16
      "r_netid", "nfs.r_netid", FT_STRING, BASE_NONE,
13977
16
      NULL, 0, NULL, HFILL }},
13978
13979
16
    { &hf_nfs4_r_addr, {
13980
16
      "r_addr", "nfs.r_addr", FT_STRING, BASE_NONE,
13981
16
      NULL, 0, NULL, HFILL }},
13982
13983
16
    { &hf_nfs_fh_fhandle_data, {
13984
16
      "FileHandle", "nfs.fhandle", FT_BYTES, BASE_NONE,
13985
16
      NULL, 0, "Opaque nfs filehandle", HFILL }},
13986
13987
16
    { &hf_nfs4_secinfo_arr, {
13988
16
      "Flavors Info", "nfs.flavors.info", FT_NONE, BASE_NONE,
13989
16
      NULL, 0, NULL, HFILL }},
13990
13991
16
    { &hf_nfs3_gxfh_utlfield, {
13992
16
      "utility", "nfs.gxfh3.utility", FT_UINT8, BASE_HEX,
13993
16
      NULL, 0, NULL, HFILL }},
13994
13995
16
    { &hf_nfs3_gxfh_utlfield_tree, {
13996
16
      "tree R/W", "nfs.gxfh3.utlfield.tree", FT_BOOLEAN, 8,
13997
16
      TFS(&tfs_read_write), NFS3GX_FH_TREE_MASK, NULL, HFILL }},
13998
13999
16
    { &hf_nfs3_gxfh_utlfield_jun, {
14000
16
      "broken junction", "nfs.gxfh3.utlfield.junction", FT_BOOLEAN, 8,
14001
16
      TFS(&tfs_yes_no), NFS3GX_FH_JUN_MASK, NULL, HFILL }},
14002
14003
16
    { &hf_nfs3_gxfh_utlfield_ver, {
14004
16
      "file handle version", "nfs.gxfh3.utlfield.version", FT_UINT8, BASE_HEX,
14005
16
      NULL, NFS3GX_FH_VER_MASK, NULL, HFILL }},
14006
14007
16
    { &hf_nfs3_gxfh_volcnt, {
14008
16
      "volume count", "nfs.gxfh3.volcnt", FT_UINT8, BASE_HEX_DEC,
14009
16
      NULL, 0, NULL, HFILL }},
14010
14011
16
    { &hf_nfs3_gxfh_epoch, {
14012
16
      "epoch", "nfs.gxfh3.epoch", FT_UINT16, BASE_HEX_DEC,
14013
16
      NULL, 0, NULL, HFILL }},
14014
14015
16
    { &hf_nfs3_gxfh_ldsid, {
14016
16
      "local dsid", "nfs.gxfh3.ldsid", FT_UINT32, BASE_HEX_DEC,
14017
16
      NULL, 0, NULL, HFILL }},
14018
14019
16
    { &hf_nfs3_gxfh_cid, {
14020
16
      "cluster id", "nfs.gxfh3.cid", FT_UINT16, BASE_HEX_DEC,
14021
16
      NULL, 0, NULL, HFILL }},
14022
14023
16
    { &hf_nfs3_gxfh_resv, {
14024
16
      "reserved", "nfs.gxfh3.reserved", FT_UINT16, BASE_HEX_DEC,
14025
16
      NULL, 0, NULL, HFILL }},
14026
14027
16
    { &hf_nfs3_gxfh_sfhflags, {
14028
16
      "flags", "nfs.gxfh3.sfhflags", FT_UINT8, BASE_HEX,
14029
16
      NULL, 0, NULL, HFILL }},
14030
14031
16
    { &hf_nfs3_gxfh_sfhflags_resv1, {
14032
16
      "reserved", "nfs.gxfh3.sfhflags.reserve1", FT_UINT8, BASE_HEX,
14033
16
      NULL, SPINNP_FH_FLAG_RESV1, NULL, HFILL }},
14034
14035
16
    { &hf_nfs3_gxfh_sfhflags_resv2, {
14036
16
      "reserved", "nfs.gxfh3.sfhflags.reserv2", FT_UINT8, BASE_HEX,
14037
16
      NULL, SPINNP_FH_FLAG_RESV2, NULL, HFILL }},
14038
14039
16
    { &hf_nfs3_gxfh_sfhflags_ontap7G, {
14040
16
      "ontap-7g", "nfs.gxfh3.sfhflags.ontap7g", FT_UINT8, BASE_HEX,
14041
16
      NULL, SPINNP_FH_FLAG_ONTAP_MASK, NULL, HFILL }},
14042
14043
16
    { &hf_nfs3_gxfh_sfhflags_ontapGX, {
14044
16
      "ontap-gx", "nfs.gxfh3.sfhflags.ontapgx", FT_UINT8, BASE_HEX,
14045
16
      NULL, SPINNP_FH_FLAG_ONTAP_MASK, NULL, HFILL }},
14046
14047
16
    { &hf_nfs3_gxfh_sfhflags_striped, {
14048
16
      "striped", "nfs.gxfh3.sfhflags.striped", FT_BOOLEAN, 8,
14049
16
      TFS(&tfs_set_notset), SPINNP_FH_FLAG_STRIPED_MASK, NULL, HFILL }},
14050
14051
16
    { &hf_nfs3_gxfh_sfhflags_empty, {
14052
16
      "empty", "nfs.gxfh3.sfhflags.empty", FT_BOOLEAN, 8,
14053
16
      TFS(&tfs_set_notset), SPINNP_FH_FLAG_EMPTY_MASK, NULL, HFILL }},
14054
14055
16
    { &hf_nfs3_gxfh_sfhflags_snapdirent, {
14056
16
      "snap dir ent", "nfs.gxfh3.sfhflags.snapdirent", FT_BOOLEAN, 8,
14057
16
      TFS(&tfs_set_notset), SPINNP_FH_FLAG_SNAPDIR_ENT_MASK, NULL, HFILL }},
14058
14059
16
    { &hf_nfs3_gxfh_sfhflags_snapdir, {
14060
16
      "snap dir", "nfs.gxfh3.sfhflags.snapdir", FT_BOOLEAN, 8,
14061
16
      TFS(&tfs_set_notset), SPINNP_FH_FLAG_SNAPDIR_MASK, NULL, HFILL }},
14062
14063
16
    { &hf_nfs3_gxfh_sfhflags_streamdir, {
14064
16
      "stream dir", "nfs.gxfh3.sfhflags.streamdir", FT_BOOLEAN, 8,
14065
16
      TFS(&tfs_set_notset), SPINNP_FH_FLAG_STREAMDIR_MASK, NULL, HFILL }},
14066
14067
16
    { &hf_nfs3_gxfh_spinfid, {
14068
16
      "spin file id", "nfs.gxfh3.spinfid", FT_UINT32, BASE_HEX_DEC,
14069
16
      NULL, 0, NULL, HFILL }},
14070
14071
16
    { &hf_nfs3_gxfh_spinfuid, {
14072
16
      "spin file unique id", "nfs.gxfh3.spinfuid", FT_UINT32, BASE_HEX_DEC,
14073
16
      NULL, 0, NULL, HFILL }},
14074
14075
16
    { &hf_nfs3_gxfh_exportptid, {
14076
16
      "export point id", "nfs.gxfh3.exportptid", FT_UINT32, BASE_HEX_DEC,
14077
16
      NULL, 0, NULL, HFILL }},
14078
14079
16
    { &hf_nfs3_gxfh_exportptuid, {
14080
16
      "export point unique id", "nfs.gxfh3.exportptuid", FT_UINT32, BASE_HEX_DEC,
14081
16
      NULL, 0, NULL, HFILL }},
14082
14083
16
    { &hf_nfs3_verifier, {
14084
16
      "Verifier", "nfs.verifier", FT_BYTES, BASE_NONE,
14085
16
      NULL, 0, NULL, HFILL }},
14086
14087
16
    { &hf_nfs3_specdata1, {
14088
16
      "specdata1", "nfs.specdata1", FT_UINT32, BASE_DEC,
14089
16
      NULL, 0, NULL, HFILL }},
14090
14091
16
    { &hf_nfs3_specdata2, {
14092
16
      "specdata2", "nfs.specdata2", FT_UINT32, BASE_DEC,
14093
16
      NULL, 0, NULL, HFILL }},
14094
14095
16
    { &hf_nfs3_attributes_follow, {
14096
16
      "attributes_follow", "nfs.attributes_follow", FT_UINT32, BASE_DEC,
14097
16
      VALS(value_follows), 0, NULL, HFILL }},
14098
14099
16
    { &hf_nfs3_handle_follow, {
14100
16
      "handle_follow", "nfs.handle_follow", FT_UINT32, BASE_DEC,
14101
16
      VALS(value_follows), 0, NULL, HFILL }},
14102
14103
16
    { &hf_nfs3_sattrguard3, {
14104
16
      "check", "nfs.sattrguard3", FT_UINT32, BASE_DEC,
14105
16
      VALS(value_follows), 0, NULL, HFILL }},
14106
14107
16
    { &hf_nfs4_length_minlength, {
14108
16
      "min length", "nfs.minlength4", FT_UINT64, BASE_DEC,
14109
16
      NULL, 0, NULL, HFILL }},
14110
14111
16
    { &hf_nfs4_layout_type, {
14112
16
      "layout type", "nfs.layouttype", FT_UINT32, BASE_DEC,
14113
16
      VALS(layouttype_names), 0, NULL, HFILL }},
14114
14115
16
    { &hf_nfs4_layout_return_type, {
14116
16
      "return type", "nfs.returntype", FT_UINT32, BASE_DEC,
14117
16
      VALS(layoutreturn_names), 0, NULL, HFILL }},
14118
14119
16
    { &hf_nfs4_lrf_body_content, {
14120
16
      "lrf_body_content", "nfs.lrf_body_content", FT_BYTES, BASE_NONE,
14121
16
      NULL, 0, NULL, HFILL }},
14122
14123
16
    { &hf_nfs4_iomode, {
14124
16
      "IO mode", "nfs.iomode", FT_UINT32, BASE_DEC,
14125
16
      VALS(iomode_names), 0, NULL, HFILL }},
14126
14127
#if 0
14128
    { &hf_nfs4_stripetype, {
14129
      "stripe type", "nfs.stripetype", FT_UINT32, BASE_DEC,
14130
      VALS(stripetype_names), 0, NULL, HFILL }},
14131
#endif
14132
14133
16
    { &hf_nfs4_stripeunit, {
14134
16
      "stripe unit", "nfs.stripeunit", FT_UINT64, BASE_DEC,
14135
16
      NULL, 0, NULL, HFILL }},
14136
14137
#if 0
14138
    { &hf_nfs4_util, {
14139
      "util", "nfs.util", FT_UINT32, BASE_DEC,
14140
      NULL, 0, NULL, HFILL }},
14141
#endif
14142
14143
#if 0
14144
    { &hf_nfs4_first_stripe_idx, {
14145
      "first stripe index", "nfs.stripeindex", FT_UINT32, BASE_DEC,
14146
      NULL, 0, NULL, HFILL }},
14147
#endif
14148
14149
#if 0
14150
    { &hf_nfs4_pattern_offset, {
14151
      "layout pattern offset", "nfs.patternoffset", FT_UINT64, BASE_DEC,
14152
      NULL, 0, NULL, HFILL }},
14153
#endif
14154
14155
16
    { &hf_nfs4_notify_mask, {
14156
16
      "notify_mask", "nfs.notify_mask", FT_UINT32, BASE_HEX,
14157
16
      NULL, 0, NULL, HFILL }},
14158
14159
16
    { &hf_nfs4_notify_type, {
14160
16
      "notify_type", "nfs.notify_type", FT_UINT32,
14161
16
      BASE_DEC | BASE_EXT_STRING, &notify_type4_ext, 0, NULL, HFILL }},
14162
14163
16
    { &hf_nfs4_notify_deviceid_mask, {
14164
16
      "notify_deviceid_mask", "nfs.notify_deviceid_mask", FT_UINT32, BASE_HEX,
14165
16
      NULL, 0, NULL, HFILL }},
14166
14167
16
    { &hf_nfs4_notify_deviceid_type, {
14168
16
      "notify_deviceid_type", "nfs.notify_deviceid_type", FT_UINT32,
14169
16
      BASE_DEC | BASE_EXT_STRING, &notify_deviceid_type4_ext, 0, NULL, HFILL }},
14170
14171
16
    { &hf_nfs4_newtime, {
14172
16
      "new time?", "nfs.newtime", FT_BOOLEAN, BASE_NONE,
14173
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14174
14175
16
    { &hf_nfs4_newoffset, {
14176
16
      "new offset?", "nfs.newoffset", FT_BOOLEAN, BASE_NONE,
14177
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14178
14179
16
    { &hf_nfs4_newsize, {
14180
16
      "new size?", "nfs.newsize", FT_BOOLEAN, BASE_NONE,
14181
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14182
14183
16
    { &hf_nfs4_layout_avail, {
14184
16
      "layout available?", "nfs.layoutavail", FT_BOOLEAN, BASE_NONE,
14185
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14186
14187
#if 0
14188
    { &hf_nfs4_mdscommit, {
14189
      "MDS commit?", "nfs.mdscommit", FT_BOOLEAN, BASE_NONE,
14190
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14191
#endif
14192
14193
16
    { &hf_nfs4_layoutupdate, {
14194
16
      "layout update", "nfs.layoutupdate", FT_BYTES, BASE_NONE,
14195
16
      NULL, 0, NULL, HFILL }},
14196
14197
16
    { &hf_nfs4_deviceid, {
14198
16
      "device ID", "nfs.deviceid", FT_BYTES, BASE_NONE,
14199
16
      NULL, 0, NULL, HFILL }},
14200
14201
16
    { &hf_nfs4_devicenum, {
14202
16
      "num devices", "nfs.devicenum4", FT_UINT32, BASE_DEC,
14203
16
      NULL, 0, NULL, HFILL }},
14204
14205
16
    { &hf_nfs4_deviceidx, {
14206
16
      "device index", "nfs.deviceidx", FT_UINT32, BASE_DEC,
14207
16
      NULL, 0, NULL, HFILL }},
14208
14209
16
    { &hf_nfs4_layout, {
14210
16
      "layout", "nfs.layout", FT_BYTES, BASE_NONE,
14211
16
      NULL, 0, NULL, HFILL }},
14212
14213
#if 0
14214
    { &hf_nfs4_layout_count, {
14215
      "layout", "nfs.layoutcount", FT_UINT32, BASE_DEC,
14216
      NULL, 0, "layout count", HFILL }},
14217
#endif
14218
14219
14220
#if 0
14221
    { &hf_nfs4_stripedevs, {
14222
      "stripe devs", "nfs.stripedevs", FT_UINT32, BASE_DEC,
14223
      NULL, 0, NULL, HFILL }},
14224
#endif
14225
14226
#if 0
14227
    { &hf_nfs4_devaddr, {
14228
      "device addr", "nfs.devaddr", FT_BYTES, BASE_NONE,
14229
      NULL, 0, NULL, HFILL }},
14230
#endif
14231
14232
16
    { &hf_nfs4_devaddr_ssv_start, {
14233
16
      "slice start", "nfs.devaddr.ssv_start", FT_UINT64, BASE_DEC,
14234
16
      NULL, 0, NULL, HFILL }},
14235
14236
16
    { &hf_nfs4_devaddr_ssv_length, {
14237
16
      "slice length", "nfs.devaddr.ssv_length", FT_UINT64, BASE_DEC,
14238
16
      NULL, 0, NULL, HFILL }},
14239
14240
16
    { &hf_nfs4_devaddr_scsi_vol_type, {
14241
16
      "SCSI volume type", "nfs.devaddr.scsi_volume_type", FT_UINT32, BASE_DEC,
14242
16
      VALS(scsi_vol_type_names), 0, NULL, HFILL }},
14243
14244
16
    { &hf_nfs4_devaddr_scsi_vol_index, {
14245
16
      "volume index", "nfs.devaddr.scsi_volume_index", FT_UINT32, BASE_DEC,
14246
16
      NULL, 0, NULL, HFILL }},
14247
14248
16
    { &hf_nfs4_devaddr_scsi_vol_ref_index, {
14249
16
      "volume index ref", "nfs.devaddr.scsi_volume_ref_index", FT_UINT32, BASE_DEC,
14250
16
      NULL, 0, NULL, HFILL }},
14251
14252
16
    { &hf_nfs4_devaddr_ssv_stripe_unit, {
14253
16
      "stripe size", "nfs.devaddr.ssv_stripe_unit", FT_UINT64, BASE_DEC,
14254
16
      NULL, 0, NULL, HFILL }},
14255
14256
16
    { &hf_nfs4_devaddr_scsi_vpd_code_set, {
14257
16
      "VPD code set", "nfs.devaddr.scsi_vpd_code_set", FT_UINT32, BASE_DEC,
14258
16
      VALS(scsi_vpd_code_set_names), 0, NULL, HFILL }},
14259
14260
16
    { &hf_nfs4_devaddr_scsi_vpd_designator_type, {
14261
16
      "VPD designator type", "nfs.devaddr.scsi_vpd_designator_type", FT_UINT32, BASE_DEC,
14262
16
      VALS(scsi_vpd_designator_type_names), 0, NULL, HFILL }},
14263
14264
16
    { &hf_nfs4_devaddr_scsi_vpd_designator, {
14265
16
      "VPD designator", "nfs.devaddr.scsi_vpd_designator",
14266
16
      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
14267
14268
16
    { &hf_nfs4_devaddr_scsi_private_key, {
14269
16
      "private key", "nfs.devaddr.scsi_private_key",
14270
16
      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
14271
14272
16
    { &hf_nfs4_scsil_ext_file_offset, {
14273
16
      "file offset", "nfs.scsil_ext_file_offset", FT_UINT64, BASE_DEC,
14274
16
      NULL, 0, NULL, HFILL }},
14275
14276
16
    { &hf_nfs4_scsil_ext_length, {
14277
16
      "length", "nfs.scsil_ext_length", FT_UINT64, BASE_DEC,
14278
16
      NULL, 0, NULL, HFILL }},
14279
14280
16
    { &hf_nfs4_scsil_ext_vol_offset, {
14281
16
      "volume offset", "nfs.scsill_ext_vol_offset", FT_UINT64, BASE_DEC,
14282
16
      NULL, 0, NULL, HFILL }},
14283
14284
16
    { &hf_nfs4_scsil_ext_state, {
14285
16
      "extent state", "nfs.scsil_ext_state", FT_UINT32, BASE_DEC,
14286
16
      VALS(scsi_extent_state_names), 0, NULL, HFILL }},
14287
14288
16
    { &hf_nfs4_return_on_close, {
14289
16
      "return on close?", "nfs.retclose4", FT_BOOLEAN, BASE_NONE,
14290
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14291
14292
16
    { &hf_nfs4_nfl_mirrors, {
14293
16
      "Mirror", "nfs.nfl_mirrors", FT_UINT32, BASE_DEC,
14294
16
      NULL, 0, NULL, HFILL }},
14295
14296
16
    { &hf_nfs4_nfl_util, {
14297
16
      "nfl_util", "nfs.nfl_util", FT_UINT32, BASE_HEX,
14298
16
      NULL, 0, NULL, HFILL }},
14299
14300
16
    { &hf_nfs4_nfl_util_stripe_size, {
14301
16
      "stripe size", "nfs.nfl_util.stripe_size", FT_UINT32, BASE_DEC,
14302
16
      NULL, 0, NULL, HFILL }},
14303
14304
16
    { &hf_nfs4_nfl_util_commit_thru_mds, {
14305
16
      "commit thru mds", "nfs.nfl_util.commit_thru_mds", FT_UINT32, BASE_DEC,
14306
16
      NULL, 0, NULL, HFILL }},
14307
14308
16
    { &hf_nfs4_nfl_util_dense, {
14309
16
      "dense layout", "nfs.nfl_util.dense", FT_UINT32, BASE_DEC,
14310
16
      NULL, 0, NULL, HFILL }},
14311
14312
16
    { &hf_nfs4_nfl_fhs, {
14313
16
      "file handles", "nfs.nfl_fhs", FT_UINT32, BASE_HEX,
14314
16
      NULL, 0, NULL, HFILL }},
14315
14316
16
    { &hf_nfs4_mirror_eff, {
14317
16
      "mirror efficiency", "nfs.nff_mirror_eff", FT_UINT32, BASE_HEX,
14318
16
      NULL, 0, NULL, HFILL }},
14319
14320
16
    { &hf_nfs4_nfl_first_stripe_index, {
14321
16
      "first stripe to use index", "nfs.nfl_first_stripe_index", FT_UINT32, BASE_DEC,
14322
16
      NULL, 0, NULL, HFILL }},
14323
14324
16
    { &hf_nfs4_slotid, {
14325
16
      "slot id", "nfs.slotid", FT_UINT32, BASE_DEC,
14326
16
      NULL, 0, NULL, HFILL }},
14327
14328
16
    { &hf_nfs4_high_slotid, {
14329
16
      "high slot id", "nfs.high_slotid", FT_UINT32, BASE_DEC,
14330
16
      NULL, 0, NULL, HFILL }},
14331
16
    { &hf_nfs4_target_high_slotid, {
14332
16
      "target high slot id", "nfs.target_high_slotid", FT_UINT32, BASE_DEC,
14333
16
      NULL, 0, NULL, HFILL }},
14334
14335
16
    { &hf_nfs4_serverscope4, {
14336
16
      "server scope", "nfs.scope", FT_BYTES, BASE_NONE,
14337
16
      NULL, 0, NULL, HFILL }},
14338
14339
16
    { &hf_nfs4_minorid, {
14340
16
      "minor ID", "nfs.minorid4", FT_UINT64, BASE_DEC,
14341
16
      NULL, 0, NULL, HFILL }},
14342
14343
16
    { &hf_nfs4_majorid, {
14344
16
      "major ID", "nfs.majorid4", FT_BYTES, BASE_NONE,
14345
16
      NULL, 0, NULL, HFILL }},
14346
14347
16
    { &hf_nfs4_padsize, {
14348
16
      "hdr pad size", "nfs.padsize4", FT_UINT32, BASE_DEC,
14349
16
      NULL, 0, NULL, HFILL }},
14350
14351
#if 0
14352
    { &hf_nfs4_cbrenforce, {
14353
      "binding enforce?", "nfs.cbrenforce4", FT_BOOLEAN, BASE_NONE,
14354
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14355
#endif
14356
14357
#if 0
14358
    { &hf_nfs4_hashalg, {
14359
      "hash alg", "nfs.hashalg4", FT_UINT32, BASE_DEC,
14360
      NULL, 0, NULL, HFILL }},
14361
#endif
14362
14363
#if 0
14364
    { &hf_nfs4_ssvlen, {
14365
      "ssv len", "nfs.ssvlen4", FT_UINT32, BASE_DEC,
14366
      NULL, 0, NULL, HFILL }},
14367
#endif
14368
14369
16
    { &hf_nfs4_maxreqsize, {
14370
16
      "max req size", "nfs.maxreqsize4", FT_UINT32, BASE_DEC,
14371
16
      NULL, 0, NULL, HFILL }},
14372
14373
16
    { &hf_nfs4_maxrespsize, {
14374
16
      "max resp size", "nfs.maxrespsize4", FT_UINT32, BASE_DEC,
14375
16
      NULL, 0, NULL, HFILL }},
14376
14377
16
    { &hf_nfs4_maxrespsizecached, {
14378
16
      "max resp size cached", "nfs.maxrespsizecached4", FT_UINT32, BASE_DEC,
14379
16
      NULL, 0, NULL, HFILL }},
14380
14381
16
    { &hf_nfs4_maxops, {
14382
16
      "max ops", "nfs.maxops4", FT_UINT32, BASE_DEC,
14383
16
      NULL, 0, NULL, HFILL }},
14384
14385
16
    { &hf_nfs4_maxreqs, {
14386
16
      "max reqs", "nfs.maxreqs4", FT_UINT32, BASE_DEC,
14387
16
      NULL, 0, NULL, HFILL }},
14388
14389
16
    { &hf_nfs4_rdmachanattrs, {
14390
16
      "RDMA chan attrs", "nfs.rdmachanattrs4", FT_UINT32, BASE_DEC,
14391
16
      NULL, 0, NULL, HFILL }},
14392
14393
16
    { &hf_nfs4_machinename, {
14394
16
      "machine name", "nfs.machinename4", FT_STRING, BASE_NONE,
14395
16
      NULL, 0, NULL, HFILL }},
14396
14397
16
    { &hf_nfs4_flavor, {
14398
16
      "flavor", "nfs.flavor4", FT_UINT32, BASE_DEC,
14399
16
      VALS(rpc_auth_flavor), 0, NULL, HFILL }},
14400
14401
16
    { &hf_nfs4_stamp, {
14402
16
      "stamp", "nfs.stamp4", FT_UINT32, BASE_HEX,
14403
16
      NULL, 0, NULL, HFILL }},
14404
14405
16
    { &hf_nfs4_uid, {
14406
16
      "uid", "nfs.uid4", FT_UINT32, BASE_DEC,
14407
16
      NULL, 0, NULL, HFILL }},
14408
14409
16
    { &hf_nfs4_gid, {
14410
16
      "gid", "nfs.gid4", FT_UINT32, BASE_DEC,
14411
16
      NULL, 0, NULL, HFILL }},
14412
14413
16
    { &hf_nfs4_service, {
14414
16
      "service", "nfs.service4", FT_UINT32, BASE_DEC,
14415
16
      VALS(rpc_authgss_svc), 0, NULL, HFILL }},
14416
14417
16
    { &hf_nfs_access_check,
14418
16
      { "Check access", "nfs.access_check",
14419
16
      FT_UINT32, BASE_HEX,
14420
16
      NULL, 0x0,
14421
16
      "Access type(s) to be checked", HFILL }
14422
16
    },
14423
16
    { &hf_nfs_access_supported,
14424
16
      { "Supported types (of requested)", "nfs.access_supported",
14425
16
      FT_UINT32, BASE_HEX,
14426
16
      NULL, 0x0,
14427
16
      "Access types (of those requested) that the server can reliably verify", HFILL }
14428
16
    },
14429
16
    { &hf_nfs_access_rights,
14430
16
      { "Access rights (of requested)", "nfs.access_rights",
14431
16
      FT_UINT32, BASE_HEX,
14432
16
      NULL, 0x0,
14433
16
      "Access rights for the types requested", HFILL }
14434
16
    },
14435
16
    { &hf_nfs_access_supp_read,
14436
16
      { "0x001 READ", "nfs.access_supp_read",
14437
16
      FT_BOOLEAN, 32,
14438
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_READ,
14439
16
      NULL, HFILL }
14440
16
    },
14441
16
    { &hf_nfs_access_supp_lookup,
14442
16
      { "0x002 LOOKUP", "nfs.access_supp_lookup",
14443
16
      FT_BOOLEAN, 32,
14444
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_LOOKUP,
14445
16
      NULL, HFILL }
14446
16
    },
14447
16
    { &hf_nfs_access_supp_modify,
14448
16
      { "0x004 MODIFY", "nfs.access_supp_modify",
14449
16
      FT_BOOLEAN, 32,
14450
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_MODIFY,
14451
16
      NULL, HFILL }
14452
16
    },
14453
16
    { &hf_nfs_access_supp_extend,
14454
16
      { "0x008 EXTEND", "nfs.access_supp_extend",
14455
16
      FT_BOOLEAN, 32,
14456
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_EXTEND,
14457
16
      NULL, HFILL }
14458
16
    },
14459
16
    { &hf_nfs_access_supp_delete,
14460
16
      { "0x010 DELETE", "nfs.access_supp_delete",
14461
16
      FT_BOOLEAN, 32,
14462
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_DELETE,
14463
16
      NULL, HFILL }
14464
16
    },
14465
16
    { &hf_nfs_access_supp_execute,
14466
16
      { "0x020 EXECUTE", "nfs.access_supp_execute",
14467
16
      FT_BOOLEAN, 32,
14468
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_EXECUTE,
14469
16
      NULL, HFILL }
14470
16
    },
14471
16
    { &hf_nfs_access_supp_xattr_read,
14472
16
      { "0x040 XATTR READ", "nfs.access_supp_xattr_read",
14473
16
      FT_BOOLEAN, 32,
14474
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_READ,
14475
16
      NULL, HFILL }
14476
16
    },
14477
16
    { &hf_nfs_access_supp_xattr_write,
14478
16
      { "0x080 XATTR WRITE", "nfs.access_supp_xattr_write",
14479
16
      FT_BOOLEAN, 32,
14480
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_WRITE,
14481
16
      NULL, HFILL }
14482
16
    },
14483
16
    { &hf_nfs_access_supp_xattr_list,
14484
16
      { "0x100 XATTR LIST", "nfs.access_supp_xattr_list",
14485
16
      FT_BOOLEAN, 32,
14486
16
      TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_LIST,
14487
16
      NULL, HFILL }
14488
16
    },
14489
16
    { &hf_nfs_access_read,
14490
16
      { "0x001 READ", "nfs.access_read",
14491
16
      FT_BOOLEAN, 32,
14492
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_READ,
14493
16
      NULL, HFILL }
14494
16
    },
14495
16
    { &hf_nfs_access_lookup,
14496
16
      { "0x002 LOOKUP", "nfs.access_lookup",
14497
16
      FT_BOOLEAN, 32,
14498
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_LOOKUP,
14499
16
      NULL, HFILL }
14500
16
    },
14501
16
    { &hf_nfs_access_modify,
14502
16
      { "0x004 MODIFY", "nfs.access_modify",
14503
16
      FT_BOOLEAN, 32,
14504
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_MODIFY,
14505
16
      NULL, HFILL }
14506
16
    },
14507
16
    { &hf_nfs_access_extend,
14508
16
      { "0x008 EXTEND", "nfs.access_extend",
14509
16
      FT_BOOLEAN, 32,
14510
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_EXTEND,
14511
16
      NULL, HFILL }
14512
16
    },
14513
16
    { &hf_nfs_access_delete,
14514
16
      { "0x010 DELETE", "nfs.access_delete",
14515
16
      FT_BOOLEAN, 32,
14516
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_DELETE,
14517
16
      NULL, HFILL }
14518
16
    },
14519
16
    { &hf_nfs_access_execute,
14520
16
      { "0x020 EXECUTE", "nfs.access_execute",
14521
16
      FT_BOOLEAN, 32,
14522
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_EXECUTE,
14523
16
      NULL, HFILL }
14524
16
    },
14525
16
    { &hf_nfs_access_xattr_read,
14526
16
      { "0x040 XATTR READ", "nfs.access_xattr_read",
14527
16
      FT_BOOLEAN, 32,
14528
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_READ,
14529
16
      NULL, HFILL }
14530
16
    },
14531
16
    { &hf_nfs_access_xattr_write,
14532
16
      { "0x080 XATTR WRITE", "nfs.access_xattr_write",
14533
16
      FT_BOOLEAN, 32,
14534
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_WRITE,
14535
16
      NULL, HFILL }
14536
16
    },
14537
16
    { &hf_nfs_access_xattr_list,
14538
16
      { "0x100 XATTR LIST", "nfs.access_xattr_list",
14539
16
      FT_BOOLEAN, 32,
14540
16
      TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_LIST,
14541
16
      NULL, HFILL }
14542
16
    },
14543
16
    { &hf_nfs_access_denied,
14544
16
      { "Access Denied", "nfs.access_denied",
14545
16
      FT_BOOLEAN, BASE_NONE,
14546
16
      NULL, 0x0,
14547
16
      "True if access has been denied to one or more of the requested types", HFILL }
14548
16
    },
14549
16
    { &hf_nfs4_sessionid, {
14550
16
      "sessionid", "nfs.session_id4", FT_BYTES, BASE_NONE,
14551
16
      NULL, 0, NULL, HFILL }},
14552
16
    { &hf_nfs4_exchid_call_flags, {
14553
16
      "flags", "nfs.exchange_id.call_flags", FT_UINT32, BASE_HEX,
14554
16
      NULL, 0, NULL, HFILL}},
14555
16
    { &hf_nfs4_exchid_reply_flags, {
14556
16
      "flags", "nfs.exchange_id.reply_flags", FT_UINT32, BASE_HEX,
14557
16
      NULL, 0, NULL, HFILL}},
14558
16
    { &hf_nfs4_exchid_flags_moved_refer, {
14559
16
      "EXCHGID4_FLAG_SUPP_MOVED_REFER", "nfs.exchange_id.flags.moved_refer", FT_BOOLEAN, 32,
14560
16
      TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
14561
16
    { &hf_nfs4_exchid_flags_moved_migr, {
14562
16
      "EXCHGID4_FLAG_SUPP_MOVED_MIGR", "nfs.exchange_id.flags.moved_migr", FT_BOOLEAN, 32,
14563
16
      TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
14564
16
    { &hf_nfs4_exchid_flags_bind_princ, {
14565
16
      "EXCHGID4_FLAG_BIND_PRINC_STATEID", "nfs.exchange_id.flags.bind_princ", FT_BOOLEAN, 32,
14566
16
      TFS(&tfs_set_notset), 0x00000100, NULL, HFILL}},
14567
16
    { &hf_nfs4_exchid_flags_non_pnfs, {
14568
16
      "EXCHGID4_FLAG_USE_NON_PNFS", "nfs.exchange_id.flags.non_pnfs", FT_BOOLEAN, 32,
14569
16
      TFS(&tfs_set_notset), 0x00010000, NULL, HFILL}},
14570
16
    { &hf_nfs4_exchid_flags_pnfs_mds, {
14571
16
      "EXCHGID4_FLAG_USE_PNFS_MDS", "nfs.exchange_id.flags.pnfs_mds", FT_BOOLEAN, 32,
14572
16
      TFS(&tfs_set_notset), 0x00020000, NULL, HFILL}},
14573
16
    { &hf_nfs4_exchid_flags_pnfs_ds, {
14574
16
      "EXCHGID4_FLAG_USE_PNFS_DS", "nfs.exchange_id.flags.pnfs_ds", FT_BOOLEAN, 32,
14575
16
      TFS(&tfs_set_notset), 0x00040000, NULL, HFILL}},
14576
16
    { &hf_nfs4_exchid_flags_upd_conf_rec_a, {
14577
16
      "EXCHGID4_FLAG_UPD_CONFIRMED_REC_A", "nfs.exchange_id.flags.confirmed_rec_a",
14578
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x40000000, NULL, HFILL}},
14579
16
    { &hf_nfs4_exchid_flags_confirmed_r, {
14580
16
      "EXCHGID4_FLAG_CONFIRMED_R", "nfs.exchange_id.flags.confirmed_r", FT_BOOLEAN, 32,
14581
16
      TFS(&tfs_set_notset), 0x80000000, NULL, HFILL}},
14582
16
    { &hf_nfs4_sp_parms_hash_algs, {
14583
16
      "State Protect hash algorithms", "nfs.sp_parms4_hash_algs", FT_NONE, BASE_NONE,
14584
16
      NULL, 0, NULL, HFILL }},
14585
16
    { &hf_nfs4_sp_parms_encr_algs, {
14586
16
      "State Protect encryption algorithms", "nfs.sp_parms4_encr_algs", FT_NONE, BASE_NONE,
14587
16
      NULL, 0, NULL, HFILL }},
14588
16
    { &hf_nfs4_prot_info_hash_alg, {
14589
16
      "Prot Info hash algorithm", "nfs.prot_info4_hash_alg", FT_UINT32, BASE_HEX,
14590
16
      NULL, 0, NULL, HFILL }},
14591
16
    { &hf_nfs4_prot_info_encr_alg, {
14592
16
      "Prot Info encryption algorithm", "nfs.prot_info4_encr_alg", FT_UINT32, BASE_HEX,
14593
16
      NULL, 0, NULL, HFILL }},
14594
16
    { &hf_nfs4_prot_info_svv_length, {
14595
16
      "Prot Info svv_length", "nfs.prot_info4_svv_length", FT_UINT32, BASE_HEX,
14596
16
      NULL, 0, NULL, HFILL }},
14597
16
    { &hf_nfs4_prot_info_spi_window, {
14598
16
      "Prot Info spi window", "nfs.prot_info4_spi_window", FT_UINT32, BASE_HEX,
14599
16
      NULL, 0, NULL, HFILL }},
14600
16
    { &hf_nfs4_state_protect_window, {
14601
16
      "State Protect window", "nfs.state_protect_window", FT_UINT32, BASE_HEX,
14602
16
      NULL, 0, NULL, HFILL }},
14603
16
    { &hf_nfs4_state_protect_num_gss_handles, {
14604
16
      "State Protect num gss handles", "nfs.state_protect_num_gss_handles", FT_UINT32, BASE_HEX,
14605
16
      NULL, 0, NULL, HFILL }},
14606
16
    { &hf_nfs4_nii_domain, {
14607
16
      "Implementor DNS domain name(nii_domain)", "nfs.nii_domain4", FT_STRING, BASE_NONE,
14608
16
      NULL, 0, NULL, HFILL }},
14609
16
    { &hf_nfs4_nii_name, {
14610
16
      "Implementation product name(nii_name)", "nfs.nii_name4", FT_STRING, BASE_NONE,
14611
16
      NULL, 0, NULL, HFILL }},
14612
16
    { &hf_nfs4_create_session_flags_csa, {
14613
16
      "csa_flags", "nfs.create_session_flags", FT_UINT32, BASE_HEX,
14614
16
      NULL, 0, NULL, HFILL }},
14615
16
    { &hf_nfs4_create_session_flags_csr, {
14616
16
      "csr_flags", "nfs.create_session_flags", FT_UINT32, BASE_HEX,
14617
16
      NULL, 0, NULL, HFILL }},
14618
16
    { &hf_nfs4_create_session_flags_persist, {
14619
16
      "CREATE_SESSION4_FLAG_PERSIST", "nfs.create_session.flags.persist", FT_BOOLEAN, 32,
14620
16
      TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
14621
16
    { &hf_nfs4_create_session_flags_conn_back_chan, {
14622
16
      "CREATE_SESSION4_FLAG_CONN_BACK_CHAN", "nfs.create_session.flags.conn_back_chan",
14623
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
14624
16
    { &hf_nfs4_create_session_flags_conn_rdma, {
14625
16
      "CREATE_SESSION4_FLAG_CONN_RDMA", "nfs.create_session.flags.conn_rdma",
14626
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000004, NULL, HFILL}},
14627
16
    { &hf_nfs4_cachethis, {
14628
16
      "cache this?", "nfs.cachethis4", FT_BOOLEAN, BASE_NONE,
14629
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14630
16
    { &hf_nfs4_reclaim_one_fs, {
14631
16
      "reclaim one fs?", "nfs.reclaim_one_fs4", FT_BOOLEAN,
14632
16
      BASE_NONE, TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14633
16
    { &hf_nfs4_cb_procedure, {
14634
16
       "CB Procedure", "nfs.cb_procedure", FT_UINT32, BASE_DEC,
14635
16
      VALS(nfs_cb_proc_vals), 0, NULL, HFILL }},
14636
16
    { &hf_nfs4_cb_op, {
14637
16
        "Opcode", "nfs.cb.operation", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
14638
16
        &names_nfs_cb_operation_ext, 0, NULL, HFILL }},
14639
16
    { &hf_nfs4_lrs_present, {
14640
16
      "StateID present?", "nfs.lrs_present", FT_BOOLEAN, BASE_NONE,
14641
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14642
16
    { &hf_nfs4_cb_truncate, {
14643
16
        "Truncate?", "nfs.truncate", FT_BOOLEAN, BASE_NONE,
14644
16
        TFS(&tfs_yes_no), 0, NULL, HFILL }},
14645
16
    { &hf_nfs4_cb_layoutrecall_type, {
14646
16
      "recall type", "nfs.recalltype", FT_UINT32, BASE_DEC,
14647
16
      VALS(layoutrecall_names), 0, NULL, HFILL }},
14648
16
    { &hf_nfs4_cb_clorachanged, {
14649
16
      "Clora changed", "nfs.clorachanged", FT_BOOLEAN, BASE_NONE,
14650
16
      TFS(&tfs_yes_no), 0, NULL, HFILL }},
14651
14652
16
    { &hf_nfs4_bctsa_dir, {
14653
16
      "bctsa_dir", "nfs.bctsa_dir", FT_UINT32, BASE_HEX,
14654
16
      VALS(names_channel_dir_from_client), 0, NULL, HFILL }},
14655
16
    { &hf_nfs4_bctsa_use_conn_in_rdma_mode, {
14656
16
      "bctsa_use_conn_in_rdma_mode", "nfs.bctsa_use_conn_in_rdma_mode", FT_BOOLEAN, BASE_NONE,
14657
16
      NULL, 0, NULL, HFILL }},
14658
16
    { &hf_nfs4_bctsr_dir, {
14659
16
      "bctsr_dir", "nfs.bctsr_dir", FT_UINT32, BASE_HEX,
14660
16
      VALS(names_channel_dir_from_server), 0, NULL, HFILL }},
14661
16
    { &hf_nfs4_bctsr_use_conn_in_rdma_mode, {
14662
16
      "bctsr_use_conn_in_rdma_mode", "nfs.bctsr_use_conn_in_rdma_mode", FT_BOOLEAN, BASE_NONE,
14663
16
      NULL, 0, NULL, HFILL }},
14664
14665
16
    { &hf_nfs3_mode, {
14666
16
      "Mode", "nfs.mode3", FT_UINT32, BASE_OCT,
14667
16
      NULL, 0, NULL, HFILL }},
14668
14669
16
    { &hf_nfs3_mode_suid, {
14670
16
      "S_ISUID", "nfs.mode3.suid", FT_BOOLEAN, 32,
14671
16
      TFS(&tfs_yes_no), 0x00000800, NULL, HFILL }},
14672
14673
16
    { &hf_nfs3_mode_sgid, {
14674
16
      "S_ISGID", "nfs.mode3.sgid", FT_BOOLEAN, 32,
14675
16
      TFS(&tfs_yes_no), 0x00000400, NULL, HFILL }},
14676
14677
16
    { &hf_nfs3_mode_sticky, {
14678
16
      "S_ISVTX", "nfs.mode3.sticky", FT_BOOLEAN, 32,
14679
16
      TFS(&tfs_yes_no), 0x00000200, NULL, HFILL }},
14680
14681
16
    { &hf_nfs3_mode_rusr, {
14682
16
      "S_IRUSR", "nfs.mode3.rusr", FT_BOOLEAN, 32,
14683
16
      TFS(&tfs_yes_no), 0x00000100, NULL, HFILL }},
14684
14685
16
    { &hf_nfs3_mode_wusr, {
14686
16
      "S_IWUSR", "nfs.mode3.wusr", FT_BOOLEAN, 32,
14687
16
      TFS(&tfs_yes_no), 0x00000080, NULL, HFILL }},
14688
14689
16
    { &hf_nfs3_mode_xusr, {
14690
16
      "S_IXUSR", "nfs.mode3.xusr", FT_BOOLEAN, 32,
14691
16
      TFS(&tfs_yes_no), 0x00000040, NULL, HFILL }},
14692
14693
16
    { &hf_nfs3_mode_rgrp, {
14694
16
      "S_IRGRP", "nfs.mode3.rgrp", FT_BOOLEAN, 32,
14695
16
      TFS(&tfs_yes_no), 0x00000020, NULL, HFILL }},
14696
14697
16
    { &hf_nfs3_mode_wgrp, {
14698
16
      "S_IWGRP", "nfs.mode3.wgrp", FT_BOOLEAN, 32,
14699
16
      TFS(&tfs_yes_no), 0x00000010, NULL, HFILL }},
14700
14701
16
    { &hf_nfs3_mode_xgrp, {
14702
16
      "S_IXGRP", "nfs.mode3.xgrp", FT_BOOLEAN, 32,
14703
16
      TFS(&tfs_yes_no), 0x00000008, NULL, HFILL }},
14704
14705
16
    { &hf_nfs3_mode_roth, {
14706
16
      "S_IROTH", "nfs.mode3.roth", FT_BOOLEAN, 32,
14707
16
      TFS(&tfs_yes_no), 0x00000004, NULL, HFILL }},
14708
14709
16
    { &hf_nfs3_mode_woth, {
14710
16
      "S_IWOTH", "nfs.mode3.woth", FT_BOOLEAN, 32,
14711
16
      TFS(&tfs_yes_no), 0x00000002, NULL, HFILL }},
14712
14713
16
    { &hf_nfs3_mode_xoth, {
14714
16
      "S_IXOTH", "nfs.mode3.xoth", FT_BOOLEAN, 32,
14715
16
      TFS(&tfs_yes_no), 0x00000001, NULL, HFILL }},
14716
14717
16
    { &hf_nfs2_ftype, {
14718
16
      "type", "nfs.ftype", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
14719
16
      &nfs2_ftype_ext, 0, NULL, HFILL }},
14720
14721
16
    { &hf_nfs2_mode, {
14722
16
      "mode", "nfs.mode", FT_UINT32, BASE_OCT,
14723
16
      NULL, 0, NULL, HFILL }},
14724
14725
16
    { &hf_nfs2_mode_name, {
14726
16
      "Name", "nfs.mode.name", FT_UINT32, BASE_DEC,
14727
16
      VALS(nfs2_mode_names), 0160000, NULL, HFILL }},
14728
14729
16
    { &hf_nfs2_mode_set_user_id, {
14730
16
      "Set user id on exec", "nfs.mode.set_user_id", FT_BOOLEAN, 32,
14731
16
      TFS(&tfs_yes_no), 04000, NULL, HFILL }},
14732
14733
16
    { &hf_nfs2_mode_set_group_id, {
14734
16
      "Set group id on exec", "nfs.mode.set_group_id", FT_BOOLEAN, 32,
14735
16
      TFS(&tfs_yes_no), 02000, NULL, HFILL }},
14736
14737
16
    { &hf_nfs2_mode_save_swap_text, {
14738
16
      "Save swapped text even after use", "nfs.mode.save_swap_text", FT_BOOLEAN, 32,
14739
16
      TFS(&tfs_yes_no), 01000, NULL, HFILL }},
14740
14741
16
    { &hf_nfs2_mode_read_owner, {
14742
16
      "Read permission for owner", "nfs.mode.read_owner", FT_BOOLEAN, 32,
14743
16
      TFS(&tfs_yes_no), 0400, NULL, HFILL }},
14744
14745
16
    { &hf_nfs2_mode_write_owner, {
14746
16
      "Write permission for owner", "nfs.mode.write_owner", FT_BOOLEAN, 32,
14747
16
      TFS(&tfs_yes_no), 0200, NULL, HFILL }},
14748
14749
16
    { &hf_nfs2_mode_exec_owner, {
14750
16
      "Execute permission for owner", "nfs.mode.exec_owner", FT_BOOLEAN, 32,
14751
16
      TFS(&tfs_yes_no), 0100, NULL, HFILL }},
14752
14753
16
    { &hf_nfs2_mode_read_group, {
14754
16
      "Read permission for group", "nfs.mode.read_group", FT_BOOLEAN, 32,
14755
16
      TFS(&tfs_yes_no), 040, NULL, HFILL }},
14756
14757
16
    { &hf_nfs2_mode_write_group, {
14758
16
      "Write permission for group", "nfs.mode.write_group", FT_BOOLEAN, 32,
14759
16
      TFS(&tfs_yes_no), 020, NULL, HFILL }},
14760
14761
16
    { &hf_nfs2_mode_exec_group, {
14762
16
      "Execute permission for group", "nfs.mode.exec_group", FT_BOOLEAN, 32,
14763
16
      TFS(&tfs_yes_no), 010, NULL, HFILL }},
14764
14765
16
    { &hf_nfs2_mode_read_other, {
14766
16
      "Read permission for others", "nfs.mode.read_other", FT_BOOLEAN, 32,
14767
16
      TFS(&tfs_yes_no), 04, NULL, HFILL }},
14768
14769
16
    { &hf_nfs2_mode_write_other, {
14770
16
      "Write permission for others", "nfs.mode.write_other", FT_BOOLEAN, 32,
14771
16
      TFS(&tfs_yes_no), 02, NULL, HFILL }},
14772
14773
16
    { &hf_nfs2_mode_exec_other, {
14774
16
      "Execute permission for others", "nfs.mode.exec_other", FT_BOOLEAN, 32,
14775
16
      TFS(&tfs_yes_no), 01, NULL, HFILL }},
14776
14777
16
    { &hf_nfs4_sequence_status_flags, {
14778
16
      "status flags", "nfs.sequence.flags", FT_UINT32, BASE_HEX,
14779
16
      NULL, 0, NULL, HFILL }},
14780
14781
16
    { &hf_nfs4_sequence_status_flags_cb_path_down, {
14782
16
      "SEQ4_STATUS_CB_PATH_DOWN", "nfs.sequence.flags.cb_path_down", FT_BOOLEAN, 32,
14783
16
      TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
14784
14785
16
    { &hf_nfs4_sequence_status_flags_cb_gss_contexts_expiring, {
14786
16
      "SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING", "nfs.sequence.flags.cb_gss_contexts_expiring",
14787
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
14788
14789
16
    { &hf_nfs4_sequence_status_flags_cb_gss_contexts_expired, {
14790
16
      "SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED", "nfs.sequence.flags.cb_gss_contexts_expired",
14791
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000004, NULL, HFILL}},
14792
14793
16
    { &hf_nfs4_sequence_status_flags_expired_all_state_revoked, {
14794
16
      "SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED", "nfs.sequence.flags.expired_all_state_revoked",
14795
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000008, NULL, HFILL}},
14796
14797
16
    { &hf_nfs4_sequence_status_flags_expired_some_state_revoked, {
14798
16
      "SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED", "nfs.sequence.flags.expired_some_state_revoked",
14799
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000010, NULL, HFILL}},
14800
14801
16
    { &hf_nfs4_sequence_status_flags_admin_state_revoked, {
14802
16
      "SEQ4_STATUS_ADMIN_STATE_REVOKED", "nfs.sequence.flags.admin_state_revoked",
14803
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000020, NULL, HFILL}},
14804
14805
16
    { &hf_nfs4_sequence_status_flags_recallable_state_revoked, {
14806
16
      "SEQ4_STATUS_RECALLABLE_STATE_REVOKED", "nfs.sequence.flags.recallable_state_revoked",
14807
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000040, NULL, HFILL}},
14808
14809
16
    { &hf_nfs4_sequence_status_flags_lease_moved, {
14810
16
      "SEQ4_STATUS_LEASE_MOVED", "nfs.sequence.flags.lease_moved", FT_BOOLEAN, 32,
14811
16
      TFS(&tfs_set_notset), 0x00000080, NULL, HFILL}},
14812
14813
16
    { &hf_nfs4_sequence_status_flags_restart_reclaim_needed, {
14814
16
      "SEQ4_STATUS_RESTART_RECLAIM_NEEDED", "nfs.sequence.flags.restart_reclaim_needed",
14815
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000100, NULL, HFILL}},
14816
14817
16
    { &hf_nfs4_sequence_status_flags_cb_path_down_session, {
14818
16
      "SEQ4_STATUS_CB_PATH_DOWN_SESSION", "nfs.sequence.flags.cb_path_down_session",
14819
16
      FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000200, NULL, HFILL}},
14820
14821
16
    { &hf_nfs4_sequence_status_flags_backchannel_fault, {
14822
16
      "SEQ4_STATUS_BACKCHANNEL_FAULT", "nfs.sequence.flags.backchannel_fault", FT_BOOLEAN, 32,
14823
16
      TFS(&tfs_set_notset), 0x00000400, NULL, HFILL}},
14824
14825
16
    { &hf_nfs4_sequence_status_flags_devid_changed, {
14826
16
      "SEQ4_STATUS_DEVID_CHANGED", "nfs.sequence.flags.devid_changed", FT_BOOLEAN, 32,
14827
16
      TFS(&tfs_set_notset), 0x00000800, NULL, HFILL}},
14828
14829
16
    { &hf_nfs4_sequence_status_flags_devid_deleted, {
14830
16
      "SEQ4_STATUS_DEVID_DELETED", "nfs.sequence.flags.devid_deleted", FT_BOOLEAN, 32,
14831
16
      TFS(&tfs_set_notset), 0x00001000, NULL, HFILL}},
14832
14833
16
    { &hf_nfs4_test_stateid_arg, {
14834
16
      "StateID List", "nfs.test_stateid.stateids",
14835
16
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
14836
14837
16
    { &hf_nfs4_test_stateid_res, {
14838
16
      "StateID Result List", "nfs.test_stateid.results",
14839
16
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
14840
14841
16
    { &hf_nfs4_seek_data_content, {
14842
16
      "data content", "nfs.data_content", FT_UINT32, BASE_DEC,
14843
16
      VALS(names_data_content), 0, NULL, HFILL }},
14844
14845
16
    { &hf_nfs4_bitmap_data, {
14846
16
      "Undissected bitmap data", "nfs.bitmap_data", FT_BYTES, BASE_NONE,
14847
16
      NULL, 0, NULL, HFILL }},
14848
14849
16
    { &hf_nfs4_huge_bitmap_length, {
14850
16
      "Huge bitmap length", "nfs.huge_bitmap_length", FT_UINT32, BASE_DEC,
14851
16
      NULL, 0, NULL, HFILL }},
14852
14853
16
    { &hf_nfs4_universal_address_ipv4, {
14854
16
      "universal_address", "nfs.universal_address.ipv4", FT_IPv4, BASE_NONE,
14855
16
      NULL, 0, NULL, HFILL }},
14856
14857
16
    { &hf_nfs4_universal_address_ipv6, {
14858
16
      "universal_address", "nfs.universal_address.ipv6", FT_IPv6, BASE_NONE,
14859
16
      NULL, 0, NULL, HFILL }},
14860
14861
16
    { &hf_nfs4_getdevinfo, {
14862
16
      "dev info", "nfs.devinfo", FT_BYTES,
14863
16
      BASE_NONE, NULL, 0, NULL, HFILL }},
14864
14865
16
    { &hf_nfs4_ff_version, {
14866
16
      "version", "nfs.ff.version", FT_UINT32, BASE_DEC,
14867
16
      NULL, 0, NULL, HFILL }},
14868
14869
16
    { &hf_nfs4_ff_minorversion, {
14870
16
      "minorversion", "nfs.ff.minorversion", FT_UINT32,
14871
16
      BASE_DEC, NULL, 0, NULL, HFILL }},
14872
14873
16
    { &hf_nfs4_ff_rsize, {
14874
16
      "max_rsize", "nfs.ff.rsize", FT_UINT32,
14875
16
      BASE_DEC, NULL, 0, NULL, HFILL }},
14876
14877
16
    { &hf_nfs4_ff_wsize, {
14878
16
      "max_wsize", "nfs.ff.wsize", FT_UINT32,
14879
16
      BASE_DEC, NULL, 0, NULL, HFILL }},
14880
14881
16
    { &hf_nfs4_ff_tightly_coupled, {
14882
16
                        "tightly coupled", "nfs.ff.tightly_coupled",
14883
16
      FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
14884
16
      NULL, HFILL }},
14885
14886
16
    { &hf_nfs4_ff_layout_flags, {
14887
16
      "layout flags", "nfs.ff.layout_flags", FT_UINT32, BASE_HEX,
14888
16
      NULL, 0, NULL, HFILL }},
14889
14890
16
    { &hf_nfs4_ff_synthetic_owner, {
14891
16
      "synthetic owner", "nfs.ff.synthetic_owner", FT_STRING, BASE_NONE,
14892
16
      NULL, 0, NULL, HFILL }},
14893
14894
16
    { &hf_nfs4_ff_synthetic_owner_group, {
14895
16
      "synthetic group", "nfs.ff.synthetic_owner_group", FT_STRING, BASE_NONE,
14896
16
      NULL, 0, NULL, HFILL }},
14897
14898
16
    { &hf_nfs4_ff_layout_flags_no_layoutcommit, {
14899
16
      "FLAG_NO_LAYOUTCOMMIT", "nfs.ff.layout_flags.no_layoutcommit", FT_BOOLEAN, 32,
14900
16
      TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
14901
14902
16
    { &hf_nfs4_ff_layout_flags_no_io_thru_mds, {
14903
16
      "FLAG_NO_IO_THRU_MDS", "nfs.ff.layout_flags.no_io_thru_mds", FT_BOOLEAN, 32,
14904
16
      TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
14905
14906
16
    { &hf_nfs4_ff_layout_flags_no_read_io, {
14907
16
      "FLAG_NO_READ_IO", "nfs.ff.layout_flags.no_read_io", FT_BOOLEAN, 32,
14908
16
      TFS(&tfs_set_notset), 0x00000004, NULL, HFILL}},
14909
14910
16
    { &hf_nfs4_ff_stats_collect_hint, {
14911
16
      "stats collect hint", "nfs.ff.stats_collect_hint", FT_UINT32, BASE_DEC,
14912
16
      NULL, 0, "Layoutstats sampling period hint, Seconds", HFILL }},
14913
14914
16
    { &hf_nfs4_fattr_clone_blocksize, {
14915
16
      "clone block size", "nfs.fattr4.clone_block_size", FT_UINT32, BASE_DEC,
14916
16
      NULL, 0, NULL, HFILL }},
14917
14918
16
    { &hf_nfs4_fattr_space_freed, {
14919
16
      "space freed", "nfs.fattr4.space_freed", FT_UINT64, BASE_DEC,
14920
16
      NULL, 0, NULL, HFILL }},
14921
14922
16
    { &hf_nfs4_fattr_change_attr_type, {
14923
16
      "change attr type", "nfs.fattr4.change_attr_type", FT_UINT32, BASE_DEC,
14924
16
      VALS(names_nfs_change_attr_types), 0, NULL, HFILL }},
14925
14926
16
    { &hf_nfs4_callback_stateids, {
14927
16
      "Callback StateIds", "nfs.callback_ids", FT_UINT32, BASE_DEC,
14928
16
      NULL, 0, NULL, HFILL }},
14929
14930
16
    { &hf_nfs4_callback_stateids_index, {
14931
16
      "Callback Id", "nfs.ff.callback_id_index", FT_UINT32, BASE_DEC,
14932
16
      NULL, 0, NULL, HFILL }},
14933
14934
16
    { &hf_nfs4_num_offload_status, {
14935
16
      "Number of offload status", "nfs.num_offload_status", FT_UINT32, BASE_DEC,
14936
16
      NULL, 0, NULL, HFILL }},
14937
14938
16
    { &hf_nfs4_offload_status_index, {
14939
16
      "nfsstat4", "nfs.offload_status", FT_UINT32, BASE_DEC,
14940
16
      NULL, 0, NULL, HFILL }},
14941
14942
16
    { &hf_nfs4_consecutive, {
14943
16
      "copy consecutively?", "nfs.consecutive", FT_BOOLEAN, BASE_NONE,
14944
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14945
14946
16
    { &hf_nfs4_netloc, {
14947
16
      "net loc", "nfs.netloc", FT_BYTES,
14948
16
      BASE_NONE, NULL, 0, NULL, HFILL }},
14949
14950
16
    { &hf_nfs4_netloc_type, {
14951
16
      "netloc type", "nfs.netloctype", FT_UINT32, BASE_DEC,
14952
16
      VALS(netloctype_names), 0, NULL, HFILL }},
14953
14954
16
    { &hf_nfs4_nl_name, {
14955
16
      "net loc name", "nfs.nl_name", FT_STRING, BASE_NONE,
14956
16
      NULL, 0, NULL, HFILL }},
14957
14958
16
    { &hf_nfs4_nl_url, {
14959
16
      "net loc url", "nfs.nl_url", FT_STRING, BASE_NONE,
14960
16
      NULL, 0, NULL, HFILL }},
14961
14962
16
    { &hf_nfs4_source_servers, {
14963
16
      "Source Server count", "nfs.source_servers", FT_UINT32, BASE_DEC,
14964
16
      NULL, 0, NULL, HFILL }},
14965
14966
16
    { &hf_nfs4_source_server_index, {
14967
16
      "Source Server", "nfs.ff.source_server_index", FT_UINT32, BASE_DEC,
14968
16
      NULL, 0, NULL, HFILL }},
14969
14970
16
    { &hf_nfs4_synchronous, {
14971
16
      "copy synchronous?", "nfs.synchronous", FT_BOOLEAN, BASE_NONE,
14972
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14973
14974
16
    { &hf_nfs4_io_hints_mask, {
14975
16
      "Hint mask", "nfs.hint.mask", FT_UINT32, BASE_HEX,
14976
16
      NULL, 0, NULL, HFILL }},
14977
14978
16
    { &hf_nfs4_io_hint_count, {
14979
16
      "Hint count", "nfs.hint.count", FT_UINT32, BASE_DEC,
14980
16
      NULL, 0, NULL, HFILL }},
14981
14982
16
    { &hf_nfs4_io_advise_hint, {
14983
16
      "Hint", "nfs.hint.hint", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
14984
16
      &io_advise_names_ext, 0, NULL, HFILL }},
14985
14986
16
    { &hf_nfs4_cb_recall_any_objs, {
14987
16
      "Objects to keep", "nfs.objects_to_keep", FT_UINT32, BASE_DEC,
14988
16
      NULL, 0, NULL, HFILL }},
14989
14990
16
    { &hf_nfs4_cb_recall_any_count, {
14991
16
      "Number of masks", "nfs.mask.count", FT_UINT32, BASE_DEC,
14992
16
      NULL, 0, NULL, HFILL }},
14993
14994
16
    { &hf_nfs4_cb_recall_any_mask, {
14995
16
      "Type mask", "nfs.mask", FT_UINT32, BASE_HEX,
14996
16
      NULL, 0, NULL, HFILL }},
14997
14998
16
    { &hf_nfs4_cb_recall_any_item, {
14999
16
      "Type", "nfs.mask.item", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
15000
16
      &cb_recall_any_names_ext, 0, NULL, HFILL }},
15001
15002
16
    { &hf_nfs4_bytes_copied, {
15003
16
      "bytes copied", "nfs.bytes_copied", FT_UINT64, BASE_DEC,
15004
16
      NULL, 0, NULL, HFILL }},
15005
15006
16
    { &hf_nfs4_read_plus_contents, {
15007
16
      "Contents", "nfs.contents",
15008
16
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
15009
15010
16
    { &hf_nfs4_read_plus_content_type, {
15011
16
      "Content Type", "nfs.content.type", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
15012
16
      &read_plus_content_names_ext, 0, NULL, HFILL }},
15013
15014
16
    { &hf_nfs4_block_size, {
15015
16
      "Content index", "nfs.content.index", FT_UINT32, BASE_DEC,
15016
16
      NULL, 0, NULL, HFILL }},
15017
15018
16
    { &hf_nfs4_block_count, {
15019
16
      "Number of Blocks", "nfs.adb.block.count", FT_UINT32, BASE_DEC,
15020
16
      NULL, 0, NULL, HFILL }},
15021
15022
16
    { &hf_nfs4_reloff_blocknum, {
15023
16
      "Relative Offset Block Number", "nfs.adb.block.reloff_num", FT_UINT32, BASE_DEC,
15024
16
      NULL, 0, NULL, HFILL }},
15025
15026
16
    { &hf_nfs4_blocknum, {
15027
16
      "Block Number", "nfs.adb.block.num", FT_UINT32, BASE_DEC,
15028
16
      NULL, 0, NULL, HFILL }},
15029
15030
16
    { &hf_nfs4_reloff_pattern, {
15031
16
      "Relative Offset Pattern", "nfs.adb.pattern.reloff", FT_UINT32, BASE_DEC,
15032
16
      NULL, 0, NULL, HFILL }},
15033
15034
16
    { &hf_nfs4_pattern_hash, {
15035
16
      "hash (CRC-32)", "nfs.adb.pattern_hash", FT_UINT32, BASE_HEX,
15036
16
      NULL, 0, "ADB pattern hash", HFILL }},
15037
15038
16
    { &hf_nfs4_xattrkey, {
15039
16
      "Name", "nfs.xattr.key", FT_STRING, BASE_NONE,
15040
16
      NULL, 0, "Xattr key", HFILL }},
15041
15042
16
    { &hf_nfs4_setxattr_options, {
15043
16
      "setxattr options", "nfs.setxattr.options", FT_UINT32, BASE_DEC,
15044
16
      VALS(names_setxattr_options), 0, NULL, HFILL }},
15045
15046
16
    { &hf_nfs4_listxattr_maxcount, {
15047
16
      "maxcount", "nfs.lisxtattr.maxcount", FT_UINT32, BASE_DEC,
15048
16
      NULL, 0, "Lixtxattr maxcount", HFILL }},
15049
15050
16
    { &hf_nfs4_listxattr_cookie, {
15051
16
      "cookie", "nfs.lisxtattr.cookie", FT_UINT64, BASE_DEC,
15052
16
      NULL, 0, "Lixtxattr cookie", HFILL }},
15053
15054
16
    { &hf_nfs4_listxattr_names_len, {
15055
16
      "xattr names count", "nfs.listxattr.names.count", FT_UINT32, BASE_DEC,
15056
16
      NULL, 0, "Number of xattrkey names", HFILL }},
15057
15058
16
    { &hf_nfs4_listxattr_eof, {
15059
16
      "eof", "nfs.lisxtattr.eof", FT_UINT32, BASE_DEC,
15060
16
      NULL, 0, "Lixtxattr eof", HFILL }},
15061
15062
16
    { &hf_nfs4_gdd_non_fatal_status, {
15063
16
      "Non-fatal status", "nfs.gdd.non_fatal_status", FT_UINT32, BASE_DEC,
15064
16
      VALS(gdd_non_fatal_status_names), 0,
15065
16
      "GET_DIR_DELEGATION non-fatal status code", HFILL }},
15066
15067
16
    { &hf_nfs4_gdd_signal_deleg_avail, {
15068
16
      "Signal delegation available", "nfs.gdd.signal_deleg_avail", FT_BOOLEAN, BASE_NONE,
15069
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
15070
15071
16
    { &hf_nfs4_gdd_child_attr_delay, {
15072
16
      "Child attr notification delay", "nfs.gdd.child_attr_delay",
15073
16
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
15074
15075
16
    { &hf_nfs4_gdd_dir_attr_delay, {
15076
16
      "Dir attr notification delay", "nfs.gdd.dir_attr_delay",
15077
16
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
15078
15079
16
    { &hf_nfs4_gdd_child_attrs, {
15080
16
      "Child notification attrs", "nfs.gdd.child_attrs",
15081
16
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
15082
15083
16
    { &hf_nfs4_gdd_dir_attrs, {
15084
16
      "Dir notification attrs", "nfs.gdd.dir_attrs",
15085
16
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
15086
15087
16
    { &hf_nfs4_nad_last_entry, {
15088
16
      "last entry?", "nfs.notify.add.last_entry", FT_BOOLEAN, BASE_NONE,
15089
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
15090
15091
16
    { &hf_nfs4_ff_local, {
15092
16
      "client used cache?", "nfs.ff.local", FT_BOOLEAN, BASE_NONE,
15093
16
      TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
15094
15095
16
    { &hf_nfs4_io_count, {
15096
16
      "count", "nfs.io_count", FT_UINT64, BASE_DEC,
15097
16
      NULL, 0, NULL, HFILL }},
15098
15099
16
    { &hf_nfs4_io_bytes, {
15100
16
      "bytes", "nfs.io_bytes", FT_UINT64, BASE_DEC,
15101
16
      NULL, 0, NULL, HFILL }},
15102
15103
16
    { &hf_nfs4_ff_ops_requested, {
15104
16
      "ops requested", "nfs.ff.ops_requested", FT_UINT64, BASE_DEC,
15105
16
      NULL, 0, NULL, HFILL }},
15106
15107
16
    { &hf_nfs4_ff_bytes_requested, {
15108
16
      "bytes requested", "nfs.ff.bytes_requested", FT_UINT64, BASE_DEC,
15109
16
      NULL, 0, NULL, HFILL }},
15110
15111
16
    { &hf_nfs4_ff_ops_completed, {
15112
16
      "ops completed", "nfs.ff.ops_completed", FT_UINT64, BASE_DEC,
15113
16
      NULL, 0, NULL, HFILL }},
15114
15115
16
    { &hf_nfs4_ff_bytes_completed, {
15116
16
      "bytes completed", "nfs.ff.bytes_completed", FT_UINT64, BASE_DEC,
15117
16
      NULL, 0, NULL, HFILL }},
15118
15119
16
    { &hf_nfs4_ff_bytes_not_delivered, {
15120
16
      "bytes not delivered", "nfs.ff.bytes_not_delivered", FT_UINT64, BASE_DEC,
15121
16
      NULL, 0, NULL, HFILL }},
15122
15123
16
    { &hf_nfs4_layoutstats, {
15124
16
      "Layout Stats", "nfs.layoutstats", FT_BYTES, BASE_NONE,
15125
16
      NULL, 0, NULL, HFILL }},
15126
15127
16
    { &hf_nfs4_device_error_count, {
15128
16
      "Device Error count", "nfs.device_error_count", FT_UINT32, BASE_DEC,
15129
16
      NULL, 0, NULL, HFILL }},
15130
15131
16
    { &hf_nfs4_device_errors_index, {
15132
16
      "Device Error index", "nfs.device_errors_index", FT_UINT32, BASE_DEC,
15133
16
      NULL, 0, NULL, HFILL }},
15134
15135
16
    { &hf_nfs4_ff_ioerrs_count, {
15136
16
      "IO Errors count", "nfs.ff.ioerrs_count", FT_UINT32, BASE_DEC,
15137
16
      NULL, 0, NULL, HFILL }},
15138
15139
16
    { &hf_nfs4_ff_ioerrs_index, {
15140
16
      "IO Errors index", "nfs.ff.ioerrs_index", FT_UINT32, BASE_DEC,
15141
16
      NULL, 0, NULL, HFILL }},
15142
15143
16
    { &hf_nfs4_ff_ioerrs_length, {
15144
16
      "length", "nfs.ff.ioerrs_length", FT_UINT64, BASE_DEC,
15145
16
      NULL, 0, NULL, HFILL }},
15146
15147
16
    { &hf_nfs4_ff_ioerrs_offset, {
15148
16
      "offset", "nfs.ff.ioerrs_offset", FT_UINT64, BASE_DEC,
15149
16
      NULL, 0, NULL, HFILL }},
15150
15151
16
    { &hf_nfs4_ff_iostats_count, {
15152
16
      "IO Stats count", "nfs.ff.iostats_count", FT_UINT32, BASE_DEC,
15153
16
      NULL, 0, NULL, HFILL }},
15154
15155
16
    { &hf_nfs4_ff_iostats_index, {
15156
16
      "IO Stats index", "nfs.ff.iostats_index", FT_UINT32, BASE_DEC,
15157
16
      NULL, 0, NULL, HFILL }},
15158
15159
16
    { &hf_nfs4_io_error_op, {
15160
16
      "OP", "nfs.ff_ioerrs_op", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
15161
16
      &names_nfs4_operation_ext, 0, NULL, HFILL }},
15162
15163
  /* Hidden field for v2, v3, and v4 status */
15164
16
    { &hf_nfs_status, {
15165
16
      "Status", "nfs.status", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
15166
16
      &names_nfs_nfsstat_ext, 0, "Reply status", HFILL }}
15167
16
  };
15168
15169
16
  static int *ett[] = {
15170
16
    &ett_nfs,
15171
16
    &ett_nfs_fh_encoding,
15172
16
    &ett_nfs_fh_fsid,
15173
16
    &ett_nfs_fh_file,
15174
16
    &ett_nfs_fh_mount,
15175
16
    &ett_nfs_fh_export,
15176
16
    &ett_nfs_fh_xfsid,
15177
16
    &ett_nfs_fh_fn,
15178
16
    &ett_nfs_fh_xfn,
15179
16
    &ett_nfs_fh_hp,
15180
16
    &ett_nfs_fh_auth,
15181
16
    &ett_nfs_fhandle,
15182
16
    &ett_nfs_timeval,
15183
16
    &ett_nfs_fattr,
15184
16
    &ett_nfs_fh_obj,
15185
16
    &ett_nfs_fh_ex,
15186
16
    &ett_nfs_readdir_entry,
15187
16
    &ett_nfs_utf8string,
15188
15189
16
    &ett_nfs2_mode,
15190
16
    &ett_nfs2_sattr,
15191
16
    &ett_nfs2_diropargs,
15192
15193
16
    &ett_nfs3_gxfh_utlfield,
15194
16
    &ett_nfs3_gxfh_sfhfield,
15195
16
    &ett_nfs3_gxfh_sfhflags,
15196
16
    &ett_nfs3_mode,
15197
16
    &ett_nfs3_specdata,
15198
16
    &ett_nfs3_fh,
15199
16
    &ett_nfs3_nfstime,
15200
16
    &ett_nfs3_fattr,
15201
16
    &ett_nfs3_post_op_fh,
15202
16
    &ett_nfs3_sattr,
15203
16
    &ett_nfs3_diropargs,
15204
16
    &ett_nfs3_sattrguard,
15205
16
    &ett_nfs3_set_mode,
15206
16
    &ett_nfs3_set_uid,
15207
16
    &ett_nfs3_set_gid,
15208
16
    &ett_nfs3_set_size,
15209
16
    &ett_nfs3_set_atime,
15210
16
    &ett_nfs3_set_mtime,
15211
16
    &ett_nfs3_pre_op_attr,
15212
16
    &ett_nfs3_post_op_attr,
15213
16
    &ett_nfs3_wcc_attr,
15214
16
    &ett_nfs3_wcc_data,
15215
16
    &ett_nfs3_access,
15216
16
    &ett_nfs3_fsinfo_properties,
15217
15218
16
    &ett_nfs4_fh_file,
15219
16
    &ett_nfs4_fh_file_flags,
15220
16
    &ett_nfs4_fh_export,
15221
16
    &ett_nfs4_compound_call,
15222
16
    &ett_nfs4_request_op,
15223
16
    &ett_nfs4_response_op,
15224
16
    &ett_nfs4_access,
15225
16
    &ett_nfs4_access_supp,
15226
16
    &ett_nfs4_close,
15227
16
    &ett_nfs4_commit,
15228
16
    &ett_nfs4_create,
15229
16
    &ett_nfs4_delegpurge,
15230
16
    &ett_nfs4_delegreturn,
15231
16
    &ett_nfs4_getattr,
15232
16
    &ett_nfs4_getattr_args,
15233
16
    &ett_nfs4_getattr_resp,
15234
16
    &ett_nfs4_resok4,
15235
16
    &ett_nfs4_obj_attrs,
15236
16
    &ett_nfs4_fattr_new_attr_vals,
15237
16
    &ett_nfs4_fattr4_attrmask,
15238
16
    &ett_nfs4_attribute,
15239
16
    &ett_nfs4_getfh,
15240
16
    &ett_nfs4_link,
15241
16
    &ett_nfs4_lock,
15242
16
    &ett_nfs4_lockt,
15243
16
    &ett_nfs4_locku,
15244
16
    &ett_nfs4_lookup,
15245
16
    &ett_nfs4_lookupp,
15246
16
    &ett_nfs4_nverify,
15247
16
    &ett_nfs4_open,
15248
16
    &ett_nfs4_openattr,
15249
16
    &ett_nfs4_open_confirm,
15250
16
    &ett_nfs4_open_downgrade,
15251
16
    &ett_nfs4_putfh,
15252
16
    &ett_nfs4_putpubfh,
15253
16
    &ett_nfs4_putrootfh,
15254
16
    &ett_nfs4_read,
15255
16
    &ett_nfs4_readdir,
15256
16
    &ett_nfs4_readlink,
15257
16
    &ett_nfs4_test_stateid,
15258
16
    &ett_nfs4_destroy_clientid,
15259
16
    &ett_nfs4_reclaim_complete,
15260
16
    &ett_nfs4_remove,
15261
16
    &ett_nfs4_rename,
15262
16
    &ett_nfs4_renew,
15263
16
    &ett_nfs4_restorefh,
15264
16
    &ett_nfs4_savefh,
15265
16
    &ett_nfs4_setattr,
15266
16
    &ett_nfs4_setclientid,
15267
16
    &ett_nfs4_setclientid_confirm,
15268
16
    &ett_nfs4_verify,
15269
16
    &ett_nfs4_write,
15270
16
    &ett_nfs4_release_lockowner,
15271
16
    &ett_nfs4_backchannel_ctl,
15272
16
    &ett_nfs4_bind_conn_to_session,
15273
16
    &ett_nfs4_exchange_id,
15274
16
    &ett_nfs4_create_session,
15275
16
    &ett_nfs4_destroy_session,
15276
16
    &ett_nfs4_free_stateid,
15277
16
    &ett_nfs4_get_dir_delegation,
15278
16
    &ett_nfs4_secinfo_no_name,
15279
16
    &ett_nfs4_sequence,
15280
16
    &ett_nfs4_layoutget,
15281
16
    &ett_nfs4_layoutcommit,
15282
16
    &ett_nfs4_layoutreturn,
15283
16
    &ett_nfs4_getdevinfo,
15284
16
    &ett_nfs4_getdevlist,
15285
16
    &ett_nfs4_seek,
15286
16
    &ett_nfs4_allocate,
15287
16
    &ett_nfs4_deallocate,
15288
16
    &ett_nfs4_illegal,
15289
16
    &ett_nfs4_verifier,
15290
16
    &ett_nfs4_dirlist,
15291
16
    &ett_nfs4_dir_entry,
15292
16
    &ett_nfs4_pathname,
15293
16
    &ett_nfs4_change_info,
15294
16
    &ett_nfs4_open_delegation,
15295
16
    &ett_nfs4_open_why_no_deleg,
15296
16
    &ett_nfs4_open_claim,
15297
16
    &ett_nfs4_opentype,
15298
16
    &ett_nfs4_lock_owner,
15299
16
    &ett_nfs4_cb_client,
15300
16
    &ett_nfs4_client_id,
15301
16
    &ett_nfs4_clientowner,
15302
16
    &ett_nfs4_exchangeid_call_flags,
15303
16
    &ett_nfs4_exchangeid_reply_flags,
15304
16
    &ett_nfs4_server_owner,
15305
16
    &ett_nfs4_bitmap,
15306
16
    &ett_nfs4_attr_request,
15307
16
    &ett_nfs4_fattr,
15308
16
    &ett_nfs4_fsid,
15309
16
    &ett_nfs4_fs_locations,
15310
16
    &ett_nfs4_fs_location,
15311
16
    &ett_nfs4_open_result_flags,
15312
16
    &ett_nfs4_secinfo,
15313
16
    &ett_nfs4_secinfo_flavor_info,
15314
16
    &ett_nfs4_stateid,
15315
16
    &ett_nfs4_fattr_fh_expire_type,
15316
16
    &ett_nfs4_fattr_aclsupport,
15317
16
    &ett_nfs4_fattr_fs_charset_cap,
15318
16
    &ett_nfs4_aclflag,
15319
16
    &ett_nfs4_ace,
15320
16
    &ett_nfs4_clientaddr,
15321
16
    &ett_nfs4_aceflag,
15322
16
    &ett_nfs4_acemask,
15323
16
    &ett_nfs4_slotid,
15324
16
    &ett_nfs4_sr_status,
15325
16
    &ett_nfs4_serverscope,
15326
16
    &ett_nfs4_minorid,
15327
16
    &ett_nfs4_majorid,
15328
16
    &ett_nfs4_persist,
15329
16
    &ett_nfs4_backchan,
15330
16
    &ett_nfs4_rdmamode,
15331
16
    &ett_nfs4_padsize,
15332
16
    &ett_nfs4_cbrenforce,
15333
16
    &ett_nfs4_hashalg,
15334
16
    &ett_nfs4_ssvlen,
15335
16
    &ett_nfs4_maxreqsize,
15336
16
    &ett_nfs4_maxrespsize,
15337
16
    &ett_nfs4_maxrespsizecached,
15338
16
    &ett_nfs4_maxops,
15339
16
    &ett_nfs4_maxreqs,
15340
16
    &ett_nfs4_streamchanattrs,
15341
16
    &ett_nfs4_rdmachanattrs,
15342
16
    &ett_nfs4_sec_parms_array,
15343
16
    &ett_nfs4_sec_parms_item,
15344
16
    &ett_nfs4_gids,
15345
16
    &ett_nfs4_machinename,
15346
16
    &ett_nfs4_flavor,
15347
16
    &ett_nfs4_stamp,
15348
16
    &ett_nfs4_uid,
15349
16
    &ett_nfs4_gid,
15350
16
    &ett_nfs4_service,
15351
16
    &ett_nfs4_sessionid,
15352
16
    &ett_nfs4_layoutseg,
15353
16
    &ett_nfs4_layoutseg_sub,
15354
16
    &ett_nfs4_nfl_util,
15355
16
    &ett_nfs4_cb_request_op,
15356
16
    &ett_nfs4_cb_resop,
15357
16
    &ett_nfs4_cb_getattr,
15358
16
    &ett_nfs4_cb_recall,
15359
16
    &ett_nfs4_cb_layoutrecall,
15360
16
    &ett_nfs4_cb_pushdeleg,
15361
16
    &ett_nfs4_cb_recallany,
15362
16
    &ett_nfs4_cb_recallableobjavail,
15363
16
    &ett_nfs4_cb_recallslot,
15364
16
    &ett_nfs4_cb_sequence,
15365
16
    &ett_nfs4_cb_wantscancelled,
15366
16
    &ett_nfs4_cb_notifylock,
15367
16
    &ett_nfs4_cb_notifydeviceid,
15368
16
    &ett_nfs4_cb_notify,
15369
16
    &ett_nfs4_cb_reflists,
15370
16
    &ett_nfs4_cb_refcalls,
15371
16
    &ett_nfs4_cb_illegal,
15372
16
    &ett_nfs4_chan_attrs,
15373
16
    &ett_nfs4_create_session_flags,
15374
16
    &ett_nfs4_sequence_status_flags,
15375
16
    &ett_nfs4_want_notify_flags,
15376
16
    &ett_nfs4_ff_layout_flags,
15377
16
    &ett_nfs4_scsi_layout_vol,
15378
16
    &ett_nfs4_scsi_layout_vol_indices,
15379
16
    &ett_nfs4_layoutstats,
15380
16
    &ett_nfs4_io_info,
15381
16
    &ett_nfs4_io_latency,
15382
16
    &ett_nfs4_io_time,
15383
16
    &ett_nfs4_callback_stateids_sub,
15384
16
    &ett_nfs4_source_servers_sub,
15385
16
    &ett_nfs4_copy,
15386
16
    &ett_nfs4_copy_notify,
15387
16
    &ett_nfs4_device_errors_sub,
15388
16
    &ett_nfs4_layouterror,
15389
16
    &ett_nfs4_ff_ioerrs_sub,
15390
16
    &ett_nfs4_ff_iostats_sub,
15391
16
    &ett_nfs4_clone,
15392
16
    &ett_nfs4_getxattr,
15393
16
    &ett_nfs4_setxattr,
15394
16
    &ett_nfs4_listxattr,
15395
16
    &ett_nfs4_removexattr,
15396
16
    &ett_nfs4_offload_cancel,
15397
16
    &ett_nfs4_offload_status,
15398
16
    &ett_nfs4_osr_complete_sub,
15399
16
    &ett_nfs4_io_advise,
15400
16
    &ett_nfs4_read_plus,
15401
16
    &ett_nfs4_read_plus_content_sub,
15402
16
    &ett_nfs4_write_same,
15403
16
    &ett_nfs4_fh_pd_flags,
15404
16
    &ett_nfs4_fh_pd_sites,
15405
16
    &ett_nfs4_fh_pd_spaces,
15406
16
    &ett_nfs4_listxattr_names,
15407
16
    &ett_nfs4_notify_delay,
15408
16
    &ett_nfs4_notify_attrs,
15409
16
    &ett_nfs4_cb_notify_changes,
15410
16
    &ett_nfs4_cb_notify_list_entries,
15411
16
    &ett_nfs4_cb_notify_attr4_dir,
15412
16
    &ett_nfs4_cb_notify_attr4_child,
15413
16
    &ett_nfs4_cb_notify_remove4,
15414
16
    &ett_nfs4_cb_notify_add4,
15415
16
    &ett_nfs4_cb_notify_rename4,
15416
16
    &ett_nfs4_nfstime,
15417
16
  };
15418
15419
16
  static ei_register_info ei[] = {
15420
16
    { &ei_nfs_too_many_ops, { "nfs.too_many_ops", PI_PROTOCOL, PI_NOTE, "Too many operations", EXPFILL }},
15421
16
    { &ei_nfs_not_vnx_file, { "nfs.not_vnx_file", PI_UNDECODED, PI_WARN, "Not a Celerra|VNX file handle", EXPFILL }},
15422
16
    { &ei_nfs_too_many_bitmaps, { "nfs.too_many_bitmaps", PI_PROTOCOL, PI_NOTE, "Too many bitmap array items", EXPFILL }},
15423
16
    { &ei_nfs_bitmap_no_dissector, { "nfs.bitmap_no_dissector", PI_PROTOCOL, PI_WARN,
15424
16
      "Unknown dissector for bitmap attribute", EXPFILL }},
15425
16
    { &ei_nfs_bitmap_skip_value, { "nfs.bitmap_skip_value", PI_PROTOCOL, PI_WARN,
15426
16
      "Not dissecting value since a previous value was not dissected", EXPFILL }},
15427
16
    { &ei_nfs_bitmap_undissected_data, { "nfs.bitmap_undissected_data", PI_PROTOCOL, PI_WARN,
15428
16
      "There is some bitmap data left undissected", EXPFILL }},
15429
16
    { &ei_nfs4_stateid_deprecated, { "nfs.stateid.deprecated", PI_PROTOCOL, PI_WARN, "State ID deprecated in CLOSE responses [RFC7530 16.2.5]", EXPFILL }},
15430
16
    { &ei_nfs_file_system_cycle, { "nfs.file_system_cycle", PI_PROTOCOL, PI_WARN, "Possible file system cycle detected", EXPFILL }},
15431
16
  };
15432
15433
16
  module_t *nfs_module;
15434
16
  expert_module_t* expert_nfs;
15435
15436
16
  proto_nfs = proto_register_protocol("Network File System", "NFS", "nfs");
15437
15438
  /* "protocols" registered just for Decode As */
15439
16
  proto_nfs_unknown = proto_register_protocol_in_name_only("Unknown NFS", "nfs_unknown", "nfs.unknown", proto_nfs, FT_PROTOCOL);
15440
16
  proto_nfs_svr4 = proto_register_protocol_in_name_only("SVR4", "svr4", "nfs.svr4", proto_nfs, FT_PROTOCOL);
15441
16
  proto_nfs_knfsd_le = proto_register_protocol_in_name_only("KNFSD_LE", "knfsd_le", "nfs.knfsd_le", proto_nfs, FT_PROTOCOL);
15442
16
  proto_nfs_nfsd_le = proto_register_protocol_in_name_only("NFSD_LE", "nfsd_le", "nfs.nfsd_le", proto_nfs, FT_PROTOCOL);
15443
16
  proto_nfs_knfsd_new = proto_register_protocol_in_name_only("KNFSD_NEW", "knfsd_new", "nfs.knfsd_new", proto_nfs, FT_PROTOCOL);
15444
16
  proto_nfs_ontap_v3 = proto_register_protocol_in_name_only("ONTAP_V3", "ontap_v3", "nfs.ontap_v3", proto_nfs, FT_PROTOCOL);
15445
16
  proto_nfs_ontap_v4 = proto_register_protocol_in_name_only("ONTAP_V4", "ontap_v4", "nfs.ontap_v4", proto_nfs, FT_PROTOCOL);
15446
16
  proto_nfs_ontap_gx_v3 = proto_register_protocol_in_name_only("ONTAP_GX_V3", "ontap_gx_v3", "nfs.ontap_gx_v3", proto_nfs, FT_PROTOCOL);
15447
16
  proto_nfs_celerra_vnx = proto_register_protocol_in_name_only("CELERRA_VNX", "celerra_vnx", "nfs.celerra_vnx", proto_nfs, FT_PROTOCOL);
15448
16
  proto_nfs_gluster = proto_register_protocol_in_name_only("GLUSTER", "gluster", "nfs.gluster", proto_nfs, FT_PROTOCOL);
15449
16
  proto_nfs_dcache = proto_register_protocol_in_name_only("dCache", "dcache", "nfs.dcache", proto_nfs, FT_PROTOCOL);
15450
16
  proto_nfs_primary_data = proto_register_protocol_in_name_only("Primary_Data", "pd", "nfs.primary_data", proto_nfs, FT_PROTOCOL);
15451
15452
  /* "protocols" registered just for ONC-RPC Service Response Time */
15453
16
  proto_nfs_cb = proto_register_protocol_in_name_only("Network File System CB", "NFS CB", "nfs.cb", proto_nfs, FT_PROTOCOL);
15454
15455
  /* "protocol" registered just for NFSv4 Service Response Time (the
15456
   * protocol short name is used for, e.g. the GUI menu item.) */
15457
16
  proto_nfsv4 = proto_register_protocol_in_name_only("Network File System v4", "NFSv4", "nfsv4", proto_nfs, FT_PROTOCOL);
15458
15459
16
  proto_register_field_array(proto_nfs, hf, array_length(hf));
15460
16
  proto_register_subtree_array(ett, array_length(ett));
15461
16
  expert_nfs = expert_register_protocol(proto_nfs);
15462
16
  expert_register_field_array(expert_nfs, ei, array_length(ei));
15463
15464
16
  nfs_module = prefs_register_protocol(proto_nfs, NULL);
15465
16
  prefs_register_bool_preference(nfs_module, "file_name_snooping",
15466
16
               "Snoop FH to filename mappings",
15467
16
               "Whether the dissector should snoop the FH to"
15468
16
               " filename mappings by looking inside certain packets",
15469
16
               &nfs_file_name_snooping);
15470
16
  prefs_register_bool_preference(nfs_module, "file_full_name_snooping",
15471
16
               "Snoop full path to filenames",
15472
16
               "Whether the dissector should snoop the full pathname"
15473
16
               " for files for matching FH's",
15474
16
               &nfs_file_name_full_snooping);
15475
16
  prefs_register_bool_preference(nfs_module, "fhandle_find_both_reqrep",
15476
16
               "Fhandle filters finds both request/response",
15477
16
               "With this option display filters for nfs fhandles"
15478
16
               " (nfs.fh.{name|full_name|hash}) will find both the request"
15479
16
               " and response packets for a RPC call, even if the actual"
15480
16
               " fhandle is only present in one of the packets",
15481
16
               &nfs_fhandle_reqrep_matching);
15482
16
  prefs_register_bool_preference(nfs_module, "display_nfsv4_tag",
15483
16
               "Display NFSv4 tag in info Column",
15484
16
               "When enabled, this option will print the NFSv4 tag"
15485
16
               " (if one exists) in the Info column in the Summary pane",
15486
16
          &nfs_display_v4_tag);
15487
16
  prefs_register_bool_preference(nfs_module, "display_major_nfsv4_ops",
15488
16
               "Display only 'significant' NFSv4 Operations in info Column",
15489
16
               "When enabled, shows only the significant NFSv4 Operations"
15490
16
               " in the info column.  Others (like GETFH, PUTFH, etc) are not displayed",
15491
16
          &display_major_nfs4_ops);
15492
15493
16
  prefs_register_obsolete_preference(nfs_module, "default_fhandle_type");
15494
15495
16
  nfs_name_snoop_known    = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
15496
16
  nfs_file_handles        = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
15497
16
  nfs_fhandle_frame_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
15498
16
  register_init_routine(nfs_name_snoop_init);
15499
16
  register_cleanup_routine(nfs_name_snoop_cleanup);
15500
16
  register_init_routine(nfs4_cb_init);
15501
16
  register_cleanup_routine(nfs4_cb_cleanup);
15502
15503
16
  nfs_fhandle_table = register_decode_as_next_proto(proto_nfs, "nfs_fhandle.type",
15504
16
                "NFS File Handle types", nfs_prompt);
15505
15506
16
  nfsv4_tap = register_tap("nfsv4");
15507
15508
16
  register_srt_table(proto_nfsv4, "nfsv4", 1, nfsstat_packet, nfsstat_init, NULL);
15509
16
}
15510
15511
15512
void
15513
proto_reg_handoff_nfs(void)
15514
16
{
15515
16
  dissector_handle_t fhandle_handle;
15516
15517
  /* Register the protocol as RPC */
15518
16
  rpc_init_prog(proto_nfs, NFS_PROGRAM, ett_nfs,
15519
16
      G_N_ELEMENTS(nfs_vers_info), nfs_vers_info);
15520
15521
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_SVR4, proto_nfs_svr4);
15522
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15523
15524
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_LINUX_KNFSD_LE, proto_nfs_knfsd_le);
15525
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15526
15527
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_LINUX_NFSD_LE, proto_nfs_nfsd_le);
15528
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15529
15530
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_LINUX_KNFSD_NEW, proto_nfs_knfsd_new);
15531
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15532
15533
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_NETAPP, proto_nfs_ontap_v3);
15534
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15535
15536
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_NETAPP_V4, proto_nfs_ontap_v4);
15537
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15538
15539
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_NETAPP_GX_v3, proto_nfs_ontap_gx_v3);
15540
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15541
15542
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_CELERRA_VNX, proto_nfs_celerra_vnx);
15543
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15544
15545
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_GLUSTER, proto_nfs_gluster);
15546
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15547
15548
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_DCACHE, proto_nfs_dcache);
15549
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15550
15551
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_PRIMARY_DATA, proto_nfs_primary_data);
15552
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15553
15554
16
  fhandle_handle = create_dissector_handle(dissect_fhandle_data_unknown, proto_nfs_unknown);
15555
16
  dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
15556
16
}
15557
15558
/*
15559
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
15560
 *
15561
 * Local variables:
15562
 * c-basic-offset: 8
15563
 * tab-width: 8
15564
 * indent-tabs-mode: t
15565
 * End:
15566
 *
15567
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
15568
 * :indentSize=8:tabSize=8:noTabs=false:
15569
 */