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>
18 #include <stdbool.h>
19
20 #include <epan/packet.h>
21 #include <epan/prefs.h>
22 #include <epan/exceptions.h>
23 #include <epan/expert.h>
24 #include <epan/proto_data.h>
25 #include <epan/to_str.h>
26 #include <epan/decode_as.h>
27 #include <epan/crc16-tvb.h>
28 #include <epan/crc32-tvb.h>
29 #include <wsutil/str_util.h>
30 #include "packet-nfs.h"
31 #include "packet-rpcrdma.h"
32
33 void proto_register_nfs(void);
34 void proto_reg_handoff_nfs(void);
35
36 /* NON-NFS-version-specific hf variables */
37 static int proto_nfs = -1;
38 static int proto_nfs_unknown = -1;
39 static int proto_nfs_svr4 = -1;
40 static int proto_nfs_knfsd_le = -1;
41 static int proto_nfs_nfsd_le = -1;
42 static int proto_nfs_knfsd_new = -1;
43 static int proto_nfs_ontap_v3 = -1;
44 static int proto_nfs_ontap_v4 = -1;
45 static int proto_nfs_ontap_gx_v3 = -1;
46 static int proto_nfs_celerra_vnx = -1;
47 static int proto_nfs_gluster = -1;
48 static int proto_nfs_dcache = -1;
49 static int proto_nfs_primary_data = -1;
50 static int proto_nfs_cb = -1;
51 static int hf_nfs_access_check = -1;
52 static int hf_nfs_access_supported = -1;
53 static int hf_nfs_access_rights = -1;
54 static int hf_nfs_access_supp_read = -1;
55 static int hf_nfs_access_supp_lookup = -1;
56 static int hf_nfs_access_supp_modify = -1;
57 static int hf_nfs_access_supp_extend = -1;
58 static int hf_nfs_access_supp_delete = -1;
59 static int hf_nfs_access_supp_execute = -1;
60 static int hf_nfs_access_supp_xattr_read = -1;
61 static int hf_nfs_access_supp_xattr_write = -1;
62 static int hf_nfs_access_supp_xattr_list = -1;
63 static int hf_nfs_access_read = -1;
64 static int hf_nfs_access_lookup = -1;
65 static int hf_nfs_access_modify = -1;
66 static int hf_nfs_access_extend = -1;
67 static int hf_nfs_access_delete = -1;
68 static int hf_nfs_access_execute = -1;
69 static int hf_nfs_access_xattr_read = -1;
70 static int hf_nfs_access_xattr_write = -1;
71 static int hf_nfs_access_xattr_list = -1;
72 static int hf_nfs_access_denied = -1;
73 static int hf_nfs_fh_length = -1;
74 static int hf_nfs_fh_hash = -1;
75 static int hf_nfs_fh_fhandle_data = -1;
76 static int hf_nfs_fh_mount_fileid = -1;
77 static int hf_nfs_fh_mount_generation = -1;
78 static int hf_nfs_fh_snapid = -1;
79 static int hf_nfs_fh_unused = -1;
80 static int hf_nfs_fh_flags = -1;
81 static int hf_nfs_fh_fileid = -1;
82 static int hf_nfs_fh_generation = -1;
83 static int hf_nfs_fh_fsid = -1;
84 static int hf_nfs_fh_export_fileid = -1;
85 static int hf_nfs_fh_export_generation = -1;
86 static int hf_nfs_fh_export_snapid = -1;
87 static int hf_nfs_fh_exportid = -1;
88 static int hf_nfs_fh_file_flag_mntpoint = -1;
89 static int hf_nfs_fh_file_flag_snapdir = -1;
90 static int hf_nfs_fh_file_flag_snapdir_ent = -1;
91 static int hf_nfs_fh_file_flag_empty = -1;
92 static int hf_nfs_fh_file_flag_vbn_access = -1;
93 static int hf_nfs_fh_file_flag_multivolume = -1;
94 static int hf_nfs_fh_file_flag_metadata = -1;
95 static int hf_nfs_fh_file_flag_orphan = -1;
96 static int hf_nfs_fh_file_flag_foster = -1;
97 static int hf_nfs_fh_file_flag_named_attr = -1;
98 static int hf_nfs_fh_file_flag_exp_snapdir = -1;
99 static int hf_nfs_fh_file_flag_vfiler = -1;
100 static int hf_nfs_fh_file_flag_aggr = -1;
101 static int hf_nfs_fh_file_flag_striped = -1;
102 static int hf_nfs_fh_file_flag_private = -1;
103 static int hf_nfs_fh_file_flag_next_gen = -1;
104 static int hf_nfs_fh_gfid = -1;
105 static int hf_nfs_fh_handle_type = -1;
106 static int hf_nfs_fh_fsid_major16_mask = -1;
107 static int hf_nfs_fh_fsid_minor16_mask = -1;
108 static int hf_nfs_fh_fsid_major16 = -1;
109 static int hf_nfs_fh_fsid_minor16 = -1;
110 static int hf_nfs_fh_fsid_major32 = -1;
111 static int hf_nfs_fh_fsid_minor32 = -1;
112 static int hf_nfs_fh_fsid_inode = -1;
113 static int hf_nfs_fh_xfsid_major = -1;
114 static int hf_nfs_fh_xfsid_minor = -1;
115 static int hf_nfs_fh_fstype = -1;
116 static int hf_nfs_fh_fn = -1;
117 static int hf_nfs_fh_fn_len = -1;
118 static int hf_nfs_fh_fn_inode = -1;
119 static int hf_nfs_fh_fn_generation = -1;
120 static int hf_nfs_fh_xfn = -1;
121 static int hf_nfs_fh_xfn_len = -1;
122 static int hf_nfs_fh_xfn_inode = -1;
123 static int hf_nfs_fh_xfn_generation = -1;
124 static int hf_nfs_fh_dentry = -1;
125 /* static int hf_nfs_fh_dev = -1; */
126 /* static int hf_nfs_fh_xdev = -1; */
127 static int hf_nfs_fh_dirinode = -1;
128 static int hf_nfs_fh_pinode = -1;
129 static int hf_nfs_fh_hp_len = -1;
130 static int hf_nfs_fh_hp_key = -1;
131 static int hf_nfs_fh_version = -1;
132 static int hf_nfs_fh_auth_type = -1;
133 static int hf_nfs_fh_fsid_type = -1;
134 static int hf_nfs_fh_fileid_type = -1;
135 static int hf_nfs_fh_obj_id = -1;
136 static int hf_nfs_fh_ro_node = -1;
137 static int hf_nfs_fh_obj = -1;
138 static int hf_nfs_fh_obj_fsid = -1;
139 static int hf_nfs_fh_obj_treeid = -1;
140 static int hf_nfs_fh_obj_kindid = -1;
141 static int hf_nfs_fh_obj_inode = -1;
142 static int hf_nfs_fh_obj_gen = -1;
143 static int hf_nfs_fh_ex = -1;
144 static int hf_nfs_fh_ex_fsid = -1;
145 static int hf_nfs_fh_ex_treeid = -1;
146 static int hf_nfs_fh_ex_kindid = -1;
147 static int hf_nfs_fh_ex_inode = -1;
148 static int hf_nfs_fh_ex_gen = -1;
149 static int hf_nfs_fh_flag = -1;
150 static int hf_nfs_fh_endianness = -1;
151 static int hf_nfs_fh_dc_opaque = -1;
152 static int hf_nfs_fh_dc_exportid = -1;
153 static int hf_nfs_fh_dc_handle_type = -1;
154 static int hf_nfs4_fh_pd_share = -1;
155 static int hf_nfs4_fh_pd_flags = -1;
156 static int hf_nfs4_fh_pd_flags_reserved = -1;
157 static int hf_nfs4_fh_pd_flags_version = -1;
158 static int hf_nfs4_fh_pd_container = -1;
159 static int hf_nfs4_fh_pd_inum = -1;
160 static int hf_nfs4_fh_pd_sites = -1;
161 static int hf_nfs4_fh_pd_sites_inum = -1;
162 static int hf_nfs4_fh_pd_sites_siteid = -1;
163 static int hf_nfs4_fh_pd_spaces = -1;
164 static int hf_nfs4_fh_pd_spaces_snapid = -1;
165 static int hf_nfs4_fh_pd_spaces_container = -1;
166 static int hf_nfs_full_name = -1;
167 static int hf_nfs_name = -1;
168 static int hf_nfs_data = -1;
169 static int hf_nfs_symlink_to = -1;
170 static int hf_nfs_readdir_eof = -1;
171 static int hf_nfs_readdir_entry = -1;
172 static int hf_nfs_atime = -1;
173 static int hf_nfs_atime_sec = -1;
174 static int hf_nfs_atime_nsec = -1;
175 static int hf_nfs_atime_usec = -1;
176 static int hf_nfs_mtime = -1;
177 static int hf_nfs_mtime_sec = -1;
178 static int hf_nfs_mtime_nsec = -1;
179 static int hf_nfs_mtime_usec = -1;
180 static int hf_nfs_ctime = -1;
181 static int hf_nfs_ctime_sec = -1;
182 static int hf_nfs_ctime_nsec = -1;
183 static int hf_nfs_ctime_usec = -1;
184 static int hf_nfs_dtime = -1;
185 static int hf_nfs_dtime_sec = -1;
186 static int hf_nfs_dtime_nsec = -1;
187
188 /* Hidden field for v2, v3, and v4 status; also used in dissect-nfsacl.c */
189 int hf_nfs_status = -1;
190
191 /* NFSv2 RFC 1094 hf variables */
192 static int hf_nfs2_procedure = -1;
193 static int hf_nfs2_status = -1;
194 static int hf_nfs2_readlink_data = -1;
195 /* static int hf_nfs2_fattr_type = -1; */
196 static int hf_nfs2_fattr_nlink = -1;
197 static int hf_nfs2_fattr_uid = -1;
198 static int hf_nfs2_fattr_gid = -1;
199 static int hf_nfs2_fattr_size = -1;
200 static int hf_nfs2_fattr_blocksize = -1;
201 static int hf_nfs2_fattr_rdev = -1;
202 static int hf_nfs2_fattr_blocks = -1;
203 static int hf_nfs2_fattr_fsid = -1;
204 static int hf_nfs2_fattr_fileid = -1;
205 static int hf_nfs2_ftype = -1;
206 static int hf_nfs2_mode = -1;
207 static int hf_nfs2_mode_name = -1;
208 static int hf_nfs2_mode_set_user_id = -1;
209 static int hf_nfs2_mode_set_group_id = -1;
210 static int hf_nfs2_mode_save_swap_text = -1;
211 static int hf_nfs2_mode_read_owner = -1;
212 static int hf_nfs2_mode_write_owner = -1;
213 static int hf_nfs2_mode_exec_owner = -1;
214 static int hf_nfs2_mode_read_group = -1;
215 static int hf_nfs2_mode_write_group = -1;
216 static int hf_nfs2_mode_exec_group = -1;
217 static int hf_nfs2_mode_read_other = -1;
218 static int hf_nfs2_mode_write_other = -1;
219 static int hf_nfs2_mode_exec_other = -1;
220 static int hf_nfs2_read_offset = -1;
221 static int hf_nfs2_read_count = -1;
222 static int hf_nfs2_read_totalcount = -1;
223 static int hf_nfs2_write_beginoffset = -1;
224 static int hf_nfs2_write_offset = -1;
225 static int hf_nfs2_write_totalcount = -1;
226 static int hf_nfs2_readdir_cookie = -1;
227 static int hf_nfs2_readdir_count = -1;
228 static int hf_nfs2_readdir_entry_fileid = -1;
229 static int hf_nfs2_readdir_entry_name = -1;
230 static int hf_nfs2_readdir_entry_cookie = -1;
231 static int hf_nfs2_statfs_tsize = -1;
232 static int hf_nfs2_statfs_bsize = -1;
233 static int hf_nfs2_statfs_blocks = -1;
234 static int hf_nfs2_statfs_bfree = -1;
235 static int hf_nfs2_statfs_bavail = -1;
236
237 /* NFSv3 RFC 1813 header format variables */
238 static int hf_nfs3_procedure = -1;
239 static int hf_nfs3_fattr_type = -1;
240 static int hf_nfs3_fattr_nlink = -1;
241 static int hf_nfs3_fattr_uid = -1;
242 static int hf_nfs3_fattr_gid = -1;
243 static int hf_nfs3_fattr_size = -1;
244 static int hf_nfs3_fattr_used = -1;
245 /* static int hf_nfs3_fattr_rdev = -1; */
246 static int hf_nfs3_fattr_fsid = -1;
247 static int hf_nfs3_fattr_fileid = -1;
248 static int hf_nfs3_wcc_attr_size = -1;
249 static int hf_nfs3_set_size = -1;
250 static int hf_nfs3_cookie = -1;
251 static int hf_nfs3_fsstat_resok_tbytes = -1;
252 static int hf_nfs3_fsstat_resok_fbytes = -1;
253 static int hf_nfs3_fsstat_resok_abytes = -1;
254 static int hf_nfs3_fsstat_resok_tfiles = -1;
255 static int hf_nfs3_fsstat_resok_ffiles = -1;
256 static int hf_nfs3_fsstat_resok_afiles = -1;
257 static int hf_nfs3_uid = -1;
258 static int hf_nfs3_gid = -1;
259 static int hf_nfs3_offset = -1;
260 static int hf_nfs3_count = -1;
261 static int hf_nfs3_count_maxcount = -1;
262 static int hf_nfs3_count_dircount= -1;
263 static int hf_nfs3_mode = -1;
264 static int hf_nfs3_mode_suid = -1;
265 static int hf_nfs3_mode_sgid = -1;
266 static int hf_nfs3_mode_sticky = -1;
267 static int hf_nfs3_mode_rusr = -1;
268 static int hf_nfs3_mode_wusr = -1;
269 static int hf_nfs3_mode_xusr = -1;
270 static int hf_nfs3_mode_rgrp = -1;
271 static int hf_nfs3_mode_wgrp = -1;
272 static int hf_nfs3_mode_xgrp = -1;
273 static int hf_nfs3_mode_roth = -1;
274 static int hf_nfs3_mode_woth = -1;
275 static int hf_nfs3_mode_xoth = -1;
276 static int hf_nfs3_readdir_entry_fileid = -1;
277 static int hf_nfs3_readdir_entry_name = -1;
278 static int hf_nfs3_readdir_entry_cookie = -1;
279 static int hf_nfs3_readdirplus_entry_fileid = -1;
280 static int hf_nfs3_readdirplus_entry_name = -1;
281 static int hf_nfs3_readdirplus_entry_cookie = -1;
282 static int hf_nfs3_ftype = -1;
283 static int hf_nfs3_status = -1;
284 static int hf_nfs3_read_eof = -1;
285 static int hf_nfs3_write_stable = -1;
286 static int hf_nfs3_write_committed = -1;
287 static int hf_nfs3_createmode = -1;
288 static int hf_nfs3_fsstat_invarsec = -1;
289 static int hf_nfs3_fsinfo_rtmax = -1;
290 static int hf_nfs3_fsinfo_rtpref = -1;
291 static int hf_nfs3_fsinfo_rtmult = -1;
292 static int hf_nfs3_fsinfo_wtmax = -1;
293 static int hf_nfs3_fsinfo_wtpref = -1;
294 static int hf_nfs3_fsinfo_wtmult = -1;
295 static int hf_nfs3_fsinfo_dtpref = -1;
296 static int hf_nfs3_fsinfo_maxfilesize = -1;
297 static int hf_nfs3_fsinfo_properties = -1;
298 static int hf_nfs3_fsinfo_properties_setattr = -1;
299 static int hf_nfs3_fsinfo_properties_pathconf = -1;
300 static int hf_nfs3_fsinfo_properties_symlinks = -1;
301 static int hf_nfs3_fsinfo_properties_hardlinks = -1;
302 static int hf_nfs3_pathconf_linkmax = -1;
303 static int hf_nfs3_pathconf_name_max = -1;
304 static int hf_nfs3_pathconf_no_trunc = -1;
305 static int hf_nfs3_pathconf_chown_restricted = -1;
306 static int hf_nfs3_pathconf_case_insensitive = -1;
307 static int hf_nfs3_pathconf_case_preserving = -1;
308 static int hf_nfs3_gxfh_utlfield = -1;
309 static int hf_nfs3_gxfh_utlfield_tree = -1;
310 static int hf_nfs3_gxfh_utlfield_jun = -1;
311 static int hf_nfs3_gxfh_utlfield_ver = -1;
312 static int hf_nfs3_gxfh_volcnt = -1;
313 static int hf_nfs3_gxfh_epoch = -1;
314 static int hf_nfs3_gxfh_ldsid = -1;
315 static int hf_nfs3_gxfh_cid = -1;
316 static int hf_nfs3_gxfh_resv = -1;
317 static int hf_nfs3_gxfh_sfhflags = -1;
318 static int hf_nfs3_gxfh_sfhflags_resv1 = -1;
319 static int hf_nfs3_gxfh_sfhflags_resv2 = -1;
320 static int hf_nfs3_gxfh_sfhflags_ontap7G = -1;
321 static int hf_nfs3_gxfh_sfhflags_ontapGX = -1;
322 static int hf_nfs3_gxfh_sfhflags_striped = -1;
323 static int hf_nfs3_gxfh_sfhflags_empty = -1;
324 static int hf_nfs3_gxfh_sfhflags_snapdirent = -1;
325 static int hf_nfs3_gxfh_sfhflags_snapdir = -1;
326 static int hf_nfs3_gxfh_sfhflags_streamdir = -1;
327 static int hf_nfs3_gxfh_spinfid = -1;
328 static int hf_nfs3_gxfh_spinfuid = -1;
329 static int hf_nfs3_gxfh_exportptid = -1;
330 static int hf_nfs3_gxfh_exportptuid = -1;
331 static int hf_nfs3_verifier = -1;
332 static int hf_nfs3_specdata1 = -1;
333 static int hf_nfs3_specdata2 = -1;
334 static int hf_nfs3_attributes_follow = -1;
335 static int hf_nfs3_handle_follow = -1;
336 static int hf_nfs3_sattrguard3 = -1;
337
338
339 /* NFSv4 RFC 5661 header format variables */
340 static int hf_nfs4_procedure = -1;
341 static int hf_nfs4_status = -1;
342 static int hf_nfs4_op = -1;
343 static int hf_nfs4_main_opcode = -1;
344 static int hf_nfs4_linktext = -1;
345 static int hf_nfs4_tag = -1;
346 static int hf_nfs4_ops_count = -1;
347 static int hf_nfs4_pathname_components = -1;
348 static int hf_nfs4_component = -1;
349 static int hf_nfs4_clientid = -1;
350 /* static int hf_nfs4_ace = -1; */
351 static int hf_nfs4_recall = -1;
352 static int hf_nfs4_open_claim_type = -1;
353 static int hf_nfs4_opentype = -1;
354 static int hf_nfs4_state_protect_how = -1;
355 static int hf_nfs4_limit_by = -1;
356 static int hf_nfs4_open_delegation_type = -1;
357 static int hf_nfs4_why_no_delegation = -1;
358 static int hf_nfs4_ftype = -1;
359 static int hf_nfs4_change_info_atomic = -1;
360 static int hf_nfs4_open_share_access = -1;
361 static int hf_nfs4_open_share_deny = -1;
362 static int hf_nfs4_want_flags = -1;
363 static int hf_nfs4_want_notify_flags = -1;
364 static int hf_nfs4_want_signal_deleg_when_resrc_avail = -1;
365 static int hf_nfs4_want_push_deleg_when_uncontended = -1;
366 static int hf_nfs4_want_deleg_timestamps = -1;
367 static int hf_nfs4_seqid = -1;
368 static int hf_nfs4_lock_seqid = -1;
369 static int hf_nfs4_reqd_attr = -1;
370 static int hf_nfs4_reco_attr = -1;
371 static int hf_nfs4_attr_mask = -1;
372 static int hf_nfs4_attr_count = -1;
373 static int hf_nfs4_set_it_value_follows = -1;
374 static int hf_nfs4_time_how = -1;
375 static int hf_nfs4_time_how4 = -1;
376 static int hf_nfs4_fattr_link_support = -1;
377 static int hf_nfs4_fattr_symlink_support = -1;
378 static int hf_nfs4_fattr_named_attr = -1;
379 static int hf_nfs4_fattr_unique_handles = -1;
380 static int hf_nfs4_fattr_archive = -1;
381 static int hf_nfs4_fattr_cansettime = -1;
382 static int hf_nfs4_fattr_case_insensitive = -1;
383 static int hf_nfs4_fattr_case_preserving = -1;
384 static int hf_nfs4_fattr_chown_restricted = -1;
385 static int hf_nfs4_fattr_fh_expire_type = -1;
386 static int hf_nfs4_fattr_fh_expiry_noexpire_with_open = -1;
387 static int hf_nfs4_fattr_fh_expiry_volatile_any = -1;
388 static int hf_nfs4_fattr_fh_expiry_vol_migration = -1;
389 static int hf_nfs4_fattr_fh_expiry_vol_rename = -1;
390 static int hf_nfs4_fattr_hidden = -1;
391 static int hf_nfs4_fattr_homogeneous = -1;
392 static int hf_nfs4_fattr_mimetype = -1;
393 static int hf_nfs4_fattr_no_trunc = -1;
394 static int hf_nfs4_fattr_system = -1;
395 static int hf_nfs4_fattr_owner = -1;
396 static int hf_nfs4_fattr_owner_group = -1;
397 static int hf_nfs4_fattr_size = -1;
398 static int hf_nfs4_fattr_aclsupport = -1;
399 static int hf_nfs4_aclsupport_allow_acl = -1;
400 static int hf_nfs4_aclsupport_deny_acl = -1;
401 static int hf_nfs4_aclsupport_audit_acl = -1;
402 static int hf_nfs4_aclsupport_alarm_acl = -1;
403 static int hf_nfs4_fattr_lease_time = -1;
404 static int hf_nfs4_fattr_fs_charset_cap = -1;
405 static int hf_nfs4_fs_charset_cap_nonutf8 = -1;
406 static int hf_nfs4_fs_charset_cap_utf8 = -1;
407 static int hf_nfs4_fattr_fileid = -1;
408 static int hf_nfs4_fattr_files_avail = -1;
409 static int hf_nfs4_fattr_files_free = -1;
410 static int hf_nfs4_fattr_files_total = -1;
411 static int hf_nfs4_fattr_maxfilesize = -1;
412 static int hf_nfs4_fattr_maxlink = -1;
413 static int hf_nfs4_fattr_maxname = -1;
414 static int hf_nfs4_fattr_numlinks = -1;
415 static int hf_nfs4_fattr_maxread = -1;
416 static int hf_nfs4_fattr_maxwrite = -1;
417 static int hf_nfs4_fattr_quota_hard = -1;
418 static int hf_nfs4_fattr_quota_soft = -1;
419 static int hf_nfs4_fattr_quota_used = -1;
420 static int hf_nfs4_fattr_space_avail = -1;
421 static int hf_nfs4_fattr_space_free = -1;
422 static int hf_nfs4_fattr_space_total = -1;
423 static int hf_nfs4_fattr_space_used = -1;
424 static int hf_nfs4_fattr_mounted_on_fileid = -1;
425 static int hf_nfs4_fattr_layout_blksize = -1;
426 static int hf_nfs4_mdsthreshold_item = -1;
427 static int hf_nfs4_mdsthreshold_hint_mask = -1;
428 static int hf_nfs4_mdsthreshold_hint_count = -1;
429 static int hf_nfs4_mdsthreshold_mask_count = -1;
430 static int hf_nfs4_mdsthreshold_hint_file = -1;
431 static int hf_nfs4_fattr_security_label_lfs = -1;
432 static int hf_nfs4_fattr_security_label_pi = -1;
433 static int hf_nfs4_fattr_security_label_context = -1;
434 static int hf_nfs4_fattr_umask_mask = -1;
435 static int hf_nfs4_fattr_xattr_support = -1;
436 static int hf_nfs4_fattr_offline = -1;
437 static int hf_nfs4_who = -1;
438 static int hf_nfs4_server = -1;
439 static int hf_nfs4_servers = -1;
440 static int hf_nfs4_fslocation = -1;
441 static int hf_nfs4_stable_how = -1;
442 static int hf_nfs4_dirlist_eof = -1;
443 static int hf_nfs4_offset = -1;
444 static int hf_nfs4_specdata1 = -1;
445 static int hf_nfs4_specdata2 = -1;
446 static int hf_nfs4_lock_type = -1;
447 static int hf_nfs4_open_rflags = -1;
448 static int hf_nfs4_open_rflags_confirm = -1;
449 static int hf_nfs4_open_rflags_locktype_posix = -1;
450 static int hf_nfs4_open_rflags_preserve_unlinked = -1;
451 static int hf_nfs4_open_rflags_may_notify_lock = -1;
452 static int hf_nfs4_reclaim = -1;
453 static int hf_nfs4_length = -1;
454 static int hf_nfs4_changeid = -1;
455 static int hf_nfs4_changeid_before = -1;
456 static int hf_nfs4_changeid_after = -1;
457 static int hf_nfs4_time_seconds = -1;
458 static int hf_nfs4_time_nseconds = -1;
459 static int hf_nfs4_fsid_major = -1;
460 static int hf_nfs4_fsid_minor = -1;
461 static int hf_nfs4_acetype = -1;
462 static int hf_nfs4_aceflags = -1;
463 static int hf_nfs4_aceflag_file_inherit = -1;
464 static int hf_nfs4_aceflag_dir_inherit = -1;
465 static int hf_nfs4_aceflag_no_prop_inherit = -1;
466 static int hf_nfs4_aceflag_inherit_only = -1;
467 static int hf_nfs4_aceflag_successful_access = -1;
468 static int hf_nfs4_aceflag_failed_access = -1;
469 static int hf_nfs4_aceflag_id_group = -1;
470 static int hf_nfs4_aceflag_inherited_ace = -1;
471 static int hf_nfs4_acemask = -1;
472 static int hf_nfs4_ace_permission = -1;
473 static int hf_nfs4_delegate_type = -1;
474 static int hf_nfs4_secinfo_flavor = -1;
475 static int hf_nfs4_secinfo_arr = -1;
476 static int hf_nfs4_num_blocks = -1;
477 static int hf_nfs4_bytes_per_block = -1;
478 static int hf_nfs4_eof = -1;
479 static int hf_nfs4_verifier = -1;
480 static int hf_nfs4_value_follows = -1;
481 static int hf_nfs4_cookie = -1;
482 static int hf_nfs4_dir_entry_name = -1;
483 static int hf_nfs4_cookie_verf = -1;
484 static int hf_nfs4_cb_program = -1;
485 /* static int hf_nfs4_cb_location = -1; */
486 static int hf_nfs4_recall4 = -1;
487 static int hf_nfs4_filesize = -1;
488 static int hf_nfs4_count = -1;
489 static int hf_nfs4_count_dircount = -1;
490 static int hf_nfs4_count_maxcount = -1;
491 static int hf_nfs4_minorversion = -1;
492 static int hf_nfs4_open_owner = -1;
493 static int hf_nfs4_lock_owner = -1;
494 static int hf_nfs4_new_lock_owner = -1;
495 static int hf_nfs4_sec_oid = -1;
496 static int hf_nfs4_qop = -1;
497 static int hf_nfs4_secinfo_rpcsec_gss_info_service = -1;
498 static int hf_nfs4_attr_dir_create = -1;
499 static int hf_nfs4_client_id = -1;
500 static int hf_nfs4_stateid = -1;
501 static int hf_nfs4_seqid_stateid = -1;
502 static int hf_nfs4_stateid_other = -1;
503 static int hf_nfs4_stateid_hash = -1;
504 static int hf_nfs4_stateid_other_hash = -1;
505 static int hf_nfs4_lock_reclaim = -1;
506 static int hf_nfs4_aclflags = -1;
507 static int hf_nfs4_aclflag_auto_inherit = -1;
508 static int hf_nfs4_aclflag_protected = -1;
509 static int hf_nfs4_aclflag_defaulted = -1;
510 static int hf_nfs4_num_aces = -1;
511 static int hf_nfs4_callback_ident = -1;
512 static int hf_nfs4_r_netid = -1;
513 static int hf_nfs4_gsshandle = -1;
514 static int hf_nfs4_r_addr = -1;
515 static int hf_nfs4_createmode = -1;
516 static int hf_nfs4_op_mask = -1;
517 static int hf_nfs4_read_data_length = -1;
518 static int hf_nfs4_write_data_length = -1;
519 static int hf_nfs4_length_minlength = -1;
520 static int hf_nfs4_layout_type = -1;
521 static int hf_nfs4_layout_return_type = -1;
522 static int hf_nfs4_iomode = -1;
523 /* static int hf_nfs4_stripetype = -1; */
524 /* static int hf_nfs4_mdscommit = -1; */
525 static int hf_nfs4_stripeunit = -1;
526 static int hf_nfs4_newtime = -1;
527 static int hf_nfs4_newoffset = -1;
528 static int hf_nfs4_layout_avail = -1;
529 static int hf_nfs4_newsize = -1;
530 static int hf_nfs4_layoutupdate = -1;
531 static int hf_nfs4_deviceid = -1;
532 static int hf_nfs4_devicenum = -1;
533 static int hf_nfs4_deviceidx = -1;
534 static int hf_nfs4_layout = -1;
535 /* static int hf_nfs4_stripedevs = -1; */
536 /* static int hf_nfs4_devaddr = -1; */
537 static int hf_nfs4_devaddr_ssv_start = -1;
538 static int hf_nfs4_devaddr_ssv_length = -1;
539 static int hf_nfs4_devaddr_scsi_vol_type = -1;
540 static int hf_nfs4_devaddr_scsi_vol_index = -1;
541 static int hf_nfs4_devaddr_scsi_vol_ref_index = -1;
542 static int hf_nfs4_devaddr_ssv_stripe_unit = -1;
543 static int hf_nfs4_devaddr_scsi_vpd_code_set = -1;
544 static int hf_nfs4_devaddr_scsi_vpd_designator_type = -1;
545 static int hf_nfs4_devaddr_scsi_vpd_designator = -1;
546 static int hf_nfs4_devaddr_scsi_private_key = -1;
547 static int hf_nfs4_scsil_ext_file_offset = -1;
548 static int hf_nfs4_scsil_ext_length = -1;
549 static int hf_nfs4_scsil_ext_vol_offset = -1;
550 static int hf_nfs4_scsil_ext_state = -1;
551 static int hf_nfs4_return_on_close = -1;
552 static int hf_nfs4_slotid = -1;
553 static int hf_nfs4_high_slotid = -1;
554 static int hf_nfs4_target_high_slotid = -1;
555 static int hf_nfs4_serverscope4 = -1;
556 static int hf_nfs4_minorid = -1;
557 static int hf_nfs4_majorid = -1;
558 static int hf_nfs4_padsize = -1;
559 /* static int hf_nfs4_cbrenforce = -1; */
560 /* static int hf_nfs4_hashalg = -1; */
561 /* static int hf_nfs4_ssvlen = -1; */
562 static int hf_nfs4_maxreqsize = -1;
563 static int hf_nfs4_maxrespsize = -1;
564 static int hf_nfs4_maxrespsizecached = -1;
565 static int hf_nfs4_maxops = -1;
566 static int hf_nfs4_maxreqs = -1;
567 static int hf_nfs4_rdmachanattrs = -1;
568 static int hf_nfs4_machinename = -1;
569 static int hf_nfs4_flavor = -1;
570 static int hf_nfs4_stamp = -1;
571 static int hf_nfs4_uid = -1;
572 static int hf_nfs4_gid = -1;
573 static int hf_nfs4_service = -1;
574 static int hf_nfs4_sessionid = -1;
575 static int hf_nfs4_exchid_call_flags = -1;
576 static int hf_nfs4_exchid_reply_flags = -1;
577 static int hf_nfs4_exchid_flags_moved_refer = -1;
578 static int hf_nfs4_exchid_flags_moved_migr = -1;
579 static int hf_nfs4_exchid_flags_bind_princ = -1;
580 static int hf_nfs4_exchid_flags_non_pnfs = -1;
581 static int hf_nfs4_exchid_flags_pnfs_mds = -1;
582 static int hf_nfs4_exchid_flags_pnfs_ds = -1;
583 static int hf_nfs4_exchid_flags_upd_conf_rec_a = -1;
584 static int hf_nfs4_exchid_flags_confirmed_r = -1;
585 static int hf_nfs4_state_protect_window = -1;
586 static int hf_nfs4_state_protect_num_gss_handles = -1;
587 static int hf_nfs4_sp_parms_hash_algs = -1;
588 static int hf_nfs4_sp_parms_encr_algs = -1;
589 static int hf_nfs4_prot_info_spi_window = -1;
590 static int hf_nfs4_prot_info_svv_length = -1;
591 static int hf_nfs4_prot_info_encr_alg = -1;
592 static int hf_nfs4_prot_info_hash_alg = -1;
593 static int hf_nfs4_nii_domain = -1;
594 static int hf_nfs4_nii_name = -1;
595 static int hf_nfs4_create_session_flags_csa = -1;
596 static int hf_nfs4_create_session_flags_csr = -1;
597 static int hf_nfs4_create_session_flags_persist = -1;
598 static int hf_nfs4_create_session_flags_conn_back_chan = -1;
599 static int hf_nfs4_create_session_flags_conn_rdma = -1;
600 static int hf_nfs4_cachethis = -1;
601 /* static int hf_nfs4_util = -1; */
602 /* static int hf_nfs4_first_stripe_idx = -1; */
603 /* static int hf_nfs4_layout_count = -1; */
604 /* static int hf_nfs4_pattern_offset = -1; */
605 static int hf_nfs4_notification_mask = -1;
606 static int hf_nfs4_notification_type = -1;
607 static int hf_nfs4_lrs_present = -1;
608 static int hf_nfs4_nfl_mirrors = -1;
609 static int hf_nfs4_nfl_util = -1;
610 static int hf_nfs4_nfl_util_stripe_size = -1;
611 static int hf_nfs4_nfl_util_commit_thru_mds = -1;
612 static int hf_nfs4_nfl_util_dense = -1;
613 static int hf_nfs4_nfl_fhs = -1;
614 static int hf_nfs4_mirror_eff = -1;
615 static int hf_nfs4_nfl_first_stripe_index = -1;
616 static int hf_nfs4_lrf_body_content = -1;
617 static int hf_nfs4_reclaim_one_fs = -1;
618 static int hf_nfs4_bctsa_dir = -1;
619 static int hf_nfs4_bctsa_use_conn_in_rdma_mode = -1;
620 static int hf_nfs4_bctsr_dir = -1;
621 static int hf_nfs4_bctsr_use_conn_in_rdma_mode = -1;
622 static int hf_nfs4_sequence_status_flags = -1;
623 static int hf_nfs4_sequence_status_flags_cb_path_down = -1;
624 static int hf_nfs4_sequence_status_flags_cb_gss_contexts_expiring = -1;
625 static int hf_nfs4_sequence_status_flags_cb_gss_contexts_expired = -1;
626 static int hf_nfs4_sequence_status_flags_expired_all_state_revoked = -1;
627 static int hf_nfs4_sequence_status_flags_expired_some_state_revoked = -1;
628 static int hf_nfs4_sequence_status_flags_admin_state_revoked = -1;
629 static int hf_nfs4_sequence_status_flags_recallable_state_revoked = -1;
630 static int hf_nfs4_sequence_status_flags_lease_moved = -1;
631 static int hf_nfs4_sequence_status_flags_restart_reclaim_needed = -1;
632 static int hf_nfs4_sequence_status_flags_cb_path_down_session = -1;
633 static int hf_nfs4_sequence_status_flags_backchannel_fault = -1;
634 static int hf_nfs4_sequence_status_flags_devid_changed = -1;
635 static int hf_nfs4_sequence_status_flags_devid_deleted = -1;
636 static int hf_nfs4_secinfo_style = -1;
637 static int hf_nfs4_test_stateid_arg = -1;
638 static int hf_nfs4_test_stateid_res = -1;
639 static int hf_nfs4_seek_data_content = -1;
640 /* static int hf_nfs4_impl_id_len = -1; */
641 static int hf_nfs4_bitmap_data = -1;
642 static int hf_nfs4_huge_bitmap_length = -1;
643 static int hf_nfs4_universal_address_ipv4 = -1;
644 static int hf_nfs4_universal_address_ipv6 = -1;
645 static int hf_nfs4_getdevinfo = -1;
646 static int hf_nfs4_ff_version = -1;
647 static int hf_nfs4_ff_minorversion = -1;
648 static int hf_nfs4_ff_tightly_coupled = -1;
649 static int hf_nfs4_ff_rsize = -1;
650 static int hf_nfs4_ff_wsize = -1;
651 static int hf_nfs4_fattr_clone_blocksize = -1;
652 static int hf_nfs4_fattr_space_freed = -1;
653 static int hf_nfs4_fattr_change_attr_type = -1;
654 static int hf_nfs4_ff_layout_flags = -1;
655 static int hf_nfs4_ff_layout_flags_no_layoutcommit = -1;
656 static int hf_nfs4_ff_layout_flags_no_io_thru_mds = -1;
657 static int hf_nfs4_ff_layout_flags_no_read_io = -1;
658 static int hf_nfs4_ff_stats_collect_hint = -1;
659 static int hf_nfs4_ff_synthetic_owner = -1;
660 static int hf_nfs4_ff_synthetic_owner_group = -1;
661 static int hf_nfs4_ff_bytes_completed = -1;
662 static int hf_nfs4_ff_bytes_not_delivered = -1;
663 static int hf_nfs4_ff_bytes_requested = -1;
664 static int hf_nfs4_ff_local = -1;
665 static int hf_nfs4_ff_ops_completed = -1;
666 static int hf_nfs4_ff_ops_requested = -1;
667 static int hf_nfs4_io_bytes = -1;
668 static int hf_nfs4_io_count = -1;
669 static int hf_nfs4_layoutstats = -1;
670 static int hf_nfs4_callback_stateids = -1;
671 static int hf_nfs4_callback_stateids_index = -1;
672 static int hf_nfs4_num_offload_status = -1;
673 static int hf_nfs4_offload_status_index = -1;
674 static int hf_nfs4_consecutive = -1;
675 static int hf_nfs4_netloc = -1;
676 static int hf_nfs4_netloc_type = -1;
677 static int hf_nfs4_nl_name = -1;
678 static int hf_nfs4_nl_url = -1;
679 static int hf_nfs4_source_server_index = -1;
680 static int hf_nfs4_source_servers = -1;
681 static int hf_nfs4_synchronous = -1;
682 static int hf_nfs4_device_error_count = -1;
683 static int hf_nfs4_device_errors_index = -1;
684 static int hf_nfs4_ff_ioerrs_count = -1;
685 static int hf_nfs4_ff_ioerrs_index = -1;
686 static int hf_nfs4_ff_ioerrs_length = -1;
687 static int hf_nfs4_ff_ioerrs_offset = -1;
688 static int hf_nfs4_ff_iostats_count = -1;
689 static int hf_nfs4_ff_iostats_index = -1;
690 static int hf_nfs4_io_error_op = -1;
691 static int hf_nfs4_io_hints_mask = -1;
692 static int hf_nfs4_io_hint_count = -1;
693 static int hf_nfs4_io_advise_hint = -1;
694 static int hf_nfs4_bytes_copied = -1;
695 static int hf_nfs4_read_plus_contents = -1;
696 static int hf_nfs4_read_plus_content_type = -1;
697 static int hf_nfs4_block_size = -1;
698 static int hf_nfs4_block_count = -1;
699 static int hf_nfs4_reloff_blocknum = -1;
700 static int hf_nfs4_blocknum = -1;
701 static int hf_nfs4_reloff_pattern = -1;
702 static int hf_nfs4_pattern_hash = -1;
703 static int hf_nfs4_setxattr_options = -1;
704 static int hf_nfs4_listxattr_maxcount = -1;
705 static int hf_nfs4_listxattr_cookie = -1;
706 static int hf_nfs4_listxattr_names_len = -1;
707 static int hf_nfs4_xattrkey = -1;
708 static int hf_nfs4_listxattr_eof = -1;
709
710 static gint ett_nfs = -1;
711 static gint ett_nfs_fh_encoding = -1;
712 static gint ett_nfs_fh_mount = -1;
713 static gint ett_nfs_fh_file = -1;
714 static gint ett_nfs_fh_export = -1;
715 static gint ett_nfs_fh_fsid = -1;
716 static gint ett_nfs_fh_xfsid = -1;
717 static gint ett_nfs_fh_fn = -1;
718 static gint ett_nfs_fh_xfn = -1;
719 static gint ett_nfs_fh_hp = -1;
720 static gint ett_nfs_fh_auth = -1;
721 static gint ett_nfs_fhandle = -1;
722 static gint ett_nfs_timeval = -1;
723 static gint ett_nfs_fattr = -1;
724 static gint ett_nfs_readdir_entry = -1;
725 static gint ett_nfs_fh_obj = -1;
726 static gint ett_nfs_fh_ex = -1;
727 static gint ett_nfs_utf8string = -1;
728
729 static gint ett_nfs2_mode = -1;
730 static gint ett_nfs2_sattr = -1;
731 static gint ett_nfs2_diropargs = -1;
732
733 static gint ett_nfs3_mode = -1;
734 static gint ett_nfs3_specdata = -1;
735 static gint ett_nfs3_fh = -1;
736 static gint ett_nfs3_nfstime = -1;
737 static gint ett_nfs3_fattr = -1;
738 static gint ett_nfs3_post_op_fh = -1;
739 static gint ett_nfs3_sattr = -1;
740 static gint ett_nfs3_diropargs = -1;
741 static gint ett_nfs3_sattrguard = -1;
742 static gint ett_nfs3_set_mode = -1;
743 static gint ett_nfs3_set_uid = -1;
744 static gint ett_nfs3_set_gid = -1;
745 static gint ett_nfs3_set_size = -1;
746 static gint ett_nfs3_set_atime = -1;
747 static gint ett_nfs3_set_mtime = -1;
748 static gint ett_nfs3_pre_op_attr = -1;
749 static gint ett_nfs3_post_op_attr = -1;
750 static gint ett_nfs3_wcc_attr = -1;
751 static gint ett_nfs3_wcc_data = -1;
752 static gint ett_nfs3_access = -1;
753 static gint ett_nfs3_fsinfo_properties = -1;
754 static gint ett_nfs3_gxfh_utlfield = -1;
755 static gint ett_nfs3_gxfh_sfhfield = -1;
756 static gint ett_nfs3_gxfh_sfhflags = -1;
757 static gint ett_nfs4_fh_pd_flags = -1;
758 static gint ett_nfs4_fh_pd_sites = -1;
759 static gint ett_nfs4_fh_pd_spaces = -1;
760
761 static gint ett_nfs4_compound_call = -1;
762 static gint ett_nfs4_request_op = -1;
763 static gint ett_nfs4_response_op = -1;
764 static gint ett_nfs4_access = -1;
765 static gint ett_nfs4_access_supp = -1;
766 static gint ett_nfs4_close = -1;
767 static gint ett_nfs4_commit = -1;
768 static gint ett_nfs4_create = -1;
769 static gint ett_nfs4_delegpurge = -1;
770 static gint ett_nfs4_delegreturn = -1;
771 static gint ett_nfs4_getattr = -1;
772 static gint ett_nfs4_getattr_args = -1;
773 static gint ett_nfs4_getattr_resp = -1;
774 static gint ett_nfs4_resok4 = -1;
775 static gint ett_nfs4_obj_attrs = -1;
776 static gint ett_nfs4_fattr_new_attr_vals = -1;
777 static gint ett_nfs4_fattr4_attrmask = -1;
778 static gint ett_nfs4_attribute = -1;
779 static gint ett_nfs4_getfh = -1;
780 static gint ett_nfs4_link = -1;
781 static gint ett_nfs4_lock = -1;
782 static gint ett_nfs4_lockt = -1;
783 static gint ett_nfs4_locku = -1;
784 static gint ett_nfs4_lookup = -1;
785 static gint ett_nfs4_lookupp = -1;
786 static gint ett_nfs4_nverify = -1;
787 static gint ett_nfs4_open = -1;
788 static gint ett_nfs4_openattr = -1;
789 static gint ett_nfs4_open_confirm = -1;
790 static gint ett_nfs4_open_downgrade = -1;
791 static gint ett_nfs4_putfh = -1;
792 static gint ett_nfs4_putpubfh = -1;
793 static gint ett_nfs4_putrootfh = -1;
794 static gint ett_nfs4_read = -1;
795 static gint ett_nfs4_readdir = -1;
796 static gint ett_nfs4_readlink = -1;
797 static gint ett_nfs4_remove = -1;
798 static gint ett_nfs4_rename = -1;
799 static gint ett_nfs4_renew = -1;
800 static gint ett_nfs4_restorefh = -1;
801 static gint ett_nfs4_savefh = -1;
802 static gint ett_nfs4_secinfo = -1;
803 static gint ett_nfs4_setattr = -1;
804 static gint ett_nfs4_setclientid = -1;
805 static gint ett_nfs4_setclientid_confirm = -1;
806 static gint ett_nfs4_verify = -1;
807 static gint ett_nfs4_write = -1;
808 static gint ett_nfs4_release_lockowner = -1;
809 static gint ett_nfs4_backchannel_ctl = -1;
810 static gint ett_nfs4_illegal = -1;
811 static gint ett_nfs4_verifier = -1;
812 static gint ett_nfs4_dirlist = -1;
813 static gint ett_nfs4_dir_entry = -1;
814 static gint ett_nfs4_pathname = -1;
815 static gint ett_nfs4_change_info = -1;
816 static gint ett_nfs4_open_delegation = -1;
817 static gint ett_nfs4_open_claim = -1;
818 static gint ett_nfs4_opentype = -1;
819 static gint ett_nfs4_lock_owner = -1;
820 static gint ett_nfs4_cb_client = -1;
821 static gint ett_nfs4_client_id = -1;
822 static gint ett_nfs4_clientowner = -1;
823 static gint ett_nfs4_exchangeid_call_flags = -1;
824 static gint ett_nfs4_exchangeid_reply_flags = -1;
825 static gint ett_nfs4_server_owner = -1;
826 static gint ett_nfs4_bitmap = -1;
827 static gint ett_nfs4_attr_request = -1;
828 static gint ett_nfs4_fattr = -1;
829 static gint ett_nfs4_fsid = -1;
830 static gint ett_nfs4_fs_locations = -1;
831 static gint ett_nfs4_fs_location = -1;
832 static gint ett_nfs4_open_result_flags = -1;
833 static gint ett_nfs4_secinfo_flavor_info = -1;
834 static gint ett_nfs4_stateid = -1;
835 static gint ett_nfs4_fattr_fh_expire_type = -1;
836 static gint ett_nfs4_fattr_fs_charset_cap = -1;
837 static gint ett_nfs4_fattr_aclsupport = -1;
838 static gint ett_nfs4_aclflag = -1;
839 static gint ett_nfs4_ace = -1;
840 static gint ett_nfs4_clientaddr = -1;
841 static gint ett_nfs4_aceflag = -1;
842 static gint ett_nfs4_acemask = -1;
843 static gint ett_nfs4_create_session_flags = -1;
844 static gint ett_nfs4_sequence_status_flags = -1;
845 static gint ett_nfs4_fh_file = -1;
846 static gint ett_nfs4_fh_file_flags = -1;
847 static gint ett_nfs4_fh_export = -1;
848 static gint ett_nfs4_layoutget = -1;
849 static gint ett_nfs4_layoutcommit = -1;
850 static gint ett_nfs4_layoutreturn = -1;
851 static gint ett_nfs4_getdevinfo = -1;
852 static gint ett_nfs4_getdevlist = -1;
853 static gint ett_nfs4_bind_conn_to_session = -1;
854 static gint ett_nfs4_exchange_id = -1;
855 static gint ett_nfs4_create_session = -1;
856 static gint ett_nfs4_destroy_session = -1;
857 static gint ett_nfs4_free_stateid = -1;
858 static gint ett_nfs4_secinfo_no_name = -1;
859 static gint ett_nfs4_sequence = -1;
860 static gint ett_nfs4_slotid = -1;
861 static gint ett_nfs4_sr_status = -1;
862 static gint ett_nfs4_serverscope = -1;
863 static gint ett_nfs4_minorid = -1;
864 static gint ett_nfs4_majorid = -1;
865 static gint ett_nfs4_persist = -1;
866 static gint ett_nfs4_backchan = -1;
867 static gint ett_nfs4_rdmamode = -1;
868 static gint ett_nfs4_padsize = -1;
869 static gint ett_nfs4_cbrenforce = -1;
870 static gint ett_nfs4_hashalg = -1;
871 static gint ett_nfs4_ssvlen = -1;
872 static gint ett_nfs4_maxreqsize = -1;
873 static gint ett_nfs4_maxrespsize = -1;
874 static gint ett_nfs4_maxrespsizecached = -1;
875 static gint ett_nfs4_maxops = -1;
876 static gint ett_nfs4_maxreqs = -1;
877 static gint ett_nfs4_streamchanattrs = -1;
878 static gint ett_nfs4_rdmachanattrs = -1;
879 static gint ett_nfs4_machinename = -1;
880 static gint ett_nfs4_flavor = -1;
881 static gint ett_nfs4_stamp = -1;
882 static gint ett_nfs4_uid = -1;
883 static gint ett_nfs4_gid = -1;
884 static gint ett_nfs4_service = -1;
885 static gint ett_nfs4_sessionid = -1;
886 static gint ett_nfs4_layoutseg = -1;
887 static gint ett_nfs4_layoutseg_sub = -1;
888 static gint ett_nfs4_nfl_util = -1;
889 static gint ett_nfs4_test_stateid = -1;
890 static gint ett_nfs4_destroy_clientid = -1;
891 static gint ett_nfs4_reclaim_complete = -1;
892 static gint ett_nfs4_allocate = -1;
893 static gint ett_nfs4_deallocate = -1;
894 static gint ett_nfs4_seek = -1;
895 static gint ett_nfs4_chan_attrs = -1;
896 static gint ett_nfs4_want_notify_flags = -1;
897 static gint ett_nfs4_ff_layout_flags = -1;
898 static gint ett_nfs4_scsi_layout_vol = -1;
899 static gint ett_nfs4_scsi_layout_vol_indices = -1;
900 static gint ett_nfs4_layoutstats = -1;
901 static gint ett_nfs4_io_info = -1;
902 static gint ett_nfs4_io_latency = -1;
903 static gint ett_nfs4_io_time = -1;
904 static gint ett_nfs4_callback_stateids_sub = -1;
905 static gint ett_nfs4_source_servers_sub = -1;
906 static gint ett_nfs4_copy = -1;
907 static gint ett_nfs4_copy_notify = -1;
908 static gint ett_nfs4_device_errors_sub = -1;
909 static gint ett_nfs4_layouterror = -1;
910 static gint ett_nfs4_ff_ioerrs_sub = -1;
911 static gint ett_nfs4_ff_iostats_sub = -1;
912 static gint ett_nfs4_clone = -1;
913 static gint ett_nfs4_getxattr = -1;
914 static gint ett_nfs4_setxattr = -1;
915 static gint ett_nfs4_listxattr = -1;
916 static gint ett_nfs4_removexattr = -1;
917 static gint ett_nfs4_offload_cancel = -1;
918 static gint ett_nfs4_offload_status = -1;
919 static gint ett_nfs4_osr_complete_sub = -1;
920 static gint ett_nfs4_io_advise = -1;
921 static gint ett_nfs4_read_plus = -1;
922 static gint ett_nfs4_read_plus_content_sub = -1;
923 static gint ett_nfs4_write_same = -1;
924 static gint ett_nfs4_listxattr_names = -1;
925
926 static expert_field ei_nfs_too_many_ops = EI_INIT;
927 static expert_field ei_nfs_not_vnx_file = EI_INIT;
928 static expert_field ei_protocol_violation = EI_INIT;
929 static expert_field ei_nfs_too_many_bitmaps = EI_INIT;
930 static expert_field ei_nfs_bitmap_no_dissector = EI_INIT;
931 static expert_field ei_nfs_bitmap_skip_value = EI_INIT;
932 static expert_field ei_nfs_bitmap_undissected_data = EI_INIT;
933 static expert_field ei_nfs4_stateid_deprecated = EI_INIT;
934 static expert_field ei_nfs_file_system_cycle = EI_INIT;
935
936 static const true_false_string tfs_read_write = { "Read", "Write" };
937
938 /*
939 * Bitmaps are currently used for attributes and state_protect bits.
940 * Currently we don't expect more than 4 words, but future protocol
941 * revisions might add more bits, and in theory an implementation
942 * might legally zero-pad a bitmask out to something longer. We keep
943 * a generous maximum here just as a sanity check:
944 */
945 #define MAX_BITMAPS 100
946
947 /* Prototype for function to dissect attribute value */
948 typedef int (dissect_bitmap_item_t)(tvbuff_t *tvb, int offset, packet_info *pinfo,
949 rpc_call_info_value *civ, proto_tree *attr_tree, proto_item *attr_item,
950 guint32 bit_num, void *battr_data);
951
952 /* Prototype for function to return the header field for the item label */
953 typedef int (get_bitmap_hinfo_t)(guint32 bit_num);
954
955 /* Bitmap type */
956 typedef enum {
957 NFS4_BITMAP_MASK, /* Dissect the bitmap mask only */
958 NFS4_BITMAP_VALUES /* Dissect the bitmap mask and their values */
959 } nfs4_bitmap_type_t;
960
961 /*
962 * Bitmap info structure to customize dissect_nfs4_bitmap() behavior
963 * Do not display the item when its corresponding hf_* label is set to NULL
964 */
965 typedef struct _nfs4_bitmap_info_t {
966 value_string_ext *vse_names_ext; /* Extended value strings which maps bit number to attribute name,
967 * append list of attribute names to the attr mask header line */
968 dissect_bitmap_item_t *dissect_battr; /* Function to dissect attribute value given by the bit number */
969
970 void *battr_data; /* Data pass to function dissect_battr */
971
972 int *hf_mask_label; /* Label for bitmap mask. If this is set to NULL the mask bytes are just consumed */
973 int *hf_item_label; /* Label for bitmap item (see get_item_label below) */
974 int *hf_item_count; /* Label for hidden attribute to display the number of bits set */
975 int *hf_mask_count; /* Label to display the number of masks in the bitmap */
976 int *hf_btmap_data; /* Label to display bitmap value data as an opaque */
977
978 get_bitmap_hinfo_t *get_item_label; /* Pointer to function to return a dynamically generated hf variable
979 * for the item label, this takes precedence over hf_item_label */
980 } nfs4_bitmap_info_t;
981
982 /* Types of fhandles we can dissect */
983 static dissector_table_t nfs_fhandle_table;
984
985 typedef struct nfs_fhandle_data {
986 int len;
987 const unsigned char *fh;
988 } nfs_fhandle_data_t;
989
990 /* For dissector helpers which take a "levels" argument to indicate how
991 * many expansions up they should populate the expansion items with
992 * text to enhance useability, this flag to "levels" specify that the
993 * text should also be appended to COL_INFO
994 */
995 #define COL_INFO_LEVEL 0x80000000
996
997
998 /* fhandle displayfilters to match also corresponding request/response
999 packet in addition to the one containing the actual filehandle */
1000 gboolean nfs_fhandle_reqrep_matching = FALSE;
1001 static wmem_tree_t *nfs_fhandle_frame_table = NULL;
1002
1003
1004 /* file name snooping */
1005 gboolean nfs_file_name_snooping = FALSE;
1006 static gboolean nfs_file_name_full_snooping = FALSE;
1007 typedef struct nfs_name_snoop {
1008 int fh_length;
1009 unsigned char *fh;
1010 int name_len;
1011 char *name;
1012 int parent_len;
1013 unsigned char *parent;
1014 int full_name_len;
1015 char *full_name;
1016 bool fs_cycle;
1017 } nfs_name_snoop_t;
1018
1019 typedef struct nfs_name_snoop_key {
1020 int key;
1021 int fh_length;
1022 const unsigned char *fh;
1023 } nfs_name_snoop_key_t;
1024
1025 static GHashTable *nfs_name_snoop_unmatched = NULL;
1026
1027 static GHashTable *nfs_name_snoop_matched = NULL;
1028
1029 static wmem_tree_t *nfs_name_snoop_known = NULL;
1030 static wmem_tree_t *nfs_file_handles = NULL;
1031
1032 static gboolean nfs_display_v4_tag = TRUE;
1033 static gboolean display_major_nfs4_ops = TRUE;
1034
1035 /* Types of RDMA reduced opaque data */
1036 typedef enum {
1037 R_UTF8STRING,
1038 R_NFS2_PATH,
1039 R_NFS3_PATH,
1040 R_NFSDATA,
1041 } rdma_reduce_type_t;
1042
1043 static int dissect_nfsdata_reduced(rdma_reduce_type_t rtype, tvbuff_t *tvb,
1044 int offset, proto_tree *tree, int hf, const char **name);
1045
1046 static int dissect_nfs4_stateid(tvbuff_t *tvb, int offset, proto_tree *tree, guint16 *hash);
1047
nfs_prompt(packet_info * pinfo _U_,gchar * result)1048 static void nfs_prompt(packet_info *pinfo _U_, gchar* result)
1049 {
1050 g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Decode NFS file handles as");
1051 }
1052
1053 /* This function will store one nfs filehandle in our global tree of
1054 * filehandles.
1055 * We store all filehandles we see in this tree so that every unique
1056 * filehandle is only stored once with a unique pointer.
1057 * We need to store pointers to filehandles in several of our other
1058 * structures and this is a way to make sure we don't keep any redundant
1059 * copies around for a specific filehandle.
1060 *
1061 * If this is the first time this filehandle has been seen an se block
1062 * is allocated to store the filehandle in.
1063 * If this filehandle has already been stored in the tree this function returns
1064 * a pointer to the original copy.
1065 */
1066 static nfs_fhandle_data_t *
store_nfs_file_handle(nfs_fhandle_data_t * nfs_fh)1067 store_nfs_file_handle(nfs_fhandle_data_t *nfs_fh)
1068 {
1069 guint32 fhlen;
1070 guint32 *fhdata;
1071 wmem_tree_key_t fhkey[3];
1072 nfs_fhandle_data_t *new_nfs_fh;
1073
1074 fhlen = nfs_fh->len/4;
1075 /* align the file handle data */
1076 fhdata = (guint32 *)g_memdup2(nfs_fh->fh, fhlen*4);
1077 fhkey[0].length = 1;
1078 fhkey[0].key = &fhlen;
1079 fhkey[1].length = fhlen;
1080 fhkey[1].key = fhdata;
1081 fhkey[2].length = 0;
1082
1083 new_nfs_fh = (nfs_fhandle_data_t *)wmem_tree_lookup32_array(nfs_file_handles, &fhkey[0]);
1084 if (new_nfs_fh) {
1085 g_free(fhdata);
1086 return new_nfs_fh;
1087 }
1088
1089 new_nfs_fh = wmem_new(wmem_file_scope(), nfs_fhandle_data_t);
1090 new_nfs_fh->len = nfs_fh->len;
1091 new_nfs_fh->fh = (const unsigned char *)wmem_memdup(wmem_file_scope(), nfs_fh->fh, nfs_fh->len);
1092 fhlen = nfs_fh->len/4;
1093 fhkey[0].length = 1;
1094 fhkey[0].key = &fhlen;
1095 fhkey[1].length = fhlen;
1096 fhkey[1].key = fhdata;
1097 fhkey[2].length = 0;
1098 wmem_tree_insert32_array(nfs_file_handles, &fhkey[0], new_nfs_fh);
1099
1100 g_free(fhdata);
1101 return new_nfs_fh;
1102 }
1103
1104
1105 static gint
nfs_name_snoop_matched_equal(gconstpointer k1,gconstpointer k2)1106 nfs_name_snoop_matched_equal(gconstpointer k1, gconstpointer k2)
1107 {
1108 const nfs_name_snoop_key_t *key1 = (const nfs_name_snoop_key_t *)k1;
1109 const nfs_name_snoop_key_t *key2 = (const nfs_name_snoop_key_t *)k2;
1110
1111 return (key1->key == key2->key)
1112 &&(key1->fh_length == key2->fh_length)
1113 &&(!memcmp(key1->fh, key2->fh, key1->fh_length));
1114 }
1115
1116
1117 static guint
nfs_name_snoop_matched_hash(gconstpointer k)1118 nfs_name_snoop_matched_hash(gconstpointer k)
1119 {
1120 const nfs_name_snoop_key_t *key = (const nfs_name_snoop_key_t *)k;
1121 int i;
1122 guint hash;
1123
1124 hash = key->key;
1125 for (i=0; i<key->fh_length; i++)
1126 hash ^= key->fh[i];
1127
1128 return hash;
1129 }
1130
1131
1132 static gint
nfs_name_snoop_unmatched_equal(gconstpointer k1,gconstpointer k2)1133 nfs_name_snoop_unmatched_equal(gconstpointer k1, gconstpointer k2)
1134 {
1135 guint32 key1 = GPOINTER_TO_UINT(k1);
1136 guint32 key2 = GPOINTER_TO_UINT(k2);
1137
1138 return key1 == key2;
1139 }
1140
1141
1142 static guint
nfs_name_snoop_unmatched_hash(gconstpointer k)1143 nfs_name_snoop_unmatched_hash(gconstpointer k)
1144 {
1145 guint32 key = GPOINTER_TO_UINT(k);
1146
1147 return key;
1148 }
1149
1150
1151 static void
nfs_name_snoop_value_destroy(gpointer value)1152 nfs_name_snoop_value_destroy(gpointer value)
1153 {
1154 nfs_name_snoop_t *nns = (nfs_name_snoop_t *)value;
1155
1156 g_free((gpointer)nns->name);
1157 g_free((gpointer)nns->full_name);
1158 wmem_free(NULL, nns->parent);
1159 wmem_free(NULL, nns->fh);
1160 g_free(nns);
1161 }
1162
1163
1164 static void
nfs_name_snoop_init(void)1165 nfs_name_snoop_init(void)
1166 {
1167 nfs_name_snoop_unmatched =
1168 g_hash_table_new_full(nfs_name_snoop_unmatched_hash,
1169 nfs_name_snoop_unmatched_equal,
1170 NULL, nfs_name_snoop_value_destroy);
1171 nfs_name_snoop_matched =
1172 g_hash_table_new_full(nfs_name_snoop_matched_hash,
1173 nfs_name_snoop_matched_equal,
1174 NULL, nfs_name_snoop_value_destroy);
1175 }
1176
1177 static void
nfs_name_snoop_cleanup(void)1178 nfs_name_snoop_cleanup(void)
1179 {
1180 g_hash_table_destroy(nfs_name_snoop_unmatched);
1181 g_hash_table_destroy(nfs_name_snoop_matched);
1182 }
1183
1184
1185 void
nfs_name_snoop_add_name(int xid,tvbuff_t * tvb,int name_offset,int name_len,int parent_offset,int parent_len,const char * name)1186 nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len, int parent_offset,
1187 int parent_len, const char *name)
1188 {
1189 nfs_name_snoop_t *nns;
1190 const char *ptr;
1191
1192 if (name_len <= 0) {
1193 /* Do we need some way to signal an error here? This could be
1194 * programmatic or just a corrupt packet, depending on the
1195 * caller... */
1196 return;
1197 }
1198
1199 /* filter out all '.' and '..' names */
1200 if (!name) {
1201 ptr = (const char *)tvb_get_ptr(tvb, name_offset, name_len);
1202 } else {
1203 ptr = name;
1204 }
1205 if (ptr[0] == '.') {
1206 if (name_len <= 1 || ptr[1] == 0) {
1207 return;
1208 }
1209 if (ptr[1] == '.') {
1210 if (name_len <= 2 || ptr[2] == 0) {
1211 return;
1212 }
1213 }
1214 }
1215
1216 nns = g_new(nfs_name_snoop_t, 1);
1217
1218 nns->fh_length = 0;
1219 nns->fh = NULL;
1220
1221 if (parent_len) {
1222 nns->parent_len = parent_len;
1223 nns->parent = (unsigned char *)tvb_memdup(NULL, tvb, parent_offset, parent_len);
1224 } else {
1225 nns->parent_len = 0;
1226 nns->parent = NULL;
1227 }
1228
1229 if (name) {
1230 nns->name_len = (int)strlen(name);
1231 nns->name = g_strdup(name);
1232 } else {
1233 nns->name_len = name_len;
1234 nns->name = (char *)g_malloc(name_len+1);
1235 memcpy(nns->name, ptr, name_len);
1236 }
1237 nns->name[nns->name_len] = 0;
1238
1239 nns->full_name_len = 0;
1240 nns->full_name = NULL;
1241 nns->fs_cycle = false;
1242
1243 /* any old entry will be deallocated and removed */
1244 g_hash_table_insert(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid), nns);
1245 }
1246
1247
1248 static void
nfs_name_snoop_add_fh(int xid,tvbuff_t * tvb,int fh_offset,int fh_length)1249 nfs_name_snoop_add_fh(int xid, tvbuff_t *tvb, int fh_offset, int fh_length)
1250 {
1251 unsigned char *fh;
1252 nfs_name_snoop_t *nns;
1253 nfs_name_snoop_key_t *key;
1254
1255 /* find which request we correspond to */
1256 nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
1257 if (!nns) {
1258 /* oops couldn't find matching request, bail out */
1259 return;
1260 }
1261
1262 /* if we have already seen this response earlier */
1263 if (nns->fh) {
1264 return;
1265 }
1266
1267 /* oki, we have a new entry */
1268 fh = (unsigned char *)tvb_memdup(NULL, tvb, fh_offset, fh_length);
1269 nns->fh = fh;
1270 nns->fh_length = fh_length;
1271
1272 key = wmem_new(wmem_file_scope(), nfs_name_snoop_key_t);
1273 key->key = 0;
1274 key->fh_length = nns->fh_length;
1275 key->fh = nns->fh;
1276
1277 g_hash_table_steal(nfs_name_snoop_unmatched, GINT_TO_POINTER(xid));
1278 g_hash_table_replace(nfs_name_snoop_matched, key, nns);
1279 }
1280
1281 #define NFS_MAX_FS_DEPTH 100
1282
1283 static void
nfs_full_name_snoop(packet_info * pinfo,nfs_name_snoop_t * nns,int * len,char ** name,char ** pos)1284 nfs_full_name_snoop(packet_info *pinfo, nfs_name_snoop_t *nns, int *len, char **name, char **pos)
1285 {
1286 nfs_name_snoop_t *parent_nns = NULL;
1287 nfs_name_snoop_key_t key;
1288
1289 /* check if the nns component ends with a '/' else we just allocate
1290 an extra byte to len to accommodate for it later */
1291 if (nns->name[nns->name_len-1] != '/') {
1292 (*len)++;
1293 }
1294
1295 (*len) += nns->name_len;
1296
1297 if (nns->parent == NULL) {
1298 *name = (char *)g_malloc((*len)+1);
1299 *pos = *name;
1300
1301 *pos += g_snprintf(*pos, (*len)+1, "%s", nns->name);
1302 DISSECTOR_ASSERT((*pos-*name) <= *len);
1303 return;
1304 }
1305
1306 key.key = 0;
1307 key.fh_length = nns->parent_len;
1308 key.fh = nns->parent;
1309
1310 parent_nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_matched, &key);
1311
1312 if (parent_nns) {
1313 unsigned fs_depth = p_get_proto_depth(pinfo, proto_nfs);
1314 if (++fs_depth >= NFS_MAX_FS_DEPTH) {
1315 nns->fs_cycle = true;
1316 return;
1317 }
1318 p_set_proto_depth(pinfo, proto_nfs, fs_depth);
1319
1320 nfs_full_name_snoop(pinfo, parent_nns, len, name, pos);
1321 if (*name) {
1322 /* make sure components are '/' separated */
1323 *pos += g_snprintf(*pos, (*len+1) - (gulong)(*pos-*name), "%s%s",
1324 ((*pos)[-1] != '/')?"/":"", nns->name);
1325 DISSECTOR_ASSERT((*pos-*name) <= *len);
1326 }
1327 p_set_proto_depth(pinfo, proto_nfs, fs_depth - 1);
1328 return;
1329 }
1330
1331 return;
1332 }
1333
1334
1335 static void
nfs_name_snoop_fh(packet_info * pinfo,proto_tree * tree,tvbuff_t * tvb,int fh_offset,int fh_length,gboolean hidden)1336 nfs_name_snoop_fh(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int fh_offset,
1337 int fh_length, gboolean hidden)
1338 {
1339 nfs_name_snoop_key_t key;
1340 nfs_name_snoop_t *nns = NULL;
1341
1342 /* if this is a new packet, see if we can register the mapping */
1343 if (!pinfo->fd->visited) {
1344 key.key = 0;
1345 key.fh_length = fh_length;
1346 key.fh = (const unsigned char *)tvb_get_ptr(tvb, fh_offset, fh_length);
1347
1348 nns = (nfs_name_snoop_t *)g_hash_table_lookup(nfs_name_snoop_matched, &key);
1349 if (nns) {
1350 guint32 fhlen;
1351 guint32 *fhdata;
1352 wmem_tree_key_t fhkey[3];
1353
1354 fhlen = nns->fh_length;
1355 /* align it */
1356 fhdata = (guint32 *)g_memdup2(nns->fh, fhlen);
1357 fhkey[0].length = 1;
1358 fhkey[0].key = &fhlen;
1359 fhkey[1].length = fhlen/4;
1360 fhkey[1].key = fhdata;
1361 fhkey[2].length = 0;
1362 wmem_tree_insert32_array(nfs_name_snoop_known, &fhkey[0], nns);
1363 g_free(fhdata);
1364
1365 if (nfs_file_name_full_snooping) {
1366 char *name = NULL, *pos = NULL;
1367 int len = 0;
1368
1369 nfs_full_name_snoop(pinfo, nns, &len, &name, &pos);
1370 if (name) {
1371 nns->full_name = name;
1372 nns->full_name_len = len;
1373 }
1374 }
1375 }
1376 }
1377
1378 /* see if we know this mapping */
1379 if (!nns) {
1380 guint32 fhlen;
1381 guint32 *fhdata;
1382 wmem_tree_key_t fhkey[3];
1383
1384 fhlen = fh_length;
1385 /* align it */
1386 fhdata = (guint32 *)tvb_memdup(wmem_packet_scope(), tvb, fh_offset, fh_length);
1387 fhkey[0].length = 1;
1388 fhkey[0].key = &fhlen;
1389 fhkey[1].length = fhlen/4;
1390 fhkey[1].key = fhdata;
1391 fhkey[2].length = 0;
1392
1393 nns = (nfs_name_snoop_t *)wmem_tree_lookup32_array(nfs_name_snoop_known, &fhkey[0]);
1394 }
1395
1396 /* if we know the mapping, print the filename */
1397 if (nns) {
1398 proto_item *fh_item = NULL;
1399
1400 if (hidden) {
1401 fh_item = proto_tree_add_string(tree, hf_nfs_name, NULL,
1402 0, 0, nns->name);
1403 proto_item_set_hidden(fh_item);
1404 } else {
1405 fh_item = proto_tree_add_string(tree, hf_nfs_name, tvb,
1406 fh_offset, 0, nns->name);
1407 }
1408 proto_item_set_generated(fh_item);
1409
1410 if (nns->full_name) {
1411 if (hidden) {
1412 fh_item = proto_tree_add_string(tree, hf_nfs_full_name, NULL,
1413 0, 0, nns->full_name);
1414 proto_item_set_hidden(fh_item);
1415 } else {
1416 fh_item = proto_tree_add_string_format_value(tree, hf_nfs_full_name, tvb,
1417 fh_offset, 0, nns->full_name, "%s", nns->full_name);
1418 }
1419 proto_item_set_generated(fh_item);
1420 }
1421
1422 if (nns->fs_cycle) {
1423 proto_tree_add_expert(tree, pinfo, &ei_nfs_file_system_cycle, tvb, 0, 0);
1424 }
1425 }
1426 }
1427
1428
1429 /* file handle dissection */
1430
1431 static const true_false_string tfs_endianness = { "Little Endian", "Big Endian" };
1432
1433 static void
nfs_fmt_fsid(gchar * result,guint32 revision)1434 nfs_fmt_fsid( gchar *result, guint32 revision )
1435 {
1436 guint32 fsid_major;
1437 guint32 fsid_minor;
1438
1439 fsid_major = ( revision>>18 ) & 0x3fff; /* 14 bits */
1440 fsid_minor = ( revision ) & 0x3ffff; /* 18 bits */
1441
1442 g_snprintf( result, ITEM_LABEL_LENGTH, "%d,%d", fsid_major, fsid_minor);
1443 }
1444
1445 /* SVR4: checked with ReliantUNIX (5.43, 5.44, 5.45), OpenSolaris (build 101a) */
1446 static int
dissect_fhandle_data_SVR4(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)1447 dissect_fhandle_data_SVR4(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1448 {
1449 guint encoding = ENC_BIG_ENDIAN; /* We support little endian and big endian. Default is big endian*/
1450 gboolean have_flag = FALSE; /* The flag field at the end is optional. Assume no flag is there */
1451 gboolean found = FALSE; /* Did we really detect the file handle format? */
1452 guint32 nof = 0;
1453 guint32 len1;
1454 guint32 len2;
1455 guint32 fhlen; /* File handle length. */
1456
1457 static int * const fsid_fields[] = {
1458 &hf_nfs_fh_fsid_major32,
1459 &hf_nfs_fh_fsid_minor32,
1460 NULL
1461 };
1462
1463 /* Somehow this is no calling argument, so we have to re-calculate it. */
1464 fhlen = tvb_reported_length(tvb);
1465
1466 /* Check for little endianness. */
1467 len1 = tvb_get_letohs(tvb, 8);
1468 if (tvb_bytes_exist(tvb, 10+len1, 2)) {
1469 len2 = tvb_get_letohs(tvb, 10+len1);
1470
1471 if (12+len1+len2 == fhlen) {
1472 encoding = ENC_LITTLE_ENDIAN;
1473 have_flag = FALSE;
1474 found = TRUE;
1475 }
1476 if (16+len1+len2 == fhlen) {
1477 encoding = ENC_LITTLE_ENDIAN;
1478 have_flag = TRUE;
1479 found = TRUE;
1480 }
1481 }
1482
1483 if (!found) {
1484 /* Check for big endianness. */
1485 len1 = tvb_get_ntohs(tvb, 8);
1486 if (tvb_bytes_exist(tvb, 10+len1, 2)) {
1487 len2 = tvb_get_ntohs(tvb, 10+len1);
1488
1489 if (12+len1+len2 == fhlen) {
1490 have_flag = FALSE;
1491 }
1492 if (16+len1+len2 == fhlen) {
1493 have_flag = TRUE;
1494 }
1495 }
1496 }
1497
1498 proto_tree_add_boolean(tree, hf_nfs_fh_endianness, tvb, 0, fhlen, (encoding == ENC_LITTLE_ENDIAN));
1499
1500 /* We are fairly sure, that when found == FALSE, the following code will
1501 throw an exception. */
1502
1503 /* file system id */
1504 proto_tree_add_bitmask(tree, tvb, nof, hf_nfs_fh_fsid,
1505 ett_nfs_fh_fsid, fsid_fields, encoding);
1506 nof += 4;
1507
1508 /* file system type */
1509 proto_tree_add_item(tree, hf_nfs_fh_fstype, tvb, nof, 4, encoding);
1510 nof += 4;
1511
1512 /* file number */
1513 {
1514 guint32 fn_O;
1515 guint32 fn_len_O;
1516 guint32 fn_len_L;
1517 guint32 fn_len;
1518 guint32 fn_data_O;
1519 guint32 fn_data_inode_O;
1520 guint32 fn_data_inode_L;
1521 guint32 inode;
1522 guint32 fn_data_gen_O;
1523 guint32 fn_data_gen_L;
1524 guint32 gen;
1525 guint32 fn_L;
1526
1527 fn_O = nof;
1528 fn_len_O = fn_O;
1529 fn_len_L = 2;
1530 fn_len = tvb_get_guint16(tvb, fn_len_O, encoding);
1531 fn_data_O = fn_O + fn_len_L;
1532 fn_data_inode_O = fn_data_O + 2;
1533 fn_data_inode_L = 4;
1534 inode = tvb_get_guint32(tvb, fn_data_inode_O, encoding);
1535 fn_data_gen_O = fn_data_inode_O + fn_data_inode_L;
1536 fn_data_gen_L = 4;
1537 gen = tvb_get_guint32(tvb, fn_data_gen_O, encoding);
1538 fn_L = fn_len_L + fn_len;
1539 if (tree) {
1540 proto_item *fn_item = NULL;
1541 proto_tree *fn_tree = NULL;
1542
1543 fn_item = proto_tree_add_uint(tree, hf_nfs_fh_fn, tvb,
1544 fn_O, fn_L, inode);
1545 fn_tree = proto_item_add_subtree(fn_item,
1546 ett_nfs_fh_fn);
1547 proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_len,
1548 tvb, fn_len_O, fn_len_L, fn_len);
1549 proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_inode,
1550 tvb, fn_data_inode_O, fn_data_inode_L, inode);
1551 proto_tree_add_uint(fn_tree, hf_nfs_fh_fn_generation,
1552 tvb, fn_data_gen_O, fn_data_gen_L, gen);
1553 }
1554 nof = fn_O + fn_len_L + fn_len;
1555 }
1556
1557 /* exported file number */
1558 {
1559 guint32 xfn_O;
1560 guint32 xfn_len_O;
1561 guint32 xfn_len_L;
1562 guint32 xfn_len;
1563 guint32 xfn_data_O;
1564 guint32 xfn_data_inode_O;
1565 guint32 xfn_data_inode_L;
1566 guint32 xinode;
1567 guint32 xfn_data_gen_O;
1568 guint32 xfn_data_gen_L;
1569 guint32 xgen;
1570 guint32 xfn_L;
1571
1572 xfn_O = nof;
1573 xfn_len_O = xfn_O;
1574 xfn_len_L = 2;
1575 xfn_len = tvb_get_guint16(tvb, xfn_len_O, encoding);
1576 xfn_data_O = xfn_O + xfn_len_L;
1577 xfn_data_inode_O = xfn_data_O + 2;
1578 xfn_data_inode_L = 4;
1579 xinode = tvb_get_guint32(tvb, xfn_data_inode_O, encoding);
1580 xfn_data_gen_O = xfn_data_inode_O + xfn_data_inode_L;
1581 xfn_data_gen_L = 4;
1582 xgen = tvb_get_guint32(tvb, xfn_data_gen_O, encoding);
1583 xfn_L = xfn_len_L + xfn_len;
1584
1585 if (tree) {
1586 proto_item *xfn_item = NULL;
1587 proto_tree *xfn_tree = NULL;
1588
1589 xfn_item = proto_tree_add_uint(tree, hf_nfs_fh_xfn, tvb,
1590 xfn_O, xfn_L, xinode);
1591 xfn_tree = proto_item_add_subtree(xfn_item,
1592 ett_nfs_fh_xfn);
1593 proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_len,
1594 tvb, xfn_len_O, xfn_len_L, xfn_len);
1595 proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_inode,
1596 tvb, xfn_data_inode_O, xfn_data_inode_L, xinode);
1597 proto_tree_add_uint(xfn_tree, hf_nfs_fh_xfn_generation,
1598 tvb, xfn_data_gen_O, xfn_data_gen_L, xgen);
1599 }
1600 nof = xfn_O + xfn_len_L + xfn_len;
1601 }
1602
1603 /* flag */
1604 if (have_flag)
1605 proto_tree_add_item(tree, hf_nfs_fh_flag, tvb, nof, 4, encoding);
1606
1607 return tvb_captured_length(tvb);
1608 }
1609
1610
1611 /* Checked with RedHat Linux 6.2 (kernel 2.2.14 knfsd) */
1612
1613 static int
dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)1614 dissect_fhandle_data_LINUX_KNFSD_LE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1615 {
1616 if (tree) {
1617 int offset = 0;
1618 guint32 temp;
1619 guint32 fsid_major;
1620 guint32 fsid_minor;
1621 guint32 xfsid_major;
1622 guint32 xfsid_minor;
1623
1624 temp = tvb_get_letohs (tvb, offset+12);
1625 fsid_major = (temp >> 8) & 0xff;
1626 fsid_minor = (temp ) & 0xff;
1627 temp = tvb_get_letohs(tvb, offset+16);
1628 xfsid_major = (temp >> 8) & 0xff;
1629 xfsid_minor = (temp ) & 0xff;
1630
1631 proto_tree_add_item(tree, hf_nfs_fh_dentry, tvb, offset+0, 4, ENC_LITTLE_ENDIAN);
1632 proto_tree_add_item(tree, hf_nfs_fh_fn_inode, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
1633 proto_tree_add_item(tree, hf_nfs_fh_dirinode, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
1634
1635 /* file system id (device) */
1636 {
1637 proto_tree *fsid_tree;
1638
1639 fsid_tree = proto_tree_add_subtree_format(tree, tvb,
1640 offset+12, 4, ett_nfs_fh_fsid, NULL,
1641 "file system ID: %d,%d",
1642 fsid_major, fsid_minor);
1643 proto_tree_add_item(fsid_tree, hf_nfs_fh_fsid_major16_mask, tvb, offset+12, 2, ENC_LITTLE_ENDIAN);
1644 proto_tree_add_item(fsid_tree, hf_nfs_fh_fsid_minor16_mask, tvb, offset+12, 2, ENC_LITTLE_ENDIAN);
1645 }
1646
1647 /* exported file system id (device) */
1648 {
1649 proto_tree *xfsid_tree;
1650
1651 xfsid_tree = proto_tree_add_subtree_format(tree, tvb,
1652 offset+16, 4, ett_nfs_fh_xfsid, NULL,
1653 "exported file system ID: %d,%d", xfsid_major, xfsid_minor);
1654 proto_tree_add_item(xfsid_tree, hf_nfs_fh_xfsid_major, tvb, offset+16, 2, ENC_LITTLE_ENDIAN);
1655 proto_tree_add_item(xfsid_tree, hf_nfs_fh_xfsid_minor, tvb, offset+16, 2, ENC_LITTLE_ENDIAN);
1656 }
1657
1658 proto_tree_add_item(tree, hf_nfs_fh_xfn_inode, tvb, offset+20, 4, ENC_LITTLE_ENDIAN);
1659 proto_tree_add_item(tree, hf_nfs_fh_fn_generation, tvb, offset+24, 4, ENC_LITTLE_ENDIAN);
1660 }
1661 return tvb_captured_length(tvb);
1662 }
1663
1664
1665 /* Checked with RedHat Linux 5.2 (nfs-server 2.2beta47 user-land nfsd) */
1666
1667 static int
dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)1668 dissect_fhandle_data_LINUX_NFSD_LE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1669 {
1670 int offset = 0;
1671
1672 /* pseudo inode */
1673 proto_tree_add_item(tree, hf_nfs_fh_pinode, tvb, offset+0, 4, ENC_LITTLE_ENDIAN);
1674
1675 /* hash path */
1676 {
1677 guint32 hashlen;
1678
1679 hashlen = tvb_get_guint8(tvb, offset+4);
1680 if (tree) {
1681 proto_tree *hash_tree;
1682
1683 hash_tree = proto_tree_add_subtree_format(tree, tvb, offset+4, hashlen + 1, ett_nfs_fh_hp, NULL,
1684 "hash path: %s", tvb_bytes_to_str(wmem_packet_scope(), tvb, offset+5, hashlen));
1685 proto_tree_add_uint(hash_tree,
1686 hf_nfs_fh_hp_len, tvb, offset+4, 1,
1687 hashlen);
1688 proto_tree_add_item(hash_tree, hf_nfs_fh_hp_key, tvb, offset+5, hashlen, ENC_NA);
1689 }
1690 }
1691 return tvb_captured_length(tvb);
1692 }
1693
1694
1695 static int
dissect_fhandle_data_NETAPP(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)1696 dissect_fhandle_data_NETAPP(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1697 {
1698 int offset = 0;
1699 static int * const flags[] = {
1700 &hf_nfs_fh_file_flag_mntpoint,
1701 &hf_nfs_fh_file_flag_snapdir,
1702 &hf_nfs_fh_file_flag_snapdir_ent,
1703 &hf_nfs_fh_file_flag_empty,
1704 &hf_nfs_fh_file_flag_vbn_access,
1705 &hf_nfs_fh_file_flag_multivolume,
1706 &hf_nfs_fh_file_flag_metadata,
1707 NULL
1708 };
1709
1710 if (tree) {
1711 guint32 mount = tvb_get_letohl(tvb, offset + 0);
1712
1713 guint32 inum = tvb_get_ntohl( tvb, offset + 12);
1714 guint32 nfsexport = tvb_get_letohl(tvb, offset + 24);
1715 guint32 export_snapgen = tvb_get_letohl(tvb, offset + 28);
1716
1717 proto_tree *subtree = NULL;
1718
1719 subtree = proto_tree_add_subtree_format(tree, tvb, offset + 0, 8,
1720 ett_nfs_fh_mount, NULL, "mount (inode %u)", mount);
1721 proto_tree_add_uint(subtree, hf_nfs_fh_mount_fileid,
1722 tvb, offset + 0, 4, mount);
1723 proto_tree_add_item(subtree, hf_nfs_fh_mount_generation, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1724 subtree = proto_tree_add_subtree_format(tree, tvb, offset + 8, 16,
1725 ett_nfs_fh_file, NULL, "file (inode %u)", inum);
1726
1727 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);
1728
1729 proto_tree_add_item(subtree, hf_nfs_fh_snapid, tvb, offset + 10, 1, ENC_NA);
1730 proto_tree_add_item(subtree, hf_nfs_fh_unused, tvb, offset + 11, 1, ENC_NA);
1731 proto_tree_add_item(subtree, hf_nfs_fh_fileid, tvb, offset + 12, 4, ENC_BIG_ENDIAN);
1732 proto_tree_add_item(subtree, hf_nfs_fh_generation, tvb, offset + 16, 4, ENC_LITTLE_ENDIAN);
1733 proto_tree_add_item(subtree, hf_nfs_fh_fsid, tvb, offset + 20, 4, ENC_LITTLE_ENDIAN);
1734 subtree = proto_tree_add_subtree_format(tree, tvb, offset + 24, 8,
1735 ett_nfs_fh_export, NULL, "export (inode %u)", nfsexport);
1736 proto_tree_add_uint(subtree, hf_nfs_fh_export_fileid,
1737 tvb, offset + 24, 4, nfsexport);
1738 proto_tree_add_uint(subtree,
1739 hf_nfs_fh_export_generation,
1740 tvb, offset + 28, 3,
1741 export_snapgen & 0xffffff);
1742 proto_tree_add_uint(subtree, hf_nfs_fh_export_snapid,
1743 tvb, offset + 31, 1,
1744 export_snapgen >> 24);
1745 }
1746 return tvb_captured_length(tvb);
1747 }
1748
1749 static const value_string handle_type_strings[] = {
1750 { 0, "NORMAL" },
1751 { 1, "UNEXP" },
1752 { 2, "VOLDIR" },
1753 { 3, "ROOT" },
1754 { 4, "ABSENT" },
1755 { 0, NULL }
1756 };
1757
1758 static int
dissect_fhandle_data_NETAPP_V4(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)1759 dissect_fhandle_data_NETAPP_V4(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1760 {
1761 static int * const flags[] = {
1762 &hf_nfs_fh_file_flag_mntpoint,
1763 &hf_nfs_fh_file_flag_snapdir,
1764 &hf_nfs_fh_file_flag_snapdir_ent,
1765 &hf_nfs_fh_file_flag_empty,
1766 &hf_nfs_fh_file_flag_vbn_access,
1767 &hf_nfs_fh_file_flag_multivolume,
1768 &hf_nfs_fh_file_flag_metadata,
1769 &hf_nfs_fh_file_flag_orphan,
1770 &hf_nfs_fh_file_flag_foster,
1771 &hf_nfs_fh_file_flag_named_attr,
1772 &hf_nfs_fh_file_flag_exp_snapdir,
1773 &hf_nfs_fh_file_flag_vfiler,
1774 &hf_nfs_fh_file_flag_aggr,
1775 &hf_nfs_fh_file_flag_striped,
1776 &hf_nfs_fh_file_flag_private,
1777 &hf_nfs_fh_file_flag_next_gen,
1778 NULL
1779 };
1780
1781 if (tree == NULL)
1782 return tvb_captured_length(tvb);
1783
1784 {
1785 int offset = 0;
1786 proto_tree *subtree;
1787 guint32 fileid;
1788 guint32 handle_type;
1789 guint32 inum;
1790 guint encoding;
1791
1792 handle_type = tvb_get_ntohl(tvb, offset + 24);
1793 inum = tvb_get_ntohl(tvb, offset + 12);
1794
1795 if ( handle_type != 0 && handle_type <= 255) {
1796 encoding = ENC_BIG_ENDIAN;
1797 } else {
1798 encoding = ENC_LITTLE_ENDIAN;
1799 }
1800 fileid = tvb_get_guint32(tvb, offset, encoding);
1801 subtree = proto_tree_add_subtree_format(tree, tvb, offset + 0, 8, ett_nfs4_fh_export, NULL, "export (inode %u)", fileid);
1802
1803 proto_tree_add_item(subtree, hf_nfs_fh_export_fileid, tvb, offset + 0, 4, encoding);
1804 proto_tree_add_item(subtree, hf_nfs_fh_export_generation, tvb, offset + 4, 4, encoding);
1805 subtree = proto_tree_add_subtree_format(tree, tvb, offset + 8, 16, ett_nfs4_fh_file, NULL, "file (inode %u)", inum);
1806
1807 proto_tree_add_bitmask_with_flags(subtree, tvb, offset + 8, hf_nfs_fh_flags, ett_nfs4_fh_file_flags, flags, encoding, BMT_NO_FALSE);
1808
1809 proto_tree_add_item(subtree, hf_nfs_fh_snapid, tvb, offset + 10, 1, ENC_NA);
1810 proto_tree_add_item(subtree, hf_nfs_fh_unused, tvb, offset + 11, 1, ENC_NA);
1811 proto_tree_add_item(subtree, hf_nfs_fh_fileid, tvb, offset + 12, 4, encoding);
1812 proto_tree_add_item(subtree, hf_nfs_fh_generation, tvb, offset + 16, 4, encoding);
1813 proto_tree_add_item(subtree, hf_nfs_fh_fsid, tvb, offset + 20, 4, encoding);
1814 proto_tree_add_item(tree, hf_nfs_fh_handle_type, tvb, offset+24, 4, encoding);
1815 }
1816 return tvb_captured_length(tvb);
1817 }
1818
1819 #define NETAPP_GX_FH3_LENGTH 44
1820 #define NFS3GX_FH_TREE_MASK 0x80
1821 #define NFS3GX_FH_JUN_MASK 0x40
1822 #define NFS3GX_FH_VER_MASK 0x3F
1823 #define SPINNP_FH_FLAG_RESV1 0x80
1824 #define SPINNP_FH_FLAG_RESV2 0x40
1825 #define SPINNP_FH_FLAG_ONTAP_MASK 0x20
1826 #define SPINNP_FH_FLAG_STRIPED_MASK 0x10
1827 #define SPINNP_FH_FLAG_EMPTY_MASK 0x08
1828 #define SPINNP_FH_FLAG_SNAPDIR_ENT_MASK 0x04
1829 #define SPINNP_FH_FLAG_SNAPDIR_MASK 0x02
1830 #define SPINNP_FH_FLAG_STREAMDIR_MASK 0x01
1831
1832 static int
dissect_fhandle_data_NETAPP_GX_v3(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)1833 dissect_fhandle_data_NETAPP_GX_v3(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1834 {
1835 if (tree) {
1836 proto_tree *field_tree;
1837 guint8 flags;
1838 guint32 offset = 0;
1839 static int * const fh_flags[] = {
1840 &hf_nfs3_gxfh_sfhflags_resv1,
1841 &hf_nfs3_gxfh_sfhflags_resv2,
1842 &hf_nfs3_gxfh_sfhflags_ontapGX,
1843 &hf_nfs3_gxfh_sfhflags_striped,
1844 &hf_nfs3_gxfh_sfhflags_empty,
1845 &hf_nfs3_gxfh_sfhflags_snapdirent,
1846 &hf_nfs3_gxfh_sfhflags_snapdir,
1847 &hf_nfs3_gxfh_sfhflags_streamdir,
1848 NULL
1849 };
1850
1851 static int * const fh_flags_ontap[] = {
1852 &hf_nfs3_gxfh_sfhflags_resv1,
1853 &hf_nfs3_gxfh_sfhflags_resv2,
1854 &hf_nfs3_gxfh_sfhflags_ontap7G,
1855 &hf_nfs3_gxfh_sfhflags_striped,
1856 &hf_nfs3_gxfh_sfhflags_empty,
1857 &hf_nfs3_gxfh_sfhflags_snapdirent,
1858 &hf_nfs3_gxfh_sfhflags_snapdir,
1859 &hf_nfs3_gxfh_sfhflags_streamdir,
1860 NULL
1861 };
1862
1863 static int * const utility_flags[] = {
1864 &hf_nfs3_gxfh_utlfield_tree,
1865 &hf_nfs3_gxfh_utlfield_jun,
1866 &hf_nfs3_gxfh_utlfield_ver,
1867 NULL
1868 };
1869
1870 /* = utility = */
1871 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs3_gxfh_utlfield, ett_nfs3_gxfh_utlfield, utility_flags, ENC_NA);
1872
1873 /* = volume count== */
1874 proto_tree_add_item(tree, hf_nfs3_gxfh_volcnt, tvb, offset+1, 1, ENC_NA);
1875 /* = epoch = */
1876 proto_tree_add_item(tree, hf_nfs3_gxfh_epoch, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1877 /* = spin file handle = */
1878 flags = tvb_get_guint8(tvb, offset+11);
1879
1880 field_tree = proto_tree_add_subtree(tree, tvb, offset+4, 16,
1881 ett_nfs3_gxfh_sfhfield, NULL, " spin file handle");
1882
1883 proto_tree_add_item(field_tree, hf_nfs3_gxfh_ldsid, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1884 proto_tree_add_item(field_tree, hf_nfs3_gxfh_cid, tvb, offset+8, 2, ENC_BIG_ENDIAN);
1885 proto_tree_add_item(field_tree, hf_nfs3_gxfh_resv, tvb, offset+10, 1, ENC_BIG_ENDIAN);
1886
1887 if (flags & SPINNP_FH_FLAG_ONTAP_MASK) {
1888 proto_tree_add_bitmask(field_tree, tvb, offset+11, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags_ontap, ENC_NA);
1889 }
1890 else {
1891 proto_tree_add_bitmask(field_tree, tvb, offset+11, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags, ENC_NA);
1892 }
1893
1894 proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfid, tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
1895 proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfuid, tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
1896
1897 /* = spin file handle (mount point) = */
1898 flags = tvb_get_guint8(tvb, offset+27);
1899
1900 field_tree = proto_tree_add_subtree(tree, tvb, offset+20, 16,
1901 ett_nfs3_gxfh_sfhfield, NULL, " spin (mount point) file handle");
1902
1903 proto_tree_add_item(field_tree, hf_nfs3_gxfh_ldsid, tvb, offset+20, 4, ENC_BIG_ENDIAN);
1904 proto_tree_add_item(field_tree, hf_nfs3_gxfh_cid, tvb, offset+24, 2, ENC_BIG_ENDIAN);
1905 proto_tree_add_item(field_tree, hf_nfs3_gxfh_resv, tvb, offset+26, 1, ENC_BIG_ENDIAN);
1906
1907 if (flags & SPINNP_FH_FLAG_ONTAP_MASK) {
1908 proto_tree_add_bitmask(field_tree, tvb, offset+27, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags_ontap, ENC_NA);
1909 }
1910 else {
1911 proto_tree_add_bitmask(field_tree, tvb, offset+27, hf_nfs3_gxfh_sfhflags, ett_nfs3_gxfh_sfhflags, fh_flags, ENC_NA);
1912 }
1913
1914 proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfid, tvb, offset+28, 4, ENC_LITTLE_ENDIAN);
1915 proto_tree_add_item(field_tree, hf_nfs3_gxfh_spinfuid, tvb, offset+32, 4, ENC_LITTLE_ENDIAN);
1916 /* = export point id = */
1917 proto_tree_add_item(tree, hf_nfs3_gxfh_exportptid, tvb, offset+36, 4, ENC_LITTLE_ENDIAN);
1918 /* = export point unique id = */
1919 proto_tree_add_item(tree, hf_nfs3_gxfh_exportptuid, tvb, offset+40, 4, ENC_LITTLE_ENDIAN);
1920
1921 } /* end of (tree) */
1922 return tvb_captured_length(tvb);
1923 }
1924
1925 /* Checked with SuSE 7.1 (kernel 2.4.0 knfsd) */
1926 /* read linux-2.4.5/include/linux/nfsd/nfsfh.h for more details */
1927
1928 #define AUTH_TYPE_NONE 0
1929 static const value_string auth_type_names[] = {
1930 { AUTH_TYPE_NONE, "no authentication" },
1931 { 0, NULL}
1932 };
1933
1934 #define FSID_TYPE_MAJOR_MINOR_INODE 0
1935 static const value_string fsid_type_names[] = {
1936 { FSID_TYPE_MAJOR_MINOR_INODE, "major/minor/inode" },
1937 { 0, NULL}
1938 };
1939
1940 #define FILEID_TYPE_ROOT 0
1941 #define FILEID_TYPE_INODE_GENERATION 1
1942 #define FILEID_TYPE_INODE_GENERATION_PARENT 2
1943 static const value_string fileid_type_names[] = {
1944 { FILEID_TYPE_ROOT, "root" },
1945 { FILEID_TYPE_INODE_GENERATION, "inode/generation" },
1946 { FILEID_TYPE_INODE_GENERATION_PARENT, "inode/generation/parent" },
1947 { 0, NULL}
1948 };
1949
1950 static int
dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)1951 dissect_fhandle_data_LINUX_KNFSD_NEW(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
1952 {
1953 int offset = 0;
1954 guint32 version;
1955 guint8 auth_type = 0;
1956 guint8 fsid_type;
1957 guint8 fileid_type;
1958 proto_tree *fileid_tree;
1959 proto_item *fileid_item;
1960
1961 proto_tree_add_item_ret_uint(tree, hf_nfs_fh_version, tvb, offset+0, 1, ENC_NA, &version);
1962
1963 switch (version) {
1964 case 1:
1965 auth_type = tvb_get_guint8(tvb, offset + 1);
1966 fsid_type = tvb_get_guint8(tvb, offset + 2);
1967 fileid_type = tvb_get_guint8(tvb, offset + 3);
1968 if (tree) {
1969 proto_tree *encoding_tree = proto_tree_add_subtree_format(tree, tvb,
1970 offset + 1, 3,
1971 ett_nfs_fh_encoding, NULL, "encoding: %u %u %u",
1972 auth_type, fsid_type, fileid_type);
1973
1974 proto_tree_add_uint(encoding_tree, hf_nfs_fh_auth_type,
1975 tvb, offset+1, 1, auth_type);
1976 proto_tree_add_uint(encoding_tree, hf_nfs_fh_fsid_type,
1977 tvb, offset+2, 1, fsid_type);
1978 proto_tree_add_uint(encoding_tree, hf_nfs_fh_fileid_type,
1979 tvb, offset+3, 1, fileid_type);
1980 }
1981 offset += 4;
1982 break;
1983 default: {
1984 /* unknown version */
1985 return 1;
1986 }
1987 }
1988
1989 if (auth_type != 0)
1990 {
1991 /* unknown authentication type */
1992 return 2;
1993 }
1994
1995 if (fsid_type != 0)
1996 {
1997 /* unknown authentication type */
1998 return 3;
1999 }
2000
2001 {
2002 guint16 fsid_major;
2003 guint16 fsid_minor;
2004 guint32 fsid_inode;
2005
2006 fsid_major = tvb_get_ntohs(tvb, offset + 0);
2007 fsid_minor = tvb_get_ntohs(tvb, offset + 2);
2008 fsid_inode = tvb_get_letohl(tvb, offset + 4);
2009 if (tree) {
2010 proto_tree *fsid_tree = proto_tree_add_subtree_format(tree, tvb,
2011 offset+0, 8, ett_nfs_fh_fsid, NULL,
2012 "file system ID: %u,%u (inode %u)",
2013 fsid_major, fsid_minor, fsid_inode);
2014
2015 proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_major16,
2016 tvb, offset+0, 2, fsid_major);
2017 proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_minor16,
2018 tvb, offset+2, 2, fsid_minor);
2019 proto_tree_add_uint(fsid_tree, hf_nfs_fh_fsid_inode,
2020 tvb, offset+4, 4, fsid_inode);
2021 }
2022
2023 offset += 8;
2024 }
2025
2026 fileid_tree = proto_tree_add_subtree_format(tree, tvb,
2027 offset, 0, ett_nfs_fh_fn, &fileid_item, "file ID");
2028
2029 switch (fileid_type) {
2030 case 0: {
2031 proto_item_append_text(fileid_item, ": root inode");
2032 } break;
2033 case 1: {
2034 guint32 inode;
2035 guint32 generation;
2036
2037 inode = tvb_get_letohl(tvb, offset + 0);
2038 generation = tvb_get_letohl(tvb, offset + 4);
2039
2040 if (tree) {
2041 proto_item_append_text(fileid_item, ": %u (%u)", inode, generation);
2042 proto_item_set_len(fileid_item, 8);
2043
2044 proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_inode,
2045 tvb, offset+0, 4, inode);
2046 proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_generation,
2047 tvb, offset+4, 4, generation);
2048 }
2049
2050 /*offset += 8;*/
2051 } break;
2052 case 2: {
2053 guint32 inode;
2054 guint32 generation;
2055
2056 inode = tvb_get_letohl(tvb, offset + 0);
2057 generation = tvb_get_letohl(tvb, offset + 4);
2058
2059 if (tree) {
2060 proto_item_append_text(fileid_item, ": %u (%u)", inode, generation);
2061 proto_item_set_len(fileid_item, 12);
2062
2063 proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_inode,
2064 tvb, offset+0, 4, inode);
2065 proto_tree_add_uint(fileid_tree, hf_nfs_fh_fn_generation,
2066 tvb, offset+4, 4, generation);
2067 proto_tree_add_item(fileid_tree, hf_nfs_fh_dirinode,
2068 tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
2069 }
2070
2071 /*offset += 12;*/
2072 } break;
2073 default: {
2074 proto_item_append_text(fileid_item, ": unknown");
2075 /* unknown fileid type */
2076 return offset;
2077 }
2078 }
2079 return tvb_captured_length(tvb);
2080 }
2081
2082
2083 /*
2084 * Dissect GlusterFS/NFS NFSv3 File Handle - glusterfs-3.3+
2085 * The filehandle is always 32 bytes and first 4 bytes of ident ":OGL"
2086 */
2087 static int
dissect_fhandle_data_GLUSTER(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2088 dissect_fhandle_data_GLUSTER(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2089 {
2090 guint16 offset=0;
2091 guint16 fhlen;
2092 char *ident;
2093
2094 if (!tree)
2095 return tvb_captured_length(tvb);
2096
2097 fhlen = tvb_reported_length(tvb);
2098 if (fhlen != 36)
2099 return tvb_captured_length(tvb);
2100
2101 ident = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 4, ENC_ASCII);
2102 if (strncmp(":OGL", ident, 4))
2103 return 4;
2104 offset += 4;
2105
2106 proto_tree_add_item(tree, hf_nfs_fh_exportid, tvb, offset, 16, ENC_NA);
2107 offset += 16;
2108 proto_tree_add_item(tree, hf_nfs_fh_gfid, tvb, offset, 16, ENC_NA);
2109 offset += 16;
2110 return offset;
2111 }
2112
2113 /*
2114 * Dissect dCache NFS File Handle - dcache > 2.6
2115 */
2116
2117 #define DCACHE_MAGIC_MASK 0x00FFFFFF
2118 #define DCACHE_VERSION_MASK 0xFF000000
2119 #define DCACHE_MAGIC 0xCAFFEE
2120
2121 static const value_string dcache_handle_types[] = {
2122 { 0, "INODE" },
2123 { 1, "TAG" },
2124 { 2, "TAGS" },
2125 { 3, "ID" },
2126 { 4, "PATHOF" },
2127 { 5, "PARENT" },
2128 { 6, "NAMEOF" },
2129 { 7, "PGET" },
2130 { 8, "PSET" },
2131 { 9, "CONST" },
2132 { 0, NULL }
2133 };
2134
2135 static int
dissect_fhandle_data_DCACHE(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2136 dissect_fhandle_data_DCACHE(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2137 {
2138 int offset = 0;
2139 guint32 version;
2140 guint32 magic;
2141 guint8 obj_len;
2142
2143 if (!tree)
2144 return tvb_captured_length(tvb);
2145
2146 version = (tvb_get_ntohl(tvb, offset) & DCACHE_VERSION_MASK) >> 24;
2147 magic = (tvb_get_ntohl(tvb, offset) & DCACHE_MAGIC_MASK);
2148
2149 if ((version != 1) || (magic != DCACHE_MAGIC)) {
2150 /* unknown file handle */
2151 return 0;
2152 }
2153
2154 proto_tree_add_item(tree, hf_nfs_fh_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2155 proto_tree_add_item(tree, hf_nfs_fh_generation, tvb, offset+4, 4, ENC_BIG_ENDIAN);
2156 proto_tree_add_item(tree, hf_nfs_fh_dc_exportid, tvb, offset+8, 4, ENC_BIG_ENDIAN);
2157 proto_tree_add_item(tree, hf_nfs_fh_dc_handle_type, tvb, offset+15, 1, ENC_BIG_ENDIAN);
2158 obj_len = tvb_get_guint8(tvb, offset + 16);
2159 proto_tree_add_item(tree, hf_nfs_fh_dc_opaque, tvb, offset + 17, obj_len, ENC_NA);
2160 return tvb_captured_length(tvb);
2161 }
2162
2163 #define PD_VERSION_MASK 0xf0000000
2164 #define PD_RESERVED_MASK 0x0ffffffF
2165 #define PD_INUM_MASK G_GUINT64_CONSTANT(0x0007ffffffffffff)
2166 #define PD_SITEID_MASK G_GUINT64_CONSTANT(0xfff8000000000000)
2167 #define PD_SNAPID_MASK G_GUINT64_CONSTANT(0x0000000000001fff)
2168 #define PD_CONTAINER_MASK G_GUINT64_CONSTANT(0xffffffffffffe000)
2169
2170 static int
dissect_fhandle_data_PRIMARY_DATA(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2171 dissect_fhandle_data_PRIMARY_DATA(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2172 {
2173 int offset = 0;
2174 guint32 version;
2175
2176 static int * const fh_flags[] = {
2177 &hf_nfs4_fh_pd_flags_version,
2178 &hf_nfs4_fh_pd_flags_reserved,
2179 NULL
2180 };
2181
2182 static int * const fh_sites[] = {
2183 &hf_nfs4_fh_pd_sites_inum,
2184 &hf_nfs4_fh_pd_sites_siteid,
2185 NULL
2186 };
2187
2188 static int * const fh_spaces[] = {
2189 &hf_nfs4_fh_pd_spaces_snapid,
2190 &hf_nfs4_fh_pd_spaces_container,
2191 NULL
2192 };
2193
2194
2195 if (!tree)
2196 return tvb_captured_length(tvb);
2197
2198
2199 version = (tvb_get_letohl(tvb, offset + 4) & PD_VERSION_MASK) >> 28;
2200 if (version > 2) {
2201 return 0;
2202 }
2203
2204 proto_tree_add_item(tree, hf_nfs4_fh_pd_share, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2205 proto_tree_add_bitmask(tree, tvb, offset + 4, hf_nfs4_fh_pd_flags, ett_nfs4_fh_pd_flags, fh_flags, ENC_LITTLE_ENDIAN);
2206
2207 if (version == 0) {
2208 proto_tree_add_item(tree, hf_nfs4_fh_pd_inum, tvb, offset + 8, 8, ENC_LITTLE_ENDIAN);
2209 } else if (version == 1) {
2210 proto_tree_add_item(tree, hf_nfs4_fh_pd_container, tvb, offset + 8, 8, ENC_LITTLE_ENDIAN);
2211 proto_tree_add_item(tree, hf_nfs4_fh_pd_inum, tvb, offset + 16, 8, ENC_LITTLE_ENDIAN);
2212 } else if (version == 2) {
2213 proto_tree_add_bitmask(tree, tvb, offset + 8, hf_nfs4_fh_pd_spaces, ett_nfs4_fh_pd_spaces, fh_spaces, ENC_LITTLE_ENDIAN);
2214 proto_tree_add_bitmask(tree, tvb, offset + 16, hf_nfs4_fh_pd_sites, ett_nfs4_fh_pd_sites, fh_sites, ENC_LITTLE_ENDIAN);
2215 }
2216
2217 return tvb_captured_length(tvb);
2218 }
2219
2220 /* Dissect EMC Celerra or VNX NFSv3/v4 File Handle */
2221 static int
dissect_fhandle_data_CELERRA_VNX(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2222 dissect_fhandle_data_CELERRA_VNX(tvbuff_t* tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2223 {
2224 guint16 offset = 0;
2225 guint16 fhlen;
2226 guint32 obj_id;
2227
2228 fhlen = tvb_reported_length(tvb);
2229
2230 /* Display the entire file handle */
2231 proto_tree_add_item(tree, hf_nfs_fh_fhandle_data, tvb, 0, fhlen, ENC_NA);
2232
2233 /* If fhlen = 32, it's an NFSv3 file handle */
2234 if (fhlen == 32) {
2235 /* Create a "File/Dir" subtree: bytes 0 thru 15 of the 32-byte file handle */
2236 {
2237 proto_item *obj_item;
2238 proto_tree *obj_tree;
2239
2240 if (!tree)
2241 return tvb_captured_length(tvb);
2242
2243 obj_item = proto_tree_add_item(tree, hf_nfs_fh_obj, tvb, offset+0, 16, ENC_NA );
2244 obj_tree = proto_item_add_subtree(obj_item, ett_nfs_fh_obj);
2245
2246 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_fsid, tvb, offset+0, 4, ENC_LITTLE_ENDIAN);
2247 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_kindid, tvb, offset+4, 2, ENC_LITTLE_ENDIAN);
2248 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_treeid, tvb, offset+6, 2, ENC_LITTLE_ENDIAN);
2249 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_inode, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
2250 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_gen, tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
2251 }
2252 {
2253 /* Create "Export" subtree (NFSv3: Bytes 16 thru 31 of the 32-byte file handle */
2254 proto_item *ex_item;
2255 proto_tree *ex_tree;
2256 ex_item = proto_tree_add_item(tree, hf_nfs_fh_ex, tvb, offset+16, 16, ENC_NA );
2257 ex_tree = proto_item_add_subtree(ex_item, ett_nfs_fh_ex);
2258
2259 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_fsid, tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
2260 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_kindid, tvb, offset+20, 2, ENC_LITTLE_ENDIAN);
2261 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_treeid, tvb, offset+22, 2, ENC_LITTLE_ENDIAN);
2262 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_inode, tvb, offset+24, 4, ENC_LITTLE_ENDIAN);
2263 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_gen, tvb, offset+28, 4, ENC_LITTLE_ENDIAN);
2264 }
2265 } else if (fhlen == 40) {
2266 /*
2267 If fhlen = 40, it's an NFSv4 file handle). In Celerra|VNX NFSv4 file handles,
2268 the first 4 bytes hold the Named Attribute ID, and the next 4 bytes hold the
2269 RO_Node boolean which if true, the file/dir is Read Only. Unlike NFSv3 file
2270 handles where the file/dir info precedes the export info, the next 16 bytes contain
2271 the *export* info followed by 16 bytes containing the *file/dir* info.
2272 */
2273
2274 if (!tree)
2275 return tvb_captured_length(tvb);
2276
2277 /* "Named Attribute ID" or "Object ID" (bytes 0 thru 3) */
2278 obj_id = tvb_get_letohl(tvb, offset+0);
2279 if (obj_id <= 0 || obj_id > 9) obj_id = 1;
2280 proto_tree_add_uint(tree, hf_nfs_fh_obj_id, tvb, offset+0, 4, obj_id);
2281
2282 /* "RO_Node" boolean (bytes 4 thru 7) */
2283 proto_tree_add_item(tree, hf_nfs_fh_ro_node, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
2284
2285 /* Create "Export" subtree (bytes 8 thru 23 of the 40-byte file handle */
2286 {
2287 proto_item *ex_item;
2288 proto_tree *ex_tree;
2289 ex_item = proto_tree_add_item(tree, hf_nfs_fh_ex, tvb, offset+8, 16, ENC_NA );
2290 ex_tree = proto_item_add_subtree(ex_item, ett_nfs_fh_ex);
2291
2292 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_fsid, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
2293 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_kindid, tvb, offset+12, 2, ENC_LITTLE_ENDIAN);
2294 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_treeid, tvb, offset+14, 2, ENC_LITTLE_ENDIAN);
2295 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_inode, tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
2296 proto_tree_add_item(ex_tree, hf_nfs_fh_ex_gen, tvb, offset+20, 4, ENC_LITTLE_ENDIAN);
2297 }
2298 /* Create a "File/Dir/Object" subtree (bytes 24 thru 39 of the 40-byte file handle) */
2299 {
2300 proto_item *obj_item;
2301 proto_tree *obj_tree;
2302 obj_item = proto_tree_add_item(tree, hf_nfs_fh_obj, tvb, offset+24, 16, ENC_NA);
2303 obj_tree = proto_item_add_subtree(obj_item, ett_nfs_fh_obj);
2304
2305 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_fsid, tvb, offset+24, 4, ENC_LITTLE_ENDIAN);
2306 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_kindid, tvb, offset+28, 2, ENC_LITTLE_ENDIAN);
2307 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_treeid, tvb, offset+30, 2, ENC_LITTLE_ENDIAN);
2308 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_inode, tvb, offset+32, 4, ENC_LITTLE_ENDIAN);
2309 proto_tree_add_item(obj_tree, hf_nfs_fh_obj_gen, tvb, offset+36, 4, ENC_LITTLE_ENDIAN);
2310 }
2311 } else {
2312 /* This is not a Celerra|VNX file handle. Display a warning. */
2313 expert_add_info_format(pinfo, tree, &ei_nfs_not_vnx_file,
2314 "Celerra|VNX file handles are 32 (NFSv3) or 40 (NFSv4) but the length is %u.\n"
2315 "Change the 'Decode NFS file handles as' pref to the correct type or 'Unknown'.",
2316 fhlen);
2317 }
2318 return tvb_captured_length(tvb);
2319 }
2320
2321
2322 static int
dissect_fhandle_data_unknown(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2323 dissect_fhandle_data_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2324 {
2325 guint fhlen = tvb_reported_length(tvb);
2326
2327 proto_tree_add_item(tree, hf_nfs_fh_fhandle_data, tvb, 0, fhlen, ENC_NA);
2328 return tvb_captured_length(tvb);
2329 }
2330
2331
2332 static void
dissect_fhandle_data(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,unsigned int fhlen,gboolean hidden,guint32 * hash)2333 dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
2334 unsigned int fhlen, gboolean hidden, guint32 *hash)
2335 {
2336 /* this is to set up fhandle display filters to find both packets
2337 of an RPC call */
2338 if (nfs_fhandle_reqrep_matching && (!hidden) ) {
2339 nfs_fhandle_data_t *old_fhd = NULL;
2340
2341 if ( !pinfo->fd->visited ) {
2342 nfs_fhandle_data_t fhd;
2343
2344 /* first check if we have seen this fhandle before */
2345 fhd.len = fhlen;
2346 fhd.fh = (const unsigned char *)tvb_get_ptr(tvb, offset, fhlen);
2347 old_fhd = store_nfs_file_handle(&fhd);
2348
2349 /* XXX here we should really check that we haven't stored
2350 this fhandle for this frame number already.
2351 We should also make sure we can handle when we have multiple
2352 fhandles seen for the same frame, which WILL happen for certain
2353 nfs calls. For now, we don't handle this and those calls will
2354 not work properly with this feature
2355 */
2356 wmem_tree_insert32(nfs_fhandle_frame_table, pinfo->num, old_fhd);
2357 }
2358 }
2359
2360 /* Create a unique hash value for the filehandle using CRC32 */
2361 {
2362 guint32 fhhash;
2363 proto_item *fh_item = NULL;
2364
2365 fhhash = crc32_ccitt_tvb_offset(tvb, offset, fhlen);
2366
2367 if (hidden) {
2368 fh_item = proto_tree_add_uint(tree, hf_nfs_fh_hash, NULL, 0,
2369 0, fhhash);
2370 proto_item_set_hidden(fh_item);
2371 } else {
2372 fh_item = proto_tree_add_uint(tree, hf_nfs_fh_hash, tvb, offset,
2373 fhlen, fhhash);
2374 }
2375 proto_item_set_generated(fh_item);
2376 if (hash) {
2377 *hash = fhhash;
2378 }
2379 }
2380 if (nfs_file_name_snooping) {
2381 nfs_name_snoop_fh(pinfo, tree, tvb, offset, fhlen, hidden);
2382 }
2383
2384 if (!hidden) {
2385 tvbuff_t *fh_tvb;
2386
2387 fh_tvb = tvb_new_subset_length_caplen(tvb, offset, fhlen, fhlen);
2388 if (!dissector_try_payload(nfs_fhandle_table, fh_tvb, pinfo, tree))
2389 dissect_fhandle_data_unknown(fh_tvb, pinfo, tree, NULL);
2390 }
2391 }
2392
2393
2394 void
dissect_fhandle_hidden(packet_info * pinfo,proto_tree * tree,int frame)2395 dissect_fhandle_hidden(packet_info *pinfo, proto_tree *tree, int frame)
2396 {
2397 nfs_fhandle_data_t *nfd;
2398
2399 nfd = (nfs_fhandle_data_t *)wmem_tree_lookup32(nfs_fhandle_frame_table, frame);
2400 if (nfd && nfd->len) {
2401 tvbuff_t *tvb;
2402 tvb = tvb_new_real_data(nfd->fh, nfd->len, nfd->len);
2403 /* There's no need to call add_new_data_source() since
2404 dissect_fhandle(), in the the 'hidden' case, never refers
2405 to the tvb when displaying a field based on the tvb */
2406 dissect_fhandle_data(tvb, 0, pinfo, tree, nfd->len, TRUE, NULL);
2407 tvb_free(tvb);
2408 }
2409 }
2410
2411
2412 /***************************/
2413 /* NFS Version 2, RFC 1094 */
2414 /***************************/
2415
2416 /* NFSv2 RFC 1094, Page 12..14 */
2417 static const value_string names_nfs2_stat[] =
2418 {
2419 { 0, "NFS_OK" },
2420 { 1, "NFS2ERR_PERM" },
2421 { 2, "NFS2ERR_NOENT" },
2422 { 5, "NFS2ERR_IO" },
2423 { 6, "NFS2ERR_NXIO" },
2424 { 11, "NFS2ERR_EAGAIN" },
2425 { 13, "NFS2ERR_ACCES" },
2426 { 17, "NFS2ERR_EXIST" },
2427 { 18, "NFS2ERR_XDEV" }, /* not in spec, but can happen */
2428 { 19, "NFS2ERR_NODEV" },
2429 { 20, "NFS2ERR_NOTDIR" },
2430 { 21, "NFS2ERR_ISDIR" },
2431 { 22, "NFS2ERR_INVAL" }, /* not in spec, but I think it can happen */
2432 { 26, "NFS2ERR_TXTBSY" }, /* not in spec, but I think it can happen */
2433 { 27, "NFS2ERR_FBIG" },
2434 { 28, "NFS2ERR_NOSPC" },
2435 { 30, "NFS2ERR_ROFS" },
2436 { 31, "NFS2ERR_MLINK" }, /* not in spec, but can happen */
2437 { 45, "NFS2ERR_OPNOTSUPP" }, /* not in spec, but I think it can happen */
2438 { 63, "NFS2ERR_NAMETOOLONG" },
2439 { 66, "NFS2ERR_NOTEMPTY" },
2440 { 69, "NFS2ERR_DQUOT" },
2441 { 70, "NFS2ERR_STALE" },
2442 { 71, "NFS2ERR_REMOTE" },
2443 { 99, "NFS2ERR_WFLUSH" },
2444 { 10001, "NFS2ERR_BADHANDLE" },
2445 { 10002, "NFS2ERR_NOT_SYNC" },
2446 { 10003, "NFS2ERR_BAD_COOKIE" },
2447 { 10004, "NFS2ERR_NOTSUPP" },
2448 { 10005, "NFS2ERR_TOOSMALL" },
2449 { 10006, "NFS2ERR_SERVERFAULT" },
2450 { 10007, "NFS2ERR_BADTYPE" },
2451 { 10008, "NFS2ERR_JUKEBOX" },
2452 { 10009, "NFS2ERR_SAME" },
2453 { 10010, "NFS2ERR_DENIED" },
2454 { 10011, "NFS2ERR_EXPIRED" },
2455 { 10012, "NFS2ERR_LOCKED" },
2456 { 10013, "NFS2ERR_GRACE" },
2457 { 10014, "NFS2ERR_FHEXPIRED" },
2458 { 10015, "NFS2ERR_SHARE_DENIED" },
2459 { 10016, "NFS2ERR_WRONGSEC" },
2460 { 10017, "NFS2ERR_CLID_INUSE" },
2461 { 10018, "NFS2ERR_RESOURCE" },
2462 { 10019, "NFS2ERR_MOVED" },
2463 { 10020, "NFS2ERR_NOFILEHANDLE" },
2464 { 10021, "NFS2ERR_MINOR_VERS_MISMATCH" },
2465 { 10022, "NFS2ERR_STALE_CLIENTID" },
2466 { 10023, "NFS2ERR_STALE_STATEID" },
2467 { 10024, "NFS2ERR_OLD_STATEID" },
2468 { 10025, "NFS2ERR_BAD_STATEID" },
2469 { 10026, "NFS2ERR_BAD_SEQID" },
2470 { 10027, "NFS2ERR_NOT_SAME" },
2471 { 10028, "NFS2ERR_LOCK_RANGE" },
2472 { 10029, "NFS2ERR_SYMLINK" },
2473 { 10030, "NFS2ERR_RESTOREFH" },
2474 { 10031, "NFS2ERR_LEASE_MOVED" },
2475 { 10032, "NFS2ERR_ATTRNOTSUPP" },
2476 { 10033, "NFS2ERR_NO_GRACE" },
2477 { 10034, "NFS2ERR_RECLAIM_BAD" },
2478 { 10035, "NFS2ERR_RECLAIM_CONFLICT" },
2479 { 10036, "NFS2ERR_BAD_XDR" },
2480 { 10037, "NFS2ERR_LOCKS_HELD" },
2481 { 10038, "NFS2ERR_OPENMODE" },
2482 { 10039, "NFS2ERR_BADOWNER" },
2483 { 10040, "NFS2ERR_BADCHAR" },
2484 { 10041, "NFS2ERR_BADNAME" },
2485 { 10042, "NFS2ERR_BAD_RANGE" },
2486 { 10043, "NFS2ERR_LOCK_NOTSUPP" },
2487 { 10044, "NFS2ERR_OP_ILLEGAL" },
2488 { 10045, "NFS2ERR_DEADLOCK" },
2489 { 10046, "NFS2ERR_FILE_OPEN" },
2490 { 10047, "NFS2ERR_ADMIN_REVOKED" },
2491 { 10048, "NFS2ERR_CB_PATH_DOWN" },
2492 { 10049, "NFS2ERR_REPLAY_ME" },
2493 { 0, NULL }
2494 };
2495 static value_string_ext names_nfs2_stat_ext = VALUE_STRING_EXT_INIT(names_nfs2_stat);
2496
2497 /* NFSv2 RFC 1094, Page 12..14 */
2498 static int
dissect_nfs2_status(tvbuff_t * tvb,int offset,proto_tree * tree,guint32 * status)2499 dissect_nfs2_status(tvbuff_t *tvb, int offset, proto_tree *tree, guint32 *status)
2500 {
2501 guint32 stat;
2502 proto_item *stat_item;
2503
2504 proto_tree_add_item_ret_uint(tree, hf_nfs2_status, tvb, offset+0, 4, ENC_BIG_ENDIAN, &stat);
2505 stat_item = proto_tree_add_uint(tree, hf_nfs_status, tvb, offset+0, 4, stat);
2506 proto_item_set_hidden(stat_item);
2507
2508 offset += 4;
2509
2510 if (status)
2511 *status = stat;
2512
2513 return offset;
2514 }
2515
2516
2517 /* NFSv2 RFC 1094, Page 12..14 */
2518 static int
dissect_nfs2_rmdir_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2519 dissect_nfs2_rmdir_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2520 {
2521 guint32 status;
2522 const char *err;
2523 int offset = 0;
2524
2525 offset = dissect_nfs2_status(tvb, offset, tree, &status);
2526 switch (status) {
2527 case 0:
2528 proto_item_append_text(tree, ", RMDIR Reply");
2529 break;
2530 default:
2531 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
2532 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2533 proto_item_append_text(tree, ", RMDIR Reply Error: %s", err);
2534 }
2535
2536 return offset;
2537 }
2538
2539
2540 static int
dissect_nfs2_symlink_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2541 dissect_nfs2_symlink_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2542 {
2543 guint32 status;
2544 const char *err;
2545 int offset = 0;
2546
2547 offset = dissect_nfs2_status(tvb, offset, tree, &status);
2548 switch (status) {
2549 case 0:
2550 proto_item_append_text(tree, ", SYMLINK Reply");
2551 break;
2552 default:
2553 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
2554 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2555 proto_item_append_text(tree, ", SYMLINK Reply Error: %s", err);
2556 }
2557
2558 return offset;
2559 }
2560
2561
2562 static int
dissect_nfs2_link_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2563 dissect_nfs2_link_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2564 {
2565 guint32 status;
2566 const char *err;
2567 int offset = 0;
2568
2569 offset = dissect_nfs2_status(tvb, offset, tree, &status);
2570 switch (status) {
2571 case 0:
2572 proto_item_append_text(tree, ", LINK Reply");
2573 break;
2574 default:
2575 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
2576 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2577 proto_item_append_text(tree, ", LINK Reply Error: %s", err);
2578 }
2579
2580 return offset;
2581 }
2582
2583
2584 static int
dissect_nfs2_rename_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2585 dissect_nfs2_rename_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2586 {
2587 guint32 status;
2588 const char *err;
2589 int offset = 0;
2590
2591 offset = dissect_nfs2_status(tvb, offset, tree, &status);
2592 switch (status) {
2593 case 0:
2594 proto_item_append_text(tree, ", RENAME Reply");
2595 break;
2596 default:
2597 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
2598 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2599 proto_item_append_text(tree, ", RENAME Reply Error: %s", err);
2600 }
2601
2602 return offset;
2603 }
2604
2605
2606 static int
dissect_nfs2_remove_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2607 dissect_nfs2_remove_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2608 {
2609 guint32 status;
2610 const char *err;
2611 int offset = 0;
2612
2613 offset = dissect_nfs2_status(tvb, offset, tree, &status);
2614 switch (status) {
2615 case 0:
2616 proto_item_append_text(tree, ", REMOVE Reply");
2617 break;
2618 default:
2619 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
2620 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2621 proto_item_append_text(tree, ", REMOVE Reply Error: %s", err);
2622 }
2623
2624 return offset;
2625 }
2626
2627
2628 /* NFSv2 RFC 1094, Page 15 */
2629 static const value_string nfs2_ftype[] =
2630 {
2631 { 0, "Non-File" },
2632 { 1, "Regular File" },
2633 { 2, "Directory" },
2634 { 3, "Block Special Device" },
2635 { 4, "Character Special Device" },
2636 { 5, "Symbolic Link" },
2637 { 0, NULL }
2638 };
2639 static value_string_ext nfs2_ftype_ext = VALUE_STRING_EXT_INIT(nfs2_ftype);
2640
2641 static int
dissect_nfs2_ftype(tvbuff_t * tvb,int offset,proto_tree * tree)2642 dissect_nfs2_ftype(tvbuff_t *tvb, int offset, proto_tree *tree)
2643 {
2644 proto_tree_add_item(tree, hf_nfs2_ftype, tvb, offset, 4, ENC_BIG_ENDIAN);
2645 offset += 4;
2646 return offset;
2647 }
2648
2649
2650 /* NFSv2 RFC 1094, Page 15 */
2651 int
dissect_fhandle(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * name,guint32 * hash,rpc_call_info_value * civ)2652 dissect_fhandle(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
2653 const char *name, guint32 *hash, rpc_call_info_value *civ)
2654 {
2655 proto_tree *ftree;
2656
2657 ftree = proto_tree_add_subtree(tree, tvb, offset, FHSIZE,
2658 ett_nfs_fhandle, NULL, name);
2659
2660
2661 /* are we snooping fh to filenames ?*/
2662 if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
2663
2664 /* NFS v2 LOOKUP, CREATE, MKDIR calls might give us a mapping*/
2665 if ( (civ->prog == 100003)
2666 &&(civ->vers == 2)
2667 &&(!civ->request)
2668 &&((civ->proc == 4)||(civ->proc == 9)||(civ->proc == 14))
2669 ) {
2670 nfs_name_snoop_add_fh(civ->xid, tvb,
2671 offset, 32);
2672 }
2673
2674 /* MOUNT v1,v2 MNT replies might give us a filehandle*/
2675 if ( (civ->prog == 100005)
2676 &&(civ->proc == 1)
2677 &&((civ->vers == 1)||(civ->vers == 2))
2678 &&(!civ->request)
2679 ) {
2680 nfs_name_snoop_add_fh(civ->xid, tvb,
2681 offset, 32);
2682 }
2683 }
2684
2685 dissect_fhandle_data(tvb, offset, pinfo, ftree, FHSIZE, FALSE, hash);
2686
2687 offset += FHSIZE;
2688 return offset;
2689 }
2690
2691
2692 /* NFSv2 RFC 1094, Page 15 */
2693 static int
dissect_nfs2_statfs_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)2694 dissect_nfs2_statfs_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2695 {
2696 guint32 hash;
2697 int offset = 0;
2698
2699 offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
2700
2701 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
2702 proto_item_append_text(tree, ", STATFS Call FH: 0x%08x", hash);
2703
2704 return offset;
2705 }
2706
2707
2708 static int
dissect_nfs2_readlink_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)2709 dissect_nfs2_readlink_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2710 {
2711 guint32 hash;
2712 int offset = 0;
2713
2714 offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
2715
2716 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
2717 proto_item_append_text(tree, ", READLINK Call FH: 0x%08x", hash);
2718
2719 return offset;
2720 }
2721
2722
2723 static int
dissect_nfs2_getattr_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)2724 dissect_nfs2_getattr_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2725 {
2726 guint32 hash;
2727 int offset = 0;
2728
2729 offset = dissect_fhandle(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
2730
2731 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
2732 proto_item_append_text(tree, ", GETATTR Call FH: 0x%08x", hash);
2733
2734 return offset;
2735 }
2736
2737
2738 /* NFSv2 RFC 1094, Page 15 */
2739 static int
dissect_timeval(tvbuff_t * tvb,int offset,proto_tree * tree,int hf_time,int hf_time_sec,int hf_time_usec)2740 dissect_timeval(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_time, int hf_time_sec,
2741 int hf_time_usec)
2742 {
2743
2744 if (tree) {
2745 proto_item *time_item;
2746 proto_tree *time_tree;
2747 guint32 seconds;
2748 guint32 useconds;
2749 nstime_t ts;
2750
2751 seconds = tvb_get_ntohl(tvb, offset+0);
2752 useconds = tvb_get_ntohl(tvb, offset+4);
2753 ts.secs = seconds;
2754 ts.nsecs = useconds * 1000;
2755
2756 time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8,
2757 &ts);
2758
2759 time_tree = proto_item_add_subtree(time_item, ett_nfs_timeval);
2760
2761 proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4,
2762 seconds);
2763 proto_tree_add_uint(time_tree, hf_time_usec, tvb, offset+4, 4,
2764 useconds);
2765 }
2766 offset += 8;
2767 return offset;
2768 }
2769
2770 /* NFSv2 RFC 1094, Page 16 */
2771 static const value_string nfs2_mode_names[] = {
2772 { 0040000, "Directory" },
2773 { 0020000, "Character Special Device" },
2774 { 0060000, "Block Special Device" },
2775 { 0100000, "Regular File" },
2776 { 0120000, "Symbolic Link" },
2777 { 0140000, "Named Socket" },
2778 { 0000000, NULL }
2779 };
2780
2781 static int
dissect_nfs2_mode(tvbuff_t * tvb,int offset,proto_tree * tree)2782 dissect_nfs2_mode(tvbuff_t *tvb, int offset, proto_tree *tree)
2783 {
2784 static int * const modes[] = {
2785 &hf_nfs2_mode_name,
2786 &hf_nfs2_mode_set_user_id,
2787 &hf_nfs2_mode_set_group_id,
2788 &hf_nfs2_mode_save_swap_text,
2789 &hf_nfs2_mode_read_owner,
2790 &hf_nfs2_mode_write_owner,
2791 &hf_nfs2_mode_exec_owner,
2792 &hf_nfs2_mode_read_group,
2793 &hf_nfs2_mode_write_group,
2794 &hf_nfs2_mode_exec_group,
2795 &hf_nfs2_mode_read_other,
2796 &hf_nfs2_mode_write_other,
2797 &hf_nfs2_mode_exec_other,
2798 NULL
2799 };
2800
2801 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs2_mode, ett_nfs2_mode, modes, ENC_BIG_ENDIAN);
2802
2803 offset += 4;
2804 return offset;
2805 }
2806
2807
2808 /* NFSv2 RFC 1094, Page 15 */
2809 int
dissect_nfs2_fattr(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)2810 dissect_nfs2_fattr(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
2811 {
2812 proto_item *fattr_item;
2813 proto_tree *fattr_tree;
2814 int old_offset = offset;
2815
2816 fattr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
2817 ett_nfs_fattr, &fattr_item, name);
2818
2819 offset = dissect_nfs2_ftype(tvb, offset, fattr_tree);
2820 offset = dissect_nfs2_mode(tvb, offset, fattr_tree);
2821 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_nlink, offset);
2822 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_uid, offset);
2823 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_gid, offset);
2824 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_size, offset);
2825 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_blocksize, offset);
2826 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_rdev, offset);
2827 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_blocks, offset);
2828 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_fsid, offset);
2829 offset = dissect_rpc_uint32(tvb, fattr_tree, hf_nfs2_fattr_fileid, offset);
2830
2831 offset = dissect_timeval(tvb, offset, fattr_tree,
2832 hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_usec);
2833 offset = dissect_timeval(tvb, offset, fattr_tree,
2834 hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_usec);
2835 offset = dissect_timeval(tvb, offset, fattr_tree,
2836 hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_usec);
2837
2838 /* now we know, that fattr is shorter */
2839 proto_item_set_len(fattr_item, offset - old_offset);
2840
2841 return offset;
2842 }
2843
2844
2845 /* NFSv2 RFC 1094, Page 17 */
2846 static int
dissect_nfs2_sattr(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)2847 dissect_nfs2_sattr(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
2848 {
2849 proto_item *sattr_item;
2850 proto_tree *sattr_tree;
2851 int old_offset = offset;
2852
2853 sattr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
2854 ett_nfs2_sattr, &sattr_item, name);
2855
2856 if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2857 offset = dissect_nfs2_mode(tvb, offset, sattr_tree);
2858 else {
2859 proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_mode, tvb, offset, 4, 0xffffffff, "no value");
2860 offset += 4;
2861 }
2862
2863 if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2864 offset = dissect_rpc_uint32(tvb, sattr_tree, hf_nfs2_fattr_uid,
2865 offset);
2866 else {
2867 proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_fattr_uid, tvb, offset, 4, 0xffffffff, "no value");
2868 offset += 4;
2869 }
2870
2871 if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2872 offset = dissect_rpc_uint32(tvb, sattr_tree, hf_nfs2_fattr_gid,
2873 offset);
2874 else {
2875 proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_fattr_gid, tvb, offset, 4, 0xffffffff, "no value");
2876 offset += 4;
2877 }
2878
2879 if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff)
2880 offset = dissect_rpc_uint32(tvb, sattr_tree, hf_nfs2_fattr_size,
2881 offset);
2882 else {
2883 proto_tree_add_uint_format_value(sattr_tree, hf_nfs2_fattr_size, tvb, offset, 4, 0xffffffff, "no value");
2884 offset += 4;
2885 }
2886
2887 if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) {
2888 offset = dissect_timeval(tvb, offset, sattr_tree,
2889 hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_usec);
2890 } else {
2891 nstime_t ts;
2892
2893 ts.secs = 0xffffffff;
2894 ts.nsecs = 0;
2895
2896 proto_tree_add_time_format_value(sattr_tree, hf_nfs_atime, tvb, offset, 8, &ts, "no value");
2897 offset += 8;
2898 }
2899
2900 if (tvb_get_ntohl(tvb, offset+0) != 0xffffffff) {
2901 offset = dissect_timeval(tvb, offset, sattr_tree,
2902 hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_usec);
2903 } else {
2904 nstime_t ts;
2905
2906 ts.secs = 0xffffffff;
2907 ts.nsecs = 0;
2908
2909 proto_tree_add_time_format_value(sattr_tree, hf_nfs_mtime, tvb, offset, 8, &ts, "no value");
2910 offset += 8;
2911 }
2912
2913 /* now we know, that sattr is shorter */
2914 proto_item_set_len(sattr_item, offset - old_offset);
2915
2916 return offset;
2917 }
2918
2919
2920 /* NFSv2 RFC 1094, Page 17 */
2921 static int
dissect_filename(tvbuff_t * tvb,int offset,proto_tree * tree,int hf,const char ** string_ret)2922 dissect_filename(tvbuff_t *tvb, int offset, proto_tree *tree, int hf, const char **string_ret)
2923 {
2924 offset = dissect_rpc_string(tvb, tree, hf, offset, string_ret);
2925 return offset;
2926 }
2927
2928
2929 /* NFSv2 RFC 1094, Page 17 */
2930 static int
dissect_path(tvbuff_t * tvb,int offset,proto_tree * tree,int hf,const char ** name)2931 dissect_path(tvbuff_t *tvb, int offset, proto_tree *tree, int hf, const char **name)
2932 {
2933 offset = dissect_rpc_string(tvb, tree, hf, offset, name);
2934 return offset;
2935 }
2936
2937
2938 /* NFSv2 RFC 1094, Page 17,18 */
2939 static int
dissect_attrstat(tvbuff_t * tvb,int offset,proto_tree * tree,packet_info * pinfo,const char * funcname)2940 dissect_attrstat(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo, const char *funcname)
2941 {
2942 guint32 status;
2943 const char *err;
2944
2945 offset = dissect_nfs2_status(tvb, offset, tree, &status);
2946 switch (status) {
2947 case 0:
2948 offset = dissect_nfs2_fattr(tvb, offset, tree, "attributes");
2949 proto_item_append_text(tree, ", %s Reply", funcname);
2950 break;
2951 default:
2952 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
2953 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
2954 proto_item_append_text(tree, ", %s Reply Error: %s", funcname, err);
2955 break;
2956 }
2957
2958 return offset;
2959 }
2960
2961
2962 /* NFSv2 RFC 1094, Page 17,18 */
2963 static int
dissect_nfs2_write_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2964 dissect_nfs2_write_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2965 {
2966 return dissect_attrstat(tvb, 0, tree, pinfo, "WRITE");
2967 }
2968
2969
2970 /* NFSv2 RFC 1094, Page 18 */
2971 static int
dissect_nfs2_setattr_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2972 dissect_nfs2_setattr_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2973 {
2974 return dissect_attrstat(tvb, 0, tree, pinfo, "SETATTR");
2975 }
2976
2977
2978 /* NFSv2 RFC 1094, Page 18 */
2979 static int
dissect_nfs2_getattr_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2980 dissect_nfs2_getattr_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2981 {
2982 return dissect_attrstat(tvb, 0, tree, pinfo, "GETATTR");
2983 }
2984
2985
2986 /* NFSv2 RFC 1094, Page 18 */
2987 static int
dissect_diropargs(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * label,guint32 * hash,const char ** name,rpc_call_info_value * civ)2988 dissect_diropargs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
2989 const char *label, guint32 *hash, const char **name, rpc_call_info_value *civ)
2990 {
2991 proto_item *diropargs_item;
2992 proto_tree *diropargs_tree;
2993 int old_offset = offset;
2994
2995 diropargs_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
2996 ett_nfs2_diropargs, &diropargs_item, label);
2997
2998 /* are we snooping fh to filenames ?*/
2999 if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
3000 /* v2 LOOKUP, CREATE, MKDIR calls might give us a mapping*/
3001
3002 if ( (civ->prog == 100003)
3003 &&(civ->vers == 2)
3004 &&(civ->request)
3005 &&((civ->proc == 4)||(civ->proc == 9)||(civ->proc == 14))
3006 ) {
3007 nfs_name_snoop_add_name(civ->xid, tvb,
3008 offset+36, tvb_get_ntohl(tvb, offset+32),
3009 offset, 32, NULL);
3010 }
3011 }
3012
3013 offset = dissect_fhandle(tvb, offset, pinfo, diropargs_tree, "dir", hash, civ);
3014 offset = dissect_filename(tvb, offset, diropargs_tree, hf_nfs_name, name);
3015
3016 /* now we know, that diropargs is shorter */
3017 proto_item_set_len(diropargs_item, offset - old_offset);
3018
3019 return offset;
3020 }
3021
3022
3023 /* NFSv2 RFC 1094, Page 18 */
3024 static int
dissect_nfs2_rmdir_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3025 dissect_nfs2_rmdir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3026 {
3027 guint32 hash;
3028 const char *name = NULL;
3029 int offset = 0;
3030
3031 offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3032
3033 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3034 proto_item_append_text(tree, ", RMDIR Call DH: 0x%08x/%s", hash, name);
3035
3036 return offset;
3037 }
3038
3039
3040 /* NFSv2 RFC 1094, Page 18 */
3041 static int
dissect_nfs2_remove_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3042 dissect_nfs2_remove_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3043 {
3044 guint32 hash;
3045 const char *name = NULL;
3046 int offset = 0;
3047
3048 offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3049
3050 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3051 proto_item_append_text(tree, ", REMOVE Call DH: 0x%08x/%s", hash, name);
3052
3053 return offset;
3054 }
3055
3056
3057 /* NFSv2 RFC 1094, Page 18 */
3058 static int
dissect_nfs2_lookup_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3059 dissect_nfs2_lookup_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3060 {
3061 guint32 hash;
3062 const char *name = NULL;
3063 int offset = 0;
3064
3065 offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3066
3067 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3068 proto_item_append_text(tree, ", LOOKUP Call DH: 0x%08x/%s", hash, name);
3069
3070 return offset;
3071 }
3072
3073
3074 /* NFSv2 RFC 1094, Page 18 */
3075 static int
dissect_diropres(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * funcname,rpc_call_info_value * civ)3076 dissect_diropres(tvbuff_t *tvb, int offset, packet_info *pinfo,
3077 proto_tree *tree, const char *funcname, rpc_call_info_value* civ)
3078 {
3079 guint32 status;
3080 guint32 hash;
3081 const char *err;
3082
3083 offset = dissect_nfs2_status(tvb, offset, tree, &status);
3084 switch (status) {
3085 case 0:
3086 offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, civ);
3087 offset = dissect_nfs2_fattr (tvb, offset, tree, "attributes");
3088 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
3089 proto_item_append_text(tree, ", %s Reply FH: 0x%08x", funcname, hash);
3090 break;
3091 default:
3092 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
3093 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3094 proto_item_append_text(tree, ", %s Reply Error: %s", funcname, err);
3095 break;
3096 }
3097
3098 return offset;
3099 }
3100
3101
3102 /* nfsdata is simply a chunk of RPC opaque data (length, data, fill bytes) */
3103 static int
dissect_nfsdata(tvbuff_t * tvb,int offset,proto_tree * tree,int hf)3104 dissect_nfsdata(tvbuff_t *tvb, int offset, proto_tree *tree, int hf)
3105 {
3106 offset = dissect_rpc_data(tvb, tree, hf, offset);
3107 return offset;
3108 }
3109
3110
3111 /* NFSv2 RFC 1094, Page 18 */
3112 static int
dissect_nfs2_mkdir_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3113 dissect_nfs2_mkdir_reply(tvbuff_t *tvb, packet_info *pinfo,
3114 proto_tree *tree, void *data)
3115 {
3116 return dissect_diropres(tvb, 0, pinfo, tree, "MKDIR", (rpc_call_info_value*)data);
3117 }
3118
3119
3120 static int
dissect_nfs2_create_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3121 dissect_nfs2_create_reply(tvbuff_t *tvb, packet_info *pinfo,
3122 proto_tree *tree, void *data _U_)
3123 {
3124 return dissect_diropres(tvb, 0, pinfo, tree, "CREATE", (rpc_call_info_value*)data);
3125 }
3126
3127
3128 static int
dissect_nfs2_lookup_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3129 dissect_nfs2_lookup_reply(tvbuff_t *tvb, packet_info *pinfo,
3130 proto_tree *tree, void *data _U_)
3131 {
3132 return dissect_diropres(tvb, 0, pinfo, tree, "LOOKUP", (rpc_call_info_value*)data);
3133 }
3134
3135
3136 /* RFC 1094, Page 6 */
3137 static int
dissect_nfs2_setattr_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3138 dissect_nfs2_setattr_call(tvbuff_t *tvb, packet_info *pinfo,
3139 proto_tree *tree, void *data)
3140 {
3141 guint32 hash;
3142 int offset = 0;
3143
3144 offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
3145 offset = dissect_nfs2_sattr (tvb, offset, tree, "attributes");
3146
3147 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
3148 proto_item_append_text(tree, ", SETATTR Call FH: 0x%08x", hash);
3149 return offset;
3150 }
3151
3152
3153 /* NFSv2 RFC 1094, Page 6 */
3154 static int
dissect_nfs2_readlink_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)3155 dissect_nfs2_readlink_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
3156 proto_tree *tree, void *data _U_)
3157 {
3158 guint32 status;
3159 const char *err;
3160 const char *name = NULL;
3161 int offset = 0;
3162
3163 offset = dissect_nfs2_status(tvb, offset, tree, &status);
3164 switch (status) {
3165 case 0:
3166 offset = dissect_nfsdata_reduced(R_NFS2_PATH, tvb, offset, tree, hf_nfs2_readlink_data, &name);
3167 col_append_fstr(pinfo->cinfo, COL_INFO, " Path: %s", name);
3168 proto_item_append_text(tree, ", READLINK Reply Path: %s", name);
3169 break;
3170 default:
3171 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
3172 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3173 proto_item_append_text(tree, ", READLINK Reply Error: %s", err);
3174 break;
3175 }
3176
3177 return offset;
3178 }
3179
3180
3181 /* NFSv2 RFC 1094, Page 7 */
3182 static int
dissect_nfs2_read_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3183 dissect_nfs2_read_call(tvbuff_t *tvb, packet_info *pinfo,
3184 proto_tree *tree, void *data)
3185 {
3186 guint32 offset_value;
3187 guint32 count;
3188 guint32 totalcount;
3189 guint32 hash;
3190 int offset = 0;
3191
3192 offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
3193 proto_tree_add_item_ret_uint(tree, hf_nfs2_read_offset, tvb,
3194 offset+0, 4, ENC_BIG_ENDIAN, &offset_value);
3195 proto_tree_add_item_ret_uint(tree, hf_nfs2_read_count, tvb,
3196 offset+4, 4, ENC_BIG_ENDIAN, &count);
3197 proto_tree_add_item_ret_uint(tree, hf_nfs2_read_totalcount, tvb,
3198 offset+8, 4, ENC_BIG_ENDIAN, &totalcount);
3199 offset += 12;
3200
3201 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x Offset: %d Count: %d TotalCount: %d",
3202 hash, offset_value, count, totalcount);
3203 proto_item_append_text(tree, ", READ Call FH: 0x%08x Offset: %d Count: %d TotalCount: %d",
3204 hash, offset_value, count, totalcount);
3205
3206 return offset;
3207 }
3208
3209
3210 /* NFSv2 RFC 1094, Page 7 */
3211 static int
dissect_nfs2_read_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)3212 dissect_nfs2_read_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
3213 proto_tree *tree, void *data _U_)
3214 {
3215 guint32 status;
3216 const char *err;
3217 int offset = 0;
3218
3219 offset = dissect_nfs2_status(tvb, offset, tree, &status);
3220 switch (status) {
3221 case 0:
3222 offset = dissect_nfs2_fattr(tvb, offset, tree, "attributes");
3223 proto_item_append_text(tree, ", READ Reply");
3224 offset = dissect_nfsdata_reduced(R_NFSDATA, tvb, offset, tree, hf_nfs_data, NULL);
3225 break;
3226 default:
3227 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
3228 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3229 proto_item_append_text(tree, ", READ Reply Error: %s", err);
3230 break;
3231 }
3232
3233 return offset;
3234 }
3235
3236
3237 /* NFSv2 RFC 1094, Page 8 */
3238 static int
dissect_nfs2_write_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3239 dissect_nfs2_write_call(tvbuff_t *tvb, packet_info *pinfo,
3240 proto_tree *tree, void *data)
3241 {
3242 guint32 beginoffset;
3243 guint32 offset_value;
3244 guint32 totalcount;
3245 guint32 hash;
3246 int offset = 0;
3247
3248 offset = dissect_fhandle(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
3249
3250 proto_tree_add_item_ret_uint(tree, hf_nfs2_write_beginoffset, tvb,
3251 offset+0, 4, ENC_BIG_ENDIAN, &beginoffset);
3252 proto_tree_add_item_ret_uint(tree, hf_nfs2_write_offset, tvb,
3253 offset+4, 4, ENC_BIG_ENDIAN, &offset_value);
3254 proto_tree_add_item_ret_uint(tree, hf_nfs2_write_totalcount, tvb,
3255 offset+8, 4, ENC_BIG_ENDIAN, &totalcount);
3256 offset += 12;
3257
3258 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x BeginOffset: %d Offset: %d TotalCount: %d",
3259 hash, beginoffset, offset_value, totalcount);
3260 proto_item_append_text(tree, ", WRITE Call FH: 0x%08x BeginOffset: %d Offset: %d TotalCount: %d",
3261 hash, beginoffset, offset_value, totalcount);
3262
3263 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
3264
3265 return offset;
3266 }
3267
3268
3269 /* NFSv2 RFC 1094, Page 8 */
3270 static int
dissect_nfs2_mkdir_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3271 dissect_nfs2_mkdir_call(tvbuff_t *tvb, packet_info *pinfo,
3272 proto_tree *tree, void *data)
3273 {
3274 guint32 hash;
3275 const char *name = NULL;
3276 int offset = 0;
3277
3278 offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3279 offset = dissect_nfs2_sattr (tvb, offset, tree, "attributes");
3280
3281 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3282 proto_item_append_text(tree, ", MKDIR Call DH: 0x%08x/%s", hash, name);
3283
3284 return offset;
3285 }
3286
3287 static int
dissect_nfs2_create_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3288 dissect_nfs2_create_call(tvbuff_t *tvb, packet_info *pinfo,
3289 proto_tree *tree, void *data)
3290 {
3291 guint32 hash;
3292 const char *name = NULL;
3293 int offset = 0;
3294
3295 offset = dissect_diropargs(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
3296 offset = dissect_nfs2_sattr (tvb, offset, tree, "attributes");
3297
3298 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
3299 proto_item_append_text(tree, ", CREATE Call DH: 0x%08x/%s", hash, name);
3300
3301 return offset;
3302 }
3303
3304
3305 /* NFSv2 RFC 1094, Page 9 */
3306 static int
dissect_nfs2_rename_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3307 dissect_nfs2_rename_call(tvbuff_t *tvb, packet_info *pinfo,
3308 proto_tree *tree, void *data)
3309 {
3310 guint32 from_hash;
3311 const char *from_name = NULL;
3312 guint32 to_hash;
3313 const char *to_name = NULL;
3314 int offset = 0;
3315
3316 offset = dissect_diropargs(tvb, offset, pinfo, tree, "from", &from_hash, &from_name, (rpc_call_info_value*)data);
3317 offset = dissect_diropargs(tvb, offset, pinfo, tree, "to", &to_hash, &to_name, (rpc_call_info_value*)data);
3318
3319 col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To DH: 0x%08x/%s",
3320 from_hash, from_name, to_hash, to_name);
3321 proto_item_append_text(tree, ", RENAME Call From DH: 0x%08x/%s To DH: 0x%08x/%s",
3322 from_hash, from_name, to_hash, to_name);
3323
3324 return offset;
3325 }
3326
3327
3328 /* NFSv2 RFC 1094, Page 9 */
3329 static int
dissect_nfs2_link_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3330 dissect_nfs2_link_call(tvbuff_t *tvb, packet_info *pinfo,
3331 proto_tree *tree, void *data)
3332 {
3333 guint32 from_hash;
3334 guint32 to_hash;
3335 const char *to_name = NULL;
3336 int offset = 0;
3337
3338 offset = dissect_fhandle(tvb, offset, pinfo, tree, "from", &from_hash, (rpc_call_info_value*)data);
3339 offset = dissect_diropargs(tvb, offset, pinfo, tree, "to", &to_hash, &to_name, (rpc_call_info_value*)data);
3340
3341 col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x To DH: 0x%08x/%s",
3342 from_hash, to_hash, to_name);
3343 proto_item_append_text(tree, ", LINK Call From DH: 0x%08x To DH: 0x%08x/%s",
3344 from_hash, to_hash, to_name);
3345
3346 return offset;
3347 }
3348
3349
3350 /* NFSv2 RFC 1094, Page 10 */
3351 static int
dissect_nfs2_symlink_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3352 dissect_nfs2_symlink_call(tvbuff_t *tvb, packet_info *pinfo,
3353 proto_tree *tree, void *data)
3354 {
3355 guint32 from_hash;
3356 const char *from_name = NULL;
3357 const char *to_name = NULL;
3358 int offset = 0;
3359
3360 offset = dissect_diropargs(tvb, offset, pinfo, tree, "from", &from_hash, &from_name, (rpc_call_info_value*)data);
3361 offset = dissect_path(tvb, offset, tree, hf_nfs_symlink_to, &to_name);
3362 offset = dissect_nfs2_sattr(tvb, offset, tree, "attributes");
3363
3364 col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To %s",
3365 from_hash, from_name, to_name);
3366 proto_item_append_text(tree, ", SYMLINK Call From DH: 0x%08x/%s To %s",
3367 from_hash, from_name, to_name);
3368
3369 return offset;
3370 }
3371
3372
3373 /* NFSv2 RFC 1094, Page 11 */
3374 static int
dissect_nfs2_readdir_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3375 dissect_nfs2_readdir_call(tvbuff_t *tvb, packet_info *pinfo,
3376 proto_tree *tree, void *data)
3377 {
3378 guint32 hash;
3379 int offset = 0;
3380
3381 offset = dissect_fhandle(tvb, offset, pinfo, tree, "dir", &hash, (rpc_call_info_value*)data);
3382
3383 proto_tree_add_item(tree, hf_nfs2_readdir_cookie, tvb, offset+ 0, 4, ENC_BIG_ENDIAN);
3384 proto_tree_add_item(tree, hf_nfs2_readdir_count, tvb, offset+ 4, 4, ENC_BIG_ENDIAN);
3385 offset += 8;
3386
3387 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
3388 proto_item_append_text(tree, ", READDIR Call FH: 0x%08x", hash);
3389
3390 return offset;
3391 }
3392
3393
3394 /* NFSv2 RFC 1094, Page 11 */
3395 static int
dissect_readdir_entry(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)3396 dissect_readdir_entry(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
3397 proto_tree *tree, void *data _U_)
3398 {
3399 proto_item *entry_item = NULL;
3400 proto_tree *entry_tree = NULL;
3401 int old_offset = offset;
3402 guint32 fileid;
3403 const char *name;
3404
3405 if (tree) {
3406 entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb,
3407 offset+0, -1, ENC_NA);
3408 entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
3409 }
3410
3411 proto_tree_add_item_ret_uint(entry_tree, hf_nfs2_readdir_entry_fileid, tvb,
3412 offset, 4, ENC_BIG_ENDIAN, &fileid);
3413 offset += 4;
3414
3415 offset = dissect_filename(tvb, offset, entry_tree,
3416 hf_nfs2_readdir_entry_name, &name);
3417 if (entry_item)
3418 proto_item_set_text(entry_item, "Entry: file ID %u, name %s", fileid, name);
3419
3420 proto_tree_add_item(entry_tree, hf_nfs2_readdir_entry_cookie, tvb, offset, 4, ENC_BIG_ENDIAN);
3421 offset += 4;
3422
3423 /* now we know, that a readdir entry is shorter */
3424 if (entry_item) {
3425 proto_item_set_len(entry_item, offset - old_offset);
3426 }
3427
3428 return offset;
3429 }
3430
3431
3432 /* NFSv2 RFC 1094, Page 11 */
3433 static int
dissect_nfs2_readdir_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3434 dissect_nfs2_readdir_reply(tvbuff_t *tvb, packet_info *pinfo,
3435 proto_tree *tree, void *data _U_)
3436 {
3437 guint32 status;
3438 guint32 eof_value;
3439 const char *err;
3440 int offset = 0;
3441
3442 offset = dissect_nfs2_status(tvb, offset, tree, &status);
3443 switch (status) {
3444 case 0:
3445 proto_item_append_text(tree, ", READDIR Reply");
3446
3447 offset = dissect_rpc_list(tvb, pinfo, tree, offset,
3448 dissect_readdir_entry, NULL);
3449 proto_tree_add_item_ret_uint(tree, hf_nfs_readdir_eof, tvb,
3450 offset, 4, ENC_BIG_ENDIAN, &eof_value);
3451 offset += 4;
3452 break;
3453 default:
3454 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
3455 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3456 proto_item_append_text(tree, ", READDIR Reply Error: %s", err);
3457 break;
3458 }
3459
3460 return offset;
3461 }
3462
3463
3464 /* NFSv2 RFC 1094, Page 12 */
3465 static int
dissect_nfs2_statfs_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)3466 dissect_nfs2_statfs_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
3467 proto_tree *tree, void *data _U_)
3468 {
3469 guint32 status;
3470 const char *err;
3471 int offset = 0;
3472
3473 offset = dissect_nfs2_status(tvb, offset, tree, &status);
3474 switch (status) {
3475 case 0:
3476 proto_tree_add_item(tree, hf_nfs2_statfs_tsize, tvb, offset+ 0, 4, ENC_BIG_ENDIAN);
3477 proto_tree_add_item(tree, hf_nfs2_statfs_bsize, tvb, offset+ 4, 4, ENC_BIG_ENDIAN);
3478 proto_tree_add_item(tree, hf_nfs2_statfs_blocks, tvb, offset+ 8, 4, ENC_BIG_ENDIAN);
3479 proto_tree_add_item(tree, hf_nfs2_statfs_bfree, tvb, offset+12, 4, ENC_BIG_ENDIAN);
3480 proto_tree_add_item(tree, hf_nfs2_statfs_bavail, tvb, offset+16, 4, ENC_BIG_ENDIAN);
3481 offset += 20;
3482 proto_item_append_text(tree, ", STATFS Reply");
3483 break;
3484 default:
3485 err = val_to_str_ext(status, &names_nfs2_stat_ext, "Unknown error: %u");
3486 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
3487 proto_item_append_text(tree, ", STATFS Reply Error: %s", err);
3488 break;
3489 }
3490
3491 return offset;
3492 }
3493
3494
3495 /* proc number, "proc name", dissect_request, dissect_reply */
3496 static const vsff nfs2_proc[] = {
3497 { 0, "NULL", /* OK */
3498 dissect_rpc_void, dissect_rpc_void },
3499 { 1, "GETATTR", /* OK */
3500 dissect_nfs2_getattr_call, dissect_nfs2_getattr_reply },
3501 { 2, "SETATTR", /* OK */
3502 dissect_nfs2_setattr_call, dissect_nfs2_setattr_reply },
3503 { 3, "ROOT", /* OK */
3504 dissect_rpc_void, dissect_rpc_void },
3505 { 4, "LOOKUP", /* OK */
3506 dissect_nfs2_lookup_call, dissect_nfs2_lookup_reply },
3507 { 5, "READLINK", /* OK */
3508 dissect_nfs2_readlink_call, dissect_nfs2_readlink_reply },
3509 { 6, "READ", /* OK */
3510 dissect_nfs2_read_call, dissect_nfs2_read_reply },
3511 { 7, "WRITECACHE", /* OK */
3512 dissect_rpc_void, dissect_rpc_void },
3513 { 8, "WRITE", /* OK */
3514 dissect_nfs2_write_call, dissect_nfs2_write_reply },
3515 { 9, "CREATE", /* OK */
3516 dissect_nfs2_create_call, dissect_nfs2_create_reply },
3517 { 10, "REMOVE", /* OK */
3518 dissect_nfs2_remove_call, dissect_nfs2_remove_reply },
3519 { 11, "RENAME", /* OK */
3520 dissect_nfs2_rename_call, dissect_nfs2_rename_reply },
3521 { 12, "LINK", /* OK */
3522 dissect_nfs2_link_call, dissect_nfs2_link_reply },
3523 { 13, "SYMLINK", /* OK */
3524 dissect_nfs2_symlink_call, dissect_nfs2_symlink_reply },
3525 { 14, "MKDIR", /* OK */
3526 dissect_nfs2_mkdir_call, dissect_nfs2_mkdir_reply },
3527 { 15, "RMDIR", /* OK */
3528 dissect_nfs2_rmdir_call, dissect_nfs2_rmdir_reply },
3529 { 16, "READDIR", /* OK */
3530 dissect_nfs2_readdir_call, dissect_nfs2_readdir_reply },
3531 { 17, "STATFS", /* OK */
3532 dissect_nfs2_statfs_call, dissect_nfs2_statfs_reply },
3533 { 0, NULL, NULL, NULL }
3534 };
3535
3536 static const value_string nfs2_proc_vals[] = {
3537 { 0, "NULL" },
3538 { 1, "GETATTR" },
3539 { 2, "SETATTR" },
3540 { 3, "ROOT" },
3541 { 4, "LOOKUP" },
3542 { 5, "READLINK" },
3543 { 6, "READ" },
3544 { 7, "WRITECACHE" },
3545 { 8, "WRITE" },
3546 { 9, "CREATE" },
3547 { 10, "REMOVE" },
3548 { 11, "RENAME" },
3549 { 12, "LINK" },
3550 { 13, "SYMLINK" },
3551 { 14, "MKDIR" },
3552 { 15, "RMDIR" },
3553 { 16, "READDIR" },
3554 { 17, "STATFS" },
3555 { 0, NULL }
3556 };
3557 static value_string_ext nfs2_proc_vals_ext = VALUE_STRING_EXT_INIT(nfs2_proc_vals);
3558
3559 /* end of NFS Version 2 */
3560
3561
3562 /***************************/
3563 /* NFS Version 3, RFC 1813 */
3564 /***************************/
3565
3566 /* NFSv3 RFC 1813, Page 15 */
3567 static int
dissect_nfs3_filename(tvbuff_t * tvb,int offset,proto_tree * tree,int hf,const char ** string_ret)3568 dissect_nfs3_filename(tvbuff_t *tvb, int offset, proto_tree *tree, int hf, const char **string_ret)
3569 {
3570 offset = dissect_rpc_string(tvb, tree, hf, offset, string_ret);
3571 return offset;
3572 }
3573
3574
3575 /* NFSv3 RFC 1813, Page 15 */
3576 static int
dissect_nfs3_path(tvbuff_t * tvb,int offset,proto_tree * tree,int hf,const char ** name)3577 dissect_nfs3_path(tvbuff_t *tvb, int offset, proto_tree *tree, int hf, const char **name)
3578 {
3579 offset = dissect_rpc_string(tvb, tree, hf, offset, name);
3580 return offset;
3581 }
3582
3583
3584 /* NFSv3 RFC 1813, Page 15 */
3585 static int
dissect_nfs3_cookie_verf(tvbuff_t * tvb,int offset,proto_tree * tree)3586 dissect_nfs3_cookie_verf(tvbuff_t *tvb, int offset, proto_tree *tree)
3587 {
3588 proto_tree_add_bytes_format_value(tree, hf_nfs3_verifier, tvb, offset, NFS3_COOKIEVERFSIZE, NULL, "Opaque Data");
3589 offset += NFS3_COOKIEVERFSIZE;
3590 return offset;
3591 }
3592
3593
3594 /* NFSv3 RFC 1813, Page 16 */
3595 static int
dissect_nfs3_create_verf(tvbuff_t * tvb,int offset,proto_tree * tree)3596 dissect_nfs3_create_verf(tvbuff_t *tvb, int offset, proto_tree *tree)
3597 {
3598 proto_tree_add_bytes_format_value(tree, hf_nfs3_verifier, tvb, offset, NFS3_CREATEVERFSIZE, NULL, "Opaque Data");
3599 offset += NFS3_CREATEVERFSIZE;
3600 return offset;
3601 }
3602
3603
3604 /* NFSv3 RFC 1813, Page 16 */
3605 static int
dissect_nfs3_write_verf(tvbuff_t * tvb,int offset,proto_tree * tree)3606 dissect_nfs3_write_verf(tvbuff_t *tvb, int offset, proto_tree *tree)
3607 {
3608 proto_tree_add_bytes_format_value(tree, hf_nfs3_verifier, tvb, offset, NFS3_WRITEVERFSIZE, NULL, "Opaque Data");
3609 offset += NFS3_WRITEVERFSIZE;
3610 return offset;
3611 }
3612
3613
3614 /* RFC 1813, Page 16 */
3615 static int
dissect_nfs3_mode(tvbuff_t * tvb,int offset,proto_tree * tree,guint32 * mode)3616 dissect_nfs3_mode(tvbuff_t *tvb, int offset, proto_tree *tree, guint32 *mode)
3617 {
3618 static int * const mode_bits[] = {
3619 &hf_nfs3_mode_suid,
3620 &hf_nfs3_mode_sgid,
3621 &hf_nfs3_mode_sticky,
3622 &hf_nfs3_mode_rusr,
3623 &hf_nfs3_mode_wusr,
3624 &hf_nfs3_mode_xusr,
3625 &hf_nfs3_mode_rgrp,
3626 &hf_nfs3_mode_wgrp,
3627 &hf_nfs3_mode_xgrp,
3628 &hf_nfs3_mode_roth,
3629 &hf_nfs3_mode_woth,
3630 &hf_nfs3_mode_xoth,
3631 NULL
3632 };
3633
3634
3635 if (mode) {
3636 *mode = tvb_get_ntohl(tvb, offset+0);
3637 }
3638
3639 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs3_mode, ett_nfs3_mode, mode_bits, ENC_BIG_ENDIAN);
3640
3641 offset += 4;
3642 return offset;
3643 }
3644
3645
3646 /* NFSv3 RFC 1813, Page 16,17 */
3647 static const value_string names_nfs_nfsstat3[] =
3648 {
3649 { 0, "NFS3_OK" },
3650 { 1, "NFS3ERR_PERM" },
3651 { 2, "NFS3ERR_NOENT" },
3652 { 5, "NFS3ERR_IO" },
3653 { 6, "NFS3ERR_NXIO" },
3654 { 13, "NFS3ERR_ACCES" },
3655 { 17, "NFS3ERR_EXIST" },
3656 { 18, "NFS3ERR_XDEV" },
3657 { 19, "NFS3ERR_NODEV" },
3658 { 20, "NFS3ERR_NOTDIR" },
3659 { 21, "NFS3ERR_ISDIR" },
3660 { 22, "NFS3ERR_INVAL" },
3661 { 27, "NFS3ERR_FBIG" },
3662 { 28, "NFS3ERR_NOSPC" },
3663 { 30, "NFS3ERR_ROFS" },
3664 { 31, "NFS3ERR_MLINK" },
3665 { 63, "NFS3ERR_NAMETOOLONG" },
3666 { 66, "NFS3ERR_NOTEMPTY" },
3667 { 69, "NFS3ERR_DQUOT" },
3668 { 70, "NFS3ERR_STALE" },
3669 { 71, "NFS3ERR_REMOTE" },
3670 { 10001, "NFS3ERR_BADHANDLE" },
3671 { 10002, "NFS3ERR_NOT_SYNC" },
3672 { 10003, "NFS3ERR_BAD_COOKIE" },
3673 { 10004, "NFS3ERR_NOTSUPP" },
3674 { 10005, "NFS3ERR_TOOSMALL" },
3675 { 10006, "NFS3ERR_SERVERFAULT" },
3676 { 10007, "NFS3ERR_BADTYPE" },
3677 { 10008, "NFS3ERR_JUKEBOX" },
3678 { 0, NULL }
3679 };
3680 static value_string_ext names_nfs3_status_ext = VALUE_STRING_EXT_INIT(names_nfs_nfsstat3);
3681
3682 /* NFSv3 RFC 1813, Page 16 */
3683 static int
dissect_nfs3_status(tvbuff_t * tvb,int offset,proto_tree * tree,guint32 * status)3684 dissect_nfs3_status(tvbuff_t *tvb, int offset, proto_tree *tree, guint32 *status)
3685 {
3686 guint32 nfsstat3;
3687
3688 nfsstat3 = tvb_get_ntohl(tvb, offset+0);
3689
3690 if (tree) {
3691 proto_item *stat_item;
3692 proto_tree_add_uint(tree, hf_nfs3_status, tvb, offset+0, 4, nfsstat3);
3693 stat_item = proto_tree_add_uint(tree, hf_nfs_status, tvb, offset+0, 4, nfsstat3);
3694 proto_item_set_hidden(stat_item);
3695 }
3696
3697 offset += 4;
3698 *status = nfsstat3;
3699 return offset;
3700 }
3701
3702
3703 static const value_string names_nfs_ftype3[] =
3704 {
3705 { NF3REG, "Regular File" },
3706 { NF3DIR, "Directory" },
3707 { NF3BLK, "Block Special Device" },
3708 { NF3CHR, "Character Special Device" },
3709 { NF3LNK, "Symbolic Link" },
3710 { NF3SOCK, "Socket" },
3711 { NF3FIFO, "Named Pipe" },
3712 { 0, NULL }
3713 };
3714 static value_string_ext names_nfs_ftype3_ext = VALUE_STRING_EXT_INIT(names_nfs_ftype3);
3715
3716 /* NFSv3 RFC 1813, Page 20 */
3717 static int
dissect_ftype3(tvbuff_t * tvb,int offset,proto_tree * tree,int hf,guint32 * ftype3)3718 dissect_ftype3(tvbuff_t *tvb, int offset, proto_tree *tree, int hf,
3719 guint32* ftype3)
3720 {
3721 guint32 type;
3722
3723 proto_tree_add_item_ret_uint(tree, hf, tvb, offset, 4, ENC_BIG_ENDIAN, &type);
3724
3725 offset += 4;
3726 *ftype3 = type;
3727 return offset;
3728 }
3729
3730
3731 /* NFSv3 RFC 1813, Page 20 */
3732 static int
dissect_nfs3_specdata(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3733 dissect_nfs3_specdata(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
3734 {
3735 guint32 specdata1;
3736 guint32 specdata2;
3737
3738 specdata1 = tvb_get_ntohl(tvb, offset+0);
3739 specdata2 = tvb_get_ntohl(tvb, offset+4);
3740
3741 if (tree) {
3742 proto_tree *specdata3_tree;
3743
3744 specdata3_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
3745 ett_nfs3_specdata, NULL, "%s: %u,%u", name, specdata1, specdata2);
3746
3747 proto_tree_add_uint(specdata3_tree, hf_nfs3_specdata1, tvb, offset+0, 4, specdata1);
3748 proto_tree_add_uint(specdata3_tree, hf_nfs3_specdata2, tvb, offset+4, 4, specdata2);
3749 }
3750
3751 offset += 8;
3752 return offset;
3753 }
3754
3755
3756 /* NFSv3 RFC 1813, Page 21 */
3757 int
dissect_nfs3_fh(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * name,guint32 * hash,rpc_call_info_value * civ)3758 dissect_nfs3_fh(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
3759 const char *name, guint32 *hash, rpc_call_info_value *civ)
3760 {
3761 guint fh3_len;
3762 guint fh3_len_full;
3763 /*guint fh3_fill;*/
3764 proto_tree *ftree;
3765 int fh_offset, fh_length;
3766
3767 fh3_len = tvb_get_ntohl(tvb, offset+0);
3768 fh3_len_full = rpc_roundup(fh3_len);
3769 /*fh3_fill = fh3_len_full - fh3_len;*/
3770
3771 ftree = proto_tree_add_subtree(tree, tvb, offset, 4+fh3_len_full,
3772 ett_nfs3_fh, NULL, name);
3773
3774 /* are we snooping fh to filenames ?*/
3775 if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
3776 /* NFS v3 LOOKUP, CREATE, MKDIR, READDIRPLUS
3777 calls might give us a mapping*/
3778 if ( ((civ->prog == 100003)
3779 &&((civ->vers == 3)
3780 &&(!civ->request)
3781 &&((civ->proc == 3)||(civ->proc == 8)||(civ->proc == 9)||(civ->proc == 17))))
3782 || civ->vers == 4
3783 ) {
3784 fh_length = tvb_get_ntohl(tvb, offset);
3785 fh_offset = offset+4;
3786 nfs_name_snoop_add_fh(civ->xid, tvb, fh_offset,
3787 fh_length);
3788 }
3789
3790 /* MOUNT v3 MNT replies might give us a filehandle */
3791 if ( (civ->prog == 100005)
3792 &&(civ->vers == 3)
3793 &&(!civ->request)
3794 &&(civ->proc == 1)
3795 ) {
3796 fh_length = tvb_get_ntohl(tvb, offset);
3797 fh_offset = offset+4;
3798 nfs_name_snoop_add_fh(civ->xid, tvb, fh_offset,
3799 fh_length);
3800 }
3801 }
3802
3803 proto_tree_add_uint(ftree, hf_nfs_fh_length, tvb, offset+0, 4,
3804 fh3_len);
3805
3806 /* Handle WebNFS requests where filehandle may be 0 length */
3807 if (fh3_len > 0)
3808 {
3809 dissect_fhandle_data(tvb, offset+4, pinfo, ftree, fh3_len, FALSE, hash);
3810
3811 offset += fh3_len_full;
3812 }
3813 else if (hash) {
3814 /* Make sure hash is set regardless, as our caller expects it
3815 * to be initialized */
3816 *hash = 0;
3817 }
3818
3819 offset += 4;
3820
3821 return offset;
3822 }
3823
3824
3825 /* NFSv3 RFC 1813, Page 21 */
3826 static int
dissect_nfstime3(tvbuff_t * tvb,int offset,proto_tree * tree,int hf_time,int hf_time_sec,int hf_time_nsec)3827 dissect_nfstime3(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_time,
3828 int hf_time_sec, int hf_time_nsec)
3829 {
3830 guint32 seconds;
3831 guint32 nseconds;
3832 nstime_t ts;
3833
3834 seconds = tvb_get_ntohl(tvb, offset+0);
3835 nseconds = tvb_get_ntohl(tvb, offset+4);
3836 ts.secs = seconds;
3837 ts.nsecs = nseconds;
3838
3839 if (tree) {
3840 proto_item *time_item;
3841 proto_tree *time_tree;
3842
3843 time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8,
3844 &ts);
3845
3846 time_tree = proto_item_add_subtree(time_item, ett_nfs3_nfstime);
3847
3848 proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4,
3849 seconds);
3850 proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset+4, 4,
3851 nseconds);
3852 }
3853 offset += 8;
3854 return offset;
3855 }
3856
3857
3858 /* NFSv3 RFC 1813, Page 22
3859 * The levels parameter tells this helper how many levels up in the tree it
3860 * should display useful info such as type,mode,uid,gid
3861 * If level has the COL_INFO_LEVEL flag set it will also display
3862 * this info in the info column.
3863 */
3864 static int
dissect_nfs_fattr3(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * tree,const char * name,guint32 levels)3865 dissect_nfs_fattr3(packet_info *pinfo, tvbuff_t *tvb, int offset,
3866 proto_tree *tree, const char *name, guint32 levels)
3867 {
3868 proto_item *fattr3_item = NULL;
3869 proto_tree *fattr3_tree = NULL;
3870 int old_offset = offset;
3871 guint32 type, mode, uid, gid;
3872
3873 fattr3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
3874 ett_nfs3_fattr, &fattr3_item, name);
3875
3876 /* ftype */
3877 offset = dissect_ftype3(tvb, offset, fattr3_tree, hf_nfs3_fattr_type, &type);
3878
3879 /* mode */
3880 offset = dissect_nfs3_mode(tvb, offset, fattr3_tree, &mode);
3881
3882 /* nlink */
3883 offset = dissect_rpc_uint32(tvb, fattr3_tree, hf_nfs3_fattr_nlink,
3884 offset);
3885
3886 /* uid */
3887 uid = tvb_get_ntohl(tvb, offset);
3888 offset = dissect_rpc_uint32(tvb, fattr3_tree, hf_nfs3_fattr_uid,
3889 offset);
3890
3891 /* gid */
3892 gid = tvb_get_ntohl(tvb, offset);
3893 offset = dissect_rpc_uint32(tvb, fattr3_tree, hf_nfs3_fattr_gid,
3894 offset);
3895
3896 /* size*/
3897 offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_size,
3898 offset);
3899
3900 /* used */
3901 offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_used,
3902 offset);
3903
3904 /* rdev */
3905 offset = dissect_nfs3_specdata(tvb, offset, fattr3_tree, "rdev");
3906
3907 /* fsid */
3908 offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_fsid,
3909 offset);
3910
3911 /* fileid */
3912 offset = dissect_rpc_uint64(tvb, fattr3_tree, hf_nfs3_fattr_fileid,
3913 offset);
3914
3915 /* atime */
3916 offset = dissect_nfstime3 (tvb, offset, fattr3_tree, hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_nsec);
3917
3918 /* mtime */
3919 offset = dissect_nfstime3 (tvb, offset, fattr3_tree, hf_nfs_mtime, hf_nfs_mtime_sec, hf_nfs_mtime_nsec);
3920
3921 /* ctime */
3922 offset = dissect_nfstime3 (tvb, offset, fattr3_tree, hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_nsec);
3923
3924 /* now we know, that fattr3 is shorter */
3925 proto_item_set_len(fattr3_item, offset - old_offset);
3926
3927 /* put some nice info in COL_INFO for GETATTR replies */
3928 if (levels & COL_INFO_LEVEL) {
3929 levels &= (~COL_INFO_LEVEL);
3930 col_append_fstr(pinfo->cinfo, COL_INFO,
3931 " %s mode: %04o uid: %d gid: %d",
3932 val_to_str_ext(type, &names_nfs_ftype3_ext, "Unknown Type: 0x%x"),
3933 mode&0x0fff, uid, gid);
3934 }
3935 /* populate the expansion lines with some nice useable info */
3936 while ( fattr3_tree && levels-- ) {
3937 proto_item_append_text(fattr3_tree, " %s mode: %04o uid: %d gid: %d",
3938 val_to_str_ext(type, &names_nfs_ftype3_ext, "Unknown Type: 0x%x"),
3939 mode&0x0fff, uid, gid);
3940 fattr3_tree = fattr3_tree->parent;
3941 }
3942
3943 return offset;
3944 }
3945
3946
3947 static const value_string value_follows[] =
3948 {
3949 { 0, "no value" },
3950 { 1, "value follows" },
3951 { 0, NULL }
3952 };
3953
3954
3955 /* NFSv3 RFC 1813, Page 23 */
3956 int
dissect_nfs3_post_op_attr(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * name)3957 dissect_nfs3_post_op_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
3958 const char *name)
3959 {
3960 proto_item *post_op_attr_item;
3961 proto_tree *post_op_attr_tree;
3962 int old_offset = offset;
3963 guint32 attributes_follow = 0;
3964
3965 attributes_follow = tvb_get_ntohl(tvb, offset+0);
3966
3967 post_op_attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
3968 ett_nfs3_post_op_attr, &post_op_attr_item, name);
3969
3970 proto_tree_add_uint(post_op_attr_tree, hf_nfs3_attributes_follow, tvb, offset, 4, attributes_follow);
3971
3972 offset += 4;
3973 switch (attributes_follow) {
3974 case TRUE:
3975 offset = dissect_nfs_fattr3(pinfo, tvb, offset,
3976 post_op_attr_tree,
3977 "attributes", 2);
3978 break;
3979 case FALSE:
3980 /* void */
3981 break;
3982 }
3983
3984 /* now we know, that post_op_attr_tree is shorter */
3985 proto_item_set_len(post_op_attr_item, offset - old_offset);
3986
3987 return offset;
3988 }
3989
3990
3991 /* NFSv3 RFC 1813, Page 24 */
3992 static int
dissect_wcc_attr(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3993 dissect_wcc_attr(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
3994 {
3995 proto_item *wcc_attr_item;
3996 proto_tree *wcc_attr_tree;
3997 int old_offset = offset;
3998
3999 wcc_attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4000 ett_nfs3_wcc_attr, &wcc_attr_item, name);
4001
4002 offset = dissect_rpc_uint64(tvb, wcc_attr_tree, hf_nfs3_wcc_attr_size,
4003 offset);
4004 offset = dissect_nfstime3(tvb, offset, wcc_attr_tree, hf_nfs_mtime,
4005 hf_nfs_mtime_sec, hf_nfs_mtime_nsec);
4006 offset = dissect_nfstime3(tvb, offset, wcc_attr_tree, hf_nfs_ctime,
4007 hf_nfs_ctime_sec, hf_nfs_ctime_nsec);
4008 /* now we know, that wcc_attr_tree is shorter */
4009 proto_item_set_len(wcc_attr_item, offset - old_offset);
4010
4011 return offset;
4012 }
4013
4014
4015 /* NFSv3 RFC 1813, Page 24 */
4016 static int
dissect_pre_op_attr(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4017 dissect_pre_op_attr(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4018 {
4019 proto_item *pre_op_attr_item;
4020 proto_tree *pre_op_attr_tree;
4021 int old_offset = offset;
4022 guint32 attributes_follow;
4023
4024 pre_op_attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4025 ett_nfs3_pre_op_attr, &pre_op_attr_item, name);
4026
4027 proto_tree_add_item_ret_uint(pre_op_attr_tree, hf_nfs3_attributes_follow, tvb, offset, 4, ENC_BIG_ENDIAN, &attributes_follow);
4028 offset += 4;
4029 switch (attributes_follow) {
4030 case TRUE:
4031 offset = dissect_wcc_attr(tvb, offset, pre_op_attr_tree,
4032 "attributes");
4033 break;
4034 case FALSE:
4035 /* void */
4036 break;
4037 }
4038
4039 /* now we know, that pre_op_attr_tree is shorter */
4040 proto_item_set_len(pre_op_attr_item, offset - old_offset);
4041
4042 return offset;
4043 }
4044
4045
4046 /* NFSv3 RFC 1813, Page 24 */
4047 static int
dissect_wcc_data(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * name)4048 dissect_wcc_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, const char *name)
4049 {
4050 proto_item *wcc_data_item;
4051 proto_tree *wcc_data_tree;
4052 int old_offset = offset;
4053
4054 wcc_data_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4055 ett_nfs3_wcc_data, &wcc_data_item, name);
4056
4057 offset = dissect_pre_op_attr (tvb, offset, wcc_data_tree, "before");
4058 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, wcc_data_tree, "after" );
4059
4060 /* now we know, that wcc_data is shorter */
4061 proto_item_set_len(wcc_data_item, offset - old_offset);
4062
4063 return offset;
4064 }
4065
4066
4067 /* NFSv3 RFC 1813, Page 25 */
4068 static int
dissect_nfs3_post_op_fh(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * name,rpc_call_info_value * civ)4069 dissect_nfs3_post_op_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
4070 proto_tree *tree, const char *name, rpc_call_info_value *civ)
4071 {
4072 proto_item *post_op_fh3_item;
4073 proto_tree *post_op_fh3_tree;
4074 int old_offset = offset;
4075 guint32 handle_follows;
4076
4077 post_op_fh3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4078 ett_nfs3_post_op_fh, &post_op_fh3_item, name);
4079
4080 proto_tree_add_item_ret_uint(post_op_fh3_tree, hf_nfs3_handle_follow, tvb, offset, 4, ENC_BIG_ENDIAN, &handle_follows);
4081 offset += 4;
4082 switch (handle_follows) {
4083 case TRUE:
4084 offset = dissect_nfs3_fh(tvb, offset, pinfo, post_op_fh3_tree,
4085 "handle", NULL, civ);
4086 break;
4087 case FALSE:
4088 /* void */
4089 break;
4090 }
4091
4092 /* now we know, that post_op_fh3_tree is shorter */
4093 if (post_op_fh3_item) {
4094 proto_item_set_len(post_op_fh3_item, offset - old_offset);
4095 }
4096
4097 return offset;
4098 }
4099
4100
4101 /* NFSv3 RFC 1813, Page 25 */
4102 static int
dissect_set_mode3(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4103 dissect_set_mode3(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4104 {
4105 proto_item *set_mode3_item;
4106 proto_tree *set_mode3_tree;
4107 int old_offset = offset;
4108 guint32 set_it;
4109 const char *set_it_name;
4110
4111 set_it = tvb_get_ntohl(tvb, offset+0);
4112
4113 set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4114
4115 set_mode3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4116 ett_nfs3_set_mode, &set_mode3_item, "%s: %s", name, set_it_name);
4117
4118 proto_tree_add_uint(set_mode3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4119
4120 offset += 4;
4121
4122 switch (set_it) {
4123 case 1:
4124 offset = dissect_nfs3_mode(tvb, offset, set_mode3_tree, NULL);
4125 break;
4126 default:
4127 /* void */
4128 break;
4129 }
4130
4131 /* now we know, that set_mode3 is shorter */
4132 proto_item_set_len(set_mode3_item, offset - old_offset);
4133
4134 return offset;
4135 }
4136
4137
4138 /* NFSv3 RFC 1813, Page 26 */
4139 static int
dissect_set_uid3(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4140 dissect_set_uid3(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4141 {
4142 proto_item *set_uid3_item;
4143 proto_tree *set_uid3_tree;
4144 int old_offset = offset;
4145 guint32 set_it;
4146 const char *set_it_name;
4147
4148 set_it = tvb_get_ntohl(tvb, offset+0);
4149 set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4150
4151 set_uid3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4152 ett_nfs3_set_uid, &set_uid3_item, "%s: %s", name, set_it_name);
4153
4154 proto_tree_add_uint(set_uid3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4155 offset += 4;
4156
4157 switch (set_it) {
4158 case 1:
4159 offset = dissect_rpc_uint32(tvb, set_uid3_tree,
4160 hf_nfs3_uid, offset);
4161 break;
4162 default:
4163 /* void */
4164 break;
4165 }
4166
4167 /* now we know, that set_uid3 is shorter */
4168 proto_item_set_len(set_uid3_item, offset - old_offset);
4169
4170 return offset;
4171 }
4172
4173
4174 /* NFSv3 RFC 1813, Page 26 */
4175 static int
dissect_set_gid3(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4176 dissect_set_gid3(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4177 {
4178 proto_item *set_gid3_item;
4179 proto_tree *set_gid3_tree;
4180 int old_offset = offset;
4181 guint32 set_it;
4182 const char *set_it_name;
4183
4184 set_it = tvb_get_ntohl(tvb, offset+0);
4185
4186 set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4187 set_gid3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4188 ett_nfs3_set_gid, &set_gid3_item, "%s: %s", name, set_it_name);
4189
4190 proto_tree_add_uint(set_gid3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4191
4192 offset += 4;
4193
4194 switch (set_it) {
4195 case 1:
4196 offset = dissect_rpc_uint32(tvb, set_gid3_tree,
4197 hf_nfs3_gid, offset);
4198 break;
4199 default:
4200 /* void */
4201 break;
4202 }
4203
4204 /* now we know, that set_gid3 is shorter */
4205 proto_item_set_len(set_gid3_item, offset - old_offset);
4206
4207 return offset;
4208 }
4209
4210
4211 /* NFSv3 RFC 1813, Page 26 */
4212 static int
dissect_set_size3(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4213 dissect_set_size3(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4214 {
4215 proto_item *set_size3_item;
4216 proto_tree *set_size3_tree;
4217 int old_offset = offset;
4218 guint32 set_it;
4219 const char *set_it_name;
4220
4221 set_it = tvb_get_ntohl(tvb, offset+0);
4222
4223 set_it_name = val_to_str_const(set_it, value_follows, "Unknown");
4224
4225 set_size3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4226 ett_nfs3_set_size, &set_size3_item, "%s: %s", name, set_it_name);
4227 proto_tree_add_uint(set_size3_tree, hf_nfs4_set_it_value_follows, tvb, offset, 4, set_it);
4228
4229 offset += 4;
4230
4231 switch (set_it) {
4232 case 1:
4233 offset = dissect_rpc_uint64(tvb, set_size3_tree,
4234 hf_nfs3_set_size, offset);
4235 break;
4236 default:
4237 /* void */
4238 break;
4239 }
4240
4241 /* now we know, that set_size3 is shorter */
4242 proto_item_set_len(set_size3_item, offset - old_offset);
4243
4244 return offset;
4245 }
4246
4247
4248 /* NFSv3 RFC 1813, Page 25 */
4249 #define DONT_CHANGE 0
4250 #define SET_TO_SERVER_TIME 1
4251 #define SET_TO_CLIENT_TIME 2
4252
4253 static const value_string time_how[] =
4254 {
4255 { DONT_CHANGE, "don't change" },
4256 { SET_TO_SERVER_TIME, "set to server time" },
4257 { SET_TO_CLIENT_TIME, "set to client time" },
4258 { 0, NULL }
4259 };
4260
4261
4262 /* NFSv3 RFC 1813, Page 26 */
4263 static int
dissect_set_atime(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4264 dissect_set_atime(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4265 {
4266 proto_item *set_atime_item;
4267 proto_tree *set_atime_tree;
4268 int old_offset = offset;
4269 guint32 set_it;
4270 const char *set_it_name;
4271
4272 set_it = tvb_get_ntohl(tvb, offset+0);
4273
4274 set_it_name = val_to_str_const(set_it, time_how, "Unknown");
4275
4276 set_atime_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4277 ett_nfs3_set_atime, &set_atime_item, "%s: %s", name, set_it_name);
4278
4279 proto_tree_add_uint(set_atime_tree, hf_nfs4_time_how, tvb, offset, 4, set_it);
4280 offset += 4;
4281
4282 switch (set_it) {
4283 case SET_TO_CLIENT_TIME:
4284 offset = dissect_nfstime3(tvb, offset, set_atime_tree,
4285 hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_nsec);
4286 break;
4287 default:
4288 /* void */
4289 break;
4290 }
4291
4292 /* now we know, that set_atime is shorter */
4293 proto_item_set_len(set_atime_item, offset - old_offset);
4294
4295 return offset;
4296 }
4297
4298
4299 /* NFSv3 RFC 1813, Page 26 */
4300 static int
dissect_set_mtime(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4301 dissect_set_mtime(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4302 {
4303 proto_item *set_mtime_item;
4304 proto_tree *set_mtime_tree;
4305 int old_offset = offset;
4306 guint32 set_it;
4307 const char *set_it_name;
4308
4309 set_it = tvb_get_ntohl(tvb, offset+0);
4310
4311 set_it_name = val_to_str_const(set_it, time_how, "Unknown");
4312
4313 set_mtime_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4314 ett_nfs3_set_mtime, &set_mtime_item, "%s: %s", name, set_it_name);
4315 proto_tree_add_uint(set_mtime_tree, hf_nfs4_time_how, tvb, offset, 4, set_it);
4316
4317 offset += 4;
4318
4319 switch (set_it) {
4320 case SET_TO_CLIENT_TIME:
4321 offset = dissect_nfstime3(tvb, offset, set_mtime_tree,
4322 hf_nfs_atime, hf_nfs_atime_sec, hf_nfs_atime_nsec);
4323 break;
4324 default:
4325 /* void */
4326 break;
4327 }
4328
4329 /* now we know, that set_mtime is shorter */
4330 proto_item_set_len(set_mtime_item, offset - old_offset);
4331
4332 return offset;
4333 }
4334
4335
4336 /* NFSv3 RFC 1813, Page 25..27 */
4337 static int
dissect_nfs3_sattr(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4338 dissect_nfs3_sattr(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4339 {
4340 proto_item *sattr3_item;
4341 proto_tree *sattr3_tree;
4342 int old_offset = offset;
4343
4344 sattr3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4345 ett_nfs3_sattr, &sattr3_item, name);
4346
4347 offset = dissect_set_mode3(tvb, offset, sattr3_tree, "mode");
4348 offset = dissect_set_uid3 (tvb, offset, sattr3_tree, "uid");
4349 offset = dissect_set_gid3 (tvb, offset, sattr3_tree, "gid");
4350 offset = dissect_set_size3(tvb, offset, sattr3_tree, "size");
4351 offset = dissect_set_atime(tvb, offset, sattr3_tree, "atime");
4352 offset = dissect_set_mtime(tvb, offset, sattr3_tree, "mtime");
4353
4354 /* now we know, that sattr3 is shorter */
4355 proto_item_set_len(sattr3_item, offset - old_offset);
4356
4357 return offset;
4358 }
4359
4360
4361 /* NFSv3 RFC 1813, Page 27 */
4362 static int
dissect_diropargs3(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * label,guint32 * hash,const char ** name,rpc_call_info_value * civ)4363 dissect_diropargs3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
4364 const char *label, guint32 *hash, const char **name, rpc_call_info_value *civ)
4365 {
4366 proto_item *diropargs3_item;
4367 proto_tree *diropargs3_tree;
4368 int old_offset = offset;
4369 int parent_offset, parent_len;
4370 int name_offset, name_len;
4371
4372 diropargs3_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
4373 ett_nfs3_diropargs, &diropargs3_item, label);
4374
4375 parent_offset = offset+4;
4376 parent_len = tvb_get_ntohl(tvb, offset);
4377 offset = dissect_nfs3_fh(tvb, offset, pinfo, diropargs3_tree, "dir", hash, civ);
4378 name_offset = offset+4;
4379 name_len = tvb_get_ntohl(tvb, offset);
4380 offset = dissect_nfs3_filename(tvb, offset, diropargs3_tree,
4381 hf_nfs_name, name);
4382
4383 /* are we snooping fh to filenames ?*/
4384 if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
4385 /* v3 LOOKUP, CREATE, MKDIR calls might give us a mapping*/
4386 if ( (civ->prog == 100003)
4387 &&(civ->vers == 3)
4388 &&(civ->request)
4389 &&((civ->proc == 3)||(civ->proc == 8)||(civ->proc == 9))
4390 ) {
4391 nfs_name_snoop_add_name(civ->xid, tvb,
4392 name_offset, name_len,
4393 parent_offset, parent_len, NULL);
4394 }
4395 }
4396
4397
4398 /* now we know, that diropargs3 is shorter */
4399 proto_item_set_len(diropargs3_item, offset - old_offset);
4400
4401 return offset;
4402 }
4403
4404
4405 static int
dissect_nfs3_remove_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4406 dissect_nfs3_remove_call(tvbuff_t *tvb, packet_info *pinfo,
4407 proto_tree *tree, void *data)
4408 {
4409 guint32 hash = 0;
4410 const char *name = NULL;
4411 int offset = 0;
4412
4413 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object", &hash, &name, (rpc_call_info_value*)data);
4414
4415 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
4416 proto_item_append_text(tree, ", REMOVE Call DH: 0x%08x/%s", hash, name);
4417
4418 return offset;
4419 }
4420
4421
4422 static int
dissect_nfs3_null_call(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4423 dissect_nfs3_null_call(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
4424 proto_tree *tree, void *data _U_)
4425 {
4426 proto_item_append_text(tree, ", NULL Call");
4427
4428 return 0;
4429 }
4430
4431
4432 static int
dissect_nfs3_null_reply(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4433 dissect_nfs3_null_reply(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
4434 proto_tree *tree, void *data _U_)
4435 {
4436 proto_item_append_text(tree, ", NULL Reply");
4437
4438 return 0;
4439 }
4440
4441
4442 static int
dissect_nfs3_rmdir_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4443 dissect_nfs3_rmdir_call(tvbuff_t *tvb, packet_info *pinfo,
4444 proto_tree *tree, void *data)
4445 {
4446 guint32 hash = 0;
4447 const char *name = NULL;
4448 int offset = 0;
4449
4450 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "object", &hash, &name, (rpc_call_info_value*)data);
4451
4452 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
4453 proto_item_append_text(tree, ", RMDIR Call DH: 0x%08x/%s", hash, name);
4454
4455 return offset;
4456 }
4457
4458
4459 /* NFSv3 RFC 1813, Page 32,33 */
4460 static int
dissect_nfs3_getattr_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4461 dissect_nfs3_getattr_call(tvbuff_t *tvb, packet_info *pinfo,
4462 proto_tree *tree, void *data)
4463 {
4464 guint32 hash = 0;
4465 int offset = 0;
4466
4467 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
4468
4469 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
4470 proto_item_append_text(tree, ", GETATTR Call FH: 0x%08x", hash);
4471
4472 return offset;
4473 }
4474
4475
4476 /* NFSv3 RFC 1813, Page 32,33 */
4477 static int
dissect_nfs3_getattr_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4478 dissect_nfs3_getattr_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
4479 proto_tree *tree, void *data _U_)
4480 {
4481 guint32 status;
4482 const char *err;
4483 int offset = 0;
4484
4485 proto_item_append_text(tree, ", GETATTR Reply");
4486
4487 offset = dissect_nfs3_status(tvb, offset, tree, &status);
4488 switch (status) {
4489 case 0:
4490 offset = dissect_nfs_fattr3(pinfo, tvb, offset, tree, "obj_attributes", 2|COL_INFO_LEVEL);
4491 break;
4492 default:
4493 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
4494 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4495 proto_item_append_text(tree, " Error: %s", err);
4496 break;
4497 }
4498
4499 return offset;
4500 }
4501
4502
4503 /* NFSv3 RFC 1813, Page 33 */
4504 static int
dissect_sattrguard3(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4505 dissect_sattrguard3(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
4506 {
4507 proto_item *sattrguard3_item;
4508 proto_tree *sattrguard3_tree;
4509 int old_offset = offset;
4510 guint32 check;
4511 const char *check_name;
4512
4513 check = tvb_get_ntohl(tvb, offset+0);
4514
4515 check_name = val_to_str_const(check, value_follows, "Unknown");
4516
4517 sattrguard3_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
4518 ett_nfs3_sattrguard, &sattrguard3_item, "%s: %s", name, check_name);
4519
4520 proto_tree_add_uint(sattrguard3_tree, hf_nfs3_sattrguard3, tvb, offset, 4, check);
4521
4522
4523 offset += 4;
4524
4525 switch (check) {
4526 case TRUE:
4527 offset = dissect_nfstime3(tvb, offset, sattrguard3_tree,
4528 hf_nfs_ctime, hf_nfs_ctime_sec, hf_nfs_ctime_nsec);
4529 break;
4530 case FALSE:
4531 /* void */
4532 break;
4533 }
4534
4535 /* now we know, that sattrguard3 is shorter */
4536 proto_item_set_len(sattrguard3_item, offset - old_offset);
4537
4538 return offset;
4539 }
4540
4541
4542 /* NFSv3 RFC 1813, Page 33..36 */
4543 static int
dissect_nfs3_setattr_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4544 dissect_nfs3_setattr_call(tvbuff_t *tvb, packet_info *pinfo,
4545 proto_tree *tree, void *data)
4546 {
4547 guint32 hash = 0;
4548 int offset = 0;
4549
4550 offset = dissect_nfs3_fh (tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
4551 offset = dissect_nfs3_sattr (tvb, offset, tree, "new_attributes");
4552 offset = dissect_sattrguard3(tvb, offset, tree, "guard");
4553
4554 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
4555 proto_item_append_text(tree, ", SETATTR Call FH: 0x%08x", hash);
4556
4557 return offset;
4558 }
4559
4560
4561 /* NFSv3 RFC 1813, Page 33..36 */
4562 static int
dissect_nfs3_setattr_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4563 dissect_nfs3_setattr_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
4564 proto_tree *tree, void *data _U_)
4565 {
4566 guint32 status;
4567 const char *err;
4568 int offset = 0;
4569
4570 offset = dissect_nfs3_status(tvb, offset, tree, &status);
4571 switch (status) {
4572 case 0:
4573 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "obj_wcc");
4574 proto_item_append_text(tree, ", SETATTR Reply");
4575 break;
4576 default:
4577 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "obj_wcc");
4578
4579 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
4580 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4581 proto_item_append_text(tree, ", SETATTR Reply Error: %s", err);
4582 break;
4583 }
4584
4585 return offset;
4586 }
4587
4588
4589 /* NFSv3 RFC 1813, Page 37..39 */
4590 static int
dissect_nfs3_lookup_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4591 dissect_nfs3_lookup_call(tvbuff_t *tvb, packet_info *pinfo,
4592 proto_tree *tree, void *data)
4593 {
4594 guint32 hash = 0;
4595 const char *name = NULL;
4596 int offset = 0;
4597
4598 offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "what", &hash, &name, (rpc_call_info_value*)data);
4599
4600 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
4601 proto_item_append_text(tree, ", LOOKUP Call DH: 0x%08x/%s", hash, name);
4602
4603 return offset;
4604 }
4605
4606
4607 /* NFSv3 RFC 1813, Page 37..39 */
4608 static int
dissect_nfs3_lookup_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4609 dissect_nfs3_lookup_reply(tvbuff_t *tvb, packet_info *pinfo,
4610 proto_tree *tree, void *data)
4611 {
4612 guint32 status;
4613 const char *err;
4614 guint32 hash = 0;
4615 int offset = 0;
4616
4617 offset = dissect_nfs3_status(tvb, offset, tree, &status);
4618 switch (status) {
4619 case 0:
4620 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
4621 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4622 "obj_attributes");
4623 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4624 "dir_attributes");
4625
4626 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
4627 proto_item_append_text(tree, ", LOOKUP Reply FH: 0x%08x", hash);
4628 break;
4629 default:
4630 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4631 "dir_attributes");
4632
4633 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
4634 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4635 proto_item_append_text(tree, ", LOOKUP Reply Error: %s", err);
4636 break;
4637 }
4638
4639 return offset;
4640 }
4641
4642
4643 static const value_string accvs[] = {
4644 { 0x001, "RD" },
4645 { 0x002, "LU" },
4646 { 0x004, "MD" },
4647 { 0x008, "XT" },
4648 { 0x010, "DL" },
4649 { 0x020, "XE" },
4650 { 0x040, "XAR" },
4651 { 0x080, "XAW" },
4652 { 0x100, "XAL" },
4653 { 0, NULL }
4654 };
4655
4656 static const true_false_string tfs_access_supp = { "supported", "!NOT Supported!"};
4657 static const true_false_string tfs_access_rights = {"allowed", "*Access Denied*"};
4658
4659 proto_tree*
display_access_items(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint32 amask,char mtype,int version,wmem_strbuf_t * optext,const char * label)4660 display_access_items(tvbuff_t* tvb, int offset, packet_info* pinfo, proto_tree *tree,
4661 guint32 amask, char mtype, int version, wmem_strbuf_t* optext, const char *label)
4662 {
4663 gboolean nfsv3 = ((version == 3) ? TRUE : FALSE);
4664 proto_item *access_item = NULL;
4665 proto_tree *access_subtree = NULL;
4666 proto_item *access_subitem = NULL;
4667 guint32 itype;
4668
4669 /* XXX Legend (delete if desired)
4670
4671 'C' CHECK access: append label to both headers and create subtree and list
4672 'N' NOT SUPPORTED: append label to both headers
4673 'S' SUPPORTED or not: create subtree and list
4674 'D' DENIED: append label to both headers
4675 'A' ALLOWED: append label to both headers
4676 'R' RIGHTS: create subtree and list */
4677
4678 switch (mtype) {
4679 case 'C':
4680 access_item = proto_tree_add_item(tree, hf_nfs_access_check, tvb,
4681 offset, 4, ENC_BIG_ENDIAN);
4682 access_subtree = proto_item_add_subtree(access_item,
4683 (nfsv3 ? ett_nfs3_access : ett_nfs4_access));
4684 break;
4685 case 'S':
4686 access_item = proto_tree_add_item(tree, hf_nfs_access_supported, tvb,
4687 offset, 4, ENC_BIG_ENDIAN);
4688 access_subtree = proto_item_add_subtree(access_item, ett_nfs4_access_supp);
4689 break;
4690 case 'R':
4691 access_item = proto_tree_add_item(tree, hf_nfs_access_rights, tvb,
4692 offset, 4, ENC_BIG_ENDIAN);
4693 access_subtree = proto_item_add_subtree(access_item,
4694 (nfsv3 ? ett_nfs3_access : ett_nfs4_access));
4695 break;
4696 }
4697 /* Append label to the Info column and tree */
4698 if (mtype != 'S' && mtype != 'R') {
4699 if (nfsv3) {
4700 col_append_fstr(pinfo->cinfo, COL_INFO, ", [%s:", label);
4701 } else {
4702 wmem_strbuf_append_printf (optext, ", [%s:", label);
4703 }
4704 proto_item_append_text(tree, ", [%s:", label);
4705 }
4706
4707 for (itype=0; itype < 9; itype++) {
4708 if (amask & accvs[itype].value) {
4709 if (mtype != 'S' && mtype != 'R') {
4710 /* List access type in Info column and tree */
4711 if (nfsv3) {
4712 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", accvs[itype].strptr);
4713 } else {
4714 wmem_strbuf_append_printf (optext, " %s", accvs[itype].strptr);
4715 }
4716 proto_item_append_text(tree, " %s", accvs[itype].strptr);
4717 }
4718 if (mtype == 'C' || mtype == 'S' || mtype == 'R') {
4719
4720 switch (itype) {
4721 case 0:
4722 access_subitem = proto_tree_add_item (access_subtree,
4723 (mtype == 'S' ? hf_nfs_access_supp_read : hf_nfs_access_read),
4724 tvb, offset, 4, ENC_BIG_ENDIAN);
4725 break;
4726 case 1:
4727 access_subitem = proto_tree_add_item (access_subtree,
4728 (mtype == 'S' ? hf_nfs_access_supp_lookup : hf_nfs_access_lookup),
4729 tvb, offset, 4, ENC_BIG_ENDIAN);
4730 break;
4731 case 2:
4732 access_subitem = proto_tree_add_item (access_subtree,
4733 (mtype == 'S' ? hf_nfs_access_supp_modify : hf_nfs_access_modify),
4734 tvb, offset, 4, ENC_BIG_ENDIAN);
4735 break;
4736 case 3:
4737 access_subitem = proto_tree_add_item (access_subtree,
4738 (mtype == 'S' ? hf_nfs_access_supp_extend : hf_nfs_access_extend),
4739 tvb, offset, 4, ENC_BIG_ENDIAN);
4740 break;
4741 case 4:
4742 access_subitem = proto_tree_add_item (access_subtree,
4743 (mtype == 'S' ? hf_nfs_access_supp_delete : hf_nfs_access_delete),
4744 tvb, offset, 4, ENC_BIG_ENDIAN);
4745 break;
4746 case 5:
4747 access_subitem = proto_tree_add_item (access_subtree,
4748 (mtype == 'S' ? hf_nfs_access_supp_execute : hf_nfs_access_execute),
4749 tvb, offset, 4, ENC_BIG_ENDIAN);
4750 break;
4751 case 6:
4752 access_subitem = proto_tree_add_item (access_subtree,
4753 (mtype == 'S' ? hf_nfs_access_supp_xattr_read : hf_nfs_access_xattr_read),
4754 tvb, offset, 4, ENC_BIG_ENDIAN);
4755 break;
4756 case 7:
4757 access_subitem = proto_tree_add_item (access_subtree,
4758 (mtype == 'S' ? hf_nfs_access_supp_xattr_write : hf_nfs_access_xattr_write),
4759 tvb, offset, 4, ENC_BIG_ENDIAN);
4760 break;
4761 case 8:
4762 access_subitem = proto_tree_add_item (access_subtree,
4763 (mtype == 'S' ? hf_nfs_access_supp_xattr_list : hf_nfs_access_xattr_list),
4764 tvb, offset, 4, ENC_BIG_ENDIAN);
4765 break;
4766 }
4767 if (mtype == 'C') proto_item_append_text(access_subitem, "?" );
4768 }
4769 }
4770 }
4771 if (mtype != 'S' && mtype != 'R') {
4772 if (nfsv3) {
4773 col_append_str(pinfo->cinfo, COL_INFO, "]");
4774 } else {
4775 wmem_strbuf_append_printf (optext, "]");
4776 }
4777 proto_item_append_text(tree, "]");
4778 }
4779 return access_subtree = NULL;
4780 }
4781
4782 /* NFSv3 RFC 1813, Page 40..43 */
4783 /* NFSv4 RFC 3530, Page 140..142 */
4784 int
dissect_access_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,int version,wmem_strbuf_t * optext,rpc_call_info_value * civ)4785 dissect_access_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
4786 int version, wmem_strbuf_t *optext, rpc_call_info_value *civ)
4787 {
4788 guint32 *acc_req;
4789 guint32 acc_supp;
4790 guint32 acc_rights;
4791 guint32 mask_not_supp;
4792 guint32 mask_denied;
4793 guint32 mask_allowed;
4794 guint32 e_check, e_rights;
4795 gboolean nfsv3 = ((version == 3) ? TRUE : FALSE);
4796 gboolean nfsv4 = ((version == 4) ? TRUE : FALSE);
4797 gboolean have_acc_supp = TRUE;
4798 proto_tree *access_tree;
4799 proto_item *ditem;
4800
4801 /* Retrieve the access mask from the call if available. It
4802 will not be available if the packet containing the call is
4803 missing or truncated. */
4804 acc_req = (guint32 *)civ->private_data;
4805 if (nfsv4) {
4806 acc_supp = tvb_get_ntohl(tvb, offset+0);
4807 } else if (acc_req) {
4808 acc_supp = *acc_req;
4809 } else {
4810 have_acc_supp = FALSE;
4811 }
4812 /* V3/V4 - Get access rights mask and create a subtree for it */
4813 acc_rights = tvb_get_ntohl(tvb, (nfsv3 ? offset+0: offset+4));
4814 if (!have_acc_supp) {
4815 /* The v3 access call isn't available. Using acc_rights for
4816 acc_supp ensures mask_allowed will be correct */
4817 acc_supp = acc_rights;
4818 }
4819
4820 /* Create access masks: not_supported, denied, and allowed */
4821 if (acc_req && have_acc_supp)
4822 mask_not_supp = *acc_req ^ acc_supp;
4823 else
4824 mask_not_supp = 0;
4825
4826 e_check = acc_supp;
4827 e_rights = acc_supp & acc_rights; /* guard against broken implementations */
4828 mask_denied = e_check ^ e_rights;
4829 mask_allowed = e_check & e_rights;
4830
4831 if (nfsv4) {
4832 if (mask_not_supp > 0) {
4833 display_access_items(tvb, offset, pinfo, tree, mask_not_supp, 'N', 4,
4834 optext, "NOT Supported") ;
4835 }
4836 display_access_items(tvb, offset, pinfo, tree, acc_supp, 'S', 4,
4837 optext, "Supported");
4838 offset+=4;
4839 }
4840 if (mask_denied > 0) {
4841 display_access_items(tvb, offset, pinfo, tree, mask_denied, 'D', version,
4842 optext, "Access Denied") ;
4843 }
4844 if (mask_allowed > 0) {
4845 display_access_items(tvb, offset, pinfo, tree, mask_allowed, 'A', version,
4846 optext, "Allowed") ;
4847 }
4848 /* Pass the OR'd masks rather than acc_rights so that display_access_items will
4849 process types that have been denied access. Since proto_tree_add_item uses the
4850 mask in the tvb (not the passed mask), the correct (denied) access is displayed. */
4851 access_tree = display_access_items(tvb, offset, pinfo, tree,
4852 (mask_allowed | mask_denied), 'R', version, optext, NULL) ;
4853
4854 ditem = proto_tree_add_boolean(access_tree, hf_nfs_access_denied, tvb,
4855 offset, 4, (mask_denied > 0 ? TRUE : FALSE ));
4856 proto_item_set_generated(ditem);
4857
4858 return offset+4;
4859 }
4860
4861
4862 /* NFSv3 RFC 1813, Page 40..43 */
4863 static int
dissect_nfs3_access_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4864 dissect_nfs3_access_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4865 {
4866 int offset = 0;
4867 guint32 fhhash = 0, *acc_request, amask;
4868 rpc_call_info_value *civ = (rpc_call_info_value*)data;
4869
4870 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &fhhash, civ);
4871
4872 /* Get access mask to check and save it for comparison to the access reply. */
4873 amask = tvb_get_ntohl(tvb, offset);
4874 acc_request = (guint32 *)wmem_memdup(wmem_file_scope(), &amask, sizeof(guint32));
4875 civ->private_data = acc_request;
4876
4877 /* Append filehandle to Info column and main tree header */
4878 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", fhhash);
4879 proto_item_append_text(tree, ", ACCESS Call, FH: 0x%08x", fhhash);
4880
4881 display_access_items(tvb, offset, pinfo, tree, amask, 'C', 3, NULL, "Check") ;
4882
4883 offset+=4;
4884 return offset;
4885 }
4886
4887
4888 /* NFSv3 RFC 1813, Page 40..43 */
4889 static int
dissect_nfs3_access_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4890 dissect_nfs3_access_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
4891 proto_tree *tree, void *data _U_)
4892 {
4893 guint32 status;
4894 const char *err;
4895 int offset = 0;
4896
4897 offset = dissect_nfs3_status(tvb, offset, tree, &status);
4898 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4899 "obj_attributes");
4900
4901 if (status == 0) {
4902 proto_item_append_text(tree, ", ACCESS Reply");
4903 offset = dissect_access_reply(tvb, offset, pinfo, tree, 3, NULL, (rpc_call_info_value*)data);
4904 } else {
4905 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
4906 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4907 proto_item_append_text(tree, ", ACCESS Reply Error: %s", err);
4908 }
4909 return offset;
4910 }
4911
4912
4913 /* NFSv3 RFC 1813, Page 44,45 */
4914 static int
dissect_nfs3_readlink_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4915 dissect_nfs3_readlink_call(tvbuff_t *tvb, packet_info *pinfo,
4916 proto_tree *tree, void *data)
4917 {
4918 guint32 hash = 0;
4919 int offset = 0;
4920
4921 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
4922
4923 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
4924 proto_item_append_text(tree, ", READLINK Call FH: 0x%08x", hash);
4925
4926 return offset;
4927 }
4928
4929
4930 static int
dissect_nfs3_readlink_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4931 dissect_nfs3_readlink_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
4932 proto_tree *tree, void *data _U_)
4933 {
4934 guint32 status;
4935 const char *err;
4936 const char *name = NULL;
4937 int offset = 0;
4938
4939 offset = dissect_nfs3_status(tvb, offset, tree, &status);
4940 switch (status) {
4941 case 0:
4942 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4943 "symlink_attributes");
4944 offset = dissect_nfsdata_reduced(R_NFS3_PATH, tvb, offset, tree,
4945 hf_nfs2_readlink_data, &name);
4946
4947 col_append_fstr(pinfo->cinfo, COL_INFO, " Path: %s", name);
4948 proto_item_append_text(tree, ", READLINK Reply Path: %s", name);
4949 break;
4950 default:
4951 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
4952 "symlink_attributes");
4953
4954 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
4955 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
4956 proto_item_append_text(tree, ", READLINK Reply Error: %s", err);
4957 break;
4958 }
4959
4960 return offset;
4961 }
4962
4963
4964 /* NFSv3 RFC 1813, Page 46..48 */
4965 static int
dissect_nfs3_read_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4966 dissect_nfs3_read_call(tvbuff_t *tvb, packet_info *pinfo,
4967 proto_tree *tree, void *data)
4968 {
4969 guint64 off;
4970 guint32 len;
4971 guint32 hash = 0;
4972 int offset = 0;
4973
4974 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
4975
4976 off = tvb_get_ntoh64(tvb, offset);
4977 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_offset, offset);
4978
4979 len = tvb_get_ntohl(tvb, offset);
4980 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
4981
4982
4983 col_append_fstr(pinfo->cinfo, COL_INFO,
4984 ", FH: 0x%08x Offset: %" G_GINT64_MODIFIER "u Len: %u", hash, off, len);
4985 proto_item_append_text(tree,
4986 ", READ Call FH: 0x%08x Offset: %" G_GINT64_MODIFIER "u Len: %u", hash, off, len);
4987
4988 return offset;
4989 }
4990
4991
4992 /* NFSv3 RFC 1813, Page 46..48 */
4993 static int
dissect_nfs3_read_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4994 dissect_nfs3_read_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
4995 proto_tree *tree, void *data _U_)
4996 {
4997 guint32 status;
4998 guint32 len;
4999 const char *err;
5000 int offset = 0;
5001
5002 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5003 switch (status) {
5004 case 0:
5005 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5006 "file_attributes");
5007 len = tvb_get_ntohl(tvb, offset);
5008 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count,
5009 offset);
5010 offset = dissect_rpc_bool(tvb, tree, hf_nfs3_read_eof,
5011 offset);
5012 col_append_fstr(pinfo->cinfo, COL_INFO, " Len: %d", len);
5013 proto_item_append_text(tree, ", READ Reply Len: %d", len);
5014 offset = dissect_nfsdata_reduced(R_NFSDATA, tvb, offset, tree, hf_nfs_data, NULL);
5015 break;
5016 default:
5017 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5018 "file_attributes");
5019
5020 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5021 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5022 proto_item_append_text(tree, ", READ Reply Error: %s", err);
5023 break;
5024 }
5025
5026 return offset;
5027 }
5028
5029
5030 /* NFSv3 RFC 1813, Page 49 */
5031 static const value_string names_stable_how[] = {
5032 { UNSTABLE, "UNSTABLE" },
5033 { DATA_SYNC, "DATA_SYNC" },
5034 { FILE_SYNC, "FILE_SYNC" },
5035 { 0, NULL }
5036 };
5037
5038 /* NFSv3 RFC 1813, Page 49 */
5039 static int
dissect_stable_how(tvbuff_t * tvb,int offset,proto_tree * tree,int hfindex)5040 dissect_stable_how(tvbuff_t *tvb, int offset, proto_tree *tree, int hfindex)
5041 {
5042 proto_tree_add_item(tree, hfindex, tvb, offset, 4, ENC_BIG_ENDIAN);
5043 offset += 4;
5044
5045 return offset;
5046 }
5047
5048 /* NFSv3 RFC 1813, Page 49..54 */
5049 static int
dissect_nfs3_write_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5050 dissect_nfs3_write_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5051 {
5052 guint64 off;
5053 guint32 len;
5054 guint32 stable;
5055 guint32 hash = 0;
5056 int offset = 0;
5057
5058 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
5059
5060 off = tvb_get_ntoh64(tvb, offset);
5061 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_offset, offset);
5062
5063 len = tvb_get_ntohl(tvb, offset);
5064 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
5065
5066 stable = tvb_get_ntohl(tvb, offset);
5067 offset = dissect_stable_how(tvb, offset, tree, hf_nfs3_write_stable);
5068
5069 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x Offset: %" G_GINT64_MODIFIER "u Len: %u %s",
5070 hash, off, len, val_to_str(stable, names_stable_how, "Stable: %u"));
5071 proto_item_append_text(tree, ", WRITE Call FH: 0x%08x Offset: %" G_GINT64_MODIFIER "u Len: %u %s",
5072 hash, off, len, val_to_str(stable, names_stable_how, "Stable: %u"));
5073
5074 offset = dissect_nfsdata (tvb, offset, tree, hf_nfs_data);
5075
5076 return offset;
5077 }
5078
5079
5080 /* NFSv3 RFC 1813, Page 49..54 */
5081 static int
dissect_nfs3_write_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5082 dissect_nfs3_write_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5083 {
5084 guint32 status;
5085 guint32 len;
5086 guint32 stable;
5087 const char *err;
5088 int offset = 0;
5089
5090 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5091 switch (status) {
5092 case 0:
5093 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc");
5094 len = tvb_get_ntohl(tvb, offset);
5095 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count,
5096 offset);
5097 stable = tvb_get_ntohl(tvb, offset);
5098 offset = dissect_stable_how(tvb, offset, tree,
5099 hf_nfs3_write_committed);
5100 offset = dissect_nfs3_write_verf(tvb, offset, tree);
5101
5102 col_append_fstr(pinfo->cinfo, COL_INFO,
5103 " Len: %d %s", len, val_to_str(stable, names_stable_how, "Stable: %u"));
5104 proto_item_append_text(tree, ", WRITE Reply Len: %d %s",
5105 len, val_to_str(stable, names_stable_how, "Stable: %u"));
5106 break;
5107 default:
5108 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc");
5109
5110 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5111 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5112 proto_item_append_text(tree, ", WRITE Reply Error: %s", err);
5113 break;
5114 }
5115
5116 return offset;
5117 }
5118
5119
5120 /* NFSv3 RFC 1813, Page 54 */
5121 static const value_string names_createmode3[] = {
5122 { UNCHECKED, "UNCHECKED" },
5123 { GUARDED, "GUARDED" },
5124 { EXCLUSIVE, "EXCLUSIVE" },
5125 { 0, NULL }
5126 };
5127
5128 /* NFSv3 RFC 1813, Page 54 */
5129 static int
dissect_createmode3(tvbuff_t * tvb,int offset,proto_tree * tree,guint32 * mode)5130 dissect_createmode3(tvbuff_t *tvb, int offset, proto_tree *tree, guint32* mode)
5131 {
5132 guint32 mode_value;
5133
5134 mode_value = tvb_get_ntohl(tvb, offset + 0);
5135 if (tree)
5136 proto_tree_add_uint(tree, hf_nfs3_createmode, tvb, offset+0, 4, mode_value);
5137 offset += 4;
5138
5139 *mode = mode_value;
5140 return offset;
5141 }
5142
5143
5144 /* NFSv3 RFC 1813, Page 54..58 */
5145 static int
dissect_nfs3_create_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5146 dissect_nfs3_create_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5147 {
5148 guint32 mode;
5149 guint32 hash = 0;
5150 const char *name = NULL;
5151 int offset = 0;
5152
5153 offset = dissect_diropargs3 (tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
5154 offset = dissect_createmode3(tvb, offset, tree, &mode);
5155 switch (mode) {
5156 case UNCHECKED:
5157 case GUARDED:
5158 offset = dissect_nfs3_sattr(tvb, offset, tree, "obj_attributes");
5159 break;
5160 case EXCLUSIVE:
5161 offset = dissect_nfs3_create_verf(tvb, offset, tree);
5162 break;
5163 }
5164
5165 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s Mode: %s", hash, name,
5166 val_to_str(mode, names_createmode3, "Unknown Mode: %u"));
5167 proto_item_append_text(tree, ", CREATE Call DH: 0x%08x/%s Mode: %s", hash, name,
5168 val_to_str(mode, names_createmode3, "Unknown Mode: %u"));
5169
5170 return offset;
5171 }
5172
5173
5174 /* NFSv3 RFC 1813, Page 54..58 */
5175 static int
dissect_nfs3_create_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5176 dissect_nfs3_create_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5177 {
5178 guint32 status;
5179 const char *err;
5180 int offset = 0;
5181
5182 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5183 switch (status) {
5184 case 0:
5185 offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5186 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5187 "obj_attributes");
5188 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5189 proto_item_append_text(tree, ", CREATE Reply");
5190 break;
5191 default:
5192 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5193
5194 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5195 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5196 proto_item_append_text(tree, ", CREATE Reply Error: %s", err);
5197 break;
5198 }
5199
5200 return offset;
5201 }
5202
5203
5204 /* NFSv3 RFC 1813, Page 58..60 */
5205 static int
dissect_nfs3_mkdir_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5206 dissect_nfs3_mkdir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5207 {
5208 guint32 hash = 0;
5209 const char *name = NULL;
5210 int offset = 0;
5211
5212 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
5213 offset = dissect_nfs3_sattr (tvb, offset, tree, "attributes");
5214
5215 col_append_fstr(pinfo->cinfo, COL_INFO, ", DH: 0x%08x/%s", hash, name);
5216 proto_item_append_text(tree, ", MKDIR Call DH: 0x%08x/%s", hash, name);
5217
5218 return offset;
5219 }
5220
5221
5222 static int
dissect_nfs3_mkdir_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5223 dissect_nfs3_mkdir_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5224 {
5225 guint32 status;
5226 const char *err;
5227 int offset = 0;
5228
5229 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5230 switch (status) {
5231 case 0:
5232 offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5233 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5234 "obj_attributes");
5235 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5236 proto_item_append_text(tree, ", MKDIR Reply");
5237 break;
5238 default:
5239 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5240
5241 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5242 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5243 proto_item_append_text(tree, ", MKDIR Reply Error: %s", err);
5244 break;
5245 }
5246
5247 return offset;
5248 }
5249
5250
5251 /* NFSv3 RFC 1813, Page 61..63 */
5252 static int
dissect_nfs3_symlink_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5253 dissect_nfs3_symlink_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5254 {
5255 guint32 from_hash = 0;
5256 const char *from_name = NULL;
5257 const char *to_name = NULL;
5258 int offset = 0;
5259
5260 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &from_hash, &from_name, (rpc_call_info_value*)data);
5261 offset = dissect_nfs3_sattr (tvb, offset, tree, "symlink_attributes");
5262 offset = dissect_nfs3_path (tvb, offset, tree, hf_nfs_symlink_to, &to_name);
5263
5264 col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To %s",
5265 from_hash, from_name, to_name);
5266 proto_item_append_text(tree, ", SYMLINK Call From DH: 0x%08x/%s To %s",
5267 from_hash, from_name, to_name);
5268
5269 return offset;
5270 }
5271
5272
5273 static int
dissect_nfs3_symlink_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5274 dissect_nfs3_symlink_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5275 {
5276 guint32 status;
5277 const char *err;
5278 int offset = 0;
5279
5280 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5281 switch (status) {
5282 case 0:
5283 offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5284 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5285 "obj_attributes");
5286 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5287 proto_item_append_text(tree, ", SYMLINK Reply");
5288 break;
5289 default:
5290 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5291
5292 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5293 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5294 proto_item_append_text(tree, ", SYMLINK Reply Error: %s", err);
5295 break;
5296 }
5297
5298 return offset;
5299 }
5300
5301
5302 /* NFSv3 RFC 1813, Page 63..66 */
5303 static int
dissect_nfs3_mknod_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5304 dissect_nfs3_mknod_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5305 {
5306 guint32 type;
5307 guint32 hash = 0;
5308 const char *name = NULL;
5309 const char *type_str;
5310 int offset = 0;
5311
5312 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "where", &hash, &name, (rpc_call_info_value*)data);
5313 offset = dissect_ftype3(tvb, offset, tree, hf_nfs3_ftype, &type);
5314 switch (type) {
5315 case NF3CHR:
5316 case NF3BLK:
5317 offset = dissect_nfs3_sattr(tvb, offset, tree, "dev_attributes");
5318 offset = dissect_nfs3_specdata(tvb, offset, tree, "spec");
5319 break;
5320 case NF3SOCK:
5321 case NF3FIFO:
5322 offset = dissect_nfs3_sattr(tvb, offset, tree, "pipe_attributes");
5323 break;
5324 default:
5325 /* nothing to do */
5326 break;
5327 }
5328
5329 type_str = val_to_str_ext(type, &names_nfs_ftype3_ext, "Unknown type: %u");
5330 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x/%s %s", hash, name, type_str);
5331 proto_item_append_text(tree, ", MKNOD Call FH: 0x%08x/%s %s", hash, name, type_str);
5332
5333 return offset;
5334 }
5335
5336
5337 static int
dissect_nfs3_mknod_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5338 dissect_nfs3_mknod_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5339 {
5340 guint32 status;
5341 const char *err;
5342 int offset = 0;
5343
5344 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5345 switch (status) {
5346 case 0:
5347 offset = dissect_nfs3_post_op_fh (tvb, offset, pinfo, tree, "obj", (rpc_call_info_value*)data);
5348 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5349 "obj_attributes");
5350 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5351 proto_item_append_text(tree, ", MKNOD Reply");
5352 break;
5353 default:
5354 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5355
5356 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5357 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5358 proto_item_append_text(tree, ", MKNOD Reply Error: %s", err);
5359 break;
5360 }
5361
5362 return offset;
5363 }
5364
5365
5366 /* NFSv3 RFC 1813, Page 67..69 */
5367 static int
dissect_nfs3_remove_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5368 dissect_nfs3_remove_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5369 {
5370 guint32 status;
5371 const char *err;
5372 int offset = 0;
5373
5374 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5375 switch (status) {
5376 case 0:
5377 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5378 proto_item_append_text(tree, ", REMOVE Reply");
5379 break;
5380 default:
5381 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5382 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5383 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5384 proto_item_append_text(tree, ", REMOVE Reply Error: %s", err);
5385 break;
5386 }
5387
5388 return offset;
5389 }
5390
5391
5392 static int
dissect_nfs3_rmdir_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5393 dissect_nfs3_rmdir_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5394 {
5395 guint32 status;
5396 const char *err;
5397 int offset = 0;
5398
5399 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5400 switch (status) {
5401 case 0:
5402 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5403 proto_item_append_text(tree, ", RMDIR Reply");
5404 break;
5405 default:
5406 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "dir_wcc");
5407 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5408 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5409 proto_item_append_text(tree, ", RMDIR Reply Error: %s", err);
5410 break;
5411 }
5412
5413 return offset;
5414 }
5415
5416
5417 /* NFSv3 RFC 1813, Page 71..74 */
5418 static int
dissect_nfs3_rename_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5419 dissect_nfs3_rename_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5420 {
5421 guint32 from_hash = 0;
5422 const char *from_name = NULL;
5423 guint32 to_hash = 0;
5424 const char *to_name = NULL;
5425 int offset = 0;
5426
5427 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "from", &from_hash, &from_name, (rpc_call_info_value*)data);
5428 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "to", &to_hash, &to_name, (rpc_call_info_value*)data);
5429
5430 col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x/%s To DH: 0x%08x/%s",
5431 from_hash, from_name, to_hash, to_name);
5432 proto_item_append_text(tree, ", RENAME Call From DH: 0x%08x/%s To DH: 0x%08x/%s",
5433 from_hash, from_name, to_hash, to_name);
5434
5435 return offset;
5436 }
5437
5438
5439 /* NFSv3 RFC 1813, Page 71..74 */
5440 static int
dissect_nfs3_rename_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5441 dissect_nfs3_rename_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
5442 proto_tree *tree, void *data _U_)
5443 {
5444 guint32 status;
5445 const char *err;
5446 int offset = 0;
5447
5448 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5449 switch (status) {
5450 case 0:
5451 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "fromdir_wcc");
5452 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "todir_wcc");
5453 proto_item_append_text(tree, ", RENAME Reply");
5454 break;
5455 default:
5456 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "fromdir_wcc");
5457 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "todir_wcc");
5458
5459 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5460 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5461 proto_item_append_text(tree, ", RENAME Reply Error: %s", err);
5462 break;
5463 }
5464
5465 return offset;
5466 }
5467
5468
5469 /* NFSv3 RFC 1813, Page 74..76 */
5470 static int
dissect_nfs3_link_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5471 dissect_nfs3_link_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5472 {
5473 guint32 from_hash = 0;
5474 guint32 to_hash = 0;
5475 const char *to_name = NULL;
5476 int offset = 0;
5477
5478 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &from_hash, (rpc_call_info_value*)data);
5479 offset = dissect_diropargs3(tvb, offset, pinfo, tree, "link", &to_hash, &to_name, (rpc_call_info_value*)data);
5480
5481 col_append_fstr(pinfo->cinfo, COL_INFO, ", From DH: 0x%08x To DH: 0x%08x/%s",
5482 from_hash, to_hash, to_name);
5483 proto_item_append_text(tree, ", LINK Call From DH: 0x%08x To DH: 0x%08x/%s",
5484 from_hash, to_hash, to_name);
5485
5486 return offset;
5487 }
5488
5489
5490 /* NFSv3 RFC 1813, Page 74..76 */
5491 static int
dissect_nfs3_link_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5492 dissect_nfs3_link_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5493 {
5494 guint32 status;
5495 const char *err;
5496 int offset = 0;
5497
5498 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5499 switch (status) {
5500 case 0:
5501 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5502 "file_attributes");
5503 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "linkdir_wcc");
5504 proto_item_append_text(tree, ", LINK Reply");
5505 break;
5506 default:
5507 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5508 "file_attributes");
5509 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "linkdir_wcc");
5510
5511 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5512 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5513 proto_item_append_text(tree, ", LINK Reply Error: %s", err);
5514 break;
5515 }
5516
5517 return offset;
5518 }
5519
5520
5521 /* NFSv3 RFC 1813, Page 76..80 */
5522 static int
dissect_nfs3_readdir_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5523 dissect_nfs3_readdir_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5524 {
5525 guint32 hash = 0;
5526 int offset = 0;
5527
5528 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "dir", &hash, (rpc_call_info_value*)data);
5529 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_cookie, offset);
5530 offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5531 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
5532
5533 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5534 proto_item_append_text(tree, ", READDIR Call FH: 0x%08x", hash);
5535
5536 return offset;
5537 }
5538
5539
5540 /* NFSv3 RFC 1813, Page 76..80 */
5541 static int
dissect_entry3(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5542 dissect_entry3(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
5543 proto_tree *tree, void *data _U_)
5544 {
5545 proto_item *entry_item;
5546 proto_tree *entry_tree;
5547 int old_offset = offset;
5548 const char *name = NULL;
5549
5550 entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb, offset+0, -1, ENC_NA);
5551 entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
5552
5553 offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdir_entry_fileid, offset);
5554
5555 offset = dissect_nfs3_filename(tvb, offset, entry_tree, hf_nfs3_readdir_entry_name, &name);
5556 proto_item_set_text(entry_item, "Entry: name %s", name);
5557
5558 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
5559
5560 offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdir_entry_cookie, offset);
5561
5562 /* now we know, that a readdir entry is shorter */
5563 proto_item_set_len(entry_item, offset - old_offset);
5564
5565 return offset;
5566 }
5567
5568
5569 /* NFSv3 RFC 1813, Page 76..80 */
5570 static int
dissect_nfs3_readdir_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5571 dissect_nfs3_readdir_reply(tvbuff_t *tvb, packet_info *pinfo,
5572 proto_tree *tree, void *data _U_)
5573 {
5574 guint32 status;
5575 const char *err;
5576 int offset = 0;
5577
5578 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5579 switch (status) {
5580 case 0:
5581 proto_item_append_text(tree, ", READDIR Reply");
5582
5583 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5584 "dir_attributes");
5585 offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5586 offset = dissect_rpc_list(tvb, pinfo, tree, offset,
5587 dissect_entry3, NULL);
5588 proto_tree_add_item(tree, hf_nfs_readdir_eof, tvb,
5589 offset+ 0, 4, ENC_BIG_ENDIAN);
5590 offset += 4;
5591 break;
5592 default:
5593 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5594 "dir_attributes");
5595
5596 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5597 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5598 proto_item_append_text(tree, ", READDIR Reply Error: %s", err);
5599 break;
5600 }
5601
5602 return offset;
5603 }
5604
5605
5606 /* NFSv3 RFC 1813, Page 80..83 */
5607 static int
dissect_nfs3_readdirplus_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5608 dissect_nfs3_readdirplus_call(tvbuff_t *tvb, packet_info *pinfo,
5609 proto_tree *tree, void *data)
5610 {
5611 guint32 hash = 0;
5612 int offset = 0;
5613
5614 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "dir", &hash, (rpc_call_info_value*)data);
5615 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_cookie, offset);
5616 offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5617 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count_dircount,
5618 offset);
5619 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count_maxcount,
5620 offset);
5621
5622 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5623 proto_item_append_text(tree, ", READDIRPLUS Call FH: 0x%08x", hash);
5624
5625 return offset;
5626 }
5627
5628
5629 /* NFSv3 RFC 1813, Page 80..83 */
5630 static int
dissect_nfs3_entryplus(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,void * data)5631 dissect_nfs3_entryplus(tvbuff_t *tvb, int offset, packet_info *pinfo,
5632 proto_tree *tree, void *data)
5633 {
5634 proto_item *entry_item;
5635 proto_tree *entry_tree;
5636 int old_offset = offset;
5637 const char *name = NULL;
5638 rpc_call_info_value *civ = (rpc_call_info_value *)data;
5639
5640 entry_item = proto_tree_add_item(tree, hf_nfs_readdir_entry, tvb, offset+0, -1, ENC_NA);
5641 entry_tree = proto_item_add_subtree(entry_item, ett_nfs_readdir_entry);
5642
5643 offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdirplus_entry_fileid, offset);
5644
5645 offset = dissect_nfs3_filename(tvb, offset, entry_tree, hf_nfs3_readdirplus_entry_name, &name);
5646
5647 /* are we snooping fh to filenames ?*/
5648 if ((!pinfo->fd->visited) && nfs_file_name_snooping) {
5649 /* v3 READDIRPLUS replies will give us a mapping */
5650 if ( (civ->prog == 100003)
5651 &&(civ->vers == 3)
5652 &&(!civ->request)
5653 &&((civ->proc == 17))
5654 ) {
5655 nfs_name_snoop_add_name(civ->xid, tvb, 0, 0,
5656 0/*parent offset*/, 0/*parent len*/,
5657 name);
5658 }
5659 }
5660
5661 proto_item_set_text(entry_item, "Entry: name %s", name);
5662
5663 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", name);
5664
5665 offset = dissect_rpc_uint64(tvb, entry_tree, hf_nfs3_readdirplus_entry_cookie,
5666 offset);
5667
5668 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, entry_tree, "name_attributes");
5669
5670 offset = dissect_nfs3_post_op_fh(tvb, offset, pinfo, entry_tree, "name_handle", civ);
5671
5672 /* now we know, that a readdirplus entry is shorter */
5673 proto_item_set_len(entry_item, offset - old_offset);
5674
5675 return offset;
5676 }
5677
5678
5679 /* NFSv3 RFC 1813, Page 80..83 */
5680 static int
dissect_nfs3_readdirplus_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5681 dissect_nfs3_readdirplus_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5682 {
5683 guint32 status;
5684 const char *err;
5685 int offset = 0;
5686
5687 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5688 switch (status) {
5689 case 0:
5690 proto_item_append_text(tree, ", READDIRPLUS Reply");
5691
5692 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5693 "dir_attributes");
5694 offset = dissect_nfs3_cookie_verf(tvb, offset, tree);
5695 offset = dissect_rpc_list(tvb, pinfo, tree, offset,
5696 dissect_nfs3_entryplus, data);
5697 proto_tree_add_item(tree, hf_nfs_readdir_eof, tvb,
5698 offset+ 0, 4, ENC_BIG_ENDIAN);
5699 offset += 4;
5700 break;
5701 default:
5702 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5703 "dir_attributes");
5704
5705 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5706 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5707 proto_item_append_text(tree, ", READDIRPLUS Reply Error: %s", err);
5708 break;
5709 }
5710
5711 return offset;
5712 }
5713
5714
5715 /* NFSv3 RFC 1813, Page 84..86 */
5716 static int
dissect_nfs3_fsstat_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5717 dissect_nfs3_fsstat_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5718 {
5719 guint32 hash = 0;
5720 int offset = 0;
5721
5722 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
5723
5724 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5725 proto_item_append_text(tree, ", FSSTAT Call DH: 0x%08x", hash);
5726 return offset;
5727 }
5728
5729
5730 static int
dissect_nfs3_fsstat_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5731 dissect_nfs3_fsstat_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5732 {
5733 guint32 status;
5734 guint32 invarsec;
5735 const char *err;
5736 int offset = 0;
5737
5738 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5739 switch (status) {
5740 case 0:
5741 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5742 "obj_attributes");
5743 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_tbytes,
5744 offset);
5745 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_fbytes,
5746 offset);
5747 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_abytes,
5748 offset);
5749 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_tfiles,
5750 offset);
5751 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_ffiles,
5752 offset);
5753 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsstat_resok_afiles,
5754 offset);
5755 invarsec = tvb_get_ntohl(tvb, offset + 0);
5756 if (tree)
5757 proto_tree_add_uint(tree, hf_nfs3_fsstat_invarsec, tvb,
5758 offset+0, 4, invarsec);
5759 offset += 4;
5760
5761 proto_item_append_text(tree, ", FSSTAT Reply");
5762 break;
5763 default:
5764 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5765 "obj_attributes");
5766
5767 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5768 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5769 proto_item_append_text(tree, ", FSSTAT Reply Error: %s", err);
5770 break;
5771 }
5772
5773 return offset;
5774 }
5775
5776
5777 #define FSF3_LINK 0x0001
5778 #define FSF3_SYMLINK 0x0002
5779 #define FSF3_HOMOGENEOUS 0x0008
5780 #define FSF3_CANSETTIME 0x0010
5781
5782 static const true_false_string tfs_nfs_pathconf =
5783 { "is valid for all files", "should be get for every single file" };
5784
5785
5786 /* NFSv3 RFC 1813, Page 86..90 */
5787 static int
dissect_nfs3_fsinfo_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5788 dissect_nfs3_fsinfo_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5789 {
5790 guint32 hash = 0;
5791 int offset = 0;
5792
5793 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
5794
5795 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5796 proto_item_append_text(tree, ", FSINFO Call DH: 0x%08x", hash);
5797 return offset;
5798 }
5799
5800
5801 static int
dissect_nfs3_fsinfo_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5802 dissect_nfs3_fsinfo_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5803 {
5804 guint32 status;
5805 static int * const properties[] = {
5806 &hf_nfs3_fsinfo_properties_setattr,
5807 &hf_nfs3_fsinfo_properties_pathconf,
5808 &hf_nfs3_fsinfo_properties_symlinks,
5809 &hf_nfs3_fsinfo_properties_hardlinks,
5810 NULL
5811 };
5812 int offset = 0;
5813
5814 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5815 switch (status) {
5816 case 0:
5817 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5818 "obj_attributes");
5819 proto_tree_add_item(tree, hf_nfs3_fsinfo_rtmax, tvb, offset, 4, ENC_BIG_ENDIAN);
5820 offset += 4;
5821 proto_tree_add_item(tree, hf_nfs3_fsinfo_rtpref, tvb, offset, 4, ENC_BIG_ENDIAN);
5822 offset += 4;
5823 proto_tree_add_item(tree, hf_nfs3_fsinfo_rtmult, tvb, offset, 4, ENC_BIG_ENDIAN);
5824 offset += 4;
5825 proto_tree_add_item(tree, hf_nfs3_fsinfo_wtmax, tvb, offset, 4, ENC_BIG_ENDIAN);
5826 offset += 4;
5827 proto_tree_add_item(tree, hf_nfs3_fsinfo_wtpref, tvb, offset, 4, ENC_BIG_ENDIAN);
5828 offset += 4;
5829 proto_tree_add_item(tree, hf_nfs3_fsinfo_wtmult, tvb, offset, 4, ENC_BIG_ENDIAN);
5830 offset += 4;
5831 proto_tree_add_item(tree, hf_nfs3_fsinfo_dtpref, tvb, offset, 4, ENC_BIG_ENDIAN);
5832 offset += 4;
5833
5834 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_fsinfo_maxfilesize, offset);
5835 offset = dissect_nfstime3(tvb, offset, tree, hf_nfs_dtime, hf_nfs_dtime_sec,
5836 hf_nfs_dtime_nsec);
5837
5838 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs3_fsinfo_properties, ett_nfs3_fsinfo_properties, properties, ENC_BIG_ENDIAN);
5839 offset += 4;
5840
5841 proto_item_append_text(tree, ", FSINFO Reply");
5842 break;
5843 default:
5844 {
5845 const char *err;
5846
5847 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5848 "obj_attributes");
5849
5850 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5851 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5852 proto_item_append_text(tree, ", FSINFO Reply Error: %s", err);
5853 break;
5854 }
5855 }
5856
5857 return offset;
5858 }
5859
5860
5861 /* NFSv3 RFC 1813, Page 90..92 */
5862 static int
dissect_nfs3_pathconf_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5863 dissect_nfs3_pathconf_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5864 {
5865 guint32 hash = 0;
5866 int offset = 0;
5867
5868 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "object", &hash, (rpc_call_info_value*)data);
5869
5870 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5871 proto_item_append_text(tree, ", PATHCONF Call DH: 0x%08x", hash);
5872 return offset;
5873 }
5874
5875
5876 static int
dissect_nfs3_pathconf_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5877 dissect_nfs3_pathconf_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5878 {
5879 guint32 status;
5880 guint32 linkmax;
5881 guint32 name_max;
5882 const char *err;
5883 int offset = 0;
5884
5885 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5886 switch (status) {
5887 case 0:
5888 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5889 "obj_attributes");
5890 linkmax = tvb_get_ntohl(tvb, offset + 0);
5891 if (tree)
5892 proto_tree_add_uint(tree, hf_nfs3_pathconf_linkmax, tvb,
5893 offset+0, 4, linkmax);
5894 offset += 4;
5895 name_max = tvb_get_ntohl(tvb, offset + 0);
5896 if (tree)
5897 proto_tree_add_uint(tree, hf_nfs3_pathconf_name_max, tvb,
5898 offset+0, 4, name_max);
5899 offset += 4;
5900 offset = dissect_rpc_bool(tvb, tree,
5901 hf_nfs3_pathconf_no_trunc, offset);
5902 offset = dissect_rpc_bool(tvb, tree,
5903 hf_nfs3_pathconf_chown_restricted, offset);
5904 offset = dissect_rpc_bool(tvb, tree,
5905 hf_nfs3_pathconf_case_insensitive, offset);
5906 offset = dissect_rpc_bool(tvb, tree,
5907 hf_nfs3_pathconf_case_preserving, offset);
5908
5909 proto_item_append_text(tree, ", PATHCONF Reply");
5910 break;
5911 default:
5912 offset = dissect_nfs3_post_op_attr(tvb, offset, pinfo, tree,
5913 "obj_attributes");
5914
5915 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5916 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5917 proto_item_append_text(tree, ", PATHCONF Reply Error: %s", err);
5918 break;
5919 }
5920
5921 return offset;
5922 }
5923
5924
5925 /* NFSv3 RFC 1813, Page 92..95 */
5926 static int
dissect_nfs3_commit_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5927 dissect_nfs3_commit_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5928 {
5929 guint32 hash = 0;
5930 int offset = 0;
5931
5932 offset = dissect_nfs3_fh(tvb, offset, pinfo, tree, "file", &hash, (rpc_call_info_value*)data);
5933 offset = dissect_rpc_uint64(tvb, tree, hf_nfs3_offset, offset);
5934 offset = dissect_rpc_uint32(tvb, tree, hf_nfs3_count, offset);
5935
5936 col_append_fstr(pinfo->cinfo, COL_INFO, ", FH: 0x%08x", hash);
5937 proto_item_append_text(tree, ", COMMIT Call FH: 0x%08x", hash);
5938
5939 return offset;
5940 }
5941
5942
5943 /* NFSv3 RFC 1813, Page 92..95 */
5944 static int
dissect_nfs3_commit_reply(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)5945 dissect_nfs3_commit_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5946 {
5947 guint32 status;
5948 const char *err;
5949 int offset = 0;
5950
5951 offset = dissect_nfs3_status(tvb, offset, tree, &status);
5952 switch (status) {
5953 case 0:
5954 offset = dissect_wcc_data (tvb, offset, pinfo, tree, "file_wcc");
5955 offset = dissect_nfs3_write_verf(tvb, offset, tree);
5956
5957 proto_item_append_text(tree, ", COMMIT Reply");
5958 break;
5959 default:
5960 offset = dissect_wcc_data(tvb, offset, pinfo, tree, "file_wcc");
5961
5962 err = val_to_str_ext(status, &names_nfs3_status_ext, "Unknown error: %u");
5963 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", err);
5964 proto_item_append_text(tree, ", COMMIT Reply Error: %s", err);
5965 break;
5966 }
5967
5968 return offset;
5969 }
5970
5971 /*************************************************************************************
5972 * NFS Version 4.1, RFC 5661. Note that error 19 NFS4ERR_NOTDIR defined in RFC 3010
5973 * was eliminated in RFC 3530 (NFSv4) which replaced RFC 3010 and remains so in
5974 * RFC 5661. Nevertheless, it has been included in this table in the event that some
5975 * RFC 3010 implementations still exist out there.
5976 **************************************************************************************/
5977 static const value_string names_nfs4_status[] = {
5978 { 0, "NFS4_OK" },
5979 { 1, "NFS4ERR_PERM" },
5980 { 2, "NFS4ERR_NOENT" },
5981 { 5, "NFS4ERR_IO" },
5982 { 6, "NFS4ERR_NXIO" },
5983 { 13, "NFS4ERR_ACCESS" },
5984 { 17, "NFS4ERR_EXIST" },
5985 { 18, "NFS4ERR_XDEV" },
5986 { 19, "NFS4ERR_DQUOT" },
5987 { 20, "NFS4ERR_NOTDIR" },
5988 { 21, "NFS4ERR_ISDIR" },
5989 { 22, "NFS4ERR_INVAL" },
5990 { 27, "NFS4ERR_FBIG" },
5991 { 28, "NFS4ERR_NOSPC" },
5992 { 30, "NFS4ERR_ROFS" },
5993 { 31, "NFS4ERR_MLINK" },
5994 { 63, "NFS4ERR_NAMETOOLONG" },
5995 { 66, "NFS4ERR_NOTEMPTY" },
5996 { 69, "NFS4ERR_DQUOT" },
5997 { 70, "NFS4ERR_STALE" },
5998 { 10001, "NFS4ERR_BADHANDLE" },
5999 { 10003, "NFS4ERR_BAD_COOKIE" },
6000 { 10004, "NFS4ERR_NOTSUPP" },
6001 { 10005, "NFS4ERR_TOOSMALL" },
6002 { 10006, "NFS4ERR_SERVERFAULT" },
6003 { 10007, "NFS4ERR_BADTYPE" },
6004 { 10008, "NFS4ERR_DELAY" },
6005 { 10009, "NFS4ERR_SAME" },
6006 { 10010, "NFS4ERR_DENIED" },
6007 { 10011, "NFS4ERR_EXPIRED" },
6008 { 10012, "NFS4ERR_LOCKED" },
6009 { 10013, "NFS4ERR_GRACE" },
6010 { 10014, "NFS4ERR_FHEXPIRED" },
6011 { 10015, "NFS4ERR_SHARE_DENIED" },
6012 { 10016, "NFS4ERR_WRONGSEC" },
6013 { 10017, "NFS4ERR_CLID_INUSE" },
6014 { 10018, "NFS4ERR_RESOURCE" },
6015 { 10019, "NFS4ERR_MOVED" },
6016 { 10020, "NFS4ERR_NOFILEHANDLE" },
6017 { 10021, "NFS4ERR_MINOR_VERS_MISMATCH" },
6018 { 10022, "NFS4ERR_STALE_CLIENTID" },
6019 { 10023, "NFS4ERR_STALE_STATEID" },
6020 { 10024, "NFS4ERR_OLD_STATEID" },
6021 { 10025, "NFS4ERR_BAD_STATEID" },
6022 { 10026, "NFS4ERR_BAD_SEQID" },
6023 { 10027, "NFS4ERR_NOT_SAME" },
6024 { 10028, "NFS4ERR_LOCK_RANGE" },
6025 { 10029, "NFS4ERR_SYMLINK" },
6026 { 10030, "NFS4ERR_READDIR_NOSPC" },
6027 { 10031, "NFS4ERR_LEASE_MOVED" },
6028 { 10032, "NFS4ERR_ATTRNOTSUPP" },
6029 { 10033, "NFS4ERR_NO_GRACE" },
6030 { 10034, "NFS4ERR_RECLAIM_BAD" },
6031 { 10035, "NFS4ERR_RECLAIM_CONFLICT" },
6032 { 10036, "NFS4ERR_BADXDR" },
6033 { 10037, "NFS4ERR_LOCKS_HELD" },
6034 { 10038, "NFS4ERR_OPENMODE" },
6035 { 10039, "NFS4ERR_BADOWNER" },
6036 { 10040, "NFS4ERR_BADCHAR" },
6037 { 10041, "NFS4ERR_BADNAME" },
6038 { 10042, "NFS4ERR_BAD_RANGE" },
6039 { 10043, "NFS4ERR_LOCK_NOTSUPP" },
6040 { 10044, "NFS4ERR_OP_ILLEGAL" },
6041 { 10045, "NFS4ERR_DEADLOCK" },
6042 { 10046, "NFS4ERR_FILE_OPEN" },
6043 { 10047, "NFS4ERR_ADMIN_REVOKED" },
6044 { 10048, "NFS4ERR_CB_PATH_DOWN" },
6045 { 10049, "NFS4ERR_BADIOMODE" },
6046 { 10050, "NFS4ERR_BADLAYOUT" },
6047 { 10051, "NFS4ERR_BAD_SESSION_DIGEST" },
6048 { 10052, "NFS4ERR_BADSESSION" },
6049 { 10053, "NFS4ERR_BADSLOT" },
6050 { 10054, "NFS4ERR_COMPLETE_ALREADY" },
6051 { 10055, "NFS4ERR_CONN_NOT_BOUND_TO_SESSION" },
6052 { 10056, "NFS4ERR_DELEG_ALREADY_WANTED" },
6053 { 10057, "NFS4ERR_DIRDELEG_UNAVAIL" },
6054 { 10058, "NFS4ERR_LAYOUTTRYLATER" },
6055 { 10059, "NFS4ERR_LAYOUTUNAVAILABLE" },
6056 { 10060, "NFS4ERR_NOMATCHING_LAYOUT" },
6057 { 10061, "NFS4ERR_RECALLCONFLICT" },
6058 { 10062, "NFS4ERR_UNKNOWN_LAYOUTTYPE" },
6059 { 10063, "NFS4ERR_SEQ_MISORDERED" },
6060 { 10064, "NFS4ERR_SEQUENCE_POS" },
6061 { 10065, "NFS4ERR_REQ_TOO_BIG" },
6062 { 10066, "NFS4ERR_REP_TOO_BIG" },
6063 { 10067, "NFS4ERR_REP_TOO_BIG_TO_CACHE" },
6064 { 10068, "NFS4ERR_RETRY_UNCACHED_REP" },
6065 { 10069, "NFS4ERR_UNSAFE_COMPOUND" },
6066 { 10070, "NFS4ERR_TOO_MANY_OPS" },
6067 { 10071, "NFS4ERR_OP_NOT_IN_SESSION" },
6068 { 10072, "NFS4ERR_HASH_ALG_UNSUPP" },
6069 { 10073, "NFS4ERR_CONN_BINDING_NOT_ENFORCED" },
6070 { 10074, "NFS4ERR_CLIENTID_BUSY" },
6071 { 10075, "NFS4ERR_PNFS_IO_HOLE" },
6072 { 10076, "NFS4ERR_SEQ_FALSE_RETRY" },
6073 { 10077, "NFS4ERR_BAD_HIGH_SLOT" },
6074 { 10078, "NFS4ERR_DEADSESSION" },
6075 { 10079, "NFS4ERR_ENCR_ALG_UNSUPP" },
6076 { 10080, "NFS4ERR_PNFS_NO_LAYOUT" },
6077 { 10081, "NFS4ERR_NOT_ONLY_OP" },
6078 { 10082, "NFS4ERR_WRONG_CRED" },
6079 { 10083, "NFS4ERR_WRONG_TYPE" },
6080 { 10084, "NFS4ERR_DIRDELEG_UNAVAIL" },
6081 { 10085, "NFS4ERR_REJECT_DELEG" },
6082 { 10086, "NFS4ERR_RETURNCONFLICT" },
6083 { 10087, "NFS4ERR_DELEG_REVOKED" },
6084 { 10088, "NFS4ERR_PARTNER_NOTSUPP" },
6085 { 10089, "NFS4ERR_PARTNER_NO_AUTH" },
6086 { 10090, "NFS4ERR_UNION_NOTSUPP" },
6087 { 10091, "NFS4ERR_OFFLOAD_DENIED" },
6088 { 10092, "NFS4ERR_WRONG_LFS" },
6089 { 10093, "NFS4ERR_BADLABEL" },
6090 { 10094, "NFS4ERR_OFFLOAD_NO_REQS" },
6091 { 10095, "NFS4ERR_NOXATTR" },
6092 { 10096, "NFS4ERR_XATTR2BIG" },
6093 { 0, NULL }
6094 };
6095 static value_string_ext names_nfs4_status_ext = VALUE_STRING_EXT_INIT(names_nfs4_status);
6096
6097 static const value_string fattr4_names[] = {
6098 #define FATTR4_SUPPORTED_ATTRS 0
6099 { FATTR4_SUPPORTED_ATTRS, "Supported_Attrs" },
6100 #define FATTR4_TYPE 1
6101 { FATTR4_TYPE, "Type"},
6102 #define FATTR4_FH_EXPIRE_TYPE 2
6103 { FATTR4_FH_EXPIRE_TYPE, "FH_Expire_Type" },
6104 #define FATTR4_CHANGE 3
6105 { FATTR4_CHANGE, "Change"},
6106 #define FATTR4_SIZE 4
6107 { FATTR4_SIZE, "Size" },
6108 #define FATTR4_LINK_SUPPORT 5
6109 { FATTR4_LINK_SUPPORT, "Link_Support" },
6110 #define FATTR4_SYMLINK_SUPPORT 6
6111 { FATTR4_SYMLINK_SUPPORT, "Symlink_Support" },
6112 #define FATTR4_NAMED_ATTR 7
6113 { FATTR4_NAMED_ATTR, "Named_Attr" },
6114 #define FATTR4_FSID 8
6115 { FATTR4_FSID, "FSID" },
6116 #define FATTR4_UNIQUE_HANDLES 9
6117 { FATTR4_UNIQUE_HANDLES, "Unique_Handles" },
6118 #define FATTR4_LEASE_TIME 10
6119 { FATTR4_LEASE_TIME, "Lease_Time" },
6120 #define FATTR4_RDATTR_ERROR 11
6121 { FATTR4_RDATTR_ERROR, "RDAttr_Error" },
6122 #define FATTR4_ACL 12
6123 { FATTR4_ACL, "ACL" },
6124 #define FATTR4_ACLSUPPORT 13
6125 { FATTR4_ACLSUPPORT, "ACLSupport" },
6126 #define FATTR4_ARCHIVE 14
6127 { FATTR4_ARCHIVE, "Archive" },
6128 #define FATTR4_CANSETTIME 15
6129 { FATTR4_CANSETTIME, "CanSetTime" },
6130 #define FATTR4_CASE_INSENSITIVE 16
6131 { FATTR4_CASE_INSENSITIVE, "Case_Insensitive" },
6132 #define FATTR4_CASE_PRESERVING 17
6133 { FATTR4_CASE_PRESERVING, "Case_Preserving" },
6134 #define FATTR4_CHOWN_RESTRICTED 18
6135 { FATTR4_CHOWN_RESTRICTED, "Chown_Restricted" },
6136 #define FATTR4_FILEHANDLE 19
6137 { FATTR4_FILEHANDLE, "Filehandle" },
6138 #define FATTR4_FILEID 20
6139 { FATTR4_FILEID, "FileId" },
6140 #define FATTR4_FILES_AVAIL 21
6141 { FATTR4_FILES_AVAIL, "Files_Avail" },
6142 #define FATTR4_FILES_FREE 22
6143 { FATTR4_FILES_FREE, "Files_Free" },
6144 #define FATTR4_FILES_TOTAL 23
6145 { FATTR4_FILES_TOTAL, "Files_Total" },
6146 #define FATTR4_FS_LOCATIONS 24
6147 { FATTR4_FS_LOCATIONS, "FS_Locations" },
6148 #define FATTR4_HIDDEN 25
6149 { FATTR4_HIDDEN, "Hidden" },
6150 #define FATTR4_HOMOGENEOUS 26
6151 { FATTR4_HOMOGENEOUS, "Homogeneous" },
6152 #define FATTR4_MAXFILESIZE 27
6153 { FATTR4_MAXFILESIZE, "MaxFileSize" },
6154 #define FATTR4_MAXLINK 28
6155 { FATTR4_MAXLINK, "MaxLink" },
6156 #define FATTR4_MAXNAME 29
6157 { FATTR4_MAXNAME, "MaxName" },
6158 #define FATTR4_MAXREAD 30
6159 { FATTR4_MAXREAD, "MaxRead" },
6160 #define FATTR4_MAXWRITE 31
6161 { FATTR4_MAXWRITE, "MaxWrite" },
6162 #define FATTR4_MIMETYPE 32
6163 { FATTR4_MIMETYPE, "MimeType" },
6164 #define FATTR4_MODE 33
6165 { FATTR4_MODE, "Mode" },
6166 #define FATTR4_NO_TRUNC 34
6167 { FATTR4_NO_TRUNC, "No_Trunc" },
6168 #define FATTR4_NUMLINKS 35
6169 { FATTR4_NUMLINKS, "NumLinks" },
6170 #define FATTR4_OWNER 36
6171 { FATTR4_OWNER, "Owner" },
6172 #define FATTR4_OWNER_GROUP 37
6173 { FATTR4_OWNER_GROUP, "Owner_Group" },
6174 #define FATTR4_QUOTA_AVAIL_HARD 38
6175 { FATTR4_QUOTA_AVAIL_HARD, "Quota_Avail_Hard" },
6176 #define FATTR4_QUOTA_AVAIL_SOFT 39
6177 { FATTR4_QUOTA_AVAIL_SOFT, "Quota_Avail_Soft" },
6178 #define FATTR4_QUOTA_USED 40
6179 { FATTR4_QUOTA_USED, "Quota_Used" },
6180 #define FATTR4_RAWDEV 41
6181 { FATTR4_RAWDEV, "RawDev" },
6182 #define FATTR4_SPACE_AVAIL 42
6183 { FATTR4_SPACE_AVAIL, "Space_Avail" },
6184 #define FATTR4_SPACE_FREE 43
6185 { FATTR4_SPACE_FREE, "Space_Free" },
6186 #define FATTR4_SPACE_TOTAL 44
6187 { FATTR4_SPACE_TOTAL, "Space_Total" },
6188 #define FATTR4_SPACE_USED 45
6189 { FATTR4_SPACE_USED, "Space_Used" },
6190 #define FATTR4_SYSTEM 46
6191 { FATTR4_SYSTEM, "System" },
6192 #define FATTR4_TIME_ACCESS 47
6193 { FATTR4_TIME_ACCESS, "Time_Access" },
6194 #define FATTR4_TIME_ACCESS_SET 48
6195 { FATTR4_TIME_ACCESS_SET, "Time_Access_Set" },
6196 #define FATTR4_TIME_BACKUP 49
6197 { FATTR4_TIME_BACKUP, "Time_Backup" },
6198 #define FATTR4_TIME_CREATE 50
6199 { FATTR4_TIME_CREATE, "Time_Create" },
6200 #define FATTR4_TIME_DELTA 51
6201 { FATTR4_TIME_DELTA, "Time_Delta" },
6202 #define FATTR4_TIME_METADATA 52
6203 { FATTR4_TIME_METADATA, "Time_Metadata" },
6204 #define FATTR4_TIME_MODIFY 53
6205 { FATTR4_TIME_MODIFY, "Time_Modify" },
6206 #define FATTR4_TIME_MODIFY_SET 54
6207 { FATTR4_TIME_MODIFY_SET, "Time_Modify_Set" },
6208 #define FATTR4_MOUNTED_ON_FILEID 55
6209 { FATTR4_MOUNTED_ON_FILEID, "Mounted_on_FileId" },
6210 #define FATTR4_DIR_NOTIF_DELAY 56
6211 { FATTR4_DIR_NOTIF_DELAY, "Dir_Notif_Delay" },
6212 #define FATTR4_DIRENT_NOTIF_DELAY 57
6213 #define FATTR4_DACL 58
6214 { FATTR4_DACL, "DACL" },
6215 #define FATTR4_SACL 59
6216 { FATTR4_SACL, "SACL" },
6217 #define FATTR4_CHANGE_POLICY 60
6218 { FATTR4_CHANGE_POLICY, "Change_Policy" },
6219 #define FATTR4_FS_STATUS 61
6220 { FATTR4_FS_STATUS, "FS_Status" },
6221 #define FATTR4_FS_LAYOUT_TYPE 62
6222 { FATTR4_FS_LAYOUT_TYPE, "FS_Layout_Type" },
6223 #define FATTR4_LAYOUT_HINT 63
6224 { FATTR4_LAYOUT_HINT, "Layout_hint" },
6225 #define FATTR4_LAYOUT_TYPE 64
6226 { FATTR4_LAYOUT_TYPE, "Layout_type" },
6227 #define FATTR4_LAYOUT_BLKSIZE 65
6228 { FATTR4_LAYOUT_BLKSIZE, "Layout_blksize" },
6229 #define FATTR4_LAYOUT_ALIGNMENT 66
6230 { FATTR4_LAYOUT_ALIGNMENT, "Layout_alignment" },
6231 #define FATTR4_FS_LOCATIONS_INFO 67
6232 { FATTR4_FS_LOCATIONS_INFO, "FS_Locations_info" },
6233 #define FATTR4_MDSTHRESHOLD 68
6234 { FATTR4_MDSTHRESHOLD, "MDS_Threshold" },
6235 #define FATTR4_RETENTION_GET 69
6236 { FATTR4_RETENTION_GET, "Retention_Get" },
6237 #define FATTR4_RETENTION_SET 70
6238 { FATTR4_RETENTION_SET, "Retention_Set" },
6239 #define FATTR4_RETENTEVT_GET 71
6240 { FATTR4_RETENTEVT_GET, "RetentEvt_Get" },
6241 #define FATTR4_RETENTEVT_SET 72
6242 { FATTR4_RETENTEVT_SET, "RetentEvt_Set" },
6243 #define FATTR4_RETENTION_HOLD 73
6244 { FATTR4_RETENTION_HOLD, "Retention_Hold" },
6245 #define FATTR4_MODE_SET_MASKED 74
6246 { FATTR4_MODE_SET_MASKED, "Mode_Set_Masked" },
6247 #define FATTR4_SUPPATTR_EXCLCREAT 75
6248 { FATTR4_SUPPATTR_EXCLCREAT, "Suppattr_ExclCreat" },
6249 #define FATTR4_FS_CHARSET_CAP 76
6250 { FATTR4_FS_CHARSET_CAP, "FS_Charset_Cap" },
6251 #define FATTR4_CLONE_BLOCKSIZE 77
6252 { FATTR4_CLONE_BLOCKSIZE, "Clone_Block_Size" },
6253 #define FATTR4_SPACE_FREED 78
6254 { FATTR4_SPACE_FREED, "Space_Freed" },
6255 #define FATTR4_CHANGE_ATTR_TYPE 79
6256 { FATTR4_CHANGE_ATTR_TYPE, "Change_Attr_Type" },
6257 #define FATTR4_SECURITY_LABEL 80
6258 { FATTR4_SECURITY_LABEL, "Security_Label" },
6259 #define FATTR4_MODE_UMASK 81
6260 { FATTR4_MODE_UMASK, "Mode_Umask" },
6261 #define FATTR4_XATTR_SUPPORT 82
6262 { FATTR4_XATTR_SUPPORT, "Xattr_Support" },
6263 #define FATTR4_OFFLINE 83
6264 { FATTR4_OFFLINE, "Offline" },
6265 #define FATTR4_TIME_DELEG_ACCESS 84
6266 { FATTR4_TIME_DELEG_ACCESS, "Time_Deleg_Access" },
6267 #define FATTR4_TIME_DELEG_MODIFY 85
6268 { FATTR4_TIME_DELEG_MODIFY, "Time_Deleg_Modify" },
6269 { 0, NULL }
6270 };
6271 static value_string_ext fattr4_names_ext = VALUE_STRING_EXT_INIT(fattr4_names);
6272
6273 static int
dissect_nfs4_status(tvbuff_t * tvb,int offset,proto_tree * tree,guint32 * status)6274 dissect_nfs4_status(tvbuff_t *tvb, int offset, proto_tree *tree, guint32 *status)
6275 {
6276 guint32 stat;
6277 proto_item *stat_item;
6278
6279 proto_tree_add_item_ret_uint(tree, hf_nfs4_status, tvb, offset+0, 4, ENC_BIG_ENDIAN, &stat);
6280 stat_item = proto_tree_add_uint(tree, hf_nfs_status, tvb, offset+0, 4, stat);
6281 proto_item_set_hidden(stat_item);
6282
6283 if (status)
6284 *status = stat;
6285
6286 return offset + 4;
6287 }
6288
6289
6290 static int
dissect_nfs_utf8string(tvbuff_t * tvb,int offset,proto_tree * tree,int hf,const char ** string_ret)6291 dissect_nfs_utf8string(tvbuff_t *tvb, int offset,
6292 proto_tree *tree, int hf, const char **string_ret)
6293 {
6294 /* TODO: this dissector is subject to change; do not remove */
6295 return dissect_rpc_string(tvb, tree, hf, offset, string_ret);
6296 }
6297
6298
6299 /*
6300 * Generic function to dissect bitmap4 and optionally its corresponding
6301 * opaque data.
6302 */
6303 static int
dissect_nfs4_bitmap(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ,nfs4_bitmap_info_t * bitmap_info,nfs4_bitmap_type_t type,const char * name)6304 dissect_nfs4_bitmap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
6305 rpc_call_info_value *civ, nfs4_bitmap_info_t *bitmap_info, nfs4_bitmap_type_t type,
6306 const char *name)
6307 {
6308 int attr_offset;
6309 int hf_item = -1;
6310 guint32 i, j;
6311 guint32 count;
6312 guint32 bitmap;
6313 guint32 bit_num;
6314 guint32 bit_set;
6315 guint32 num_bitmaps;
6316 guint32 end_offset;
6317 guint32 mask_offset;
6318 guint32 opaque_offset;
6319 guint32 opaque_length = 0;
6320 guint32 opaque_padding = 0;
6321 gboolean no_idx = FALSE;
6322 gboolean first_attr = FALSE;
6323 gboolean skip_attr_values = FALSE;
6324
6325 header_field_info *hfinfo;
6326
6327 proto_item *name_tree = tree;
6328 proto_item *bitmap_item = NULL;
6329 proto_tree *bitmap_tree = NULL;
6330 proto_item *attr_item = NULL;
6331 proto_tree *attr_tree = NULL;
6332 proto_item *attr_count = NULL;
6333
6334 /* Get the number of bitmap masks */
6335 num_bitmaps = tvb_get_ntohl(tvb, offset);
6336 mask_offset = offset + 4; /* Offset of first bitmap mask */
6337 opaque_offset = mask_offset + 4*num_bitmaps;
6338
6339 if (type == NFS4_BITMAP_VALUES) {
6340 /* Get the length of opaque including padding */
6341 opaque_length = tvb_get_ntohl(tvb, opaque_offset);
6342 opaque_padding = ((opaque_length % 4) ? (4 - (opaque_length % 4)) : 0);
6343 opaque_offset += 4; /* Starting offset of bitmap values */
6344 }
6345
6346 /* Offset after the bitmap mask and values regardless of type */
6347 end_offset = opaque_offset + opaque_length + opaque_padding;
6348
6349 if (name != NULL) {
6350 /* Add subtree if name is given -- all bitmap data will be
6351 * under this main tree */
6352 name_tree = proto_tree_add_subtree(tree, tvb, offset, end_offset - offset,
6353 ett_nfs4_bitmap, NULL, name);
6354 }
6355
6356 if (type == NFS4_BITMAP_VALUES && num_bitmaps == 0) {
6357 expert_add_info(pinfo, name_tree, &ei_protocol_violation);
6358 return end_offset;
6359 }
6360
6361 if (num_bitmaps > MAX_BITMAPS) {
6362 proto_tree_add_uint(name_tree, hf_nfs4_huge_bitmap_length, tvb, offset, 4, num_bitmaps);
6363 expert_add_info(pinfo, name_tree, &ei_nfs_too_many_bitmaps);
6364 return end_offset;
6365 } else if (bitmap_info->hf_mask_count) {
6366 /* Display the number of bitmap masks if the label is given */
6367 proto_tree_add_uint(name_tree, *bitmap_info->hf_mask_count, tvb, offset, 4, num_bitmaps);
6368 }
6369
6370 /* Count the number of non-zero masks */
6371 count = 0;
6372 for (i = 0; i < num_bitmaps; i++) {
6373 bitmap = tvb_get_ntohl(tvb, mask_offset + 4*i);
6374 if (bitmap > 0)
6375 count++;
6376 }
6377
6378 /* If there is only one non-zero bitmap, don't display the bitmap index "[x]". */
6379 if (count <= 1)
6380 no_idx = TRUE;
6381
6382 /* Set the offset to the first value */
6383 offset = opaque_offset;
6384
6385 /* Show mask label when the number of bitmap masks is zero */
6386 if (num_bitmaps == 0 && name == NULL && name_tree && bitmap_info->hf_mask_label) {
6387 /* Get header field to add the mask index to the field name */
6388 hfinfo = proto_registrar_get_nth(*bitmap_info->hf_mask_label);
6389 bitmap_tree = proto_tree_add_subtree_format(name_tree, tvb, mask_offset, 0,
6390 ett_nfs4_bitmap, NULL, "%s:", hfinfo->name);
6391 }
6392
6393 for (i = 0; i < num_bitmaps; i++) {
6394 bitmap = tvb_get_ntohl(tvb, mask_offset);
6395
6396 if (bitmap) {
6397 if (name_tree && bitmap_info->hf_mask_label) {
6398 if (no_idx) {
6399 bitmap_item = proto_tree_add_uint(name_tree, *bitmap_info->hf_mask_label, tvb,
6400 mask_offset, 4, bitmap);
6401 } else {
6402 /* Get header field to add the mask index to the field name */
6403 hfinfo = proto_registrar_get_nth(*bitmap_info->hf_mask_label);
6404 bitmap_item = proto_tree_add_uint_format(name_tree, *bitmap_info->hf_mask_label, tvb,
6405 mask_offset, 4, bitmap, "%s[%u]: 0x%08x", hfinfo->name, i, bitmap);
6406 }
6407 bitmap_tree = proto_item_add_subtree(bitmap_item, ett_nfs4_bitmap);
6408 first_attr = TRUE;
6409
6410 if (bitmap_info->hf_item_count) {
6411 /* Count the number of attribute bits set */
6412 for (j = 0, count = 0; j < 32; j++)
6413 count += ((bitmap >> j) & 1);
6414 hfinfo = proto_registrar_get_nth(*bitmap_info->hf_item_count);
6415 attr_count = proto_tree_add_uint_format(bitmap_tree, *bitmap_info->hf_item_count, tvb, mask_offset,
6416 4, count, "%u %s%s", count, hfinfo->name, plurality(count, "", "s"));
6417 proto_item_set_hidden(attr_count);
6418 proto_item_set_generated(attr_count);
6419 }
6420 }
6421
6422 for (j = 0; j < 32; j++) {
6423 bit_num = 32*i + j;
6424 bit_set = ((bitmap >> j) & 1);
6425 if (bit_set) {
6426 if (bitmap_tree) {
6427 if (bitmap_info->vse_names_ext) {
6428 /* Append this attribute name to the 'attr mask' header line */
6429 proto_item_append_text(bitmap_tree, (first_attr ? " (%s" : ", %s"),
6430 val_to_str_ext(bit_num, bitmap_info->vse_names_ext, "Unknown: %u"));
6431 first_attr = FALSE;
6432 }
6433
6434 /* Get correct item label */
6435 if (bitmap_info->get_item_label)
6436 hf_item = bitmap_info->get_item_label(bit_num);
6437 else if (bitmap_info->hf_item_label)
6438 hf_item = *bitmap_info->hf_item_label;
6439
6440 if (hf_item != -1) {
6441 /* Display label */
6442 attr_item = proto_tree_add_uint(bitmap_tree, hf_item, tvb, offset, 0, bit_num);
6443 }
6444 }
6445
6446 attr_offset = offset;
6447
6448 if (skip_attr_values && attr_item) {
6449 /* Skip dissecting anymore attribute values since
6450 * a previous attribute value was not dissected */
6451 attr_tree = proto_item_add_subtree(attr_item, ett_nfs4_bitmap);
6452 expert_add_info(pinfo, attr_tree, &ei_nfs_bitmap_skip_value);
6453 } else if (type == NFS4_BITMAP_VALUES && attr_item) {
6454 /* Display bit value */
6455 attr_tree = proto_item_add_subtree(attr_item, ett_nfs4_bitmap);
6456 if (bitmap_info->dissect_battr)
6457 offset = bitmap_info->dissect_battr(tvb, offset, pinfo, civ,
6458 attr_tree, attr_item, bit_num, bitmap_info->battr_data);
6459 if (offset == attr_offset) {
6460 /* No value was dissected, this attribute is most likely not
6461 * supported yet so stop dissecting the rest of the bitmap data */
6462 expert_add_info(pinfo, attr_tree, &ei_nfs_bitmap_no_dissector);
6463 skip_attr_values = TRUE;
6464 }
6465 }
6466
6467 if (attr_item)
6468 proto_item_set_len(attr_item, offset - attr_offset);
6469 }
6470 }
6471
6472 if (bitmap_tree && !first_attr)
6473 proto_item_append_text(bitmap_tree, ")");
6474 }
6475 mask_offset += 4;
6476 }
6477
6478 if (type == NFS4_BITMAP_VALUES) {
6479 count = end_offset - offset;
6480 if (bitmap_info->hf_btmap_data && offset == (int)opaque_offset) {
6481 /* Display opaque data */
6482 offset = dissect_nfsdata(tvb, offset-4, name_tree, *bitmap_info->hf_btmap_data);
6483 } else if (count == opaque_padding) {
6484 /* Everything is good, just consume the padding bytes */
6485 offset += opaque_padding;
6486 } else if (count > 0) {
6487 /* There are still bytes remaining from the opaque
6488 * just consume the bytes */
6489 expert_add_info(pinfo, name_tree, &ei_nfs_bitmap_undissected_data);
6490 offset = dissect_rpc_bytes(tvb, name_tree, hf_nfs4_bitmap_data, offset, count, FALSE, NULL);
6491 }
6492 }
6493
6494 return offset;
6495 }
6496
6497
6498 /*
6499 * When using RPC-over-RDMA, certain opaque data are eligible for DDP
6500 * (direct data placement), so these must be reduced by sending just
6501 * the opaque length with the rest of the NFS packet and the opaque
6502 * data is sent separately using RDMA (RFC 8267).
6503 */
6504 static int
dissect_nfsdata_reduced(rdma_reduce_type_t rtype,tvbuff_t * tvb,int offset,proto_tree * tree,int hf,const char ** name)6505 dissect_nfsdata_reduced(rdma_reduce_type_t rtype, tvbuff_t *tvb, int offset,
6506 proto_tree *tree, int hf, const char **name)
6507 {
6508 if (rpcrdma_is_reduced()) {
6509 /*
6510 * The opaque data is reduced so just increment the offset
6511 * since there is no actual data yet.
6512 */
6513 offset += 4;
6514 /* Add offset (from the end) where the opaque data should be */
6515 rpcrdma_insert_offset(tvb_reported_length_remaining(tvb, offset));
6516 if (name) {
6517 /* Return non-NULL string */
6518 *name = "";
6519 }
6520 } else {
6521 /* No data reduction, dissect the opaque data */
6522 switch (rtype) {
6523 case R_UTF8STRING:
6524 offset = dissect_nfs_utf8string(tvb, offset, tree, hf, name);
6525 break;
6526 case R_NFS2_PATH:
6527 offset = dissect_path(tvb, offset, tree, hf, name);
6528 break;
6529 case R_NFS3_PATH:
6530 offset = dissect_nfs3_path(tvb, offset, tree, hf, name);
6531 break;
6532 case R_NFSDATA:
6533 offset = dissect_nfsdata(tvb, offset, tree, hf);
6534 break;
6535 }
6536 }
6537 return offset;
6538 }
6539
6540
6541 static int
dissect_nfs4_deviceid(tvbuff_t * tvb,int offset,proto_tree * tree)6542 dissect_nfs4_deviceid(tvbuff_t *tvb, int offset, proto_tree *tree)
6543 {
6544 proto_tree_add_item(tree, hf_nfs4_deviceid, tvb, offset, 16, ENC_NA);
6545 offset += 16;
6546 return offset;
6547 }
6548
6549
6550 static int
dissect_nfs4_sessionid(tvbuff_t * tvb,int offset,proto_tree * tree)6551 dissect_nfs4_sessionid(tvbuff_t *tvb, int offset, proto_tree *tree)
6552 {
6553 proto_tree_add_item(tree, hf_nfs4_sessionid, tvb, offset, 16, ENC_NA);
6554 offset += 16;
6555 return offset;
6556 }
6557
6558
6559 static int
dissect_nfs4_specdata(tvbuff_t * tvb,int offset,proto_tree * tree)6560 dissect_nfs4_specdata(tvbuff_t *tvb, int offset, proto_tree *tree)
6561 {
6562 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_specdata1, offset);
6563 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_specdata2, offset);
6564 return offset;
6565 }
6566
6567 static const value_string names_ftype4[] = {
6568 { NF4REG, "NF4REG" },
6569 { NF4DIR, "NF4DIR" },
6570 { NF4BLK, "NF4BLK" },
6571 { NF4CHR, "NF4CHR" },
6572 { NF4LNK, "NF4LNK" },
6573 { NF4SOCK, "NF4SOCK" },
6574 { NF4FIFO, "NF4FIFO" },
6575 { NF4ATTRDIR, "NF4ATTRDIR" },
6576 { NF4NAMEDATTR, "NF4NAMEDATTR" },
6577 { 0, NULL }
6578 };
6579
6580
6581 static int
dissect_nfs4_lock_owner(tvbuff_t * tvb,int offset,proto_tree * tree)6582 dissect_nfs4_lock_owner(tvbuff_t *tvb, int offset, proto_tree *tree)
6583 {
6584 proto_tree *newftree;
6585
6586 newftree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_nfs4_lock_owner, NULL, "Owner");
6587 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
6588 offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs4_lock_owner);
6589
6590 return offset;
6591 }
6592
6593
6594 static int
dissect_nfs4_pathname(tvbuff_t * tvb,int offset,proto_tree * tree)6595 dissect_nfs4_pathname(tvbuff_t *tvb, int offset, proto_tree *tree)
6596 {
6597 guint32 comp_count, i;
6598 proto_item *fitem;
6599 proto_tree *newftree;
6600
6601 fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_pathname_components, tvb, offset, 4, ENC_BIG_ENDIAN, &comp_count);
6602 offset += 4;
6603
6604 newftree = proto_item_add_subtree(fitem, ett_nfs4_pathname);
6605
6606 for (i = 0; i < comp_count; i++)
6607 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, NULL);
6608 return offset;
6609 }
6610
6611
6612 static int
dissect_nfs4_nfstime(tvbuff_t * tvb,int offset,proto_tree * tree)6613 dissect_nfs4_nfstime(tvbuff_t *tvb, int offset, proto_tree *tree)
6614 {
6615 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_time_seconds, offset);
6616 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_time_nseconds, offset);
6617
6618 return offset;
6619 }
6620
6621
6622 static const value_string names_time_how4[] = {
6623 #define SET_TO_SERVER_TIME4 0
6624 { SET_TO_SERVER_TIME4, "SET_TO_SERVER_TIME4" },
6625 #define SET_TO_CLIENT_TIME4 1
6626 { SET_TO_CLIENT_TIME4, "SET_TO_CLIENT_TIME4" },
6627 { 0, NULL }
6628 };
6629
6630 static int
dissect_nfs4_settime(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name _U_)6631 dissect_nfs4_settime(tvbuff_t *tvb, int offset,
6632 proto_tree *tree, const char *name _U_)
6633 {
6634 guint32 set_it;
6635
6636 proto_tree_add_item_ret_uint(tree, hf_nfs4_time_how4, tvb, offset+0, 4, ENC_BIG_ENDIAN, &set_it);
6637 offset += 4;
6638
6639 if (set_it == SET_TO_CLIENT_TIME4)
6640 offset = dissect_nfs4_nfstime(tvb, offset, tree);
6641
6642 return offset;
6643 }
6644
6645
6646 static int
dissect_nfs4_fsid(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)6647 dissect_nfs4_fsid(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
6648 {
6649 proto_tree *newftree;
6650
6651 newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_fsid, NULL, name);
6652 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_fsid_major, offset);
6653 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_fsid_minor, offset);
6654 return offset;
6655 }
6656
6657 /* ACE type values */
6658 static const value_string names_acetype4[] = {
6659 #define ACE4_TYPE_ACCESS_ALLOWED 0x00000000
6660 { ACE4_TYPE_ACCESS_ALLOWED, "Access_Allowed" },
6661 #define ACE4_TYPE_ACCESS_DENIED 0x00000001
6662 { ACE4_TYPE_ACCESS_DENIED, "access_denied" },
6663 #define ACE4_TYPE_SYSTEM_AUDIT 0x00000002
6664 { ACE4_TYPE_SYSTEM_AUDIT, "system_audit" },
6665 #define ACE4_TYPE_SYSTEM_ALARM 0x00000003
6666 { ACE4_TYPE_SYSTEM_ALARM, "system_alarm" },
6667 { 0, NULL }
6668 };
6669
6670 /* ACE flag values */
6671 #define ACE4_FLAG_FILE_INHERIT 0x00000001
6672 #define ACE4_FLAG_DIRECTORY_INHERIT 0x00000002
6673 #define ACE4_FLAG_NO_PROPAGATE_INHERIT 0x00000004
6674 #define ACE4_FLAG_INHERIT_ONLY 0x00000008
6675 #define ACE4_FLAG_SUCCESSFUL_ACCESS 0x00000010
6676 #define ACE4_FLAG_FAILED_ACCESS 0x00000020
6677 #define ACE4_FLAG_IDENTIFIER_GROUP 0x00000040
6678 #define ACE4_FLAG_INHERITED_ACE 0x00000080
6679
6680 static int
dissect_nfs_aceflags4(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * ace_tree)6681 dissect_nfs_aceflags4(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *ace_tree)
6682 {
6683 static int * const flags[] = {
6684 &hf_nfs4_aceflag_file_inherit,
6685 &hf_nfs4_aceflag_dir_inherit,
6686 &hf_nfs4_aceflag_no_prop_inherit,
6687 &hf_nfs4_aceflag_inherit_only,
6688 &hf_nfs4_aceflag_successful_access,
6689 &hf_nfs4_aceflag_failed_access,
6690 &hf_nfs4_aceflag_id_group,
6691 &hf_nfs4_aceflag_inherited_ace,
6692 NULL
6693 };
6694
6695 proto_tree_add_bitmask(ace_tree, tvb, offset, hf_nfs4_aceflags, ett_nfs4_aceflag, flags, ENC_BIG_ENDIAN);
6696
6697 offset += 4;
6698 return offset;
6699 }
6700
6701
6702 /* ACE4 permissions for files */
6703 static const value_string acemask4_perms_file[] = {
6704 #define ACE4_READ_DATA 0x00000001
6705 { ACE4_READ_DATA, "Read_Data" },
6706 #define ACE4_WRITE_DATA 0x00000002
6707 { ACE4_WRITE_DATA, "Write_Data" },
6708 #define ACE4_APPEND_DATA 0x00000004
6709 { ACE4_APPEND_DATA, "Append_Data" },
6710 { 0, NULL }
6711 };
6712 /* Abbreviated ACE4 permissions for files */
6713 static const value_string acemask4_abbrev_perms_file[] = {
6714 { ACE4_READ_DATA, "RdData" },
6715 { ACE4_WRITE_DATA, "WrData" },
6716 { ACE4_APPEND_DATA, "AppData" },
6717 { 0, NULL }
6718 };
6719
6720 /* ACE4 permissions for dirs */
6721 static const value_string acemask4_perms_dir[] = {
6722 #define ACE4_LIST_DIRECTORY 0x00000001
6723 { ACE4_LIST_DIRECTORY, "List_Dir" },
6724 #define ACE4_ADD_FILE 0x00000002
6725 { ACE4_ADD_FILE, "Add_File" },
6726 #define ACE4_ADD_SUBDIRECTORY 0x00000004
6727 { ACE4_ADD_SUBDIRECTORY, "Add_Subdir" },
6728 { 0, NULL }
6729 };
6730 /* Abbreviated ACE4 permissions for dirs */
6731 static const value_string acemask4_abbrev_perms_dir[] = {
6732 { ACE4_LIST_DIRECTORY, "LstDir" },
6733 { ACE4_ADD_FILE, "AddFile" },
6734 { ACE4_ADD_SUBDIRECTORY, "AddSubD" },
6735 { 0, NULL }
6736 };
6737
6738 /* ACE4 permissions for objects of unknown type */
6739 static const value_string acemask4_perms_unkwn[] = {
6740 { ACE4_READ_DATA, "Read_Data / List_Dir" },
6741 { ACE4_WRITE_DATA, "Write_Data / Add_File" },
6742 { ACE4_APPEND_DATA, "Append_Data / Add_SubDir" },
6743 { 0, NULL }
6744 };
6745 /* Abbreviated ACE4 permissions for objects of unknown type */
6746 static const value_string acemask4_abbrev_perms_unkwn[] = {
6747 { ACE4_READ_DATA, "RdData/LstDir" },
6748 { ACE4_WRITE_DATA, "WrData/AddFile" },
6749 { ACE4_APPEND_DATA, "AppData/AddSubD" },
6750 { 0, NULL }
6751 };
6752
6753 /* ACE4 permissions for object types 0x8 and above */
6754 static const value_string acemask4_perms_8_and_above[] = {
6755 #define ACE4_READ_NAMED_ATTRS 0x00000008
6756 { ACE4_READ_NAMED_ATTRS, "Read_Named_Attrs" },
6757 #define ACE4_WRITE_NAMED_ATTRS 0x00000010
6758 { ACE4_WRITE_NAMED_ATTRS, "Write_Named_Attrs" },
6759 #define ACE4_EXECUTE 0x00000020
6760 { ACE4_EXECUTE, "Execute" },
6761 #define ACE4_DELETE_CHILD 0x00000040
6762 { ACE4_DELETE_CHILD, "Delete_Child" },
6763 #define ACE4_READ_ATTRIBUTES 0x00000080
6764 { ACE4_READ_ATTRIBUTES, "Read_Attributes" },
6765 #define ACE4_WRITE_ATTRIBUTES 0x00000100
6766 { ACE4_WRITE_ATTRIBUTES, "Write_Attributes" },
6767 #define ACE4_WRITE_RETENTION 0x00000200
6768 { ACE4_WRITE_RETENTION, "Write_Retention" },
6769 #define ACE4_WRITE_RETENTION_HOLD 0x00000400
6770 { ACE4_WRITE_RETENTION_HOLD, "Write_Retention_Hold" },
6771 #define ACE4_DELETE 0x00010000
6772 { ACE4_DELETE, "Delete" },
6773 #define ACE4_READ_ACL 0x00020000
6774 { ACE4_READ_ACL, "Read_ACL" },
6775 #define ACE4_WRITE_ACL 0x00040000
6776 { ACE4_WRITE_ACL, "Write_ACL" },
6777 #define ACE4_WRITE_OWNER 0x00080000
6778 { ACE4_WRITE_OWNER, "Write_Owner" },
6779 #define ACE4_SYNCHRONIZE 0x00100000
6780 { ACE4_SYNCHRONIZE, "Synchronize" },
6781 { 0, NULL }
6782 };
6783 static value_string_ext acemask4_perms_8_and_above_ext = VALUE_STRING_EXT_INIT(acemask4_perms_8_and_above);
6784
6785 /* Abbreviated ACE4 permissions for object types 0x8 and above */
6786 static const value_string acemask4_abbrev_perms_8_and_above[] = {
6787 { ACE4_READ_NAMED_ATTRS, "RdNamAt" },
6788 { ACE4_WRITE_NAMED_ATTRS, "WrNamAt" },
6789 { ACE4_EXECUTE, "Exec" },
6790 { ACE4_DELETE_CHILD, "DelChld" },
6791 { ACE4_READ_ATTRIBUTES, "RdAttrs" },
6792 { ACE4_WRITE_ATTRIBUTES, "WrAttrs" },
6793 { ACE4_WRITE_RETENTION, "WrRet" },
6794 { ACE4_WRITE_RETENTION_HOLD, "WrRetHld" },
6795 { ACE4_DELETE, "Del" },
6796 { ACE4_READ_ACL, "RdACL" },
6797 { ACE4_WRITE_ACL, "WrACL" },
6798 { ACE4_WRITE_OWNER, "WrOwn" },
6799 { ACE4_SYNCHRONIZE, "Sync" },
6800 { 0, NULL }
6801 };
6802 static value_string_ext acemask4_abbrev_perms_8_and_above_ext = VALUE_STRING_EXT_INIT(acemask4_abbrev_perms_8_and_above);
6803
6804 static int
dissect_nfs4_acemask(tvbuff_t * tvb,int offset,proto_tree * ace_tree,guint32 acetype4,guint32 obj_type)6805 dissect_nfs4_acemask(tvbuff_t *tvb, int offset, proto_tree *ace_tree, guint32 acetype4, guint32 obj_type)
6806 {
6807 const gchar *type = NULL;
6808 const gchar *atype = NULL;
6809 guint32 acemask = tvb_get_ntohl(tvb, offset);
6810 guint32 acemask_bit = 1;
6811 gboolean first_perm = TRUE;
6812 proto_item *acemask_item;
6813 proto_tree *acemask_tree;
6814
6815 acemask_item = proto_tree_add_uint(ace_tree, hf_nfs4_acemask, tvb, offset, 4, acemask);
6816 acemask_tree = proto_item_add_subtree(acemask_item, ett_nfs4_acemask);
6817 proto_item_append_text(acemask_item, " (");
6818
6819 while (acemask_bit <= ACE4_SYNCHRONIZE)
6820 {
6821 if (acemask_bit & acemask) {
6822 if (acemask_bit <= 0x4) {
6823 if (obj_type) {
6824 if (obj_type == NF4REG) {
6825 type = val_to_str(acemask_bit, acemask4_perms_file, "Unknown: %u");
6826 atype = val_to_str(acemask_bit, acemask4_abbrev_perms_file, "Unknown: %u");
6827 } else if (obj_type == NF4DIR) {
6828 type = val_to_str(acemask_bit, acemask4_perms_dir, "Unknown: %u");
6829 atype = val_to_str(acemask_bit, acemask4_abbrev_perms_dir, "Unknown: %u");
6830 }
6831 } else {
6832 type = val_to_str(acemask_bit, acemask4_perms_unkwn, "Unknown: %u");
6833 atype = val_to_str(acemask_bit, acemask4_abbrev_perms_unkwn, "Unknown: %u");
6834 }
6835 } else {
6836 type = val_to_str_ext(acemask_bit, &acemask4_perms_8_and_above_ext, "Unknown: %u");
6837 atype = val_to_str_ext(acemask_bit, &acemask4_abbrev_perms_8_and_above_ext, "Unknown: %u");
6838 }
6839 proto_tree_add_uint_format(acemask_tree, hf_nfs4_ace_permission, tvb, offset, 4,
6840 acemask_bit, "%s: %s (0x%08x)", val_to_str(acetype4, names_acetype4, "Unknown: %u"), type, acemask_bit);
6841 proto_item_append_text(acemask_item, first_perm ? "%s" : ", %s", atype);
6842 first_perm = FALSE;
6843 }
6844 acemask_bit <<= 1;
6845 }
6846 proto_item_append_text(acemask_item, ")");
6847
6848 offset += 4;
6849
6850 return offset;
6851 }
6852
6853 /* Decode exactly one ACE (type, flags, mask, permissions, and who) */
6854 static int
dissect_nfs4_ace(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,int ace_number,guint32 obj_type)6855 dissect_nfs4_ace(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int ace_number,
6856 guint32 obj_type)
6857 {
6858 guint32 acetype4 = 0;
6859 const char *acetype4_str;
6860 proto_tree *ace_tree = NULL;
6861
6862 if (tree) {
6863 proto_item *ace_item = NULL;
6864
6865 acetype4 = tvb_get_ntohl(tvb, offset);
6866 acetype4_str = val_to_str(acetype4, names_acetype4, "Unknown: %u");
6867
6868 /* Display the ACE type and create a subtree for this ACE */
6869 if (ace_number == 0) {
6870 ace_item = proto_tree_add_uint_format(tree, hf_nfs4_acetype, tvb, offset, 4,
6871 acetype4, "ACE Type: %s (%u)", acetype4_str, acetype4);
6872 } else {
6873 ace_item = proto_tree_add_uint_format(tree, hf_nfs4_acetype, tvb, offset, 4,
6874 acetype4, "%u. ACE Type: %s (%u)", ace_number, acetype4_str, acetype4);
6875 }
6876 ace_tree = proto_item_add_subtree(ace_item, ett_nfs4_ace);
6877 }
6878
6879 offset += 4;
6880
6881 if (tree) {
6882 offset = dissect_nfs_aceflags4(tvb, offset, pinfo, ace_tree);
6883 offset = dissect_nfs4_acemask(tvb, offset, ace_tree, acetype4, obj_type);
6884 } else {
6885 offset += 8;
6886 }
6887
6888 offset = dissect_nfs_utf8string(tvb, offset, ace_tree, hf_nfs4_who, NULL);
6889
6890 return offset;
6891 }
6892
6893 #define ACL4_AUTO_INHERIT 0x00000001
6894 #define ACL4_PROTECTED 0x00000002
6895 #define ACL4_DEFAULTED 0x00000004
6896
6897 static int * const aclflags_fields[] = {
6898 &hf_nfs4_aclflag_auto_inherit,
6899 &hf_nfs4_aclflag_protected,
6900 &hf_nfs4_aclflag_defaulted,
6901 NULL
6902 };
6903
6904 static int
dissect_nfs4_aclflags(tvbuff_t * tvb,int offset,proto_tree * tree)6905 dissect_nfs4_aclflags(tvbuff_t *tvb, int offset, proto_tree *tree)
6906 {
6907 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_aclflags,
6908 ett_nfs4_aclflag, aclflags_fields, ENC_BIG_ENDIAN);
6909 offset += 4;
6910
6911 return offset;
6912 }
6913
6914 static int
dissect_nfs4_fattr_acl(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_item * attr_item,proto_tree * tree,guint32 obj_type,guint32 attr_num)6915 dissect_nfs4_fattr_acl(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_item *attr_item,
6916 proto_tree *tree, guint32 obj_type, guint32 attr_num)
6917 {
6918 guint32 num_aces;
6919 guint32 ace_number;
6920
6921 if (attr_num != FATTR4_ACL)
6922 offset = dissect_nfs4_aclflags(tvb, offset, tree);
6923
6924 num_aces = tvb_get_ntohl(tvb, offset);
6925 if (tree && num_aces > 0) {
6926 proto_tree_add_uint(tree, hf_nfs4_num_aces, tvb, offset, 4, num_aces);
6927 proto_item_append_text(attr_item, " (%u ACEs)", num_aces);
6928 }
6929 offset += 4;
6930
6931 /* Tree or not, this for loop is required due dissect_nfs_utf8string() call */
6932 for (ace_number = 1; ace_number<=num_aces; ace_number++)
6933 offset = dissect_nfs4_ace(tvb, offset, pinfo, tree, ace_number, obj_type);
6934
6935 return offset;
6936 }
6937
6938 #define ACL4_SUPPORT_ALLOW_ACL 0x00000001
6939 #define ACL4_SUPPORT_DENY_ACL 0x00000002
6940 #define ACL4_SUPPORT_AUDIT_ACL 0x00000004
6941 #define ACL4_SUPPORT_ALARM_ACL 0x00000008
6942
6943 static int * const aclsupport_fields[] = {
6944 &hf_nfs4_aclsupport_allow_acl,
6945 &hf_nfs4_aclsupport_deny_acl,
6946 &hf_nfs4_aclsupport_audit_acl,
6947 &hf_nfs4_aclsupport_alarm_acl,
6948 NULL
6949 };
6950
6951 static int
dissect_nfs4_fattr_aclsupport(tvbuff_t * tvb,int offset,proto_tree * tree)6952 dissect_nfs4_fattr_aclsupport(tvbuff_t *tvb, int offset, proto_tree *tree)
6953 {
6954 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_fattr_aclsupport,
6955 ett_nfs4_fattr_aclsupport, aclsupport_fields, ENC_BIG_ENDIAN);
6956 offset += 4;
6957
6958 return offset;
6959 }
6960
6961 static int
dissect_nfs4_fh(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * name,guint32 * hash,rpc_call_info_value * civ)6962 dissect_nfs4_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
6963 proto_tree *tree, const char *name, guint32 *hash, rpc_call_info_value *civ)
6964 {
6965 return dissect_nfs3_fh(tvb, offset, pinfo, tree, name, hash, civ);
6966 }
6967
6968
6969 static int
dissect_nfs4_server(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)6970 dissect_nfs4_server(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
6971 {
6972 return dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_server, NULL);
6973 }
6974
6975
6976 static int
dissect_nfs4_fs_location(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)6977 dissect_nfs4_fs_location(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
6978 proto_tree *tree, void *data _U_)
6979 {
6980 proto_tree *newftree;
6981
6982 newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_fs_location, NULL, "fs_location4");
6983
6984 offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_server, hf_nfs4_servers);
6985 offset = dissect_nfs4_pathname(tvb, offset, newftree);
6986
6987 return offset;
6988 }
6989
6990
6991 static int
dissect_nfs4_fs_locations(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * tree,const char * name)6992 dissect_nfs4_fs_locations(tvbuff_t *tvb, packet_info *pinfo, int offset,
6993 proto_tree *tree, const char *name)
6994 {
6995 proto_tree *newftree;
6996
6997 newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_fs_locations, NULL, name);
6998
6999 offset = dissect_nfs4_pathname(tvb, offset, newftree);
7000
7001 offset = dissect_rpc_array(tvb, pinfo, newftree, offset,
7002 dissect_nfs4_fs_location, hf_nfs4_fslocation);
7003
7004 return offset;
7005 }
7006
7007 /* RFC5661 - '14.4. UTF-8 Capabilities' */
7008 #define FSCHARSET_CAP4_CONTAINS_NON_UTF8 0x00000001
7009 #define FSCHARSET_CAP4_ALLOWS_ONLY_UTF8 0x00000002
7010
7011 static int
dissect_nfs4_fattr_fs_charset_cap(tvbuff_t * tvb,int offset,proto_tree * tree)7012 dissect_nfs4_fattr_fs_charset_cap(tvbuff_t *tvb, int offset, proto_tree *tree)
7013 {
7014 int * const fs_charset_cap_fields[] = {
7015 &hf_nfs4_fs_charset_cap_nonutf8,
7016 &hf_nfs4_fs_charset_cap_utf8,
7017 NULL
7018 };
7019
7020 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_fattr_fs_charset_cap,
7021 ett_nfs4_fattr_fs_charset_cap, fs_charset_cap_fields, ENC_BIG_ENDIAN);
7022 offset += 4;
7023
7024 return offset;
7025 }
7026
7027 static int
dissect_nfs4_mode(tvbuff_t * tvb,int offset,proto_tree * tree)7028 dissect_nfs4_mode(tvbuff_t *tvb, int offset, proto_tree *tree)
7029 {
7030 return dissect_nfs2_mode(tvb, offset, tree);
7031 }
7032
7033 #define FH4_PERSISTENT 0x00000000
7034 #define FH4_NOEXPIRE_WITH_OPEN 0x00000001
7035 #define FH4_VOLATILE_ANY 0x00000002
7036 #define FH4_VOL_MIGRATION 0x00000004
7037 #define FH4_VOL_RENAME 0x00000008
7038
7039 static const value_string nfs4_fattr4_fh_expire_type_names[] = {
7040 { FH4_PERSISTENT, "FH4_PERSISTENT" },
7041 { 0, NULL }
7042 };
7043
7044 static int * const nfs4_fattr_fh_expire_type_fields[] = {
7045 &hf_nfs4_fattr_fh_expiry_noexpire_with_open,
7046 &hf_nfs4_fattr_fh_expiry_volatile_any,
7047 &hf_nfs4_fattr_fh_expiry_vol_migration,
7048 &hf_nfs4_fattr_fh_expiry_vol_rename,
7049 NULL
7050 };
7051
7052 static int
dissect_nfs4_fattr_fh_expire_type(tvbuff_t * tvb,int offset,proto_tree * tree)7053 dissect_nfs4_fattr_fh_expire_type(tvbuff_t *tvb, int offset, proto_tree *tree)
7054 {
7055 guint32 expire_type;
7056
7057 expire_type = tvb_get_ntohl(tvb, offset + 0);
7058
7059 if (expire_type == FH4_PERSISTENT)
7060 proto_tree_add_item(tree, hf_nfs4_fattr_fh_expire_type, tvb, offset, 4, ENC_BIG_ENDIAN);
7061 else
7062 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_fattr_fh_expire_type,
7063 ett_nfs4_fattr_fh_expire_type, nfs4_fattr_fh_expire_type_fields,
7064 ENC_BIG_ENDIAN);
7065
7066 offset += 4;
7067
7068 return offset;
7069 }
7070
7071
7072 static int
dissect_nfs_fs_layout_type(tvbuff_t * tvb,proto_tree * tree,int offset)7073 dissect_nfs_fs_layout_type(tvbuff_t *tvb, proto_tree *tree, int offset)
7074 {
7075 guint count, i;
7076
7077 count = tvb_get_ntohl(tvb, offset);
7078 offset += 4;
7079
7080 for (i = 0; i < count; i++)
7081 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
7082
7083 return offset;
7084 }
7085
7086
7087 static const value_string th4_names_file[] = {
7088 #define TH4_READ_SIZE 0
7089 { TH4_READ_SIZE, "Read_Size" },
7090 #define TH4_WRITE_SIZE 1
7091 { TH4_WRITE_SIZE, "Write_Size" },
7092 #define TH4_READ_IOSIZE 2
7093 { TH4_READ_IOSIZE, "Read_IO_Size" },
7094 #define TH4_WRITE_IOSIZE 3
7095 { TH4_WRITE_IOSIZE, "Write_IO_Size" },
7096 { 0, NULL }
7097 };
7098 static value_string_ext th4_names_ext_file = VALUE_STRING_EXT_INIT(th4_names_file);
7099
7100
7101 /* Dissect the threshold_item4 bit attribute for the files layout type */
7102 static int
dissect_nfs4_threshold_item_file(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,rpc_call_info_value * civ _U_,proto_tree * attr_tree,proto_item * attr_item _U_,guint32 bit_num,void * battr_data _U_)7103 dissect_nfs4_threshold_item_file(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
7104 rpc_call_info_value *civ _U_, proto_tree *attr_tree, proto_item *attr_item _U_,
7105 guint32 bit_num, void *battr_data _U_)
7106 {
7107 guint64 size;
7108
7109 switch (bit_num) {
7110 case TH4_READ_SIZE:
7111 case TH4_WRITE_SIZE:
7112 case TH4_READ_IOSIZE:
7113 case TH4_WRITE_IOSIZE:
7114 size = tvb_get_ntoh64(tvb, offset);
7115 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_length, offset);
7116 proto_item_append_text(attr_tree, " = %" G_GUINT64_FORMAT, size);
7117 break;
7118 }
7119 return offset;
7120 }
7121
7122
7123 /* Dissect the threshold_item4 structure */
7124 static int
dissect_nfs4_threshold_item(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,void * data)7125 dissect_nfs4_threshold_item(tvbuff_t *tvb, int offset, packet_info *pinfo,
7126 proto_tree *tree, void *data)
7127 {
7128 guint32 layout_type;
7129 static nfs4_bitmap_info_t *bitmap_info_p;
7130
7131 /* Bitmap info for the files layout type */
7132 static nfs4_bitmap_info_t bitmap_info_files = {
7133 .vse_names_ext = &th4_names_ext_file,
7134 .dissect_battr = dissect_nfs4_threshold_item_file,
7135 .hf_mask_label = &hf_nfs4_mdsthreshold_hint_mask,
7136 .hf_item_label = &hf_nfs4_mdsthreshold_hint_file,
7137 .hf_item_count = &hf_nfs4_mdsthreshold_hint_count,
7138 .hf_mask_count = &hf_nfs4_mdsthreshold_mask_count
7139 };
7140
7141 /* Bitmap info for an unsupported layout type,
7142 * just display the bitmap mask and its data */
7143 static nfs4_bitmap_info_t bitmap_info_default = {
7144 .hf_mask_label = &hf_nfs4_mdsthreshold_hint_mask,
7145 .hf_mask_count = &hf_nfs4_mdsthreshold_mask_count,
7146 .hf_btmap_data = &hf_nfs4_bitmap_data,
7147 };
7148
7149 /* Get layout type */
7150 layout_type = tvb_get_ntohl(tvb, offset);
7151 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
7152
7153 switch (layout_type) {
7154 case LAYOUT4_NFSV4_1_FILES:
7155 bitmap_info_p = &bitmap_info_files;
7156 break;
7157 default:
7158 bitmap_info_p = &bitmap_info_default;
7159 break;
7160 }
7161 return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, (rpc_call_info_value *)data, bitmap_info_p, NFS4_BITMAP_VALUES, NULL);
7162 }
7163
7164
7165 /* Dissect the fattr4_mdsthreshold structure */
7166 static int
dissect_nfs4_mdsthreshold(tvbuff_t * tvb,packet_info * pinfo,int offset,proto_tree * tree)7167 dissect_nfs4_mdsthreshold(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree)
7168 {
7169 int mds_offset = offset;
7170
7171 offset = dissect_rpc_array(tvb, pinfo, tree, offset,
7172 dissect_nfs4_threshold_item, hf_nfs4_mdsthreshold_item);
7173 proto_item_set_len(tree, offset - mds_offset);
7174
7175 return offset;
7176 }
7177
7178
7179 static int
dissect_nfs4_security_label(tvbuff_t * tvb,proto_tree * tree,int offset)7180 dissect_nfs4_security_label(tvbuff_t *tvb, proto_tree *tree, int offset)
7181 {
7182
7183 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_security_label_lfs, offset);
7184 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_security_label_pi, offset);
7185 offset = dissect_nfs_utf8string(tvb, offset, tree,
7186 hf_nfs4_fattr_security_label_context, NULL);
7187
7188 return offset;
7189 }
7190
7191 static int
dissect_nfs4_mode_umask(tvbuff_t * tvb,proto_tree * tree,int offset)7192 dissect_nfs4_mode_umask(tvbuff_t *tvb, proto_tree *tree, int offset)
7193 {
7194 offset = dissect_nfs4_mode(tvb, offset, tree);
7195 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_fattr_umask_mask, offset);
7196 return offset;
7197 }
7198
7199 #define FATTR4_BITMAP_ONLY 0
7200 #define FATTR4_DISSECT_VALUES 1
7201
7202 #define CHANGE_TYPE_IS_MONOTONIC_INCR 0
7203 #define CHANGE_TYPE_IS_VERSION_COUNTER 1
7204 #define CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS 2
7205 #define CHANGE_TYPE_IS_TIME_METADATA 3
7206 #define CHANGE_TYPE_IS_UNDEFINED 4
7207
7208 static const value_string names_nfs_change_attr_types[] =
7209 {
7210 { CHANGE_TYPE_IS_MONOTONIC_INCR, "CHANGE_TYPE_IS_MONOTONIC_INCR" },
7211 { CHANGE_TYPE_IS_VERSION_COUNTER, "CHANGE_TYPE_IS_VERSION_COUNTER" },
7212 { CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS, "CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS" },
7213 { CHANGE_TYPE_IS_TIME_METADATA, "CHANGE_TYPE_IS_TIME_METADATA" },
7214 { CHANGE_TYPE_IS_UNDEFINED, "CHANGE_TYPE_IS_UNDEFINED" },
7215 { 0, NULL }
7216 };
7217
7218 static int
7219 dissect_nfs4_fattrs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int type, rpc_call_info_value *civ);
7220
7221 /* Display attribute as either required or recommended */
7222 static int
nfs4_fattr_item_label(guint32 attr_num)7223 nfs4_fattr_item_label(guint32 attr_num)
7224 {
7225 return (attr_num <= FATTR4_RDATTR_ERROR ||
7226 attr_num == FATTR4_FILEHANDLE ||
7227 attr_num == FATTR4_SUPPATTR_EXCLCREAT) ?
7228 hf_nfs4_reqd_attr: hf_nfs4_reco_attr;
7229
7230 }
7231
7232 /* Dissect the value of the attribute given by attr_num */
7233 static int
dissect_nfs4_fattr_value(tvbuff_t * tvb,int offset,packet_info * pinfo,rpc_call_info_value * civ,proto_tree * attr_tree,proto_item * attr_item,guint32 attr_num,void * battr_data)7234 dissect_nfs4_fattr_value(tvbuff_t *tvb, int offset, packet_info *pinfo,
7235 rpc_call_info_value *civ, proto_tree *attr_tree,
7236 proto_item *attr_item, guint32 attr_num, void *battr_data)
7237 {
7238 guint32 *fattr_obj_type_p = (guint32 *)battr_data;
7239 switch (attr_num) {
7240 case FATTR4_SUPPORTED_ATTRS:
7241 case FATTR4_SUPPATTR_EXCLCREAT:
7242 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, attr_tree, FATTR4_BITMAP_ONLY, civ);
7243 break;
7244
7245 case FATTR4_TYPE:
7246 *fattr_obj_type_p = tvb_get_ntohl(tvb, offset);
7247 if (attr_tree)
7248 proto_tree_add_item(attr_tree, hf_nfs4_ftype, tvb, offset, 4,
7249 ENC_BIG_ENDIAN);
7250 offset += 4;
7251 break;
7252
7253 case FATTR4_FH_EXPIRE_TYPE:
7254 offset = dissect_nfs4_fattr_fh_expire_type(tvb, offset, attr_tree);
7255 break;
7256
7257 case FATTR4_CHANGE:
7258 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_changeid, offset);
7259 break;
7260
7261 case FATTR4_SIZE:
7262 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_size, offset);
7263 break;
7264
7265 case FATTR4_LINK_SUPPORT:
7266 offset = dissect_rpc_bool(tvb,
7267 attr_tree, hf_nfs4_fattr_link_support, offset);
7268 break;
7269
7270 case FATTR4_SYMLINK_SUPPORT:
7271 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_symlink_support, offset);
7272 break;
7273
7274 case FATTR4_NAMED_ATTR:
7275 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_named_attr, offset);
7276 break;
7277
7278 case FATTR4_FSID:
7279 offset = dissect_nfs4_fsid(tvb, offset, attr_tree, "fattr4_fsid");
7280 break;
7281
7282 case FATTR4_UNIQUE_HANDLES:
7283 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_unique_handles, offset);
7284 break;
7285
7286 case FATTR4_LEASE_TIME:
7287 offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_lease_time, offset);
7288 break;
7289
7290 case FATTR4_RDATTR_ERROR:
7291 offset = dissect_nfs4_status(tvb, offset, attr_tree, NULL);
7292 break;
7293
7294 case FATTR4_ACL:
7295 case FATTR4_DACL:
7296 case FATTR4_SACL:
7297 offset = dissect_nfs4_fattr_acl(tvb, offset, pinfo, attr_item, attr_tree,
7298 *fattr_obj_type_p, attr_num);
7299 break;
7300
7301 case FATTR4_ACLSUPPORT:
7302 offset = dissect_nfs4_fattr_aclsupport(tvb, offset, attr_tree);
7303 break;
7304
7305 case FATTR4_ARCHIVE:
7306 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_archive, offset);
7307 break;
7308
7309 case FATTR4_CANSETTIME:
7310 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_cansettime, offset);
7311 break;
7312
7313 case FATTR4_CASE_INSENSITIVE:
7314 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_case_insensitive, offset);
7315 break;
7316
7317 case FATTR4_CASE_PRESERVING:
7318 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_case_preserving, offset);
7319 break;
7320
7321 case FATTR4_CHOWN_RESTRICTED:
7322 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_chown_restricted, offset);
7323 break;
7324
7325 case FATTR4_FILEID:
7326 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_fileid, offset);
7327 break;
7328
7329 case FATTR4_FILES_AVAIL:
7330 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_files_avail, offset);
7331 break;
7332
7333 case FATTR4_FILEHANDLE:
7334 offset = dissect_nfs4_fh(tvb, offset, pinfo, attr_tree, "fattr4_filehandle", NULL, civ);
7335 break;
7336
7337 case FATTR4_FILES_FREE:
7338 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_files_free, offset);
7339 break;
7340
7341 case FATTR4_FILES_TOTAL:
7342 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_files_total, offset);
7343 break;
7344
7345 case FATTR4_FS_LOCATIONS:
7346 offset = dissect_nfs4_fs_locations(tvb, pinfo, offset, attr_tree,
7347 "fattr4_fs_locations");
7348 break;
7349
7350 case FATTR4_HIDDEN:
7351 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_hidden, offset);
7352 break;
7353
7354 case FATTR4_HOMOGENEOUS:
7355 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_homogeneous, offset);
7356 break;
7357
7358 case FATTR4_MAXFILESIZE:
7359 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_maxfilesize, offset);
7360 break;
7361
7362 case FATTR4_MAXLINK:
7363 offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_maxlink, offset);
7364 break;
7365
7366 case FATTR4_MAXNAME:
7367 offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_maxname, offset);
7368 break;
7369
7370 case FATTR4_MAXREAD:
7371 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_maxread, offset);
7372 break;
7373
7374 case FATTR4_MAXWRITE:
7375 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_maxwrite, offset);
7376 break;
7377
7378 case FATTR4_MIMETYPE:
7379 offset = dissect_nfs_utf8string(tvb, offset, attr_tree, hf_nfs4_fattr_mimetype,
7380 NULL);
7381 break;
7382
7383 case FATTR4_MODE:
7384 offset = dissect_nfs4_mode(tvb, offset, attr_tree);
7385 break;
7386
7387 case FATTR4_NO_TRUNC:
7388 offset = dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_no_trunc, offset);
7389 break;
7390
7391 case FATTR4_NUMLINKS:
7392 offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_numlinks, offset);
7393 break;
7394
7395 case FATTR4_OWNER:
7396 offset = dissect_nfs_utf8string(tvb, offset, attr_tree, hf_nfs4_fattr_owner,
7397 NULL);
7398 break;
7399
7400 case FATTR4_OWNER_GROUP:
7401 offset = dissect_nfs_utf8string(tvb, offset, attr_tree,
7402 hf_nfs4_fattr_owner_group, NULL);
7403 break;
7404
7405 case FATTR4_QUOTA_AVAIL_HARD:
7406 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_quota_hard, offset);
7407 break;
7408
7409 case FATTR4_QUOTA_AVAIL_SOFT:
7410 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_quota_soft, offset);
7411 break;
7412
7413 case FATTR4_QUOTA_USED:
7414 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_quota_used, offset);
7415 break;
7416
7417 case FATTR4_RAWDEV:
7418 offset = dissect_nfs4_specdata(tvb, offset, attr_tree);
7419 break;
7420
7421 case FATTR4_SPACE_AVAIL:
7422 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_avail, offset);
7423 break;
7424
7425 case FATTR4_SPACE_FREE:
7426 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_free, offset);
7427 break;
7428
7429 case FATTR4_SPACE_TOTAL:
7430 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_total, offset);
7431 break;
7432
7433 case FATTR4_SPACE_USED:
7434 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_used, offset);
7435 break;
7436
7437 case FATTR4_SYSTEM:
7438 if (attr_tree)
7439 dissect_rpc_bool(tvb, attr_tree, hf_nfs4_fattr_system, offset);
7440 offset += 4;
7441 break;
7442
7443 case FATTR4_TIME_ACCESS:
7444 case FATTR4_TIME_BACKUP:
7445 case FATTR4_TIME_CREATE:
7446 case FATTR4_TIME_DELTA:
7447 case FATTR4_TIME_METADATA:
7448 case FATTR4_TIME_MODIFY:
7449 case FATTR4_DIR_NOTIF_DELAY:
7450 case FATTR4_DIRENT_NOTIF_DELAY:
7451 case FATTR4_TIME_DELEG_ACCESS:
7452 case FATTR4_TIME_DELEG_MODIFY:
7453 if (attr_tree)
7454 dissect_nfs4_nfstime(tvb, offset, attr_tree);
7455 offset += 12;
7456 break;
7457
7458 case FATTR4_TIME_ACCESS_SET:
7459 case FATTR4_TIME_MODIFY_SET:
7460 offset = dissect_nfs4_settime(tvb, offset, attr_tree, "settime4");
7461 break;
7462
7463 case FATTR4_MOUNTED_ON_FILEID:
7464 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_mounted_on_fileid,
7465 offset);
7466 break;
7467
7468 case FATTR4_FS_LAYOUT_TYPE:
7469 offset = dissect_nfs_fs_layout_type(tvb, attr_tree, offset);
7470 break;
7471
7472 case FATTR4_LAYOUT_BLKSIZE:
7473 offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_layout_blksize,
7474 offset);
7475 break;
7476
7477 case FATTR4_MDSTHRESHOLD:
7478 offset = dissect_nfs4_mdsthreshold(tvb, pinfo, offset, attr_tree);
7479 break;
7480
7481 case FATTR4_CLONE_BLOCKSIZE:
7482 offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_clone_blocksize,
7483 offset);
7484 break;
7485
7486 case FATTR4_SPACE_FREED:
7487 offset = dissect_rpc_uint64(tvb, attr_tree, hf_nfs4_fattr_space_freed,
7488 offset);
7489 break;
7490
7491 case FATTR4_CHANGE_ATTR_TYPE:
7492 offset = dissect_rpc_uint32(tvb, attr_tree, hf_nfs4_fattr_change_attr_type,
7493 offset);
7494 break;
7495
7496 case FATTR4_SECURITY_LABEL:
7497 offset = dissect_nfs4_security_label(tvb, attr_tree, offset);
7498 break;
7499
7500 case FATTR4_MODE_UMASK:
7501 offset = dissect_nfs4_mode_umask(tvb, attr_tree, offset);
7502 break;
7503
7504 case FATTR4_XATTR_SUPPORT:
7505 offset = dissect_rpc_bool(tvb,
7506 attr_tree, hf_nfs4_fattr_xattr_support, offset);
7507 break;
7508
7509 case FATTR4_OFFLINE:
7510 offset = dissect_rpc_bool(tvb,
7511 attr_tree, hf_nfs4_fattr_offline, offset);
7512 break;
7513
7514 case FATTR4_FS_CHARSET_CAP:
7515 offset = dissect_nfs4_fattr_fs_charset_cap(tvb, offset, attr_tree);
7516 break;
7517
7518 default:
7519 break;
7520 }
7521
7522 return offset;
7523 }
7524
7525 /* Display each attrmask bitmap and optionally dissect the value. */
7526 static int
dissect_nfs4_fattrs(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,int type,rpc_call_info_value * civ)7527 dissect_nfs4_fattrs(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int type, rpc_call_info_value *civ)
7528 {
7529 static guint32 fattr_obj_type = 0;
7530 nfs4_bitmap_type_t bitmap_type;
7531 static nfs4_bitmap_info_t bitmap_info = {
7532 .vse_names_ext = &fattr4_names_ext,
7533 .dissect_battr = dissect_nfs4_fattr_value,
7534 .battr_data = &fattr_obj_type,
7535 .hf_mask_label = &hf_nfs4_attr_mask,
7536 .hf_item_count = &hf_nfs4_attr_count,
7537 .get_item_label = nfs4_fattr_item_label
7538 };
7539
7540 fattr_obj_type = 0;
7541 bitmap_type = (type == FATTR4_BITMAP_ONLY) ? NFS4_BITMAP_MASK : NFS4_BITMAP_VALUES;
7542
7543 return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, civ, &bitmap_info, bitmap_type, NULL);
7544 }
7545
7546 static const value_string names_open4_share_access[] = {
7547 #define OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE 0x0000
7548 { OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE, "OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE" },
7549 #define OPEN4_SHARE_ACCESS_READ 0x00000001
7550 { OPEN4_SHARE_ACCESS_READ, "OPEN4_SHARE_ACCESS_READ" },
7551 #define OPEN4_SHARE_ACCESS_WRITE 0x00000002
7552 { OPEN4_SHARE_ACCESS_WRITE, "OPEN4_SHARE_ACCESS_WRITE" },
7553 #define OPEN4_SHARE_ACCESS_BOTH 0x00000003
7554 { OPEN4_SHARE_ACCESS_BOTH, "OPEN4_SHARE_ACCESS_BOTH" },
7555 #define OPEN4_SHARE_ACCESS_WANT_READ_DELEG 0x0100
7556 { OPEN4_SHARE_ACCESS_WANT_READ_DELEG, "OPEN4_SHARE_ACCESS_WANT_READ_DELEG" },
7557 #define OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG 0x0200
7558 { OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG, "OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG" },
7559 #define OPEN4_SHARE_ACCESS_WANT_ANY_DELEG 0x0300
7560 { OPEN4_SHARE_ACCESS_WANT_ANY_DELEG, "OPEN4_SHARE_ACCESS_WANT_ANY_DELEG" },
7561 #define OPEN4_SHARE_ACCESS_WANT_NO_DELEG 0x0400
7562 { OPEN4_SHARE_ACCESS_WANT_NO_DELEG, "OPEN4_SHARE_ACCESS_WANT_NO_DELEG" },
7563 #define OPEN4_SHARE_ACCESS_WANT_CANCEL 0x0500
7564 { OPEN4_SHARE_ACCESS_WANT_CANCEL, "OPEN4_SHARE_ACCESS_WANT_CANCEL" },
7565 #define OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x10000
7566 { OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL,
7567 "OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL"},
7568 #define OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED 0x20000
7569 { OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED,
7570 "OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED"},
7571 #define OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS 0x100000
7572 {OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS,
7573 "OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS"},
7574 { 0, NULL }
7575 };
7576 static value_string_ext names_open4_share_access_ext = VALUE_STRING_EXT_INIT(names_open4_share_access);
7577
7578 static int
dissect_nfs4_open_share_access(tvbuff_t * tvb,int offset,proto_tree * tree)7579 dissect_nfs4_open_share_access(tvbuff_t *tvb, int offset, proto_tree *tree)
7580 {
7581 proto_item *notify_item;
7582 proto_tree *notify_tree;
7583 guint share_access;
7584 guint want_flags;
7585 guint want_notify_flags;
7586
7587 want_notify_flags = tvb_get_ntohl(tvb, offset);
7588 share_access = want_notify_flags & 0x3;
7589 want_flags = want_notify_flags & 0xff00;
7590 want_notify_flags &= 0x130000;
7591 proto_tree_add_uint(tree, hf_nfs4_open_share_access, tvb, offset, 4, share_access);
7592 if (want_flags)
7593 proto_tree_add_uint(tree, hf_nfs4_want_flags, tvb, offset, 4, want_flags);
7594 if (want_notify_flags) {
7595 notify_item = proto_tree_add_uint(tree, hf_nfs4_want_notify_flags, tvb, offset, 4, want_notify_flags);
7596
7597 notify_tree = proto_item_add_subtree(notify_item, ett_nfs4_want_notify_flags);
7598 proto_tree_add_item(notify_tree, hf_nfs4_want_signal_deleg_when_resrc_avail, tvb, offset, 4, ENC_BIG_ENDIAN);
7599 proto_tree_add_item(notify_tree, hf_nfs4_want_push_deleg_when_uncontended, tvb, offset, 4, ENC_BIG_ENDIAN);
7600 }
7601 offset += 4;
7602
7603 return offset;
7604 }
7605
7606 static const value_string names_open4_share_deny[] = {
7607 #define OPEN4_SHARE_DENY_NONE 0x00000000
7608 { OPEN4_SHARE_DENY_NONE, "OPEN4_SHARE_DENY_NONE" },
7609 #define OPEN4_SHARE_DENY_READ 0x00000001
7610 { OPEN4_SHARE_DENY_READ, "OPEN4_SHARE_DENY_READ" },
7611 #define OPEN4_SHARE_DENY_WRITE 0x00000002
7612 { OPEN4_SHARE_DENY_WRITE, "OPEN4_SHARE_DENY_WRITE" },
7613 #define OPEN4_SHARE_DENY_BOTH 0x00000003
7614 { OPEN4_SHARE_DENY_BOTH, "OPEN4_SHARE_DENY_BOTH" },
7615 { 0, NULL }
7616 };
7617
7618
7619 static int
dissect_nfs4_open_share_deny(tvbuff_t * tvb,int offset,proto_tree * tree)7620 dissect_nfs4_open_share_deny(tvbuff_t *tvb, int offset, proto_tree *tree)
7621 {
7622 proto_tree_add_item(tree, hf_nfs4_open_share_deny, tvb, offset, 4, ENC_BIG_ENDIAN);
7623 offset += 4;
7624
7625 return offset;
7626 }
7627
7628
7629 static int
dissect_nfs4_open_owner(tvbuff_t * tvb,int offset,proto_tree * tree)7630 dissect_nfs4_open_owner(tvbuff_t *tvb, int offset, proto_tree *tree)
7631 {
7632 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_clientid, offset);
7633 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_open_owner);
7634
7635 return offset;
7636 }
7637
7638
7639 static int
dissect_nfs4_open_claim_delegate_cur(tvbuff_t * tvb,int offset,proto_tree * tree)7640 dissect_nfs4_open_claim_delegate_cur(tvbuff_t *tvb, int offset,
7641 proto_tree *tree)
7642 {
7643 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
7644 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_component, NULL);
7645
7646 return offset;
7647 }
7648
7649 #define CLAIM_NULL 0
7650 #define CLAIM_PREVIOUS 1
7651 #define CLAIM_DELEGATE_CUR 2
7652 #define CLAIM_DELEGATE_PREV 3
7653 #define CLAIM_FH 4
7654 #define CLAIM_DELEG_CUR_FH 5
7655 #define CLAIM_DELEG_CUR_PREV_FH 6
7656
7657 static const value_string names_claim_type4[] = {
7658 { CLAIM_NULL, "CLAIM_NULL" },
7659 { CLAIM_PREVIOUS, "CLAIM_PREVIOUS" },
7660 { CLAIM_DELEGATE_CUR, "CLAIM_DELEGATE_CUR" },
7661 { CLAIM_DELEGATE_PREV, "CLAIM_DELEGATE_PREV" },
7662 { CLAIM_FH, "CLAIM_FH" },
7663 { CLAIM_DELEG_CUR_FH, "CLAIM_DELEG_CUR_FH"},
7664 { CLAIM_DELEG_CUR_PREV_FH, "CLAIN_DELEG_CUR_PREV_FH"},
7665 { 0, NULL }
7666 };
7667
7668 /* XXX - need a better place to populate name than here, maybe? */
7669 static int
dissect_nfs4_open_claim(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,const char ** name,rpc_call_info_value * civ)7670 dissect_nfs4_open_claim(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
7671 proto_tree *tree, const char **name, rpc_call_info_value *civ)
7672 {
7673 guint open_claim_type4;
7674 proto_item *fitem;
7675 proto_tree *newftree = NULL;
7676 guint32 name_offset, name_len;
7677
7678 open_claim_type4 = tvb_get_ntohl(tvb, offset);
7679 fitem = proto_tree_add_uint(tree, hf_nfs4_open_claim_type, tvb,
7680 offset+0, 4, open_claim_type4);
7681 offset += 4;
7682
7683 if (open_claim_type4 == CLAIM_NULL) {
7684 dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, name);
7685 if (nfs_file_name_snooping) {
7686
7687 name_offset = offset+4;
7688 name_len = tvb_get_ntohl(tvb, offset);
7689
7690 nfs_name_snoop_add_name(civ->xid, tvb,
7691 name_offset, name_len, 0, 0, NULL);
7692 }
7693 }
7694
7695 newftree = proto_item_add_subtree(fitem, ett_nfs4_open_claim);
7696
7697 switch (open_claim_type4)
7698 {
7699 case CLAIM_NULL:
7700 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, name);
7701 break;
7702
7703 case CLAIM_PREVIOUS:
7704 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_delegate_type, offset);
7705 break;
7706
7707 case CLAIM_DELEGATE_CUR:
7708 offset = dissect_nfs4_open_claim_delegate_cur(tvb, offset, newftree);
7709 break;
7710
7711 case CLAIM_DELEGATE_PREV:
7712 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, NULL);
7713 break;
7714
7715 default:
7716 break;
7717 }
7718
7719 return offset;
7720 }
7721
7722 static const value_string names_createmode4[] = {
7723 { UNCHECKED4, "UNCHECKED4" },
7724 { GUARDED4, "GUARDED4" },
7725 { EXCLUSIVE4, "EXCLUSIVE4" },
7726 { EXCLUSIVE4_1, "EXCLUSIVE4_1" },
7727 { 0, NULL }
7728 };
7729
7730
7731 static int
dissect_nfs4_createhow(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)7732 dissect_nfs4_createhow(tvbuff_t *tvb, int offset, packet_info *pinfo,
7733 proto_tree *tree, rpc_call_info_value *civ)
7734 {
7735 guint mode;
7736
7737 mode = tvb_get_ntohl(tvb, offset);
7738 proto_tree_add_uint(tree, hf_nfs4_createmode, tvb, offset, 4, mode);
7739 offset += 4;
7740
7741 switch (mode)
7742 {
7743 case UNCHECKED4:
7744 case GUARDED4:
7745 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, tree, FATTR4_DISSECT_VALUES, civ);
7746 break;
7747
7748 case EXCLUSIVE4:
7749 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
7750 break;
7751
7752 case EXCLUSIVE4_1:
7753 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
7754 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, tree, FATTR4_DISSECT_VALUES, civ);
7755 break;
7756
7757 default:
7758 break;
7759 }
7760
7761 return offset;
7762 }
7763
7764
7765 #define OPEN4_NOCREATE 0
7766 #define OPEN4_CREATE 1
7767 static const value_string names_opentype4[] = {
7768 { OPEN4_NOCREATE, "OPEN4_NOCREATE" },
7769 { OPEN4_CREATE, "OPEN4_CREATE" },
7770 { 0, NULL }
7771 };
7772
7773 static int
dissect_nfs4_openflag(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)7774 dissect_nfs4_openflag(tvbuff_t *tvb, int offset, packet_info *pinfo,
7775 proto_tree *tree, rpc_call_info_value *civ)
7776 {
7777 guint opentype4;
7778 proto_item *fitem;
7779 proto_tree *newftree;
7780
7781 opentype4 = tvb_get_ntohl(tvb, offset);
7782 fitem = proto_tree_add_uint(tree, hf_nfs4_opentype, tvb,
7783 offset+0, 4, opentype4);
7784 offset += 4;
7785
7786 newftree = proto_item_add_subtree(fitem, ett_nfs4_opentype);
7787
7788 switch (opentype4)
7789 {
7790 case OPEN4_CREATE:
7791 offset = dissect_nfs4_createhow(tvb, offset, pinfo, newftree, civ);
7792 break;
7793
7794 default:
7795 break;
7796 }
7797
7798 return offset;
7799 }
7800
7801
7802 static int
dissect_nfs4_clientaddr(tvbuff_t * tvb,int offset,proto_tree * tree)7803 dissect_nfs4_clientaddr(tvbuff_t *tvb, int offset, proto_tree *tree)
7804 {
7805 const char *universal_ip_address = NULL;
7806 const char *protocol = NULL;
7807 guint b1, b2, b3, b4, b5, b6, b7, b8, b9, b10;
7808 guint16 port;
7809 int addr_offset;
7810 guint32 ipv4;
7811 ws_in6_addr ipv6;
7812 address addr;
7813 proto_item* ti;
7814
7815 offset = dissect_rpc_string(tvb, tree, hf_nfs4_r_netid, offset, &protocol);
7816 addr_offset = offset;
7817 offset = dissect_rpc_string(tvb, tree, hf_nfs4_r_addr, offset, &universal_ip_address);
7818
7819 if (strlen(protocol) == 3 && strncmp(protocol, "tcp", 3) == 0) {
7820 if (universal_ip_address && sscanf(universal_ip_address, "%u.%u.%u.%u.%u.%u",
7821 &b1, &b2, &b3, &b4, &b5, &b6) == 6) {
7822 /* IPv4: h1.h2.h3.h4.p1.p2 */
7823 port = (b5<<8) | b6;
7824 ipv4 = g_htonl((b1<<24) | (b2<<16) | (b3<<8) | b4);
7825 set_address(&addr, AT_IPv4, 4, &ipv4);
7826 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",
7827 address_to_str(wmem_packet_scope(), &addr), protocol, port);
7828 proto_item_set_generated(ti);
7829 } else if (universal_ip_address && sscanf(universal_ip_address, "%u.%u",
7830 &b1, &b2) == 2) {
7831 /* Some clients (linux) sometimes send only the port. */
7832 port = (b1<<8) | b2;
7833 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);
7834 proto_item_set_generated(ti);
7835 } else if (universal_ip_address && sscanf(universal_ip_address,
7836 "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x.%u.%u",
7837 &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &b9, &b10) == 10) {
7838 port = (b9<<8) | b10;
7839 memset(&ipv6, 0, sizeof(ipv6));
7840 ipv6.bytes[0] = b1; ipv6.bytes[1] = b2; ipv6.bytes[2] = b3; ipv6.bytes[3] = b4;
7841 ipv6.bytes[4] = b5; ipv6.bytes[5] = b6; ipv6.bytes[6] = b7; ipv6.bytes[7] = b8;
7842 set_address(&addr, AT_IPv6, 16, &ipv6);
7843 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",
7844 address_to_str(wmem_packet_scope(), &addr), protocol, port);
7845 proto_item_set_generated(ti);
7846 } else {
7847 ti = proto_tree_add_ipv4_format(tree, hf_nfs4_universal_address_ipv4, tvb, addr_offset, offset-addr_offset, 0, "Invalid address");
7848 proto_item_set_generated(ti);
7849 }
7850 }
7851 return offset;
7852 }
7853
7854
7855 static int
dissect_nfs4_cb_client4(tvbuff_t * tvb,int offset,proto_tree * tree)7856 dissect_nfs4_cb_client4(tvbuff_t *tvb, int offset, proto_tree *tree)
7857 {
7858 proto_tree *cb_location;
7859 proto_item *fitem;
7860 int old_offset;
7861
7862 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_cb_program, offset);
7863 old_offset = offset;
7864 cb_location = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "cb_location");
7865
7866 offset = dissect_nfs4_clientaddr(tvb, offset, cb_location);
7867 proto_item_set_len(fitem, offset - old_offset);
7868
7869 return offset;
7870 }
7871
7872
7873 static const value_string names_stable_how4[] = {
7874 #define UNSTABLE4 0
7875 { UNSTABLE4, "UNSTABLE4" },
7876 #define DATA_SYNC4 1
7877 { DATA_SYNC4, "DATA_SYNC4" },
7878 #define FILE_SYNC4 2
7879 { FILE_SYNC4, "FILE_SYNC4" },
7880 { 0, NULL }
7881 };
7882
7883 static int
dissect_nfs4_stable_how(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)7884 dissect_nfs4_stable_how(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
7885 {
7886 guint stable_how4;
7887
7888 stable_how4 = tvb_get_ntohl(tvb, offset);
7889 proto_tree_add_uint_format(tree, hf_nfs4_stable_how, tvb,
7890 offset+0, 4, stable_how4, "%s: %s (%u)", name,
7891 val_to_str(stable_how4, names_stable_how4, "%u"), stable_how4);
7892 offset += 4;
7893
7894 return offset;
7895 }
7896
7897 static const value_string names_data_content[] = {
7898 { 0, "DATA" },
7899 { 1, "HOLE" },
7900 { 0, NULL }
7901 };
7902
7903 static const value_string names_setxattr_options[] = {
7904 { 0, "EITHER" },
7905 { 1, "CREATE" },
7906 { 2, "REPLACE" },
7907 { 0, NULL }
7908 };
7909
7910 static int
dissect_nfs4_listxattr_names(tvbuff_t * tvb,int offset,proto_tree * tree)7911 dissect_nfs4_listxattr_names(tvbuff_t *tvb, int offset, proto_tree *tree)
7912 {
7913 guint32 comp_count, i;
7914 proto_item *fitem;
7915 proto_tree *newftree;
7916
7917 fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_listxattr_names_len, tvb, offset, 4, ENC_BIG_ENDIAN, &comp_count);
7918 offset += 4;
7919
7920 newftree = proto_item_add_subtree(fitem, ett_nfs4_listxattr_names);
7921
7922 for (i = 0; i < comp_count; i++)
7923 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_xattrkey, NULL);
7924 return offset;
7925 }
7926
7927 /* NFSv4 Operations */
7928 static const value_string names_nfs4_operation[] = {
7929 { NFS4_OP_ACCESS, "ACCESS" },
7930 { NFS4_OP_CLOSE, "CLOSE" },
7931 { NFS4_OP_COMMIT, "COMMIT" },
7932 { NFS4_OP_CREATE, "CREATE" },
7933 { NFS4_OP_DELEGPURGE, "DELEGPURGE" },
7934 { NFS4_OP_DELEGRETURN, "DELEGRETURN" },
7935 { NFS4_OP_GETATTR, "GETATTR" },
7936 { NFS4_OP_GETFH, "GETFH" },
7937 { NFS4_OP_LINK, "LINK" },
7938 { NFS4_OP_LOCK, "LOCK" },
7939 { NFS4_OP_LOCKT, "LOCKT" },
7940 { NFS4_OP_LOCKU, "LOCKU" },
7941 { NFS4_OP_LOOKUP, "LOOKUP" },
7942 { NFS4_OP_LOOKUPP, "LOOKUPP" },
7943 { NFS4_OP_NVERIFY, "NVERIFY" },
7944 { NFS4_OP_OPEN, "OPEN" },
7945 { NFS4_OP_OPENATTR, "OPENATTR" },
7946 { NFS4_OP_OPEN_CONFIRM, "OPEN_CONFIRM" },
7947 { NFS4_OP_OPEN_DOWNGRADE, "OPEN_DOWNGRADE" },
7948 { NFS4_OP_PUTFH, "PUTFH" },
7949 { NFS4_OP_PUTPUBFH, "PUTPUBFH" },
7950 { NFS4_OP_PUTROOTFH, "PUTROOTFH" },
7951 { NFS4_OP_READ, "READ" },
7952 { NFS4_OP_READDIR, "READDIR" },
7953 { NFS4_OP_READLINK, "READLINK" },
7954 { NFS4_OP_REMOVE, "REMOVE" },
7955 { NFS4_OP_RENAME, "RENAME" },
7956 { NFS4_OP_RENEW, "RENEW" },
7957 { NFS4_OP_RESTOREFH, "RESTOREFH" },
7958 { NFS4_OP_SAVEFH, "SAVEFH" },
7959 { NFS4_OP_SECINFO, "SECINFO" },
7960 { NFS4_OP_SETATTR, "SETATTR" },
7961 { NFS4_OP_SETCLIENTID, "SETCLIENTID" },
7962 { NFS4_OP_SETCLIENTID_CONFIRM, "SETCLIENTID_CONFIRM" },
7963 { NFS4_OP_VERIFY, "VERIFY" },
7964 { NFS4_OP_WRITE, "WRITE" },
7965 { NFS4_OP_RELEASE_LOCKOWNER, "RELEASE_LOCKOWNER" },
7966 { NFS4_OP_BACKCHANNEL_CTL, "BACKCHANNEL_CTL" },
7967 { NFS4_OP_BIND_CONN_TO_SESSION, "BIND_CONN_TO_SESSION" },
7968 { NFS4_OP_EXCHANGE_ID, "EXCHANGE_ID" },
7969 { NFS4_OP_CREATE_SESSION, "CREATE_SESSION" },
7970 { NFS4_OP_DESTROY_SESSION, "DESTROY_SESSION" },
7971 { NFS4_OP_FREE_STATEID, "FREE_STATEID" },
7972 { NFS4_OP_GET_DIR_DELEGATION, "GET_DIR_DELEGATION" },
7973 { NFS4_OP_GETDEVINFO, "GETDEVINFO" },
7974 { NFS4_OP_GETDEVLIST, "GETDEVLIST" },
7975 { NFS4_OP_LAYOUTCOMMIT, "LAYOUTCOMMIT" },
7976 { NFS4_OP_LAYOUTGET, "LAYOUTGET" },
7977 { NFS4_OP_LAYOUTRETURN, "LAYOUTRETURN" },
7978 { NFS4_OP_SECINFO_NO_NAME, "SECINFO_NO_NAME" },
7979 { NFS4_OP_SEQUENCE, "SEQUENCE" },
7980 { NFS4_OP_SET_SSV, "SET_SSV" },
7981 { NFS4_OP_TEST_STATEID, "TEST_STATEID" },
7982 { NFS4_OP_WANT_DELEGATION, "WANT_DELEG" },
7983 { NFS4_OP_DESTROY_CLIENTID, "DESTROY_CLIENTID" },
7984 { NFS4_OP_RECLAIM_COMPLETE, "RECLAIM_COMPLETE" },
7985 { NFS4_OP_ALLOCATE, "ALLOCATE" },
7986 { NFS4_OP_COPY, "COPY" },
7987 { NFS4_OP_COPY_NOTIFY, "COPY_NOTIFY" },
7988 { NFS4_OP_DEALLOCATE, "DEALLOCATE" },
7989 { NFS4_OP_IO_ADVISE, "IO_ADVISE" },
7990 { NFS4_OP_LAYOUTERROR, "LAYOUTERROR" },
7991 { NFS4_OP_LAYOUTSTATS, "LAYOUTSTATS" },
7992 { NFS4_OP_OFFLOAD_CANCEL, "OFFLOAD_CANCEL" },
7993 { NFS4_OP_OFFLOAD_STATUS, "OFFLOAD_STATUS" },
7994 { NFS4_OP_READ_PLUS, "READ_PLUS" },
7995 { NFS4_OP_SEEK, "SEEK" },
7996 { NFS4_OP_WRITE_SAME, "WRITE_SAME" },
7997 { NFS4_OP_CLONE, "CLONE" },
7998 { NFS4_OP_GETXATTR, "GETXATTR" },
7999 { NFS4_OP_SETXATTR, "SETXATTR" },
8000 { NFS4_OP_LISTXATTRS, "LISTXATTRS" },
8001 { NFS4_OP_REMOVEXATTR, "REMOVEXATTR" },
8002 { NFS4_OP_ILLEGAL, "ILLEGAL" },
8003 { 0, NULL }
8004 };
8005
8006 static value_string_ext names_nfs4_operation_ext = VALUE_STRING_EXT_INIT(names_nfs4_operation);
8007
8008 /* Each subtree number in this array corresponds to the associated item in the above
8009 * 'names_nfs4_operation array[]' array. */
8010 static gint *nfs4_operation_ett[] =
8011 {
8012 &ett_nfs4_access ,
8013 &ett_nfs4_close ,
8014 &ett_nfs4_commit ,
8015 &ett_nfs4_create ,
8016 &ett_nfs4_delegpurge ,
8017 &ett_nfs4_delegreturn ,
8018 &ett_nfs4_getattr ,
8019 &ett_nfs4_getfh ,
8020 &ett_nfs4_link ,
8021 &ett_nfs4_lock ,
8022 &ett_nfs4_lockt ,
8023 &ett_nfs4_locku ,
8024 &ett_nfs4_lookup ,
8025 &ett_nfs4_lookupp ,
8026 &ett_nfs4_nverify ,
8027 &ett_nfs4_open ,
8028 &ett_nfs4_openattr ,
8029 &ett_nfs4_open_confirm ,
8030 &ett_nfs4_open_downgrade ,
8031 &ett_nfs4_putfh ,
8032 &ett_nfs4_putpubfh ,
8033 &ett_nfs4_putrootfh ,
8034 &ett_nfs4_read ,
8035 &ett_nfs4_readdir ,
8036 &ett_nfs4_readlink ,
8037 &ett_nfs4_remove ,
8038 &ett_nfs4_rename ,
8039 &ett_nfs4_renew ,
8040 &ett_nfs4_restorefh ,
8041 &ett_nfs4_savefh ,
8042 &ett_nfs4_secinfo ,
8043 &ett_nfs4_setattr ,
8044 &ett_nfs4_setclientid ,
8045 &ett_nfs4_setclientid_confirm ,
8046 &ett_nfs4_verify ,
8047 &ett_nfs4_write,
8048 &ett_nfs4_release_lockowner,
8049 &ett_nfs4_backchannel_ctl,
8050 &ett_nfs4_bind_conn_to_session,
8051 &ett_nfs4_exchange_id,
8052 &ett_nfs4_create_session,
8053 &ett_nfs4_destroy_session,
8054 &ett_nfs4_free_stateid,
8055 NULL, /* get dir delegation */
8056 &ett_nfs4_getdevinfo,
8057 &ett_nfs4_getdevlist,
8058 &ett_nfs4_layoutcommit,
8059 &ett_nfs4_layoutget,
8060 &ett_nfs4_layoutreturn,
8061 &ett_nfs4_secinfo_no_name,
8062 &ett_nfs4_sequence,
8063 NULL, /* set ssv */
8064 &ett_nfs4_test_stateid,
8065 NULL, /* want delegation */
8066 &ett_nfs4_destroy_clientid,
8067 &ett_nfs4_reclaim_complete,
8068 &ett_nfs4_allocate,
8069 &ett_nfs4_copy,
8070 &ett_nfs4_copy_notify,
8071 &ett_nfs4_deallocate,
8072 &ett_nfs4_io_advise,
8073 &ett_nfs4_layouterror,
8074 &ett_nfs4_layoutstats,
8075 &ett_nfs4_offload_cancel,
8076 &ett_nfs4_offload_status,
8077 &ett_nfs4_read_plus,
8078 &ett_nfs4_seek,
8079 &ett_nfs4_write_same,
8080 &ett_nfs4_clone,
8081 &ett_nfs4_getxattr,
8082 &ett_nfs4_setxattr,
8083 &ett_nfs4_listxattr,
8084 &ett_nfs4_removexattr,
8085 };
8086
8087
8088 static int
dissect_nfs4_dirlist(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)8089 dissect_nfs4_dirlist(tvbuff_t *tvb, int offset, packet_info *pinfo,
8090 proto_tree *tree, rpc_call_info_value *civ)
8091 {
8092 guint32 val_follows;
8093 guint32 name_len;
8094 char *name;
8095 proto_tree *dirlist_tree;
8096 proto_item *eitem;
8097 proto_tree *entry_tree;
8098
8099 dirlist_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_dirlist, NULL, "Directory Listing");
8100
8101 while (1)
8102 {
8103 val_follows = tvb_get_ntohl(tvb, offset);
8104 if (val_follows) {
8105 int start_off = offset;
8106
8107 /* Make sure we have 16 bytes (value follows + cookie + name length) */
8108 name_len = tvb_get_ntohl(tvb, offset + 12);
8109 tvb_ensure_bytes_exist(tvb, offset, 16 + name_len);
8110 /*
8111 * Get the entry name and create subtree of field nfs.name
8112 */
8113 name = (char *)tvb_memcpy(tvb, wmem_alloc(wmem_packet_scope(), name_len+1), offset + 16, name_len);
8114 name[name_len] = '\0';
8115
8116 eitem = proto_tree_add_string_format(
8117 dirlist_tree, hf_nfs_name, tvb, offset, -1, name, "Entry: %s", name);
8118 entry_tree = proto_item_add_subtree(eitem, ett_nfs4_dir_entry);
8119
8120 /* Value Follows: <Yes|No> */
8121 proto_tree_add_boolean(entry_tree, hf_nfs4_value_follows, tvb, offset, 4, val_follows);
8122 offset += 4;
8123
8124 /* Directory entry cookie */
8125 if (entry_tree)
8126 dissect_rpc_uint64(tvb, entry_tree, hf_nfs4_cookie, offset);
8127 offset += 8;
8128
8129 /* Directory entry name (nfs.entry_name) */
8130 offset = dissect_nfs_utf8string(tvb, offset, entry_tree, hf_nfs4_dir_entry_name, NULL);
8131
8132 /* Attrmask(s) */
8133 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, entry_tree, FATTR4_DISSECT_VALUES, civ);
8134 proto_item_set_len(eitem, offset - start_off);
8135 } else {
8136 break;
8137 }
8138 }
8139 if (dirlist_tree) {
8140 proto_tree_add_boolean(dirlist_tree, hf_nfs4_value_follows, tvb, offset, 4, val_follows);
8141 offset += 4;
8142 /* The last entry in this packet has been reached but do more follow? */
8143 offset = dissect_rpc_bool(tvb, dirlist_tree, hf_nfs4_dirlist_eof, offset);
8144 } else {
8145 offset += 8;
8146 }
8147 return offset;
8148 }
8149
8150 static int
dissect_nfs4_change_info(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)8151 dissect_nfs4_change_info(tvbuff_t *tvb, int offset,
8152 proto_tree *tree, const char *name)
8153 {
8154 proto_tree *newftree;
8155 proto_tree *fitem;
8156 int old_offset = offset;
8157
8158 newftree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_change_info, &fitem, name);
8159
8160 offset = dissect_rpc_bool( tvb, newftree, hf_nfs4_change_info_atomic, offset);
8161 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_changeid_before, offset);
8162 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_changeid_after, offset);
8163 proto_item_set_len(fitem, offset - old_offset);
8164
8165 return offset;
8166 }
8167
8168
8169 static const value_string names_nfs_lock_type4[] =
8170 {
8171 #define READ_LT 1
8172 { READ_LT, "READ_LT" },
8173 #define WRITE_LT 2
8174 { WRITE_LT, "WRITE_LT" },
8175 #define READW_LT 3
8176 { READW_LT, "READW_LT" },
8177 #define WRITEW_LT 4
8178 { WRITEW_LT, "WRITEW_LT" },
8179 #define RELEASE_STATE 5
8180 { RELEASE_STATE, "RELEASE_STATE" },
8181 { 0, NULL }
8182 };
8183
8184 static int
dissect_nfs4_lockdenied(tvbuff_t * tvb,int offset,proto_tree * tree)8185 dissect_nfs4_lockdenied(tvbuff_t *tvb, int offset, proto_tree *tree)
8186 {
8187 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8188 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
8189 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_lock_type, offset);
8190 offset = dissect_nfs4_lock_owner(tvb, offset, tree);
8191 return offset;
8192 }
8193
8194
8195 #define OPEN4_RESULT_CONFIRM 0x00000002
8196 #define OPEN4_RESULT_LOCKTYPE_POSIX 0x00000004
8197 #define OPEN4_RESULT_PRESERVE_UNLINKED 0x00000008
8198 #define OPEN4_RESULT_MAY_NOTIFY_LOCK 0x00000020
8199
8200 static int * const open4_result_flag_fields[] = {
8201 &hf_nfs4_open_rflags_confirm,
8202 &hf_nfs4_open_rflags_locktype_posix,
8203 &hf_nfs4_open_rflags_preserve_unlinked,
8204 &hf_nfs4_open_rflags_may_notify_lock,
8205 NULL
8206 };
8207
8208 static int
dissect_nfs4_open_rflags(tvbuff_t * tvb,int offset,proto_tree * tree)8209 dissect_nfs4_open_rflags(tvbuff_t *tvb, int offset, proto_tree *tree)
8210 {
8211 proto_tree_add_bitmask(tree, tvb, offset, hf_nfs4_open_rflags,
8212 ett_nfs4_open_result_flags, open4_result_flag_fields, ENC_BIG_ENDIAN);
8213 offset += 4;
8214
8215 return offset;
8216 }
8217
8218
8219 static int
dissect_nfs4_stateid(tvbuff_t * tvb,int offset,proto_tree * tree,guint16 * hash)8220 dissect_nfs4_stateid(tvbuff_t *tvb, int offset, proto_tree *tree, guint16 *hash)
8221 {
8222 guint16 stateid_hash;
8223 guint32 other_hash;
8224 proto_item *sitem, *hitem, *oth_item;
8225 proto_tree *stateid_tree;
8226 int old_offset = offset;
8227
8228 sitem = proto_tree_add_bytes_format(tree, hf_nfs4_stateid, tvb, offset, 16, NULL, "StateID");
8229 stateid_tree = proto_item_add_subtree(sitem, ett_nfs4_stateid);
8230
8231 stateid_hash = crc16_ccitt_tvb_offset(tvb, offset, 16);
8232 hitem = proto_tree_add_uint(stateid_tree, hf_nfs4_stateid_hash, tvb, offset, 16, stateid_hash);
8233 proto_item_set_generated(hitem);
8234
8235 offset = dissect_rpc_uint32(tvb, sitem, hf_nfs4_seqid_stateid, offset);
8236
8237 proto_tree_add_item(stateid_tree, hf_nfs4_stateid_other, tvb, offset, 12, ENC_NA);
8238
8239 other_hash = crc32_ccitt_tvb_offset(tvb, offset, 12);
8240 oth_item = proto_tree_add_uint(stateid_tree, hf_nfs4_stateid_other_hash, tvb, offset, 12, other_hash);
8241 proto_item_set_generated(oth_item);
8242 offset+=12;
8243
8244 if (hash)
8245 *hash = stateid_hash;
8246
8247 proto_item_set_len(sitem, offset - old_offset);
8248
8249 return offset;
8250 }
8251
8252
8253 static int
dissect_nfs4_open_read_delegation(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8254 dissect_nfs4_open_read_delegation(tvbuff_t *tvb, int offset,
8255 packet_info *pinfo, proto_tree *tree)
8256 {
8257 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8258 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_recall4, offset);
8259 offset = dissect_nfs4_ace(tvb, offset, pinfo, tree, 0, 0);
8260
8261 return offset;
8262 }
8263
8264
8265 static int
dissect_nfs4_modified_limit(tvbuff_t * tvb,int offset,proto_tree * tree)8266 dissect_nfs4_modified_limit(tvbuff_t *tvb, int offset, proto_tree *tree)
8267 {
8268 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_num_blocks, offset);
8269 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_bytes_per_block, offset);
8270
8271 return offset;
8272 }
8273
8274
8275 static int
dissect_nfs4_state_protect_bitmap(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,const char * name)8276 dissect_nfs4_state_protect_bitmap(tvbuff_t *tvb, int offset, packet_info *pinfo,
8277 proto_tree *tree, const char *name)
8278 {
8279 static nfs4_bitmap_info_t bitmap_info = {
8280 .vse_names_ext = &names_nfs4_operation_ext,
8281 .hf_mask_label = &hf_nfs4_op_mask,
8282 .hf_item_label = &hf_nfs4_op
8283 };
8284
8285 return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, &bitmap_info, NFS4_BITMAP_MASK, name);
8286 }
8287
8288 #define SP4_NONE 0
8289 #define SP4_MACH_CRED 1
8290 #define SP4_SSV 2
8291 static const value_string names_state_protect_how4[] = {
8292 { SP4_NONE, "SP4_NONE" },
8293 { SP4_MACH_CRED, "SP4_MACH_CRED" },
8294 { SP4_SSV, "SP4_SSV" },
8295 { 0, NULL }
8296 };
8297
8298 static int
dissect_nfs4_state_protect_ops(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8299 dissect_nfs4_state_protect_ops(tvbuff_t *tvb, int offset,
8300 packet_info *pinfo, proto_tree *tree)
8301 {
8302 offset = dissect_nfs4_state_protect_bitmap(tvb, offset, pinfo, tree, "spo_must_enforce");
8303 offset = dissect_nfs4_state_protect_bitmap(tvb, offset, pinfo, tree, "spo_must_allow");
8304 return offset;
8305 }
8306
8307
8308 static int
dissect_nfs4_sec_oid(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,void * data _U_)8309 dissect_nfs4_sec_oid(tvbuff_t *tvb, int offset, packet_info *pinfo,
8310 proto_tree *tree, void *data _U_)
8311 {
8312 return dissect_rpc_opaque_data(tvb, offset, tree, pinfo,
8313 hf_nfs4_sec_oid, FALSE, 0, FALSE, NULL, NULL);
8314 }
8315
8316 static int
dissect_nfs4_ssv_sp_parms(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8317 dissect_nfs4_ssv_sp_parms(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
8318 {
8319 offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8320 offset = dissect_rpc_array(tvb, pinfo, tree, offset, dissect_nfs4_sec_oid, hf_nfs4_sp_parms_hash_algs);
8321 offset = dissect_rpc_array(tvb, pinfo, tree, offset, dissect_nfs4_sec_oid, hf_nfs4_sp_parms_encr_algs);
8322 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_state_protect_window, offset);
8323 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_state_protect_num_gss_handles, offset);
8324 return offset;
8325 }
8326
8327
8328 static int
dissect_nfs4_ssv_prot_info(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8329 dissect_nfs4_ssv_prot_info(tvbuff_t *tvb, int offset,
8330 packet_info *pinfo, proto_tree *tree)
8331 {
8332 offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8333 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_hash_alg, offset);
8334 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_encr_alg, offset);
8335 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_svv_length, offset);
8336 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_prot_info_spi_window, offset);
8337 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_gsshandle);
8338 return offset;
8339 }
8340
8341
8342 static int
dissect_nfs4_state_protect_a(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8343 dissect_nfs4_state_protect_a(tvbuff_t *tvb, int offset,
8344 packet_info *pinfo, proto_tree *tree)
8345 {
8346 guint stateprotect;
8347
8348 proto_tree_add_item_ret_uint(tree, hf_nfs4_state_protect_how, tvb, offset+0, 4, ENC_BIG_ENDIAN, &stateprotect);
8349 offset += 4;
8350
8351 switch (stateprotect) {
8352 case SP4_NONE:
8353 break;
8354 case SP4_MACH_CRED:
8355 offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8356 break;
8357 case SP4_SSV:
8358 offset = dissect_nfs4_ssv_sp_parms(tvb, offset, pinfo, tree);
8359 break;
8360 default:
8361 break;
8362 }
8363 return offset;
8364 }
8365
8366
8367 static int
dissect_nfs4_state_protect_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8368 dissect_nfs4_state_protect_r(tvbuff_t *tvb, int offset,
8369 packet_info *pinfo, proto_tree *tree)
8370 {
8371 guint stateprotect;
8372
8373 proto_tree_add_item_ret_uint(tree, hf_nfs4_state_protect_how, tvb, offset+0, 4,
8374 ENC_BIG_ENDIAN, &stateprotect);
8375 offset += 4;
8376
8377 switch (stateprotect) {
8378 case SP4_NONE:
8379 break;
8380 case SP4_MACH_CRED:
8381 offset = dissect_nfs4_state_protect_ops(tvb, offset, pinfo, tree);
8382 break;
8383 case SP4_SSV:
8384 offset = dissect_nfs4_ssv_prot_info(tvb, offset, pinfo, tree);
8385 break;
8386 default:
8387 break;
8388 }
8389 return offset;
8390 }
8391
8392
8393 #define NFS_LIMIT_SIZE 1
8394 #define NFS_LIMIT_BLOCKS 2
8395 static const value_string names_limit_by4[] = {
8396 { NFS_LIMIT_SIZE, "NFS_LIMIT_SIZE" },
8397 { NFS_LIMIT_BLOCKS, "NFS_LIMIT_BLOCKS" },
8398 { 0, NULL }
8399 };
8400
8401 static int
dissect_nfs4_space_limit(tvbuff_t * tvb,int offset,proto_tree * tree)8402 dissect_nfs4_space_limit(tvbuff_t *tvb, int offset,
8403 proto_tree *tree)
8404 {
8405 guint limitby;
8406
8407 proto_tree_add_item_ret_uint(tree, hf_nfs4_limit_by, tvb, offset+0, 4, ENC_BIG_ENDIAN, &limitby);
8408 offset += 4;
8409
8410 switch (limitby)
8411 {
8412 case NFS_LIMIT_SIZE:
8413 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_filesize,
8414 offset);
8415 break;
8416
8417 case NFS_LIMIT_BLOCKS:
8418 offset = dissect_nfs4_modified_limit(tvb, offset, tree);
8419 break;
8420
8421 default:
8422 break;
8423 }
8424
8425 return offset;
8426 }
8427
8428
8429 static int
dissect_nfs4_open_write_delegation(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8430 dissect_nfs4_open_write_delegation(tvbuff_t *tvb, int offset,
8431 packet_info *pinfo, proto_tree *tree)
8432 {
8433 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8434 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_recall, offset);
8435 offset = dissect_nfs4_space_limit(tvb, offset, tree);
8436 offset = dissect_nfs4_ace(tvb, offset, pinfo, tree, 0, 0);
8437
8438 return offset;
8439 }
8440
8441
8442 #define OPEN_DELEGATE_NONE 0
8443 #define OPEN_DELEGATE_READ 1
8444 #define OPEN_DELEGATE_WRITE 2
8445 #define OPEN_DELEGATE_NONE_EXT 3 /* new to v4.1 */
8446 #define OPEN_DELEGATE_READ_ATTRS_DELEG 4 /* New to V4.2 */
8447 #define OPEN_DELEGATE_WRITE_ATTRS_DELEG 5
8448 static const value_string names_open_delegation_type4[] = {
8449 { OPEN_DELEGATE_NONE, "OPEN_DELEGATE_NONE" },
8450 { OPEN_DELEGATE_READ, "OPEN_DELEGATE_READ" },
8451 { OPEN_DELEGATE_WRITE, "OPEN_DELEGATE_WRITE" },
8452 { OPEN_DELEGATE_NONE_EXT, "OPEN_DELEGATE_NONE_EXT"},
8453 { OPEN_DELEGATE_READ_ATTRS_DELEG, "OPEN_DELEGATE_READ_ATTRS_DELEG"},
8454 { OPEN_DELEGATE_WRITE_ATTRS_DELEG, "OPEN_DELEGATE_WRITE_ATTRS_DELEG"},
8455 { 0, NULL }
8456 };
8457
8458 #define WND4_NOT_WANTED 0
8459 #define WND4_CONTENTION 1
8460 #define WND4_RESOURCE 2
8461 #define WND4_NOT_SUPP_FTYPE 3
8462 #define WND4_WRITE_DELEG_NOT_SUPP_FTYPE 4
8463 #define WND4_NOT_SUPP_UPGRADE 5
8464 #define WND4_NOT_SUPP_DOWNGRADE 6
8465 #define WND4_CANCELLED 7
8466 #define WND4_IS_DIR 8
8467 static const value_string names_why_no_delegation4[] = {
8468 { WND4_NOT_WANTED, "WND4_NOT_WANTED" },
8469 { WND4_CONTENTION, "WND4_CONTENTION" },
8470 { WND4_RESOURCE, "WND4_RESOURCE" },
8471 { WND4_NOT_SUPP_FTYPE, "WND4_NOT_SUPP_FTYPE" },
8472 { WND4_WRITE_DELEG_NOT_SUPP_FTYPE, "WND4_WRITE_DELEG_NOT_SUPP_FTYPE" },
8473 { WND4_NOT_SUPP_UPGRADE, "WND4_NOT_SUPP_UPGRADE" },
8474 { WND4_NOT_SUPP_DOWNGRADE, "WND4_NOT_SUPP_DOWNGRADE" },
8475 { WND4_CANCELLED, "WND4_CANCELLED" },
8476 { WND4_IS_DIR, "WND4_IS_DIR" },
8477 { 0, NULL }
8478 };
8479
8480 static int
dissect_nfs4_open_delegation(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8481 dissect_nfs4_open_delegation(tvbuff_t *tvb, int offset, packet_info *pinfo,
8482 proto_tree *tree)
8483 {
8484 guint delegation_type;
8485 proto_tree *newftree;
8486 proto_item *fitem;
8487
8488 fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_open_delegation_type, tvb,
8489 offset+0, 4, ENC_BIG_ENDIAN, &delegation_type);
8490 newftree = proto_item_add_subtree(fitem, ett_nfs4_open_delegation);
8491 offset += 4;
8492
8493 switch (delegation_type)
8494 {
8495 case OPEN_DELEGATE_NONE:
8496 break;
8497
8498 case OPEN_DELEGATE_READ:
8499 case OPEN_DELEGATE_READ_ATTRS_DELEG:
8500 offset = dissect_nfs4_open_read_delegation(tvb, offset, pinfo, newftree);
8501 break;
8502
8503 case OPEN_DELEGATE_WRITE:
8504 case OPEN_DELEGATE_WRITE_ATTRS_DELEG:
8505 offset = dissect_nfs4_open_write_delegation(tvb, offset, pinfo, newftree);
8506 break;
8507 case OPEN_DELEGATE_NONE_EXT:
8508 proto_tree_add_item(tree, hf_nfs4_why_no_delegation, tvb, offset, 4, ENC_BIG_ENDIAN);
8509 offset += 4;
8510 break;
8511 default:
8512 break;
8513 }
8514
8515 return offset;
8516 }
8517
8518
8519 static int
dissect_nfs_rpcsec_gss_info(tvbuff_t * tvb,int offset,proto_tree * tree)8520 dissect_nfs_rpcsec_gss_info(tvbuff_t *tvb, int offset, proto_tree *tree)
8521 {
8522 offset = dissect_nfs4_sec_oid(tvb, offset, NULL, tree, NULL);
8523 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_qop, offset);
8524 offset = dissect_rpc_uint32(tvb, tree,
8525 hf_nfs4_secinfo_rpcsec_gss_info_service, offset);
8526
8527 return offset;
8528 }
8529
8530
8531 static int
dissect_nfs4_open_to_lock_owner(tvbuff_t * tvb,int offset,proto_tree * tree)8532 dissect_nfs4_open_to_lock_owner(tvbuff_t *tvb, int offset, proto_tree *tree)
8533 {
8534 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_seqid, offset);
8535 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8536 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_lock_seqid, offset);
8537 offset = dissect_nfs4_lock_owner(tvb, offset, tree);
8538
8539 return offset;
8540 }
8541
8542
8543 static int
dissect_nfs4_exist_lock_owner(tvbuff_t * tvb,int offset,proto_tree * tree)8544 dissect_nfs4_exist_lock_owner(tvbuff_t *tvb, int offset, proto_tree *tree)
8545 {
8546 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8547 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_lock_seqid, offset);
8548
8549 return offset;
8550 }
8551
8552
8553 static int
dissect_nfs4_locker(tvbuff_t * tvb,int offset,proto_tree * tree)8554 dissect_nfs4_locker(tvbuff_t *tvb, int offset, proto_tree *tree)
8555 {
8556 guint new_lock_owner;
8557
8558 new_lock_owner = tvb_get_ntohl(tvb, offset);
8559 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_new_lock_owner, offset);
8560
8561 if (new_lock_owner)
8562 offset = dissect_nfs4_open_to_lock_owner(tvb, offset, tree);
8563 else
8564 offset = dissect_nfs4_exist_lock_owner(tvb, offset, tree);
8565
8566 return offset;
8567 }
8568
8569 static const value_string read_plus_content_names[] = {
8570 #define NFS4_CONTENT_DATA 0
8571 { NFS4_CONTENT_DATA, "Data" },
8572 #define NFS4_CONTENT_HOLE 1
8573 { NFS4_CONTENT_HOLE, "Hole" },
8574 { 0, NULL }
8575 };
8576 static value_string_ext read_plus_content_names_ext = VALUE_STRING_EXT_INIT(read_plus_content_names);
8577
8578 static int
dissect_nfs4_read_plus_content(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)8579 dissect_nfs4_read_plus_content(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
8580 {
8581 proto_tree *ss_tree;
8582 proto_item *ss_fitem;
8583 guint type;
8584
8585 ss_fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_read_plus_content_type,
8586 tvb, offset, 4, ENC_BIG_ENDIAN, &type);
8587 ss_tree = proto_item_add_subtree(ss_fitem, ett_nfs4_read_plus_content_sub);
8588 offset += 4;
8589
8590 switch (type) {
8591 case NFS4_CONTENT_DATA:
8592 offset = dissect_rpc_uint64(tvb, ss_tree, hf_nfs4_offset, offset);
8593 dissect_rpc_uint32(tvb, ss_tree, hf_nfs4_read_data_length, offset); /* don't change offset */
8594 offset = dissect_nfsdata(tvb, offset, ss_tree, hf_nfs_data);
8595 break;
8596 case NFS4_CONTENT_HOLE:
8597 offset = dissect_rpc_uint64(tvb, ss_tree, hf_nfs4_offset, offset);
8598 offset = dissect_rpc_uint64(tvb, ss_tree, hf_nfs4_length, offset);
8599 break;
8600 default:
8601 break;
8602 }
8603
8604 return offset;
8605 }
8606
8607 static int
dissect_nfs4_client_id(tvbuff_t * tvb,int offset,proto_tree * tree)8608 dissect_nfs4_client_id(tvbuff_t *tvb, int offset, proto_tree *tree)
8609 {
8610 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
8611 offset = dissect_rpc_data(tvb, tree, hf_nfs4_client_id, offset);
8612
8613 return offset;
8614 }
8615
8616
8617 static int
dissect_nfs4_newtime(tvbuff_t * tvb,int offset,proto_tree * tree)8618 dissect_nfs4_newtime(tvbuff_t *tvb, int offset, proto_tree *tree)
8619 {
8620 guint new_time;
8621
8622 new_time = tvb_get_ntohl(tvb, offset);
8623 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_newtime, offset);
8624
8625 if (new_time) {
8626 offset = dissect_nfs4_nfstime(tvb, offset, tree);
8627 }
8628
8629 return offset;
8630 }
8631
8632
8633 static int
dissect_nfs4_newsize(tvbuff_t * tvb,int offset,proto_tree * tree)8634 dissect_nfs4_newsize(tvbuff_t *tvb, int offset, proto_tree *tree)
8635 {
8636 guint new_size;
8637
8638 new_size = tvb_get_ntohl(tvb, offset);
8639 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_newsize, offset);
8640
8641 if (new_size) {
8642 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
8643 }
8644
8645 return offset;
8646 }
8647
8648
8649 static int
dissect_nfs4_newoffset(tvbuff_t * tvb,int offset,proto_tree * tree)8650 dissect_nfs4_newoffset(tvbuff_t *tvb, int offset, proto_tree *tree)
8651 {
8652 guint new_offset;
8653
8654 new_offset = tvb_get_ntohl(tvb, offset);
8655 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_newoffset, offset);
8656
8657 if (new_offset) {
8658 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8659 }
8660
8661 return offset;
8662 }
8663
8664 static const value_string io_advise_names[] = {
8665 #define IO_ADVISE4_NORMAL 0
8666 { IO_ADVISE4_NORMAL, "Normal" },
8667 #define IO_ADVISE4_SEQUENTIAL 1
8668 { IO_ADVISE4_SEQUENTIAL, "Sequential" },
8669 #define IO_ADVISE4_SEQUENTIAL_BACKWARDS 2
8670 { IO_ADVISE4_SEQUENTIAL_BACKWARDS, "Sequential Backwards" },
8671 #define IO_ADVISE4_RANDOM 3
8672 { IO_ADVISE4_RANDOM, "Random" },
8673 #define IO_ADVISE4_WILLNEED 4
8674 { IO_ADVISE4_WILLNEED, "Will Need" },
8675 #define IO_ADVISE4_WILLNEED_OPPORTUNISTIC 5
8676 { IO_ADVISE4_WILLNEED_OPPORTUNISTIC, "Will Need Opportunistic" },
8677 #define IO_ADVISE4_DONTNEED 6
8678 { IO_ADVISE4_DONTNEED, "Don't Need" },
8679 #define IO_ADVISE4_NOREUSE 7
8680 { IO_ADVISE4_NOREUSE, "No Reuse" },
8681 #define IO_ADVISE4_READ 8
8682 { IO_ADVISE4_READ, "Read" },
8683 #define IO_ADVISE4_WRITE 9
8684 { IO_ADVISE4_WRITE, "Write" },
8685 #define IO_ADVISE4_INIT_PROXIMITY 10
8686 { IO_ADVISE4_INIT_PROXIMITY, "Init Proximity" },
8687 { 0, NULL }
8688 };
8689 static value_string_ext io_advise_names_ext = VALUE_STRING_EXT_INIT(io_advise_names);
8690
8691 static int
dissect_nfs4_io_hints(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree)8692 dissect_nfs4_io_hints(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
8693 {
8694 static nfs4_bitmap_info_t bitmap_info = {
8695 .vse_names_ext = &io_advise_names_ext,
8696 .hf_mask_label = &hf_nfs4_io_hints_mask,
8697 .hf_item_label = &hf_nfs4_io_advise_hint,
8698 .hf_item_count = &hf_nfs4_io_hint_count,
8699 };
8700
8701 return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, &bitmap_info, NFS4_BITMAP_MASK, NULL);
8702 }
8703
8704 static int
dissect_nfs4_app_data_block(tvbuff_t * tvb,int offset,proto_tree * tree,guint32 * hash)8705 dissect_nfs4_app_data_block(tvbuff_t *tvb, int offset, proto_tree *tree, guint32 *hash)
8706 {
8707 proto_item *fitem;
8708
8709 guint32 pattern_hash;
8710 guint pattern_len;
8711
8712 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8713 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_block_size, offset);
8714 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_block_count, offset);
8715 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_reloff_blocknum, offset);
8716 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_blocknum, offset);
8717 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_reloff_pattern, offset);
8718
8719 pattern_len = tvb_get_ntohl(tvb, offset);
8720 offset += 4;
8721
8722 pattern_hash = crc32_ccitt_tvb_offset(tvb, offset, pattern_len);
8723 fitem = proto_tree_add_uint(tree, hf_nfs4_pattern_hash, tvb, offset, pattern_len, pattern_hash);
8724 proto_item_set_generated(fitem);
8725 proto_item_set_len(fitem, pattern_len);
8726
8727 offset += pattern_len;
8728
8729 if (hash)
8730 *hash = pattern_hash;
8731
8732 return offset;
8733 }
8734
8735 static int
dissect_nfs4_io_time(tvbuff_t * tvb,int offset,proto_tree * tree,const char * timer_mode)8736 dissect_nfs4_io_time(tvbuff_t *tvb, int offset, proto_tree *tree, const char *timer_mode)
8737 {
8738 proto_tree *newtree;
8739
8740 newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_time, NULL, "%s", timer_mode);
8741 offset = dissect_nfs4_nfstime(tvb, offset, newtree);
8742
8743 return offset;
8744 }
8745
8746 static int
dissect_nfs4_io_latency(tvbuff_t * tvb,int offset,proto_tree * tree,const char * io_mode)8747 dissect_nfs4_io_latency(tvbuff_t *tvb, int offset, proto_tree *tree, const char *io_mode)
8748 {
8749 proto_tree *newtree;
8750
8751 newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_latency, NULL, "%s Latency", io_mode);
8752
8753 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_requested, offset);
8754 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_requested, offset);
8755 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ops_completed, offset);
8756 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_completed, offset);
8757 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_bytes_not_delivered, offset);
8758
8759 offset = dissect_nfs4_io_time(tvb, offset, newtree, "Busy time");
8760 offset = dissect_nfs4_io_time(tvb, offset, newtree, "Completion time");
8761
8762 return offset;
8763 }
8764
8765 static int
dissect_nfs4_io_info(tvbuff_t * tvb,int offset,proto_tree * tree,const char * io_mode)8766 dissect_nfs4_io_info(tvbuff_t *tvb, int offset, proto_tree *tree, const char *io_mode)
8767 {
8768 proto_tree *newtree;
8769
8770 newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_info, NULL, "%s Info", io_mode);
8771
8772 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_count, offset);
8773 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_io_bytes, offset);
8774
8775 return offset;
8776 }
8777
8778 static int
dissect_nfs4_layoutstats(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ,gboolean has_layout_type)8779 dissect_nfs4_layoutstats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ, gboolean has_layout_type)
8780 {
8781 guint layout_type = LAYOUT4_NO_LAYOUT_TYPE;
8782 proto_tree *netaddr;
8783 proto_item *fitem;
8784 int old_offset;
8785 guint32 last_fh_hash = 0;
8786
8787 /* FIXME: Are these here or in the caller? Check for layoutcommit */
8788 offset = dissect_nfs4_io_info(tvb, offset, tree, "Read");
8789 offset = dissect_nfs4_io_info(tvb, offset, tree, "Write");
8790 offset = dissect_nfs4_deviceid(tvb, offset, tree);
8791
8792 if (has_layout_type) {
8793 layout_type = tvb_get_ntohl(tvb, offset);
8794 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
8795 }
8796
8797 /* If not flex files layout type eat the rest and move on.. */
8798 if (!has_layout_type || layout_type == LAYOUT4_FLEX_FILES) {
8799
8800 /* NFS Flex Files */
8801 if (has_layout_type)
8802 offset += 4; /* Skip past opaque count */
8803
8804 /* The netaddr */
8805 old_offset = offset;
8806 netaddr = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "DS address");
8807
8808 offset = dissect_nfs4_clientaddr(tvb, offset, netaddr);
8809 proto_item_set_len(fitem, offset - old_offset);
8810
8811 /* The file handle */
8812 offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "Filehandle", &last_fh_hash, civ);
8813
8814 /* Read Latency */
8815 offset = dissect_nfs4_io_latency(tvb, offset, tree, "Read");
8816
8817 /* Write Latency */
8818 offset = dissect_nfs4_io_latency(tvb, offset, tree, "Write");
8819
8820 /* Duration */
8821 offset = dissect_nfs4_io_time(tvb, offset, tree, "Duration");
8822
8823 /* Local? */
8824 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_ff_local, offset);
8825 } else {
8826 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_layoutstats);
8827 }
8828
8829 return offset;
8830 }
8831
8832 static int
dissect_nfs4_ff_io_stats(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)8833 dissect_nfs4_ff_io_stats(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
8834 {
8835 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8836 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
8837 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8838
8839 /* Note that we've already determined that we are in the Flex File Layout Type */
8840 offset = dissect_nfs4_layoutstats(tvb, offset, pinfo, tree, civ, FALSE);
8841
8842 return offset;
8843 }
8844
8845 static int
dissect_nfs4_device_errors(tvbuff_t * tvb,int offset,proto_tree * tree)8846 dissect_nfs4_device_errors(tvbuff_t *tvb, int offset, proto_tree *tree)
8847 {
8848 proto_item *sub_fitem;
8849 proto_tree *ss_tree;
8850 proto_tree *subtree;
8851 proto_item *ss_fitem;
8852 guint i;
8853 guint count;
8854
8855 guint opcode;
8856
8857 count = tvb_get_ntohl(tvb, offset);
8858 sub_fitem = proto_tree_add_item(tree, hf_nfs4_device_error_count,
8859 tvb, offset, 4, ENC_BIG_ENDIAN);
8860 offset += 4;
8861
8862 subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_device_errors_sub);
8863 for (i = 0; i < count; i++) {
8864 ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_device_errors_index,
8865 tvb, offset+0, 4, i, "Error [%u]", i);
8866 ss_tree = proto_item_add_subtree(ss_fitem,
8867 ett_nfs4_device_errors_sub);
8868 offset = dissect_nfs4_deviceid(tvb, offset, ss_tree);
8869 offset = dissect_nfs4_status(tvb, offset, ss_tree, NULL);
8870
8871 opcode = tvb_get_ntohl(tvb, offset);
8872 proto_tree_add_uint(ss_tree, hf_nfs4_io_error_op, tvb, offset, 4, opcode);
8873 offset += 4;
8874 }
8875
8876 return offset;
8877 }
8878
8879 static int
dissect_nfs4_ff_io_error(tvbuff_t * tvb,int offset,proto_tree * tree)8880 dissect_nfs4_ff_io_error(tvbuff_t *tvb, int offset, proto_tree *tree)
8881 {
8882 proto_tree *newtree;
8883
8884 /* FIXME */
8885 newtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_nfs4_io_latency, NULL, "IO errors");
8886
8887 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ioerrs_offset, offset);
8888 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_ff_ioerrs_length, offset);
8889 offset = dissect_nfs4_stateid(tvb, offset, newtree, NULL);
8890
8891 offset = dissect_nfs4_device_errors(tvb, offset, newtree);
8892
8893 return offset;
8894 }
8895
8896 static int
dissect_nfs4_layoutreturn(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)8897 dissect_nfs4_layoutreturn(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
8898 {
8899 guint returntype;
8900 guint layout_type;
8901
8902 proto_item *sub_fitem;
8903 proto_tree *ss_tree;
8904 proto_tree *subtree;
8905 proto_item *ss_fitem;
8906 guint i;
8907 guint count;
8908
8909 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_reclaim, offset);
8910
8911 layout_type = tvb_get_ntohl(tvb, offset);
8912 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
8913
8914 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_iomode, offset);
8915
8916 returntype = tvb_get_ntohl(tvb, offset);
8917 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_return_type, offset);
8918 if (returntype == 1) { /* RETURN_FILE */
8919 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
8920 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
8921 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8922
8923 /* If not flex files layout type eat the rest and move on.. */
8924 if (layout_type == LAYOUT4_FLEX_FILES) {
8925 offset += 4; /* Skip past opaque count */
8926
8927 /* Get the errors */
8928 count = tvb_get_ntohl(tvb, offset);
8929 sub_fitem = proto_tree_add_item(tree, hf_nfs4_ff_ioerrs_count,
8930 tvb, offset, 4, ENC_BIG_ENDIAN);
8931 offset += 4;
8932
8933 subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_ff_ioerrs_sub);
8934 for (i = 0; i < count; i++) {
8935 ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_ff_ioerrs_index,
8936 tvb, offset+0, 4, i, "IO Error [%u]", i);
8937 ss_tree = proto_item_add_subtree(ss_fitem,
8938 ett_nfs4_ff_ioerrs_sub);
8939
8940 offset = dissect_nfs4_ff_io_error(tvb, offset, ss_tree);
8941 }
8942
8943 /* Get the stats */
8944 count = tvb_get_ntohl(tvb, offset);
8945 sub_fitem = proto_tree_add_item(tree, hf_nfs4_ff_iostats_count,
8946 tvb, offset, 4, ENC_BIG_ENDIAN);
8947 offset += 4;
8948
8949 subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_ff_iostats_sub);
8950 for (i = 0; i < count; i++) {
8951 ss_fitem = proto_tree_add_uint_format(subtree, hf_nfs4_ff_iostats_index,
8952 tvb, offset+0, 4, i, "IO Stat [%u]", i);
8953 ss_tree = proto_item_add_subtree(ss_fitem,
8954 ett_nfs4_ff_iostats_sub);
8955
8956 offset = dissect_nfs4_ff_io_stats(tvb, offset, pinfo, ss_tree, civ);
8957 }
8958
8959 } else {
8960 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_lrf_body_content);
8961 }
8962 }
8963
8964 return offset;
8965 }
8966
8967 static int
dissect_nfs_layoutreturn_stateid(tvbuff_t * tvb,proto_tree * tree,int offset)8968 dissect_nfs_layoutreturn_stateid(tvbuff_t *tvb, proto_tree *tree, int offset)
8969 {
8970 guint lrs_present;
8971
8972 lrs_present = tvb_get_ntohl(tvb, offset);
8973 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_lrs_present, offset);
8974
8975 if (lrs_present) {
8976 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
8977 }
8978
8979 return offset;
8980 }
8981
8982
8983 static const value_string notify_deviceid_type4[] = {
8984 #define NOTIFY_DEVICEID4_CHANGE 1
8985 { NOTIFY_DEVICEID4_CHANGE, "Change" },
8986 #define NOTIFY_DEVICEID4_DELETE 2
8987 { NOTIFY_DEVICEID4_DELETE, "Delete" },
8988 { 0, NULL }
8989 };
8990 static value_string_ext notify_deviceid_type4_ext = VALUE_STRING_EXT_INIT(notify_deviceid_type4);
8991
8992
8993 static int
dissect_nfs4_notification_bitmap(tvbuff_t * tvb,proto_tree * tree,packet_info * pinfo,int offset)8994 dissect_nfs4_notification_bitmap(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
8995 {
8996 static nfs4_bitmap_info_t bitmap_info = {
8997 .vse_names_ext = ¬ify_deviceid_type4_ext,
8998 .hf_mask_label = &hf_nfs4_notification_mask,
8999 .hf_item_label = &hf_nfs4_notification_type,
9000 };
9001
9002 return dissect_nfs4_bitmap(tvb, offset, pinfo, tree, NULL, &bitmap_info, NFS4_BITMAP_MASK, NULL);
9003 }
9004
9005
9006 static int
dissect_nfs4_devices_file(tvbuff_t * tvb,int offset,proto_tree * tree)9007 dissect_nfs4_devices_file(tvbuff_t *tvb, int offset, proto_tree *tree)
9008 {
9009 guint i, j;
9010 guint32 num_indices, num_multipath, num_addr;
9011
9012 /* disect indices */
9013 num_indices = tvb_get_ntohl(tvb, offset);
9014 offset += 4;
9015 for (i = 0; i < num_indices; i++) {
9016 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_deviceidx, offset);
9017 }
9018
9019 num_multipath = tvb_get_ntohl(tvb, offset);
9020 offset += 4;
9021 for (i = 0; i < num_multipath; i++) {
9022 num_addr = tvb_get_ntohl(tvb, offset);
9023 offset += 4;
9024 for (j = 0; j < num_addr; j++) {
9025 offset = dissect_rpc_string(tvb, tree, hf_nfs4_r_netid, offset, NULL);
9026 offset = dissect_rpc_string(tvb, tree, hf_nfs4_r_addr, offset, NULL);
9027 }
9028 }
9029
9030 return offset;
9031 }
9032
9033 static int
dissect_nfs4_devices_flexfile(tvbuff_t * tvb,int offset,proto_tree * tree)9034 dissect_nfs4_devices_flexfile(tvbuff_t *tvb, int offset, proto_tree *tree)
9035 {
9036 guint i;
9037 guint32 num_addr;
9038 guint32 num_vers;
9039
9040 /* disect indices */
9041 num_addr = tvb_get_ntohl(tvb, offset);
9042 offset += 4;
9043 for (i = 0; i < num_addr; i++) {
9044 offset = dissect_rpc_string(tvb, tree, hf_nfs4_r_netid, offset,
9045 NULL);
9046 offset = dissect_rpc_string(tvb, tree, hf_nfs4_r_addr, offset,
9047 NULL);
9048 }
9049
9050 num_vers = tvb_get_ntohl(tvb, offset);
9051 offset += 4;
9052
9053 for (i = 0; i < num_vers; i++) {
9054 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_version, offset);
9055 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_minorversion,
9056 offset);
9057 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_rsize,
9058 offset);
9059 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_ff_wsize,
9060 offset);
9061 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_ff_tightly_coupled,
9062 offset);
9063 }
9064
9065 return offset;
9066 }
9067
9068 static const value_string scsi_vol_type_names[] = {
9069 #define PNFS_SCSI_VOLUME_SLICE 1
9070 { PNFS_SCSI_VOLUME_SLICE, "Slice" },
9071 #define PNFS_SCSI_VOLUME_CONCAT 2
9072 { PNFS_SCSI_VOLUME_CONCAT, "Concat" },
9073 #define PNFS_SCSI_VOLUME_STRIPE 3
9074 { PNFS_SCSI_VOLUME_STRIPE, "Stripe" },
9075 #define PNFS_SCSI_VOLUME_BASE 4
9076 { PNFS_SCSI_VOLUME_BASE, "Base" },
9077 { 0, NULL }
9078 };
9079
9080 static const value_string scsi_vpd_designator_type_names[] = {
9081 #define PS_DESIGNATOR_T10 1
9082 { PS_DESIGNATOR_T10, "T10" },
9083 #define PS_DESIGNATOR_EUI64 2
9084 { PS_DESIGNATOR_EUI64, "EUI64" },
9085 #define PS_DESIGNATOR_NAA 3
9086 { PS_DESIGNATOR_NAA, "NAA" },
9087 #define PS_DESIGNATOR_NAME 8
9088 { PS_DESIGNATOR_NAME, "Name" },
9089 { 0, NULL }
9090 };
9091
9092 static const value_string scsi_vpd_code_set_names[] = {
9093 #define PS_CODE_SET_BINARY 1
9094 { PS_CODE_SET_BINARY, "binary" },
9095 #define PS_CODE_SET_ASCII 2
9096 { PS_CODE_SET_ASCII, "ASCII" },
9097 #define PS_CODE_SET_UTF8 3
9098 { PS_CODE_SET_UTF8, "UTF8" },
9099 { 0, NULL }
9100 };
9101
9102 static const value_string scsi_extent_state_names[] = {
9103 #define PNFS_SCSI_EXT_READ_WRITE_DATA 0
9104 { PNFS_SCSI_EXT_READ_WRITE_DATA, "READ_WRITE_DATA" },
9105 #define PNFS_SCSI_EXT_READ_DATA 1
9106 { PNFS_SCSI_EXT_READ_DATA, "READ_DATA" },
9107 #define PNFS_SCSI_EXT_INVALID_DATA 2
9108 { PNFS_SCSI_EXT_INVALID_DATA, "INVALID_DATA" },
9109 #define PNFS_SCSI_EXT_NONE_DATA 3
9110 { PNFS_SCSI_EXT_NONE_DATA, "NONE_DATA" },
9111 { 0, NULL }
9112 };
9113
9114 static int
dissect_nfs4_devices_scsi_base_volume(tvbuff_t * tvb,int offset,proto_tree * tree)9115 dissect_nfs4_devices_scsi_base_volume(tvbuff_t *tvb, int offset, proto_tree *tree)
9116 {
9117 guint32 desig_len;
9118
9119 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_devaddr_scsi_vpd_code_set, offset);
9120 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_devaddr_scsi_vpd_designator_type, offset);
9121
9122 desig_len = tvb_get_ntohl(tvb, offset);
9123 offset += 4;
9124 proto_tree_add_item(tree, hf_nfs4_devaddr_scsi_vpd_designator,
9125 tvb, offset, desig_len, ENC_NA);
9126 offset += desig_len;
9127
9128 proto_tree_add_item(tree, hf_nfs4_devaddr_scsi_private_key,
9129 tvb, offset, 8, ENC_NA);
9130 offset += 8;
9131
9132 return offset;
9133 }
9134
9135 static int
dissect_nfs4_vol_indices(tvbuff_t * tvb,int offset,proto_tree * tree)9136 dissect_nfs4_vol_indices(tvbuff_t *tvb, int offset, proto_tree *tree)
9137 {
9138 guint i;
9139 guint32 num_vols;
9140 proto_item *indices_item;
9141 proto_tree *indices_tree;
9142
9143 num_vols = tvb_get_ntohl(tvb, offset);
9144 offset += 4;
9145 if (num_vols == 0)
9146 return offset;
9147
9148 indices_tree = proto_tree_add_subtree_format(tree, tvb, offset, 0,
9149 ett_nfs4_scsi_layout_vol_indices, &indices_item,
9150 "volume indices");
9151 for (i = 0; i < num_vols; i++) {
9152 proto_tree_add_item(indices_tree, hf_nfs4_devaddr_scsi_vol_ref_index,
9153 tvb, offset, 4, ENC_BIG_ENDIAN);
9154 }
9155 return offset;
9156 }
9157
9158 static int
dissect_nfs4_devices_scsi(tvbuff_t * tvb,int offset,proto_tree * tree)9159 dissect_nfs4_devices_scsi(tvbuff_t *tvb, int offset, proto_tree *tree)
9160 {
9161 guint i;
9162 proto_item *vol_item;
9163 proto_tree *vol_tree;
9164 int old_offset = offset;
9165 guint32 num_vols;
9166 guint32 vol_type;
9167
9168 num_vols = tvb_get_ntohl(tvb, offset);
9169 offset += 4;
9170
9171 for (i = 0; i < num_vols; i++) {
9172
9173 vol_type = tvb_get_ntohl(tvb, offset);
9174 vol_item = proto_tree_add_item(tree, hf_nfs4_devaddr_scsi_vol_type, tvb, offset, 4, ENC_BIG_ENDIAN);
9175 vol_tree = proto_item_add_subtree(vol_item, ett_nfs4_scsi_layout_vol);
9176 offset += 4;
9177 proto_tree_add_uint(vol_tree, hf_nfs4_devaddr_scsi_vol_index, tvb, offset, 0, i);
9178 switch (vol_type)
9179 {
9180 case PNFS_SCSI_VOLUME_SLICE:
9181 proto_tree_add_item(vol_tree, hf_nfs4_devaddr_ssv_start, tvb, offset, 4, ENC_BIG_ENDIAN);
9182 proto_tree_add_item(vol_tree, hf_nfs4_devaddr_ssv_length, tvb, offset, 4, ENC_BIG_ENDIAN);
9183 proto_tree_add_item(vol_tree, hf_nfs4_devaddr_scsi_vol_ref_index, tvb, offset, 4, ENC_BIG_ENDIAN);
9184 break;
9185 case PNFS_SCSI_VOLUME_CONCAT:
9186 offset = dissect_nfs4_vol_indices(tvb, offset, vol_tree);
9187 break;
9188 case PNFS_SCSI_VOLUME_STRIPE:
9189 proto_tree_add_item(vol_tree, hf_nfs4_devaddr_ssv_stripe_unit, tvb, offset, 4, ENC_BIG_ENDIAN);
9190 offset = dissect_nfs4_vol_indices(tvb, offset, vol_tree);
9191 break;
9192 case PNFS_SCSI_VOLUME_BASE:
9193 offset = dissect_nfs4_devices_scsi_base_volume(tvb, offset, vol_tree);
9194 break;
9195 }
9196
9197 proto_item_set_len(vol_item, offset - old_offset);
9198 old_offset = offset;
9199 }
9200
9201 return offset;
9202 }
9203
9204
9205 static int
dissect_nfs4_test_stateid_arg(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)9206 dissect_nfs4_test_stateid_arg(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
9207 {
9208 return dissect_nfs4_stateid(tvb, offset, tree, NULL);
9209 }
9210
9211
9212 static int
dissect_nfs4_test_stateid_res(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)9213 dissect_nfs4_test_stateid_res(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
9214 {
9215 return dissect_nfs4_status(tvb, offset, tree, NULL);
9216 }
9217
9218 static int
dissect_nfs4_netloc(tvbuff_t * tvb,int offset,proto_tree * tree)9219 dissect_nfs4_netloc(tvbuff_t *tvb, int offset, proto_tree *tree)
9220 {
9221 guint netloc_type;
9222 proto_tree *netaddr;
9223 int old_offset;
9224 proto_item *fitem;
9225
9226 /* netloc type */
9227 netloc_type = tvb_get_ntohl(tvb, offset);
9228 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_netloc_type, offset);
9229
9230 switch (netloc_type) {
9231 case NL4_NAME:
9232 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_nl_name, NULL);
9233 break;
9234 case NL4_URL:
9235 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_nl_url, NULL);
9236 break;
9237 case NL4_NETADDR:
9238 old_offset = offset;
9239 netaddr = proto_tree_add_subtree(tree, tvb, offset, 0, ett_nfs4_clientaddr, &fitem, "netaddr");
9240
9241 offset = dissect_nfs4_clientaddr(tvb, offset, netaddr);
9242 proto_item_set_len(fitem, offset - old_offset);
9243 break;
9244 default:
9245 /* back up to re-read the length field when treating as
9246 * opaque */
9247 offset -= 4;
9248 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_netloc);
9249 break;
9250 }
9251
9252 return offset;
9253 }
9254
9255 static int
dissect_nfs4_copy_reqs(tvbuff_t * tvb,int offset,proto_tree * tree)9256 dissect_nfs4_copy_reqs(tvbuff_t *tvb, int offset, proto_tree *tree)
9257 {
9258 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_consecutive, offset);
9259 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_synchronous, offset);
9260
9261 return offset;
9262 }
9263
9264 static int
dissect_nfs4_write_response(tvbuff_t * tvb,int offset,proto_tree * tree)9265 dissect_nfs4_write_response(tvbuff_t *tvb, int offset, proto_tree *tree)
9266 {
9267 proto_item *sub_fitem;
9268 proto_tree *ss_tree;
9269 proto_tree *subtree;
9270 proto_item *ss_fitem;
9271 guint i;
9272 guint32 count;
9273
9274 /* Number of callback stateids */
9275 sub_fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_callback_stateids,
9276 tvb, offset, 4, ENC_BIG_ENDIAN, &count);
9277 offset += 4;
9278
9279 subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_callback_stateids_sub);
9280 for (i = 0; i < count; i++) {
9281 ss_fitem = proto_tree_add_item(subtree,
9282 hf_nfs4_callback_stateids_index,
9283 tvb, offset, 4, i);
9284
9285 ss_tree = proto_item_add_subtree(ss_fitem,
9286 ett_nfs4_callback_stateids_sub);
9287 offset = dissect_nfs4_stateid(tvb, offset, ss_tree, NULL);
9288 }
9289
9290 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
9291 offset = dissect_nfs4_stable_how(tvb, offset, tree, "committed");
9292 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_verifier, offset);
9293
9294 return offset;
9295 }
9296
9297 static int
dissect_nfs4_source_servers(tvbuff_t * tvb,int offset,proto_tree * tree)9298 dissect_nfs4_source_servers(tvbuff_t *tvb, int offset, proto_tree *tree)
9299 {
9300 proto_item *sub_fitem;
9301 proto_tree *ss_tree;
9302 proto_tree *subtree;
9303 proto_item *ss_fitem;
9304 guint i;
9305 guint32 source_servers;
9306
9307 /* Number of source servers */
9308 sub_fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_source_servers,
9309 tvb, offset, 4, ENC_BIG_ENDIAN, &source_servers);
9310 offset += 4;
9311
9312 subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_source_servers_sub);
9313 for (i = 0; i < source_servers; i++) {
9314 ss_fitem = proto_tree_add_item(subtree,
9315 hf_nfs4_source_server_index,
9316 tvb, offset, 4, i);
9317
9318 ss_tree = proto_item_add_subtree(ss_fitem,
9319 ett_nfs4_source_servers_sub);
9320
9321 offset = dissect_nfs4_netloc(tvb, offset, ss_tree);
9322 }
9323
9324 return offset;
9325 }
9326
9327 static int
dissect_nfs4_deviceaddr(tvbuff_t * tvb,int offset,proto_tree * tree)9328 dissect_nfs4_deviceaddr(tvbuff_t *tvb, int offset, proto_tree *tree)
9329 {
9330 guint layout_type;
9331
9332 /* layout type */
9333 layout_type = tvb_get_ntohl(tvb, offset);
9334 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
9335
9336 /* skip length */
9337 offset+=4;
9338
9339 switch (layout_type) {
9340 case LAYOUT4_NFSV4_1_FILES:
9341 offset = dissect_nfs4_devices_file(tvb, offset, tree);
9342 break;
9343 case LAYOUT4_FLEX_FILES:
9344 offset = dissect_nfs4_devices_flexfile(tvb, offset, tree);
9345 break;
9346 case LAYOUT4_SCSI:
9347 offset = dissect_nfs4_devices_scsi(tvb, offset, tree);
9348 break;
9349 default:
9350 /* back up to re-read the length field when treating as
9351 * opaque */
9352 offset -= 4;
9353 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_getdevinfo);
9354 break;
9355 }
9356
9357 return offset;
9358 }
9359
9360
9361 static int
dissect_nfs4_devicelist(tvbuff_t * tvb,int offset,proto_tree * tree)9362 dissect_nfs4_devicelist(tvbuff_t *tvb, int offset, proto_tree *tree)
9363 {
9364 guint count;
9365 guint i;
9366
9367 count = tvb_get_ntohl(tvb, offset);
9368 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_devicenum, offset);
9369 for (i = 0; i < count; i++)
9370 offset = dissect_nfs4_deviceid(tvb, offset, tree);
9371
9372 return offset;
9373 }
9374
9375
9376 static int
dissect_rpc_serverowner4(tvbuff_t * tvb,int offset,proto_tree * tree)9377 dissect_rpc_serverowner4(tvbuff_t *tvb, int offset, proto_tree *tree)
9378 {
9379 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_minorid, offset);
9380 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs4_majorid);
9381 return offset;
9382 }
9383
9384
9385 static int
dissect_rpc_chanattrs4(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)9386 dissect_rpc_chanattrs4(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
9387 {
9388 proto_tree *chan_attrs_tree;
9389 guint i, count, rdma_ird_len;
9390
9391 rdma_ird_len = tvb_get_ntohl(tvb, offset + 24);
9392 count = 28 + rdma_ird_len * 4;
9393
9394 chan_attrs_tree = proto_tree_add_subtree(tree, tvb, offset, count, ett_nfs4_chan_attrs, NULL, name);
9395
9396 offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_padsize, offset);
9397 offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxreqsize, offset);
9398 offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxrespsize, offset);
9399 offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxrespsizecached, offset);
9400 offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxops, offset);
9401 offset = dissect_rpc_uint32(tvb, chan_attrs_tree, hf_nfs4_maxreqs, offset);
9402 offset += 4;
9403 for (i = 0; i < rdma_ird_len; i++) {
9404 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_rdmachanattrs, offset);
9405 }
9406 return offset;
9407 }
9408
9409
9410 static int
dissect_rpc_nfs_impl_id4(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)9411 dissect_rpc_nfs_impl_id4(tvbuff_t *tvb, int offset, proto_tree *tree, const char *name)
9412 {
9413 proto_tree *impl_id_tree;
9414 guint i, count;
9415
9416 count = tvb_get_ntohl(tvb, offset);
9417 impl_id_tree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_nfs4_clientowner, NULL, name);
9418 offset += 4;
9419
9420 for (i = 0; i < count; i++) {
9421 proto_tree *date_tree;
9422
9423 offset = dissect_nfs_utf8string(tvb, offset, impl_id_tree, hf_nfs4_nii_domain, NULL);
9424 offset = dissect_nfs_utf8string(tvb, offset, impl_id_tree, hf_nfs4_nii_name, NULL);
9425
9426 date_tree = proto_tree_add_subtree(impl_id_tree, tvb, offset, 12, ett_nfs4_clientowner, NULL, "Build timestamp(nii_date)");
9427 offset = dissect_nfs4_nfstime(tvb, offset, date_tree);
9428 }
9429 return offset;
9430 }
9431
9432
9433 static int
dissect_rpc_secparms4(tvbuff_t * tvb,int offset,proto_tree * tree)9434 dissect_rpc_secparms4(tvbuff_t *tvb, int offset, proto_tree *tree)
9435 {
9436 guint count, i;
9437
9438 count = tvb_get_ntohl(tvb, offset);
9439 offset += 4;
9440
9441 for (i = 0; i < count; i++) {
9442 guint j, flavor = tvb_get_ntohl(tvb, offset);
9443 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_flavor, offset);
9444
9445 switch (flavor) {
9446 case 1: { /* AUTH_SYS */
9447 guint count2;
9448 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_stamp, offset);
9449 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_machinename, NULL);
9450 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_uid, offset);
9451 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_gid, offset);
9452 count2 = tvb_get_ntohl(tvb, offset);
9453 offset += 4;
9454 for (j = 0; j < count2; j++) {
9455 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_gid, offset);
9456 }
9457 break;
9458 }
9459 case 6: /* RPCSEC_GSS */
9460 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_service, offset);
9461 proto_item_append_text(tree, ", Handle from server");
9462 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
9463 proto_item_append_text(tree, ", Handle from client");
9464 offset = dissect_nfsdata(tvb, offset, tree, hf_nfs_data);
9465 break;
9466 default:
9467 break;
9468 }
9469 }
9470 return offset;
9471 }
9472
9473 static int
dissect_nfs4_layoutget(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)9474 dissect_nfs4_layoutget(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
9475 {
9476 guint layout_type;
9477 guint sub_num;
9478 guint nfl_util;
9479 guint lo_seg_count;
9480 guint i, j, k, lo_seg;
9481 proto_tree *newtree;
9482 proto_item *sub_fitem;
9483 proto_tree *subtree;
9484 proto_tree *nfl_item;
9485 proto_tree *nfl_tree;
9486
9487 static int * const layout_flags[] = {
9488 &hf_nfs4_ff_layout_flags_no_layoutcommit,
9489 &hf_nfs4_ff_layout_flags_no_io_thru_mds,
9490 &hf_nfs4_ff_layout_flags_no_read_io,
9491 NULL
9492 };
9493
9494 lo_seg_count = tvb_get_ntohl(tvb, offset);
9495
9496 newtree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_nfs4_layoutseg, NULL,
9497 "Layout Segment (count: %u)", lo_seg_count);
9498 offset += 4;
9499
9500 for (lo_seg = 0; lo_seg < lo_seg_count; lo_seg++) {
9501 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_offset, offset);
9502 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_length, offset);
9503
9504 offset = dissect_rpc_uint32(tvb, newtree, hf_nfs4_iomode, offset);
9505
9506 layout_type = tvb_get_ntohl(tvb, offset);
9507 offset = dissect_rpc_uint32(tvb, newtree, hf_nfs4_layout_type, offset);
9508
9509 /* If not files layout type eat the rest and move on.. */
9510 if (layout_type == LAYOUT4_NFSV4_1_FILES) {
9511 /* NFS Files */
9512 offset += 4; /* Skip past opaque count */
9513
9514 offset = dissect_nfs4_deviceid(tvb, offset, newtree);
9515
9516 /* Get nfl_util and break it down into its components */
9517 nfl_util = tvb_get_ntohl(tvb, offset);
9518 nfl_item = proto_tree_add_uint(newtree, hf_nfs4_nfl_util, tvb, offset, 4, nfl_util);
9519 nfl_tree = proto_item_add_subtree(nfl_item, ett_nfs4_nfl_util);
9520 proto_tree_add_uint(nfl_tree, hf_nfs4_nfl_util_stripe_size, tvb, offset, 4, nfl_util&NFL4_UFLG_STRIPE_UNIT_SIZE_MASK);
9521 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));
9522 proto_tree_add_uint(nfl_tree, hf_nfs4_nfl_util_dense, tvb, offset+3, 1, (nfl_util&NFL4_UFLG_DENSE?1:0));
9523 offset += 4;
9524
9525 offset = dissect_rpc_uint32(tvb, newtree,
9526 hf_nfs4_nfl_first_stripe_index, offset);
9527 offset = dissect_rpc_uint64(tvb, newtree,
9528 hf_nfs4_offset, offset);
9529
9530 sub_num = tvb_get_ntohl(tvb, offset); /* Len of FH list */
9531
9532 sub_fitem = proto_tree_add_item(newtree, hf_nfs4_nfl_fhs,
9533 tvb, offset, 4, ENC_BIG_ENDIAN);
9534 offset += 4;
9535
9536 subtree = proto_item_add_subtree(sub_fitem,
9537 ett_nfs4_layoutseg_sub);
9538 for (i = 0; i < sub_num; i++)
9539 offset = dissect_nfs4_fh(tvb, offset, pinfo,
9540 subtree, "lo_filehandle", NULL,
9541 civ);
9542 } else if (layout_type == LAYOUT4_FLEX_FILES) {
9543 guint ds_count, fh_count;
9544 proto_item *ds_item, *mirrors_item, *subitem;
9545 proto_tree *ds_tree, *mirrors_tree;
9546 int end_offset = offset;
9547 int mirror_start_offset, ds_start_offset;
9548
9549 /* NFS Flex Files */
9550 end_offset += tvb_get_ntohl(tvb, offset) + 4;
9551 offset += 4; /* Skip past opaque count */
9552
9553 /* stripe unit */
9554 offset = dissect_rpc_uint64(tvb, newtree, hf_nfs4_stripeunit, offset);
9555
9556 /* Len of mirror list */
9557 sub_num = tvb_get_ntohl(tvb, offset);
9558 mirrors_item = proto_tree_add_uint_format(newtree, hf_nfs4_nfl_mirrors,
9559 tvb, offset, 4, sub_num, "Mirrors (%u)", sub_num);
9560 offset += 4;
9561
9562 mirrors_tree = proto_item_add_subtree(mirrors_item, ett_nfs4_layoutseg_sub);
9563
9564 for (i = 0; i < sub_num; i++) {
9565
9566 mirror_start_offset = offset;
9567 subtree = proto_tree_add_subtree_format(mirrors_tree, tvb, offset, -1,
9568 ett_nfs4_layoutseg_sub, &subitem,
9569 "Mirror: %u", i);
9570
9571 /* data server count */
9572 ds_count = tvb_get_ntohl(tvb, offset);
9573 offset += 4;
9574
9575 for (j = 0; j < ds_count; j++) {
9576 ds_start_offset = offset;
9577 ds_tree = proto_tree_add_subtree_format(subtree, tvb, offset, -1,
9578 ett_nfs4_layoutseg_sub, &ds_item,
9579 "Data Server: %u", j);
9580
9581 offset = dissect_nfs4_deviceid(tvb, offset,
9582 ds_tree);
9583 offset = dissect_rpc_uint32(tvb, ds_tree,
9584 hf_nfs4_mirror_eff, offset);
9585 offset = dissect_nfs4_stateid(tvb, offset,
9586 ds_tree, NULL);
9587
9588 fh_count = tvb_get_ntohl(tvb, offset);
9589 offset += 4;
9590
9591 for (k = 0; k < fh_count; k++)
9592 offset = dissect_nfs4_fh(tvb, offset,
9593 pinfo, ds_tree, "fh", NULL, civ);
9594
9595 offset = dissect_nfs_utf8string(tvb, offset,
9596 ds_tree, hf_nfs4_ff_synthetic_owner,
9597 NULL);
9598 offset = dissect_nfs_utf8string(tvb, offset,
9599 ds_tree, hf_nfs4_ff_synthetic_owner_group,
9600 NULL);
9601
9602 proto_item_set_len(ds_item, offset - ds_start_offset);
9603 }
9604
9605 proto_item_set_len(subitem, offset - mirror_start_offset);
9606 }
9607
9608 proto_tree_add_bitmask(newtree, tvb, offset, hf_nfs4_ff_layout_flags,
9609 ett_nfs4_ff_layout_flags, layout_flags, ENC_BIG_ENDIAN);
9610 offset += 4;
9611
9612 if (offset + 4 <= end_offset)
9613 offset = dissect_rpc_uint32(tvb, newtree,
9614 hf_nfs4_ff_stats_collect_hint,
9615 offset);
9616 } else if (layout_type == LAYOUT4_SCSI) {
9617 guint ext_count;
9618 proto_tree *ext_tree;
9619
9620 offset += 4; /* Skip past opaque count */
9621
9622 ext_count = tvb_get_ntohl(tvb, offset);
9623
9624 subtree = proto_tree_add_subtree_format(newtree, tvb, offset, 4,
9625 ett_nfs4_layoutseg_sub, NULL, "SCSI Extents (count: %u)",
9626 ext_count);
9627 offset +=4;
9628
9629 for (i = 0; i < ext_count; i++) {
9630 ext_tree = proto_tree_add_subtree_format(subtree, tvb, offset, 4,
9631 ett_nfs4_layoutseg_sub, NULL, "extent %u", i);
9632 offset = dissect_nfs4_deviceid(tvb, offset, ext_tree);
9633 offset = dissect_rpc_uint64(tvb, ext_tree,
9634 hf_nfs4_scsil_ext_file_offset, offset);
9635 offset = dissect_rpc_uint64(tvb, ext_tree,
9636 hf_nfs4_scsil_ext_length, offset);
9637 offset = dissect_rpc_uint64(tvb, ext_tree,
9638 hf_nfs4_scsil_ext_vol_offset, offset);
9639 offset = dissect_rpc_uint32(tvb, ext_tree,
9640 hf_nfs4_scsil_ext_state, offset);
9641 }
9642 } else {
9643 offset = dissect_nfsdata(tvb, offset, newtree, hf_nfs4_layout);
9644 continue;
9645 }
9646 }
9647 return offset;
9648 }
9649
9650
9651 static int
dissect_nfs_create_session_flags(tvbuff_t * tvb,int offset,proto_tree * tree,int hf_csa)9652 dissect_nfs_create_session_flags(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_csa)
9653 {
9654 int * const flags[] = {
9655 &hf_nfs4_create_session_flags_persist,
9656 &hf_nfs4_create_session_flags_conn_back_chan,
9657 &hf_nfs4_create_session_flags_conn_rdma,
9658 NULL
9659 };
9660
9661 proto_tree_add_bitmask(tree, tvb, offset, hf_csa, ett_nfs4_create_session_flags, flags, ENC_BIG_ENDIAN);
9662 offset += 4;
9663
9664 return offset;
9665 }
9666
9667
9668 enum channel_dir_from_client4 {
9669 CDFC4_FORE = 0x1,
9670 CDFC4_BACK = 0x2,
9671 CDFC4_FORE_OR_BOTH = 0x3,
9672 CDFC4_BACK_OR_BOTH = 0x7
9673 };
9674
9675 static const value_string names_channel_dir_from_client[] = {
9676 { CDFC4_FORE, "CDFC4_FORE" },
9677 { CDFC4_BACK, "CDFC4_BACK" },
9678 { CDFC4_FORE_OR_BOTH, "CDFC4_FORE_OR_BOTH" },
9679 { CDFC4_BACK_OR_BOTH, "CDFC4_BACK_OR_BOTH" },
9680 { 0, NULL }
9681 };
9682
9683 enum channel_dir_from_server4 {
9684 CDFS4_FORE = 0x1,
9685 CDFS4_BACK = 0x2,
9686 CDFS4_BOTH = 0x3
9687 };
9688
9689 static const value_string names_channel_dir_from_server[] = {
9690 { CDFS4_FORE, "CDFS4_FORE" },
9691 { CDFS4_BACK, "CDFS4_BACK" },
9692 { CDFS4_BOTH, "CDFS4_BOTH" },
9693 { 0, NULL }
9694 };
9695
9696 #define SECINFO_STYLE4_CURRENT_FH 0
9697 #define SECINFO_STYLE4_PARENT 1
9698 static const value_string names_secinfo_style4[] = {
9699 { SECINFO_STYLE4_CURRENT_FH, "SECINFO_STYLE4_CURRENT_FH" },
9700 { SECINFO_STYLE4_PARENT, "SECINFO_STYLE4_PARENT" },
9701 { 0, NULL }
9702 };
9703
9704 typedef struct _nfs4_operation_summary {
9705 guint32 opcode;
9706 gboolean iserror;
9707 wmem_strbuf_t *optext;
9708 } nfs4_operation_summary;
9709
9710
9711 /*
9712 To try to determine which NFSv4 operations are most important in a
9713 request, we categorize the operations into different "tiers".
9714
9715 All operations falling into the highest tier (where 1 is highest, 5
9716 is lowest) are considered to be the "most significant" operations.
9717 This information is useful for display purposes, filtering, and for
9718 response time calculations.
9719
9720 For example, virtually all NFSv4 requests include a GETATTR. But in
9721 a request with PUTFH; CLOSE; GETATTR operations, CLOSE is the
9722 significant operation.
9723
9724 In a request with PUTFH; GETATTR operations, GETATTR is the
9725 significant operation. CLOSE has higher tier than GETATTR, which is
9726 in a higher tier than PUTFH.
9727
9728 In practice this seems to be a very reliable method of determining
9729 the most significant operation(s).
9730 */
9731
9732 static int nfs4_operation_tiers[] = {
9733 1 /* 0 */ ,
9734 1 /* 1 */ ,
9735 1 /* 2 */ ,
9736 2 /* 3, NFS4_OP_ACCESS */ ,
9737 1 /* 4, NFS4_OP_CLOSE */,
9738 1 /* 5, NFS4_OP_COMMIT */,
9739 1 /* 6, NFS4_OP_CREATE */,
9740 1 /* 7, NFS4_OP_DELEGPURGE */,
9741 1 /* 8, NFS4_OP_DELEGRETURN */,
9742 3 /* 9, NFS4_OP_GETATTR */,
9743 4 /* 10, NFS4_OP_GETFH */,
9744 1 /* 11, NFS4_OP_LINK */,
9745 1 /* 12, NFS4_OP_LOCK */,
9746 1 /* 13, NFS4_OP_LOCKT */,
9747 1 /* 14, NFS4_OP_LOCKU */,
9748 1 /* 15, NFS4_OP_LOOKUP */,
9749 1 /* 16, NFS4_OP_LOOKUPP */,
9750 2 /* 17, NFS4_OP_NVERIFY */,
9751 1 /* 18, NFS4_OP_OPEN */,
9752 1 /* 19, NFS4_OP_OPENATTR */,
9753 1 /* 20, NFS4_OP_OPEN_CONFIRM */,
9754 1 /* 21, NFS4_OP_OPEN_DOWNGRADE */,
9755 4 /* 22, NFS4_OP_PUTFH */,
9756 3 /* 23, NFS4_OP_PUTPUBFH */,
9757 3 /* 24, NFS4_OP_PUTROOTFH */,
9758 1 /* 25, NFS4_OP_READ */,
9759 1 /* 26, NFS4_OP_READDIR */,
9760 1 /* 27, NFS4_OP_READLINK */,
9761 1 /* 28, NFS4_OP_REMOVE */,
9762 1 /* 29, NFS4_OP_RENAME */,
9763 1 /* 30, NFS4_OP_RENEW */,
9764 4 /* 31, NFS4_OP_RESTOREFH */,
9765 4 /* 32, NFS4_OP_SAVEFH */,
9766 1 /* 33, NFS4_OP_SECINFO */,
9767 1 /* 34, NFS4_OP_SETATTR */,
9768 1 /* 35, NFS4_OP_SETCLIENTID */,
9769 1 /* 36, NFS4_OP_SETCLIENTID_CONFIRM */,
9770 1 /* 37, NFS4_OP_VERIFY */,
9771 1 /* 38, NFS4_OP_WRITE */,
9772 1 /* 39, NFS4_OP_RELEASE_LOCKOWNER */,
9773 /* Minor version 1 */
9774 1 /* 40, NFS4_OP_BACKCHANNEL_CTL */,
9775 1 /* 41, NFS4_OP_BIND_CONN_TO_SESSION */,
9776 1 /* 42, NFS4_OP_EXCHANGE_ID */,
9777 1 /* 43, NFS4_OP_CREATE_SESSION */,
9778 1 /* 44, NFS4_OP_DESTROY_SESSION */,
9779 1 /* 45, NFS4_OP_FREE_STATEID */,
9780 1 /* 46, NFS4_OP_GET_DIR_DELEGATION */,
9781 1 /* 47, NFS4_OP_GETDEVINFO */,
9782 1 /* 48, NFS4_OP_GETDEVLIST */,
9783 1 /* 49, NFS4_OP_LAYOUTCOMMIT */,
9784 1 /* 50, NFS4_OP_LAYOUTGET */,
9785 1 /* 51, NFS4_OP_LAYOUTRETURN */,
9786 1 /* 52, NFS4_OP_SECINFO_NO_NAME */,
9787 4 /* 53, NFS4_OP_SEQUENCE */,
9788 1 /* 54, NFS4_OP_SET_SSV */,
9789 1 /* 55, NFS4_OP_TEST_STATEID */,
9790 1 /* 56, NFS4_OP_WANT_DELEGATION */,
9791 1 /* 57, NFS4_OP_DESTROY_CLIENTID */,
9792 1 /* 58, NFS4_OP_RECLAIM_COMPLETE */,
9793 /* Minor version 2 */
9794 1 /* 59, NFS4_OP_ALLOCATE */,
9795 1 /* 60, NFS4_OP_COPY */,
9796 1 /* 61, NFS4_OP_COPY_NOTIFY */,
9797 1 /* 62, NFS4_OP_DEALLOCATE */,
9798 1 /* 63, NFS4_OP_IO_ADVISE */,
9799 1 /* 64, NFS4_OP_LAYOUTERROR */,
9800 1 /* 65, NFS4_OP_LAYOUTSTATS */,
9801 1 /* 66, NFS4_OP_OFFLOAD_CANCEL */,
9802 1 /* 67, NFS4_OP_OFFLOAD_STATUS */,
9803 1 /* 68, NFS4_OP_READ_PLUS */,
9804 1 /* 69, NFS4_OP_SEEK */,
9805 1 /* 70, NFS4_OP_WRITE_SAME */,
9806 1 /* 71, NFS4_OP_CLONE */,
9807 1 /* 72, NFS4_OP_GETXATTR */,
9808 1 /* 73, NFS4_OP_SETXATTR */,
9809 1 /* 74, NFS4_OP_LISTXATTRS */,
9810 1 /* 75, NFS4_OP_REMOVEXATTR */,
9811 };
9812
9813 #define NFS4_OPERATION_TIER(op) \
9814 ((op) < G_N_ELEMENTS(nfs4_operation_tiers) ? nfs4_operation_tiers[(op)] : 0)
9815
9816 static int * const nfs4_exchid_flags[] = {
9817 &hf_nfs4_exchid_flags_confirmed_r,
9818 &hf_nfs4_exchid_flags_upd_conf_rec_a,
9819 &hf_nfs4_exchid_flags_pnfs_ds,
9820 &hf_nfs4_exchid_flags_pnfs_mds,
9821 &hf_nfs4_exchid_flags_non_pnfs,
9822 &hf_nfs4_exchid_flags_bind_princ,
9823 &hf_nfs4_exchid_flags_moved_migr,
9824 &hf_nfs4_exchid_flags_moved_refer,
9825 NULL
9826 };
9827
9828 static int
dissect_nfs4_request_op(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)9829 dissect_nfs4_request_op(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
9830 {
9831 const char *name = NULL;
9832 const char *source_name = NULL;
9833 const char *dest_name = NULL;
9834 const char *opname = NULL;
9835 guint opcode;
9836 guint highest_tier = 5;
9837 guint current_tier = 5;
9838 guint first_operation = 1;
9839 /*guint name_offset = 0;*/
9840 guint16 sid_hash;
9841 guint64 clientid = 0;
9842 guint32 ops;
9843 guint32 ops_counter;
9844 guint32 summary_counter;
9845 guint32 string_length;
9846 guint32 last_fh_hash = 0;
9847 guint32 saved_fh_hash = 0;
9848 guint32 length;
9849 guint32 hash;
9850 guint64 length64;
9851 guint64 file_offset;
9852 proto_item *fitem;
9853 proto_tree *ftree;
9854 proto_tree *newftree = NULL;
9855 nfs4_operation_summary *op_summary;
9856 guint16 dst_sid_hash;
9857 guint64 dst_file_offset;
9858
9859 ops = tvb_get_ntohl(tvb, offset+0);
9860
9861 fitem = proto_tree_add_uint_format(tree, hf_nfs4_ops_count, tvb, offset+0, 4, ops,
9862 "Operations (count: %u)", ops);
9863 offset += 4;
9864
9865 #define MAX_NFSV4_OPS 128
9866 if (ops > MAX_NFSV4_OPS) {
9867 /* Limit the number of operations to something "reasonable."
9868 * This is an arbitrary number to keep us from attempting to
9869 * allocate too much memory below.
9870 */
9871 expert_add_info(pinfo, fitem, &ei_nfs_too_many_ops);
9872 ops = MAX_NFSV4_OPS;
9873 }
9874
9875 op_summary = wmem_alloc0_array(wmem_packet_scope(), nfs4_operation_summary, ops);
9876
9877 ftree = proto_item_add_subtree(fitem, ett_nfs4_request_op);
9878
9879 if (ops)
9880 proto_item_append_text(proto_tree_get_parent(tree), ", Ops(%d):", ops);
9881
9882 for (ops_counter=0; ops_counter<ops; ops_counter++)
9883 {
9884 op_summary[ops_counter].optext = wmem_strbuf_new(wmem_packet_scope(), "");
9885 opcode = tvb_get_ntohl(tvb, offset);
9886 op_summary[ops_counter].opcode = opcode;
9887
9888 fitem = proto_tree_add_uint(ftree, hf_nfs4_op, tvb, offset, 4, opcode);
9889
9890 /* the opcodes are not contiguous */
9891 if ((opcode < NFS4_OP_ACCESS || opcode > NFS4_LAST_OP)
9892 && opcode != NFS4_OP_ILLEGAL)
9893 break;
9894
9895 /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
9896 if (opcode == NFS4_OP_ILLEGAL) {
9897 newftree = proto_item_add_subtree(fitem, ett_nfs4_illegal);
9898 } else if (nfs4_operation_ett[opcode - 3]) {
9899 newftree = proto_item_add_subtree(fitem, *nfs4_operation_ett[opcode - 3]);
9900 } else {
9901 break;
9902 }
9903
9904 opname = val_to_str_ext_const(opcode, &names_nfs4_operation_ext, "Unknown");
9905 offset += 4;
9906
9907 wmem_strbuf_append_printf(op_summary[ops_counter].optext, "%s", opname);
9908
9909 proto_item_append_text(proto_tree_get_parent(tree),
9910 "%s%s", ops_counter ? ", " : " ", opname);
9911 proto_item_append_text(proto_tree_get_parent(ftree),
9912 "%s%s", ops_counter ? ", " : ": ", opname);
9913
9914 switch (opcode)
9915 {
9916 case NFS4_OP_ACCESS:
9917 {
9918 guint32 *acc_request, amask;
9919
9920 /* Get access mask to check and save it for comparison in the reply. */
9921 amask = tvb_get_ntohl(tvb, offset);
9922 acc_request = (guint32 *)wmem_memdup(wmem_file_scope(), &amask, sizeof(guint32));
9923 civ->private_data = acc_request;
9924
9925 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
9926 display_access_items(tvb, offset, pinfo, fitem, amask, 'C', 4,
9927 op_summary[ops_counter].optext, "Check") ;
9928 offset+=4;
9929 }
9930 break;
9931
9932 case NFS4_OP_CLOSE:
9933 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
9934 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
9935 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
9936 break;
9937
9938 case NFS4_OP_COMMIT:
9939 file_offset = tvb_get_ntoh64(tvb, offset);
9940 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
9941 length = tvb_get_ntohl(tvb, offset);
9942 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
9943 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
9944 " FH: 0x%08x Offset: %"G_GINT64_MODIFIER"u Len: %u",
9945 last_fh_hash, file_offset, length);
9946
9947 break;
9948
9949 case NFS4_OP_CREATE:
9950 {
9951 guint create_type;
9952
9953 create_type = tvb_get_ntohl(tvb, offset);
9954 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_ftype, offset);
9955
9956 switch (create_type)
9957 {
9958 case NF4LNK:
9959 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_linktext, NULL);
9960 break;
9961
9962 case NF4BLK:
9963 case NF4CHR:
9964 offset = dissect_nfs4_specdata(tvb, offset, newftree);
9965 break;
9966
9967 case NF4SOCK:
9968 case NF4FIFO:
9969 case NF4DIR:
9970 break;
9971
9972 default:
9973 break;
9974 }
9975
9976 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, NULL);
9977 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ);
9978 }
9979 break;
9980
9981 case NFS4_OP_DELEGPURGE:
9982 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
9983 break;
9984
9985 case NFS4_OP_DELEGRETURN:
9986 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
9987 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
9988 break;
9989
9990 case NFS4_OP_GETATTR:
9991 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ);
9992
9993 if (last_fh_hash != 0)
9994 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
9995
9996 break;
9997
9998 case NFS4_OP_GETFH:
9999 last_fh_hash = 0;
10000 break;
10001
10002 case NFS4_OP_LINK:
10003 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, NULL);
10004 break;
10005
10006 case NFS4_OP_LOCK:
10007 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_lock_type, offset);
10008 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_lock_reclaim, offset);
10009 file_offset = tvb_get_ntoh64(tvb, offset);
10010 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10011 length64 = tvb_get_ntoh64(tvb, offset);
10012 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10013 offset = dissect_nfs4_locker(tvb, offset, newftree);
10014 if (length64 == G_GUINT64_CONSTANT(0xffffffffffffffff))
10015 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10016 " FH: 0x%08x Offset: %"G_GINT64_MODIFIER"u Length: <End of File>",
10017 last_fh_hash, file_offset);
10018 else
10019 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10020 " FH: 0x%08x Offset: %"G_GINT64_MODIFIER"u Length: %"G_GINT64_MODIFIER"u ",
10021 last_fh_hash, file_offset, length64);
10022 break;
10023
10024 case NFS4_OP_LOCKT:
10025 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_lock_type, offset);
10026 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10027 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10028 offset = dissect_nfs4_lock_owner(tvb, offset, newftree);
10029 break;
10030
10031 case NFS4_OP_LOCKU:
10032 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_lock_type, offset);
10033 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_seqid, offset);
10034 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10035 file_offset = tvb_get_ntoh64(tvb, offset);
10036 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10037 length64 = tvb_get_ntoh64(tvb, offset);
10038 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10039 if (length64 == G_GUINT64_CONSTANT(0xffffffffffffffff))
10040 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10041 " FH: 0x%08x Offset: %"G_GINT64_MODIFIER"u Length: <End of File>",
10042 last_fh_hash, file_offset);
10043 else
10044 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10045 " FH: 0x%08x Offset: %"G_GINT64_MODIFIER"u Length: %"G_GINT64_MODIFIER"u ",
10046 last_fh_hash, file_offset, length64);
10047 break;
10048
10049 case NFS4_OP_LOOKUP:
10050 /*name_offset = offset;*/
10051 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, &name);
10052 if (nfs_file_name_snooping) {
10053 nfs_name_snoop_add_name(civ->xid, tvb,
10054 /*name_offset, strlen(name), */
10055 0, 0,
10056 0, 0, name);
10057 }
10058 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " ");
10059 if (last_fh_hash != 0)
10060 wmem_strbuf_append_printf (op_summary[ops_counter].optext, "DH: 0x%08x/", last_fh_hash);
10061 if (name != NULL)
10062 wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", name);
10063 break;
10064
10065 case NFS4_OP_LOOKUPP:
10066 break;
10067
10068 case NFS4_OP_NVERIFY:
10069 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ);
10070 if (last_fh_hash != 0)
10071 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10072 break;
10073
10074 case NFS4_OP_OPEN:
10075 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10076 offset = dissect_nfs4_open_share_access(tvb, offset, newftree);
10077 offset = dissect_nfs4_open_share_deny(tvb, offset, newftree);
10078 offset = dissect_nfs4_open_owner(tvb, offset, newftree);
10079 offset = dissect_nfs4_openflag(tvb, offset, pinfo, newftree, civ);
10080 offset = dissect_nfs4_open_claim(tvb, offset, pinfo, newftree, &name, civ);
10081 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " ");
10082 if (last_fh_hash != 0)
10083 wmem_strbuf_append_printf (op_summary[ops_counter].optext, "DH: 0x%08x/", last_fh_hash);
10084 if (name != NULL)
10085 wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", name);
10086 break;
10087
10088 case NFS4_OP_OPENATTR:
10089 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_attr_dir_create, offset);
10090 break;
10091
10092 case NFS4_OP_OPEN_CONFIRM:
10093 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10094 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10095 break;
10096
10097 case NFS4_OP_OPEN_DOWNGRADE:
10098 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10099 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10100 offset = dissect_nfs4_open_share_access(tvb, offset, newftree);
10101 offset = dissect_nfs4_open_share_deny(tvb, offset, newftree);
10102 break;
10103
10104 case NFS4_OP_PUTFH:
10105 offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", &last_fh_hash, civ);
10106 break;
10107
10108 case NFS4_OP_PUTPUBFH:
10109 case NFS4_OP_PUTROOTFH:
10110 break;
10111
10112 case NFS4_OP_READ:
10113 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10114 file_offset = tvb_get_ntoh64(tvb, offset);
10115 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10116 length = tvb_get_ntohl(tvb, offset);
10117 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
10118 if (sid_hash != 0)
10119 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10120 " StateID: 0x%04x Offset: %" G_GINT64_MODIFIER "u Len: %u",
10121 sid_hash, file_offset, length);
10122 break;
10123
10124 case NFS4_OP_READDIR:
10125 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie, offset);
10126 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie_verf, offset);
10127 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_dircount, offset);
10128 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount, offset);
10129 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ);
10130 if (last_fh_hash != 0)
10131 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10132 break;
10133
10134 case NFS4_OP_READLINK:
10135 break;
10136
10137 case NFS4_OP_TEST_STATEID:
10138 offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_test_stateid_arg, hf_nfs4_test_stateid_arg);
10139 break;
10140
10141 case NFS4_OP_DESTROY_CLIENTID:
10142 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10143 break;
10144 case NFS4_OP_RECLAIM_COMPLETE:
10145 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_reclaim_one_fs, offset);
10146 break;
10147
10148 case NFS4_OP_REMOVE:
10149 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, &name);
10150 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " ");
10151 if (last_fh_hash != 0)
10152 wmem_strbuf_append_printf (op_summary[ops_counter].optext, "DH: 0x%08x/", last_fh_hash);
10153 if (name != NULL)
10154 wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", name);
10155 break;
10156
10157 case NFS4_OP_RENAME:
10158 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, &source_name);
10159 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_component, &dest_name);
10160 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " From: %s To: %s",
10161 source_name ? source_name : "Unknown", dest_name ? dest_name : "Unknown");
10162 break;
10163
10164 case NFS4_OP_RENEW:
10165 clientid = tvb_get_ntoh64(tvb, offset);
10166 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10167 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " CID: 0x%016"G_GINT64_MODIFIER"x", clientid);
10168
10169 break;
10170
10171 case NFS4_OP_RESTOREFH:
10172 last_fh_hash = saved_fh_hash;
10173 break;
10174
10175 case NFS4_OP_SAVEFH:
10176 saved_fh_hash = last_fh_hash;
10177 break;
10178
10179 case NFS4_OP_SECINFO:
10180 offset = dissect_nfs_utf8string(tvb, offset, newftree,
10181 hf_nfs4_component, NULL);
10182 break;
10183
10184 case NFS4_OP_SECINFO_NO_NAME:
10185 proto_tree_add_item(newftree, hf_nfs4_secinfo_style, tvb, offset, 4, ENC_BIG_ENDIAN);
10186 offset += 4;
10187 break;
10188
10189 case NFS4_OP_SETATTR:
10190 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10191 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ);
10192 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " FH: 0x%08x", last_fh_hash);
10193 break;
10194
10195 case NFS4_OP_SETCLIENTID:
10196 {
10197 proto_tree *client_tree = NULL;
10198 proto_tree *callback_tree = NULL;
10199
10200 client_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_client_id, NULL, "client");
10201
10202 offset = dissect_nfs4_client_id(tvb, offset, client_tree);
10203
10204 callback_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_cb_client, NULL, "callback");
10205
10206 offset = dissect_nfs4_cb_client4(tvb, offset, callback_tree);
10207
10208 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_callback_ident,
10209 offset);
10210 }
10211 break;
10212
10213 case NFS4_OP_SETCLIENTID_CONFIRM:
10214 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10215 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
10216 break;
10217
10218 case NFS4_OP_VERIFY:
10219 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ);
10220 break;
10221
10222 case NFS4_OP_WRITE:
10223 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10224 file_offset = tvb_get_ntoh64(tvb, offset);
10225 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10226 offset = dissect_nfs4_stable_how(tvb, offset, newftree, "stable");
10227 string_length = tvb_get_ntohl(tvb, offset+0);
10228 dissect_rpc_uint32(tvb, newftree, hf_nfs4_write_data_length, offset); /* don't change offset */
10229 offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs_data);
10230 if (sid_hash != 0)
10231 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10232 " StateID: 0x%04x Offset: %"G_GINT64_MODIFIER"u Len: %u",
10233 sid_hash, file_offset, string_length);
10234 break;
10235
10236 case NFS4_OP_RELEASE_LOCKOWNER:
10237 offset = dissect_nfs4_lock_owner(tvb, offset, newftree);
10238 break;
10239
10240 /* Minor Version 1 */
10241 case NFS4_OP_BACKCHANNEL_CTL:
10242 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_cb_program, offset);
10243 offset = dissect_rpc_secparms4(tvb, offset, newftree);
10244 break;
10245 case NFS4_OP_BIND_CONN_TO_SESSION:
10246 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10247 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_bctsa_dir, offset);
10248 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_bctsa_use_conn_in_rdma_mode, offset);
10249 break;
10250
10251 case NFS4_OP_EXCHANGE_ID:
10252 {
10253 proto_tree *eia_clientowner_tree;
10254
10255 eia_clientowner_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_clientowner, NULL, "eia_clientowner");
10256 offset = dissect_rpc_uint64(tvb, eia_clientowner_tree, hf_nfs4_verifier, offset);
10257 offset = dissect_nfsdata(tvb, offset, eia_clientowner_tree, hf_nfs_data);
10258
10259 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);
10260 offset += 4;
10261
10262 offset = dissect_nfs4_state_protect_a(tvb, offset, pinfo, newftree);
10263 offset = dissect_rpc_nfs_impl_id4(tvb, offset, newftree, "eia_client_impl_id");
10264 }
10265 break;
10266
10267 case NFS4_OP_CREATE_SESSION:
10268 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10269 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10270 offset = dissect_nfs_create_session_flags(tvb, offset, newftree,
10271 hf_nfs4_create_session_flags_csa);
10272 offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csa_fore_chan_attrs");
10273 offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csa_back_chan_attrs");
10274 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_cb_program, offset);
10275 offset = dissect_rpc_secparms4(tvb, offset, newftree);
10276 break;
10277
10278 case NFS4_OP_DESTROY_SESSION:
10279 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10280 break;
10281 case NFS4_OP_FREE_STATEID:
10282 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10283 wmem_strbuf_append_printf(op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
10284 break;
10285
10286 /* pNFS */
10287 case NFS4_OP_LAYOUTGET:
10288 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_layout_avail, offset);
10289 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10290 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_iomode, offset);
10291 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10292 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10293 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length_minlength, offset);
10294 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10295 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount,
10296 offset);
10297 break;
10298
10299 case NFS4_OP_LAYOUTCOMMIT:
10300 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10301 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10302 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_reclaim, offset);
10303 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10304 offset = dissect_nfs4_newoffset(tvb, offset, newftree);
10305 offset = dissect_nfs4_newtime(tvb, offset, newftree);
10306 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10307 offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs4_layoutupdate);
10308 break;
10309
10310 case NFS4_OP_LAYOUTRETURN:
10311 offset = dissect_nfs4_layoutreturn(tvb, offset, pinfo, newftree, civ);
10312 break;
10313
10314 case NFS4_OP_GETDEVINFO:
10315 offset = dissect_nfs4_deviceid(tvb, offset, newftree);
10316 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10317 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount, offset);
10318 offset = dissect_nfs4_notification_bitmap(tvb, newftree, pinfo, offset);
10319 break;
10320
10321 case NFS4_OP_GETDEVLIST:
10322 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_layout_type, offset);
10323 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count_maxcount, offset);
10324 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie, offset);
10325 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie_verf, offset);
10326 break;
10327
10328 case NFS4_OP_SEQUENCE:
10329 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10330 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10331 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
10332 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
10333 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_cachethis, offset);
10334 break;
10335
10336 case NFS4_OP_ALLOCATE:
10337 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10338 file_offset = tvb_get_ntoh64(tvb, offset);
10339 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10340 length64 = tvb_get_ntoh64(tvb, offset);
10341 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10342 if (sid_hash != 0)
10343 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10344 " StateID: 0x%04x"
10345 " Offset: %" G_GINT64_MODIFIER "u"
10346 " Len: %" G_GINT64_MODIFIER "u",
10347 sid_hash, file_offset, length64);
10348 break;
10349
10350 case NFS4_OP_COPY:
10351
10352 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10353 offset = dissect_nfs4_stateid(tvb, offset, newftree, &dst_sid_hash);
10354 file_offset = tvb_get_ntoh64(tvb, offset);
10355 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10356 dst_file_offset = tvb_get_ntoh64(tvb, offset);
10357 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10358 length64 = tvb_get_ntoh64(tvb, offset);
10359 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10360 if (sid_hash != 0)
10361 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10362 " Src StateID: 0x%04x"
10363 " Offset: %" G_GINT64_MODIFIER "u"
10364 " Len: %" G_GINT64_MODIFIER "u",
10365 sid_hash, file_offset, length64);
10366
10367 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_consecutive, offset);
10368 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_synchronous, offset);
10369
10370 /* FIXME: Report consecutive and sync? */
10371
10372 if (dst_sid_hash != 0)
10373 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10374 " Dst StateID: 0x%04x"
10375 " Offset: %" G_GINT64_MODIFIER "u",
10376 dst_sid_hash, dst_file_offset);
10377
10378 offset = dissect_nfs4_source_servers(tvb, offset, newftree);
10379 break;
10380
10381 case NFS4_OP_COPY_NOTIFY:
10382 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10383 if (sid_hash != 0)
10384 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10385 " StateID: 0x%04x",
10386 sid_hash);
10387
10388 offset = dissect_nfs4_netloc(tvb, offset, newftree);
10389
10390 break;
10391
10392 case NFS4_OP_DEALLOCATE:
10393 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10394 file_offset = tvb_get_ntoh64(tvb, offset);
10395 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10396 length64 = tvb_get_ntoh64(tvb, offset);
10397 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10398 if (sid_hash != 0)
10399 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10400 " StateID: 0x%04x"
10401 " Offset: %" G_GINT64_MODIFIER "u"
10402 " Len: %" G_GINT64_MODIFIER "u",
10403 sid_hash, file_offset, length64);
10404 break;
10405
10406 case NFS4_OP_IO_ADVISE:
10407 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10408 file_offset = tvb_get_ntoh64(tvb, offset);
10409 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10410 length64 = tvb_get_ntoh64(tvb, offset);
10411 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10412 if (sid_hash != 0)
10413 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10414 " StateID: 0x%04x"
10415 " Offset: %" G_GINT64_MODIFIER "u"
10416 " Len: %" G_GINT64_MODIFIER "u",
10417 sid_hash, file_offset, length64);
10418 offset = dissect_nfs4_io_hints(tvb, offset, pinfo, tree);
10419 break;
10420
10421 case NFS4_OP_OFFLOAD_CANCEL:
10422 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10423 if (sid_hash != 0)
10424 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10425 " StateID: 0x%04x",
10426 sid_hash);
10427 break;
10428
10429 case NFS4_OP_OFFLOAD_STATUS:
10430 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10431 if (sid_hash != 0)
10432 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10433 " StateID: 0x%04x",
10434 sid_hash);
10435 break;
10436
10437 case NFS4_OP_READ_PLUS:
10438 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10439 file_offset = tvb_get_ntoh64(tvb, offset);
10440 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10441 length = tvb_get_ntohl(tvb, offset);
10442 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
10443 if (sid_hash != 0)
10444 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10445 " StateID: 0x%04x Offset: %" G_GINT64_MODIFIER "u Len: %u",
10446 sid_hash, file_offset, length);
10447 break;
10448
10449 case NFS4_OP_LAYOUTERROR:
10450 file_offset = tvb_get_ntoh64(tvb, offset);
10451 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10452 length = tvb_get_ntohl(tvb, offset);
10453 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10454 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10455 if (sid_hash != 0)
10456 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10457 " StateID: 0x%04x Offset: %" G_GINT64_MODIFIER "u Len: %u",
10458 sid_hash, file_offset, length);
10459 offset = dissect_nfs4_device_errors(tvb, offset, newftree);
10460 break;
10461
10462 case NFS4_OP_LAYOUTSTATS:
10463 file_offset = tvb_get_ntoh64(tvb, offset);
10464 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10465 length = tvb_get_ntohl(tvb, offset);
10466 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10467 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10468 if (sid_hash != 0)
10469 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10470 " StateID: 0x%04x Offset: %" G_GINT64_MODIFIER "u Len: %u",
10471 sid_hash, file_offset, length);
10472 offset = dissect_nfs4_layoutstats(tvb, offset, pinfo, newftree, civ, TRUE);
10473 break;
10474
10475 case NFS4_OP_SEEK:
10476 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10477 file_offset = tvb_get_ntoh64(tvb, offset);
10478 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10479 proto_tree_add_item(newftree, hf_nfs4_seek_data_content, tvb,
10480 offset, 4, ENC_BIG_ENDIAN);
10481 offset += 4;
10482 if (sid_hash != 0)
10483 wmem_strbuf_append_printf(op_summary[ops_counter].optext,
10484 " StateID: 0x%04x Offset: %" G_GINT64_MODIFIER "u",
10485 sid_hash, file_offset);
10486 break;
10487
10488 case NFS4_OP_WRITE_SAME:
10489 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10490 offset = dissect_nfs4_stable_how(tvb, offset, newftree, "stable");
10491 offset = dissect_nfs4_app_data_block(tvb, offset, newftree, &hash);
10492 wmem_strbuf_append_printf(op_summary[ops_counter].optext,
10493 "Pattern Hash: 0x%08x", hash);
10494
10495 break;
10496
10497 case NFS4_OP_CLONE:
10498 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10499 offset = dissect_nfs4_stateid(tvb, offset, newftree, &dst_sid_hash);
10500 file_offset = tvb_get_ntoh64(tvb, offset);
10501 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10502 dst_file_offset = tvb_get_ntoh64(tvb, offset);
10503 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
10504 length64 = tvb_get_ntoh64(tvb, offset);
10505 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
10506 if (sid_hash != 0)
10507 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10508 " Src StateID: 0x%04x"
10509 " Offset: %" G_GINT64_MODIFIER "u"
10510 " Len: %" G_GINT64_MODIFIER "u",
10511 sid_hash, file_offset, length64);
10512
10513 if (dst_sid_hash != 0)
10514 wmem_strbuf_append_printf (op_summary[ops_counter].optext,
10515 " Dst StateID: 0x%04x"
10516 " Offset: %" G_GINT64_MODIFIER "u",
10517 dst_sid_hash, dst_file_offset);
10518
10519 break;
10520
10521 case NFS4_OP_GETXATTR:
10522 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_xattrkey, NULL);
10523 break;
10524
10525 case NFS4_OP_SETXATTR:
10526 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_setxattr_options, offset);
10527 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_xattrkey, NULL);
10528 offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs_data);
10529 break;
10530
10531 case NFS4_OP_LISTXATTRS:
10532 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_listxattr_cookie, offset);
10533 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_listxattr_maxcount, offset);
10534 break;
10535
10536 case NFS4_OP_REMOVEXATTR:
10537 offset = dissect_nfs_utf8string(tvb, offset, newftree, hf_nfs4_xattrkey, NULL);
10538 break;
10539
10540 /* In theory, it's possible to get this opcode */
10541 case NFS4_OP_ILLEGAL:
10542 break;
10543
10544 default:
10545 break;
10546 }
10547 }
10548
10549 /* Detect which tiers are present in this packet */
10550 for (summary_counter=0; summary_counter < ops_counter; summary_counter++)
10551 {
10552 current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
10553 if (current_tier < highest_tier)
10554 highest_tier = current_tier;
10555 }
10556
10557 /* Display packet summary */
10558 for (summary_counter=0; summary_counter < ops_counter; summary_counter++)
10559 {
10560 guint main_opcode;
10561 proto_item *main_op_item = NULL;
10562
10563 main_opcode = op_summary[summary_counter].opcode;
10564 current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
10565
10566 /* Display summary info only for operations that are "most significant".
10567 Controlled by a user option. */
10568 if (current_tier == highest_tier || !display_major_nfs4_ops) {
10569 if (current_tier == highest_tier) {
10570 const char *main_opname = NULL;
10571
10572 /* Display a filterable field of the most significant operations in all cases. */
10573 main_opname = val_to_str_ext_const(main_opcode, &names_nfs4_operation_ext, "Unknown");
10574 main_op_item = proto_tree_add_uint_format_value(tree, hf_nfs4_main_opcode, tvb, 0, 0,
10575 main_opcode, "%s (%u)", main_opname, main_opcode);
10576 proto_item_set_generated(main_op_item);
10577 }
10578
10579 if (first_operation == 0)
10580 /* Seperator between operation text */
10581 col_append_str(pinfo->cinfo, COL_INFO, " |");
10582
10583 if (wmem_strbuf_get_len(op_summary[summary_counter].optext) > 0)
10584 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10585 wmem_strbuf_get_str(op_summary[summary_counter].optext));
10586
10587 first_operation = 0;
10588 }
10589 }
10590
10591 return offset;
10592 }
10593
10594
10595 static int
dissect_nfs4_compound_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)10596 dissect_nfs4_compound_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
10597 {
10598 const char *tag = NULL;
10599 int offset = 0;
10600
10601 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_tag, &tag);
10602 /*
10603 * Display the NFSv4 tag. If it is empty, string generator will have returned "<EMPTY>",
10604 * in which case don't display anything */
10605 if (nfs_display_v4_tag && strncmp(tag, "<EMPTY>", 7) != 0)
10606 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
10607
10608 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_minorversion, offset);
10609 offset = dissect_nfs4_request_op(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
10610
10611 return offset;
10612 }
10613
10614
10615 static int
dissect_nfs4_secinfo_res(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)10616 dissect_nfs4_secinfo_res(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
10617 proto_tree *tree, void *data _U_)
10618 {
10619 guint flavor;
10620 proto_item *fitem;
10621 proto_tree *secftree;
10622
10623 fitem = proto_tree_add_item_ret_uint(tree, hf_nfs4_secinfo_flavor, tvb, offset, 4,
10624 ENC_BIG_ENDIAN, &flavor);
10625 offset += 4;
10626
10627 switch (flavor)
10628 {
10629 case RPCSEC_GSS:
10630 secftree = proto_item_add_subtree(fitem, ett_nfs4_secinfo_flavor_info);
10631 offset = dissect_nfs_rpcsec_gss_info(tvb, offset, secftree);
10632 break;
10633
10634 default:
10635 break;
10636 }
10637
10638 return offset;
10639 }
10640
10641
10642 static int
dissect_nfs4_offload_status_res(tvbuff_t * tvb,int offset,proto_tree * tree)10643 dissect_nfs4_offload_status_res(tvbuff_t *tvb, int offset, proto_tree *tree)
10644 {
10645 proto_item *sub_fitem;
10646 proto_tree *ss_tree;
10647 proto_tree *subtree;
10648 proto_item *ss_fitem;
10649 guint i;
10650 guint32 count;
10651
10652 /* Number of osr_complete status */
10653 sub_fitem = proto_tree_add_item_ret_uint(tree,
10654 hf_nfs4_num_offload_status, tvb, offset, 4,
10655 ENC_BIG_ENDIAN, &count);
10656 offset += 4;
10657
10658 subtree = proto_item_add_subtree(sub_fitem, ett_nfs4_osr_complete_sub);
10659 for (i = 0; i < count; i++) {
10660 ss_fitem = proto_tree_add_item(subtree,
10661 hf_nfs4_offload_status_index,
10662 tvb, offset, 4, ENC_BIG_ENDIAN);
10663
10664 ss_tree = proto_item_add_subtree(ss_fitem,
10665 ett_nfs4_osr_complete_sub);
10666
10667 offset = dissect_rpc_uint32(tvb, ss_tree, hf_nfs4_status, offset);
10668 }
10669
10670 return offset;
10671 }
10672
10673 static int
dissect_nfs4_response_op(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)10674 dissect_nfs4_response_op(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
10675 {
10676 guint highest_tier = 5;
10677 guint current_tier = 5;
10678 guint first_operation = 1;
10679 guint16 sid_hash = 0;
10680 guint32 last_fh_hash = 0;
10681 guint32 ops, ops_counter;
10682 guint32 summary_counter;
10683 guint32 opcode, status;
10684 const char *opname;
10685 proto_item *fitem, *ti;
10686 proto_tree *ftree = NULL;
10687 proto_tree *newftree = NULL;
10688 nfs4_operation_summary *op_summary;
10689
10690 ops = tvb_get_ntohl(tvb, offset+0);
10691
10692 fitem = proto_tree_add_uint_format(tree, hf_nfs4_ops_count, tvb, offset+0, 4, ops,
10693 "Operations (count: %u)", ops);
10694 offset += 4;
10695
10696 if (ops > MAX_NFSV4_OPS) {
10697 expert_add_info(pinfo, fitem, &ei_nfs_too_many_ops);
10698 ops = MAX_NFSV4_OPS;
10699 }
10700
10701 op_summary = wmem_alloc0_array(wmem_packet_scope(), nfs4_operation_summary, ops);
10702
10703 ftree = proto_item_add_subtree(fitem, ett_nfs4_response_op);
10704
10705 proto_item_append_text(tree, ", Ops(%d):", ops);
10706
10707 for (ops_counter = 0; ops_counter < ops; ops_counter++)
10708 {
10709 op_summary[ops_counter].optext = wmem_strbuf_new(wmem_packet_scope(), "");
10710 opcode = tvb_get_ntohl(tvb, offset);
10711 op_summary[ops_counter].iserror = FALSE;
10712 op_summary[ops_counter].opcode = opcode;
10713
10714 /* sanity check for bogus packets */
10715 if ((opcode < NFS4_OP_ACCESS || opcode > NFS4_LAST_OP) &&
10716 (opcode != NFS4_OP_ILLEGAL))
10717 break;
10718
10719 fitem = proto_tree_add_uint(ftree, hf_nfs4_op, tvb, offset, 4, opcode);
10720
10721 /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
10722 if (opcode == NFS4_OP_ILLEGAL) {
10723 newftree = proto_item_add_subtree(fitem, ett_nfs4_illegal);
10724 } else if (nfs4_operation_ett[opcode - 3]) {
10725 newftree = proto_item_add_subtree(fitem, *nfs4_operation_ett[opcode - 3]);
10726 } else {
10727 break;
10728 }
10729
10730 opname = val_to_str_ext_const(opcode, &names_nfs4_operation_ext, "Unknown");
10731 offset += 4;
10732 wmem_strbuf_append_printf (op_summary[ops_counter].optext, "%s", opname);
10733
10734 offset = dissect_nfs4_status(tvb, offset, newftree, &status);
10735 if (status != NFS4_OK) {
10736 proto_item_append_text(tree, " %s(%s)", opname,
10737 val_to_str_ext(status, &names_nfs4_status_ext, "Unknown error: %u"));
10738 } else {
10739 proto_item_append_text(tree, " %s", opname);
10740 }
10741
10742 /*
10743 * With the exception of NFS4_OP_LOCK, NFS4_OP_LOCKT,
10744 * NFS4_OP_SETATTR, NFS4_OP_SETCLIENTID, and NFS4_OP_COPY, all other
10745 * ops do *not* return data with the failed status code.
10746 */
10747 if (status != NFS4_OK
10748 && opcode != NFS4_OP_LOCK
10749 && opcode != NFS4_OP_LOCKT
10750 && opcode != NFS4_OP_SETATTR
10751 && opcode != NFS4_OP_SETCLIENTID
10752 && opcode != NFS4_OP_COPY) {
10753 op_summary[ops_counter].iserror = TRUE;
10754 continue;
10755 }
10756
10757 /* These parsing routines are only executed if the status is NFS4_OK */
10758 switch (opcode)
10759 {
10760 case NFS4_OP_ACCESS:
10761 offset = dissect_access_reply(tvb, offset, pinfo, fitem, 4, op_summary[ops_counter].optext, civ);
10762 break;
10763
10764 case NFS4_OP_CLOSE:
10765 ti = proto_tree_add_item(newftree, hf_nfs4_stateid, tvb, offset, 16, ENC_NA);
10766 expert_add_info(pinfo, ti, &ei_nfs4_stateid_deprecated);
10767 offset += 16;
10768 break;
10769
10770 case NFS4_OP_COMMIT:
10771 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
10772 break;
10773
10774 case NFS4_OP_CREATE:
10775 offset = dissect_nfs4_change_info(tvb, offset, newftree, "change_info");
10776 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ);
10777 break;
10778
10779 case NFS4_OP_GETATTR:
10780 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ);
10781 break;
10782
10783 case NFS4_OP_GETFH:
10784 offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "Filehandle", &last_fh_hash, civ);
10785 break;
10786
10787 case NFS4_OP_LINK:
10788 offset = dissect_nfs4_change_info(tvb, offset, newftree, "change_info");
10789 break;
10790
10791 case NFS4_OP_LOCK:
10792 case NFS4_OP_LOCKT:
10793 if (status == NFS4_OK)
10794 {
10795 if (opcode == NFS4_OP_LOCK)
10796 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10797 }
10798 else
10799 if (status == NFS4ERR_DENIED)
10800 offset = dissect_nfs4_lockdenied(tvb, offset, newftree);
10801 break;
10802
10803 case NFS4_OP_LOCKU:
10804 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10805 break;
10806
10807 case NFS4_OP_OPEN:
10808 offset = dissect_nfs4_stateid(tvb, offset, newftree, &sid_hash);
10809 offset = dissect_nfs4_change_info(tvb, offset, newftree,
10810 "change_info");
10811 offset = dissect_nfs4_open_rflags(tvb, offset, newftree);
10812 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ);
10813 offset = dissect_nfs4_open_delegation(tvb, offset, pinfo, newftree);
10814 wmem_strbuf_append_printf (op_summary[ops_counter].optext, " StateID: 0x%04x", sid_hash);
10815 break;
10816
10817 case NFS4_OP_OPEN_CONFIRM:
10818 case NFS4_OP_OPEN_DOWNGRADE:
10819 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10820 break;
10821
10822 case NFS4_OP_RESTOREFH:
10823 case NFS4_OP_SAVEFH:
10824 case NFS4_OP_PUTFH:
10825 break;
10826
10827 case NFS4_OP_READ:
10828 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
10829 dissect_rpc_uint32(tvb, newftree, hf_nfs4_read_data_length, offset); /* don't change offset */
10830 offset = dissect_nfsdata_reduced(R_NFSDATA, tvb, offset, newftree, hf_nfs_data, NULL);
10831 break;
10832
10833 case NFS4_OP_READDIR:
10834 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
10835 offset = dissect_nfs4_dirlist(tvb, offset, pinfo, newftree, civ);
10836 break;
10837
10838 case NFS4_OP_READLINK:
10839 offset = dissect_nfsdata_reduced(R_UTF8STRING, tvb, offset, newftree, hf_nfs4_linktext, NULL);
10840 break;
10841
10842 case NFS4_OP_RECLAIM_COMPLETE:
10843 break;
10844
10845 case NFS4_OP_REMOVE:
10846 offset = dissect_nfs4_change_info(tvb, offset, newftree, "change_info");
10847 break;
10848
10849 case NFS4_OP_RENAME:
10850 offset = dissect_nfs4_change_info(tvb, offset, newftree, "source_cinfo");
10851 offset = dissect_nfs4_change_info(tvb, offset, newftree, "target_cinfo");
10852 break;
10853
10854 case NFS4_OP_SECINFO:
10855 case NFS4_OP_SECINFO_NO_NAME:
10856 offset = dissect_rpc_array(tvb, pinfo, newftree, offset,
10857 dissect_nfs4_secinfo_res, hf_nfs4_secinfo_arr);
10858 break;
10859
10860 case NFS4_OP_SETATTR:
10861 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_BITMAP_ONLY, civ);
10862 break;
10863
10864 case NFS4_OP_SETCLIENTID:
10865 if (status == NFS4_OK) {
10866 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid,
10867 offset);
10868 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier,
10869 offset);
10870 } else if (status == NFS4ERR_CLID_INUSE)
10871 /*
10872 * XXX: below function actually assumes
10873 * this is for a callback. Fix:
10874 */
10875 offset = dissect_nfs4_clientaddr(tvb, offset, newftree);
10876 break;
10877
10878 case NFS4_OP_WRITE:
10879 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_count, offset);
10880 offset = dissect_nfs4_stable_how(tvb, offset, newftree, "committed");
10881 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_verifier, offset);
10882 break;
10883
10884 /* Minor Version 1 */
10885 case NFS4_OP_BIND_CONN_TO_SESSION:
10886 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10887 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_bctsr_dir, offset);
10888 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_bctsr_use_conn_in_rdma_mode, offset);
10889 break;
10890
10891 case NFS4_OP_EXCHANGE_ID: {
10892 proto_tree *eir_server_owner_tree = NULL;
10893
10894 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_clientid, offset);
10895 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10896
10897 proto_tree_add_bitmask(newftree, tvb, offset, hf_nfs4_exchid_reply_flags, ett_nfs4_exchangeid_reply_flags, nfs4_exchid_flags, ENC_BIG_ENDIAN);
10898 offset += 4;
10899
10900 offset = dissect_nfs4_state_protect_r(tvb, offset, pinfo, newftree);
10901
10902 eir_server_owner_tree = proto_tree_add_subtree(newftree, tvb, offset, 0, ett_nfs4_server_owner, NULL, "eir_server_owner");
10903 offset = dissect_rpc_serverowner4(tvb, offset, eir_server_owner_tree);
10904 offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs4_serverscope4);
10905 offset = dissect_rpc_nfs_impl_id4(tvb, offset, newftree, "eir_server_impl_id");
10906 }
10907 break;
10908 case NFS4_OP_CREATE_SESSION:
10909 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10910 offset = dissect_rpc_uint32(tvb, newftree,
10911 hf_nfs4_seqid, offset);
10912 offset = dissect_nfs_create_session_flags(tvb, offset, newftree,
10913 hf_nfs4_create_session_flags_csr);
10914 offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csr_fore_chan_attrs");
10915 offset = dissect_rpc_chanattrs4(tvb, offset, newftree, "csr_back_chan_attrs");
10916 break;
10917
10918 case NFS4_OP_DESTROY_SESSION:
10919 break;
10920 case NFS4_OP_FREE_STATEID:
10921 break;
10922 case NFS4_OP_TEST_STATEID:
10923 offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_test_stateid_res, hf_nfs4_test_stateid_res);
10924 break;
10925
10926 case NFS4_OP_LAYOUTGET:
10927 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_return_on_close,
10928 offset);
10929 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10930 offset = dissect_nfs4_layoutget(tvb, offset, pinfo, newftree, civ);
10931 break;
10932
10933 case NFS4_OP_LAYOUTCOMMIT:
10934 offset = dissect_nfs4_newsize(tvb, offset, newftree);
10935 break;
10936
10937 case NFS4_OP_LAYOUTRETURN:
10938 offset = dissect_nfs_layoutreturn_stateid(tvb, newftree, offset);
10939 break;
10940
10941 case NFS4_OP_GETDEVINFO:
10942 offset = dissect_nfs4_deviceaddr(tvb, offset, newftree);
10943 offset = dissect_nfs4_notification_bitmap(tvb, newftree, pinfo, offset);
10944 break;
10945
10946 case NFS4_OP_GETDEVLIST:
10947 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie, offset);
10948 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_cookie_verf, offset);
10949 offset = dissect_nfs4_devicelist(tvb, offset, newftree);
10950 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
10951 break;
10952
10953 case NFS4_OP_SEQUENCE:
10954 {
10955 static int * const sequence_flags[] = {
10956 &hf_nfs4_sequence_status_flags_cb_path_down,
10957 &hf_nfs4_sequence_status_flags_cb_gss_contexts_expiring,
10958 &hf_nfs4_sequence_status_flags_cb_gss_contexts_expired,
10959 &hf_nfs4_sequence_status_flags_expired_all_state_revoked,
10960 &hf_nfs4_sequence_status_flags_expired_some_state_revoked,
10961 &hf_nfs4_sequence_status_flags_admin_state_revoked,
10962 &hf_nfs4_sequence_status_flags_recallable_state_revoked,
10963 &hf_nfs4_sequence_status_flags_lease_moved,
10964 &hf_nfs4_sequence_status_flags_restart_reclaim_needed,
10965 &hf_nfs4_sequence_status_flags_cb_path_down_session,
10966 &hf_nfs4_sequence_status_flags_backchannel_fault,
10967 &hf_nfs4_sequence_status_flags_devid_changed,
10968 &hf_nfs4_sequence_status_flags_devid_deleted,
10969 NULL
10970 };
10971
10972 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
10973 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
10974 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
10975 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
10976 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_target_high_slotid, offset);
10977 proto_tree_add_bitmask(newftree, tvb, offset, hf_nfs4_sequence_status_flags, ett_nfs4_sequence_status_flags, sequence_flags, ENC_BIG_ENDIAN);
10978 offset += 4;
10979 }
10980 break;
10981
10982 case NFS4_OP_ALLOCATE:
10983 break;
10984
10985 case NFS4_OP_COPY:
10986
10987 if (status == NFS4_OK) {
10988 offset = dissect_nfs4_write_response(tvb, offset, newftree);
10989 offset = dissect_nfs4_copy_reqs(tvb, offset, newftree);
10990 } else if (status == NFS4ERR_OFFLOAD_NO_REQS)
10991 offset = dissect_nfs4_copy_reqs(tvb, offset, newftree);
10992
10993 break;
10994
10995 case NFS4_OP_COPY_NOTIFY:
10996
10997 offset = dissect_nfs4_nfstime(tvb, offset, newftree);
10998 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
10999 offset = dissect_nfs4_source_servers(tvb, offset, newftree);
11000
11001 break;
11002
11003 case NFS4_OP_DEALLOCATE:
11004 break;
11005
11006 case NFS4_OP_OFFLOAD_CANCEL:
11007 break;
11008
11009 case NFS4_OP_IO_ADVISE:
11010 offset = dissect_nfs4_io_hints(tvb, offset, pinfo, tree);
11011 break;
11012
11013 case NFS4_OP_OFFLOAD_STATUS:
11014 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_length, offset);
11015 offset = dissect_nfs4_offload_status_res(tvb, offset, newftree);
11016 break;
11017
11018 case NFS4_OP_READ_PLUS:
11019 if (status == NFS4_OK) {
11020 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
11021 offset = dissect_rpc_array(tvb, pinfo, newftree, offset, dissect_nfs4_read_plus_content, hf_nfs4_read_plus_contents);
11022 }
11023 break;
11024
11025 case NFS4_OP_LAYOUTERROR:
11026 break;
11027
11028 case NFS4_OP_LAYOUTSTATS:
11029 break;
11030
11031 case NFS4_OP_SEEK:
11032 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_eof, offset);
11033 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_offset, offset);
11034 break;
11035
11036 case NFS4_OP_WRITE_SAME:
11037 if (status == NFS4_OK) {
11038 offset = dissect_nfs4_write_response(tvb, offset, newftree);
11039 }
11040 break;
11041
11042 case NFS4_OP_CLONE:
11043 break;
11044
11045 case NFS4_OP_GETXATTR:
11046 if (status == NFS4_OK) {
11047 offset = dissect_nfsdata(tvb, offset, newftree, hf_nfs_data);
11048 }
11049 break;
11050
11051 case NFS4_OP_SETXATTR:
11052 if (status == NFS4_OK) {
11053 offset = dissect_nfs4_change_info(tvb, offset, newftree, "cinfo");
11054 }
11055 break;
11056
11057 case NFS4_OP_LISTXATTRS:
11058 if (status == NFS4_OK) {
11059 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_listxattr_cookie, offset);
11060 offset = dissect_nfs4_listxattr_names(tvb, offset, newftree);
11061 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_listxattr_eof, offset);
11062 }
11063 break;
11064
11065 case NFS4_OP_REMOVEXATTR:
11066 if (status == NFS4_OK) {
11067 offset = dissect_nfs4_change_info(tvb, offset, newftree, "cinfo");
11068 }
11069 break;
11070
11071 default:
11072 break;
11073 }
11074 }
11075
11076 /* Detect which tiers are present in this packet */
11077 for (summary_counter = 0; summary_counter < ops_counter; summary_counter++)
11078 {
11079 current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
11080 if (current_tier < highest_tier)
11081 highest_tier = current_tier;
11082 }
11083
11084 /* Display packet summary */
11085 for (summary_counter = 0; summary_counter < ops_counter; summary_counter++)
11086 {
11087 guint main_opcode;
11088 proto_item *main_op_item = NULL;
11089
11090 main_opcode = op_summary[summary_counter].opcode;
11091 current_tier = NFS4_OPERATION_TIER(op_summary[summary_counter].opcode);
11092
11093 /* Display summary info only for operations that are "most significant".
11094 Controlled by a user option.
11095 Display summary info for operations that return an error as well. */
11096 if (current_tier == highest_tier
11097 || !display_major_nfs4_ops
11098 || op_summary[summary_counter].iserror == TRUE)
11099 {
11100 if (current_tier == highest_tier) {
11101 const char *main_opname = NULL;
11102
11103 /* Display a filterable field of the most significant operations in all cases. */
11104 main_opname = val_to_str_ext_const(main_opcode, &names_nfs4_operation_ext, "Unknown");
11105 main_op_item = proto_tree_add_uint_format_value(tree, hf_nfs4_main_opcode, tvb, 0, 0,
11106 main_opcode, "%s (%u)", main_opname, main_opcode);
11107 proto_item_set_generated(main_op_item);
11108 }
11109
11110 if (first_operation == 0)
11111 /* Seperator between operation text */
11112 col_append_str(pinfo->cinfo, COL_INFO, " |");
11113
11114 if (wmem_strbuf_get_len(op_summary[summary_counter].optext) > 0)
11115 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11116 wmem_strbuf_get_str(op_summary[summary_counter].optext));
11117 first_operation = 0;
11118 }
11119 }
11120
11121 return offset;
11122 }
11123
11124
11125 static int
dissect_nfs4_compound_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)11126 dissect_nfs4_compound_reply(tvbuff_t *tvb, packet_info *pinfo,
11127 proto_tree *tree, void *data)
11128 {
11129 guint32 status;
11130 const char *tag = NULL;
11131 int offset = 0;
11132
11133 offset = dissect_nfs4_status(tvb, offset, tree, &status);
11134 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_tag, &tag);
11135 /*
11136 * Display the NFSv4 tag. If it is empty, string generator will have returned "<EMPTY>", in
11137 * which case don't display anything */
11138 if (nfs_display_v4_tag && strncmp(tag, "<EMPTY>", 7) != 0)
11139 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
11140
11141 offset = dissect_nfs4_response_op(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
11142
11143 if (status != NFS4_OK)
11144 col_append_fstr(pinfo->cinfo, COL_INFO, " Status: %s",
11145 val_to_str_ext(status, &names_nfs4_status_ext, "Unknown error: %u"));
11146
11147 return offset;
11148 }
11149
11150
11151 /* proc number, "proc name", dissect_request, dissect_reply */
11152 static const vsff nfs3_proc[] = {
11153 { 0, "NULL", /* OK */
11154 dissect_nfs3_null_call, dissect_nfs3_null_reply },
11155 { 1, "GETATTR", /* OK */
11156 dissect_nfs3_getattr_call, dissect_nfs3_getattr_reply },
11157 { 2, "SETATTR", /* OK */
11158 dissect_nfs3_setattr_call, dissect_nfs3_setattr_reply },
11159 { 3, "LOOKUP", /* OK */
11160 dissect_nfs3_lookup_call, dissect_nfs3_lookup_reply },
11161 { 4, "ACCESS", /* OK */
11162 dissect_nfs3_access_call, dissect_nfs3_access_reply },
11163 { 5, "READLINK", /* OK */
11164 dissect_nfs3_readlink_call, dissect_nfs3_readlink_reply },
11165 { 6, "READ", /* OK */
11166 dissect_nfs3_read_call, dissect_nfs3_read_reply },
11167 { 7, "WRITE", /* OK */
11168 dissect_nfs3_write_call, dissect_nfs3_write_reply },
11169 { 8, "CREATE", /* OK */
11170 dissect_nfs3_create_call, dissect_nfs3_create_reply },
11171 { 9, "MKDIR", /* OK */
11172 dissect_nfs3_mkdir_call, dissect_nfs3_mkdir_reply },
11173 { 10, "SYMLINK", /* OK */
11174 dissect_nfs3_symlink_call, dissect_nfs3_symlink_reply },
11175 { 11, "MKNOD", /* OK */
11176 dissect_nfs3_mknod_call, dissect_nfs3_mknod_reply },
11177 { 12, "REMOVE", /* OK */
11178 dissect_nfs3_remove_call, dissect_nfs3_remove_reply },
11179 { 13, "RMDIR", /* OK */
11180 dissect_nfs3_rmdir_call, dissect_nfs3_rmdir_reply },
11181 { 14, "RENAME", /* OK */
11182 dissect_nfs3_rename_call, dissect_nfs3_rename_reply },
11183 { 15, "LINK", /* OK */
11184 dissect_nfs3_link_call, dissect_nfs3_link_reply },
11185 { 16, "READDIR", /* OK */
11186 dissect_nfs3_readdir_call, dissect_nfs3_readdir_reply },
11187 { 17, "READDIRPLUS", /* OK */
11188 dissect_nfs3_readdirplus_call, dissect_nfs3_readdirplus_reply },
11189 { 18, "FSSTAT", /* OK */
11190 dissect_nfs3_fsstat_call, dissect_nfs3_fsstat_reply },
11191 { 19, "FSINFO", /* OK */
11192 dissect_nfs3_fsinfo_call, dissect_nfs3_fsinfo_reply },
11193 { 20, "PATHCONF", /* OK */
11194 dissect_nfs3_pathconf_call, dissect_nfs3_pathconf_reply },
11195 { 21, "COMMIT", /* OK */
11196 dissect_nfs3_commit_call, dissect_nfs3_commit_reply },
11197 { 0, NULL, NULL, NULL }
11198 };
11199
11200 static const value_string nfs3_proc_vals[] = {
11201 { 0, "NULL" },
11202 { 1, "GETATTR" },
11203 { 2, "SETATTR" },
11204 { 3, "LOOKUP" },
11205 { 4, "ACCESS" },
11206 { 5, "READLINK" },
11207 { 6, "READ" },
11208 { 7, "WRITE" },
11209 { 8, "CREATE" },
11210 { 9, "MKDIR" },
11211 { 10, "SYMLINK" },
11212 { 11, "MKNOD" },
11213 { 12, "REMOVE" },
11214 { 13, "RMDIR" },
11215 { 14, "RENAME" },
11216 { 15, "LINK" },
11217 { 16, "READDIR" },
11218 { 17, "READDIRPLUS" },
11219 { 18, "FSSTAT" },
11220 { 19, "FSINFO" },
11221 { 20, "PATHCONF" },
11222 { 21, "COMMIT" },
11223 { 0, NULL }
11224 };
11225 static value_string_ext nfs3_proc_vals_ext = VALUE_STRING_EXT_INIT(nfs3_proc_vals);
11226
11227 /* End of NFS Version 3 */
11228
11229
11230 /* the call to dissect_nfs3_null_call & dissect_nfs3_null_reply is
11231 * intentional. The V4 NULLPROC is the same as V3.
11232 */
11233 static const vsff nfs4_proc[] = {
11234 { 0, "NULL",
11235 dissect_nfs3_null_call, dissect_nfs3_null_reply },
11236 { 1, "COMPOUND",
11237 dissect_nfs4_compound_call, dissect_nfs4_compound_reply },
11238 { 0, NULL, NULL, NULL }
11239 };
11240
11241 static const value_string nfs4_proc_vals[] = {
11242 { 0, "NULL" },
11243 { 1, "COMPOUND" },
11244 { 0, NULL }
11245 };
11246
11247 static const rpc_prog_vers_info nfs_vers_info[] = {
11248 { 2, nfs2_proc, &hf_nfs2_procedure },
11249 { 3, nfs3_proc, &hf_nfs3_procedure },
11250 { 4, nfs4_proc, &hf_nfs4_procedure },
11251 };
11252
11253 /*
11254 * Union of the NFSv2, NFSv3, and NFSv4 status codes.
11255 * Used for the "nfs.status" hidden field and in packet-nfsacl.c.
11256 */
11257 static const value_string names_nfs_nfsstat[] = {
11258 { 0, "OK" },
11259 { 1, "ERR_PERM" },
11260 { 2, "ERR_NOENT" },
11261 { 5, "ERR_IO" },
11262 { 6, "ERR_NXIO" },
11263 { 11, "ERR_EAGAIN" },
11264 { 13, "ERR_ACCESS" },
11265 { 17, "ERR_EXIST" },
11266 { 18, "ERR_XDEV" },
11267 { 19, "ERR_NODEV" },
11268 { 20, "ERR_NOTDIR" },
11269 { 21, "ERR_ISDIR" },
11270 { 22, "ERR_INVAL" },
11271 { 26, "ERR_TXTBSY" },
11272 { 27, "ERR_FBIG" },
11273 { 28, "ERR_NOSPC" },
11274 { 30, "ERR_ROFS" },
11275 { 31, "ERR_MLINK" },
11276 { 45, "ERR_OPNOTSUPP" },
11277 { 63, "ERR_NAMETOOLONG" },
11278 { 66, "ERR_NOTEMPTY" },
11279 { 69, "ERR_DQUOT" },
11280 { 70, "ERR_STALE" },
11281 { 71, "ERR_REMOTE" },
11282 { 99, "ERR_WFLUSH" },
11283 { 10001, "ERR_BADHANDLE" },
11284 { 10002, "ERR_NOT_SYNC" },
11285 { 10003, "ERR_BAD_COOKIE" },
11286 { 10004, "ERR_NOTSUPP" },
11287 { 10005, "ERR_TOOSMALL" },
11288 { 10006, "ERR_SERVERFAULT" },
11289 { 10007, "ERR_BADTYPE" },
11290 { 10008, "ERR_DELAY" },
11291 { 10009, "ERR_SAME" },
11292 { 10010, "ERR_DENIED" },
11293 { 10011, "ERR_EXPIRED" },
11294 { 10012, "ERR_LOCKED" },
11295 { 10013, "ERR_GRACE" },
11296 { 10014, "ERR_FHEXPIRED" },
11297 { 10015, "ERR_SHARE_DENIED" },
11298 { 10016, "ERR_WRONGSEC" },
11299 { 10017, "ERR_CLID_INUSE" },
11300 { 10018, "ERR_RESOURCE" },
11301 { 10019, "ERR_MOVED" },
11302 { 10020, "ERR_NOFILEHANDLE" },
11303 { 10021, "ERR_MINOR_VERS_MISMATCH" },
11304 { 10022, "ERR_STALE_CLIENTID" },
11305 { 10023, "ERR_STALE_STATEID" },
11306 { 10024, "ERR_OLD_STATEID" },
11307 { 10025, "ERR_BAD_STATEID" },
11308 { 10026, "ERR_BAD_SEQID" },
11309 { 10027, "ERR_NOT_SAME" },
11310 { 10028, "ERR_LOCK_RANGE" },
11311 { 10029, "ERR_SYMLINK" },
11312 { 10030, "ERR_READDIR_NOSPC" },
11313 { 10031, "ERR_LEASE_MOVED" },
11314 { 10032, "ERR_ATTRNOTSUPP" },
11315 { 10033, "ERR_NO_GRACE" },
11316 { 10034, "ERR_RECLAIM_BAD" },
11317 { 10035, "ERR_RECLAIM_CONFLICT" },
11318 { 10036, "ERR_BADXDR" },
11319 { 10037, "ERR_LOCKS_HELD" },
11320 { 10038, "ERR_OPENMODE" },
11321 { 10039, "ERR_BADOWNER" },
11322 { 10040, "ERR_BADCHAR" },
11323 { 10041, "ERR_BADNAME" },
11324 { 10042, "ERR_BAD_RANGE" },
11325 { 10043, "ERR_LOCK_NOTSUPP" },
11326 { 10044, "ERR_OP_ILLEGAL" },
11327 { 10045, "ERR_DEADLOCK" },
11328 { 10046, "ERR_FILE_OPEN" },
11329 { 10047, "ERR_ADMIN_REVOKED" },
11330 { 10048, "ERR_CB_PATH_DOWN" },
11331 { 10049, "ERR_REPLAY_ME_or_BADIOMODE" },
11332 { 10050, "ERR_BADLAYOUT" },
11333 { 10051, "ERR_BAD_SESSION_DIGEST" },
11334 { 10052, "ERR_BADSESSION" },
11335 { 10053, "ERR_BADSLOT" },
11336 { 10054, "ERR_COMPLETE_ALREADY" },
11337 { 10055, "ERR_CONN_NOT_BOUND_TO_SESSION" },
11338 { 10056, "ERR_DELEG_ALREADY_WANTED" },
11339 { 10057, "ERR_BACK_CHAN_BUSY" },
11340 { 10058, "ERR_LAYOUTTRYLATER" },
11341 { 10059, "ERR_LAYOUTUNAVAILABLE" },
11342 { 10060, "ERR_NOMATCHING_LAYOUT" },
11343 { 10061, "ERR_RECALLCONFLICT" },
11344 { 10062, "ERR_UNKNOWN_LAYOUTTYPE" },
11345 { 10063, "ERR_SEQ_MISORDERED" },
11346 { 10064, "ERR_SEQUENCE_POS" },
11347 { 10065, "ERR_REQ_TOO_BIG" },
11348 { 10066, "ERR_REP_TOO_BIG" },
11349 { 10067, "ERR_REP_TOO_BIG_TO_CACHE" },
11350 { 10068, "ERR_RETRY_UNCACHED_REP" },
11351 { 10069, "ERR_UNSAFE_COMPOUND" },
11352 { 10070, "ERR_TOO_MANY_OPS" },
11353 { 10071, "ERR_OP_NOT_IN_SESSION" },
11354 { 10072, "ERR_HASH_ALG_UNSUPP" },
11355 { 10073, "NFS4ERR_CONN_BINDING_NOT_ENFORCED" },
11356 { 10074, "ERR_CLIENTID_BUSY" },
11357 { 10075, "ERR_PNFS_IO_HOLE" },
11358 { 10076, "ERR_SEQ_FALSE_RETRY" },
11359 { 10077, "ERR_BAD_HIGH_SLOT" },
11360 { 10078, "ERR_DEADSESSION" },
11361 { 10079, "ERR_ENCR_ALG_UNSUPP" },
11362 { 10080, "ERR_PNFS_NO_LAYOUT" },
11363 { 10081, "ERR_NOT_ONLY_OP" },
11364 { 10082, "ERR_WRONG_CRED" },
11365 { 10083, "ERR_WRONG_TYPE" },
11366 { 10084, "ERR_DIRDELEG_UNAVAIL" },
11367 { 10085, "ERR_REJECT_DELEG" },
11368 { 10086, "ERR_RETURNCONFLICT" },
11369 { 10087, "ERR_DELEG_REVOKED" },
11370 { 10088, "ERR_PARTNER_NOTSUPP" },
11371 { 10089, "ERR_PARTNER_NO_AUTH" },
11372 { 10090, "ERR_UNION_NOTSUPP" },
11373 { 10091, "ERR_OFFLOAD_DENIED" },
11374 { 10092, "ERR_WRONG_LFS" },
11375 { 10093, "ERR_BADLABEL" },
11376 { 10094, "ERR_OFFLOAD_NO_REQS" },
11377 { 0, NULL }
11378 };
11379 static value_string_ext names_nfs_nfsstat_ext = VALUE_STRING_EXT_INIT(names_nfs_nfsstat);
11380
11381 static const value_string iomode_names[] = {
11382 { 1, "IOMODE_READ" },
11383 { 2, "IOMODE_RW" },
11384 { 3, "IOMODE_ANY" },
11385 { 0, NULL }
11386 };
11387
11388 #if 0
11389 static const value_string stripetype_names[] = {
11390 { 1, "STRIPE_SPARSE" },
11391 { 2, "STRIPE_DENSE" },
11392 { 0, NULL }
11393 };
11394 #endif
11395
11396 static const value_string netloctype_names[] = {
11397 { NL4_NAME, "NL4_NAME" },
11398 { NL4_URL, "NL4_URL" },
11399 { NL4_NETADDR, "NL4_NETADDR" },
11400 { 0, NULL }
11401 };
11402
11403 static const value_string layouttype_names[] = {
11404 { 1, "LAYOUT4_NFSV4_1_FILES" },
11405 { 2, "LAYOUT4_OSD2_OBJECTS" },
11406 { 3, "LAYOUT4_BLOCK_VOLUME" },
11407 { 4, "LAYOUT4_FLEX_FILES" },
11408 { 5, "LAYOUT4_SCSI" },
11409 { 0, NULL }
11410 };
11411
11412 static const value_string layoutreturn_names[] = {
11413 { 1, "RETURN_FILE" },
11414 { 2, "RETURN_FSID" },
11415 { 3, "RETURN_ALL" },
11416 { 0, NULL }
11417 };
11418
11419 static const value_string nfs_fh_obj_id[] = {
11420 { 1, "NF4REG" },
11421 { 2, "NF4DIR" },
11422 { 3, "NF4BLK" },
11423 { 4, "NF4CHR" },
11424 { 5, "NF4LNK" },
11425 { 6, "NF4SOCK" },
11426 { 7, "NF4FIFO" },
11427 { 8, "NF4ATTRDIR" },
11428 { 9, "NF4NAMEDATTR"},
11429 { 0, NULL }
11430 };
11431
11432 static const true_false_string nfs4_ro_boolean = {
11433 "object is read only",
11434 "object is *not* read-only"
11435 };
11436
11437 static const value_string layoutrecall_names[] = {
11438 { 1, "RECALL_FILE" },
11439 { 2, "RECALL_FSID" },
11440 { 3, "RECALL_ALL" },
11441 { 0, NULL }
11442 };
11443
11444 /* NFS Callback */
11445 static int hf_nfs4_cb_procedure = -1;
11446 static int hf_nfs4_cb_op = -1;
11447 static int hf_nfs4_cb_truncate = -1;
11448 static int hf_nfs4_cb_layoutrecall_type = -1;
11449 static int hf_nfs4_cb_clorachanged = -1;
11450
11451 static gint ett_nfs4_cb_request_op = -1;
11452 static gint ett_nfs4_cb_resop = -1;
11453 static gint ett_nfs4_cb_getattr = -1;
11454 static gint ett_nfs4_cb_recall = -1;
11455 static gint ett_nfs4_cb_layoutrecall = -1;
11456 static gint ett_nfs4_cb_pushdeleg = -1;
11457 static gint ett_nfs4_cb_recallany = -1;
11458 static gint ett_nfs4_cb_recallableobjavail = -1;
11459 static gint ett_nfs4_cb_recallslot = -1;
11460 static gint ett_nfs4_cb_sequence = -1;
11461 static gint ett_nfs4_cb_wantscancelled = -1;
11462 static gint ett_nfs4_cb_notifylock = -1;
11463 static gint ett_nfs4_cb_notifydeviceid = -1;
11464 static gint ett_nfs4_cb_notify = -1;
11465 static gint ett_nfs4_cb_reflists = -1;
11466 static gint ett_nfs4_cb_refcalls = -1;
11467 static gint ett_nfs4_cb_illegal = -1;
11468
11469 static const value_string names_nfs_cb_operation[] = {
11470 { NFS4_OP_CB_GETATTR, "CB_GETATTR" },
11471 { NFS4_OP_CB_RECALL, "CB_RECALL" },
11472 { NFS4_OP_CB_LAYOUTRECALL, "CB_LAYOUTRECALL" },
11473 { NFS4_OP_CB_NOTIFY, "CB_NOTIFY" },
11474 { NFS4_OP_CB_PUSH_DELEG, "CB_PUSH_DELEG" },
11475 { NFS4_OP_CB_RECALL_ANY, "CB_RECALL_ANY" },
11476 { NFS4_OP_CB_RECALLABLE_OBJ_AVAIL, "CB_RECALLABLE_OBJ_AVAIL" },
11477 { NFS4_OP_CB_RECALL_SLOT, "CB_RECALL_SLOT"},
11478 { NFS4_OP_CB_SEQUENCE, "CB_SEQUENCE" },
11479 { NFS4_OP_CB_WANTS_CANCELLED, "CB_WANTS_CANCELLED" },
11480 { NFS4_OP_CB_NOTIFY_LOCK, "CB_NOTIFY_LOCK" },
11481 { NFS4_OP_CB_NOTIFY_DEVICEID, "CB_NOTIFY_DEVICEID" },
11482 { NFS4_OP_CB_OFFLOAD, "CB_OFFLOAD" },
11483 { NFS4_OP_CB_ILLEGAL, "CB_ILLEGAL"},
11484 { 0, NULL }
11485 };
11486 static value_string_ext names_nfs_cb_operation_ext = VALUE_STRING_EXT_INIT(names_nfs_cb_operation);
11487
11488 static gint *nfs4_cb_operation_ett[] =
11489 {
11490 &ett_nfs4_cb_getattr,
11491 &ett_nfs4_cb_recall,
11492 &ett_nfs4_cb_layoutrecall,
11493 &ett_nfs4_cb_notify,
11494 &ett_nfs4_cb_pushdeleg,
11495 &ett_nfs4_cb_recallany,
11496 &ett_nfs4_cb_recallableobjavail,
11497 &ett_nfs4_cb_recallslot,
11498 &ett_nfs4_cb_sequence,
11499 &ett_nfs4_cb_wantscancelled,
11500 &ett_nfs4_cb_notifylock,
11501 &ett_nfs4_cb_notifydeviceid,
11502 &ett_nfs4_cb_illegal
11503 };
11504
11505 static int
dissect_nfs4_cb_referring_calls(tvbuff_t * tvb,int offset,proto_tree * tree)11506 dissect_nfs4_cb_referring_calls(tvbuff_t *tvb, int offset, proto_tree *tree)
11507 {
11508 guint num_reflists, num_refcalls, i, j;
11509 proto_tree *rl_tree, *rc_tree;
11510
11511 num_reflists = tvb_get_ntohl(tvb, offset);
11512 rl_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4,
11513 ett_nfs4_cb_reflists, NULL, "referring call lists (count: %u)", num_reflists);
11514 offset += 4;
11515
11516 for (i = 0; i < num_reflists; i++) {
11517 offset = dissect_nfs4_sessionid(tvb, offset, rl_tree);
11518 num_refcalls = tvb_get_ntohl(tvb, offset);
11519 rc_tree = proto_tree_add_subtree_format(rl_tree, tvb, offset, 4,
11520 ett_nfs4_cb_refcalls, NULL, "referring calls (count: %u)", num_refcalls);
11521 offset += 4;
11522 for (j = 0; j < num_refcalls; j++) {
11523 offset = dissect_rpc_uint32(tvb, rc_tree, hf_nfs4_seqid, offset);
11524 offset = dissect_rpc_uint32(tvb, rc_tree, hf_nfs4_slotid, offset);
11525 }
11526 }
11527
11528 return offset;
11529 }
11530
11531 static int
dissect_nfs4_cb_layoutrecall(tvbuff_t * tvb,int offset,proto_tree * tree,packet_info * pinfo,rpc_call_info_value * civ)11532 dissect_nfs4_cb_layoutrecall(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo, rpc_call_info_value *civ)
11533 {
11534 guint recall_type;
11535
11536 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_layout_type, offset);
11537 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_iomode, offset);
11538 offset = dissect_rpc_bool(tvb, tree, hf_nfs4_cb_clorachanged, offset);
11539
11540 recall_type = tvb_get_ntohl(tvb, offset);
11541 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_cb_layoutrecall_type, offset);
11542
11543 if (recall_type == 1) { /* RECALL_FILE */
11544 offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "FileHandle", NULL, civ);
11545 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_offset, offset);
11546 offset = dissect_rpc_uint64(tvb, tree, hf_nfs4_length, offset);
11547 offset = dissect_nfs4_stateid(tvb, offset, tree, NULL);
11548 } else if (recall_type == 2) { /* RECALL_FSID */
11549 offset = dissect_nfs4_fsid(tvb, offset, tree, "fsid");
11550 }
11551
11552 return offset;
11553 }
11554
11555
11556 static int
dissect_nfs4_cb_request(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)11557 dissect_nfs4_cb_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
11558 {
11559 guint32 ops, ops_counter;
11560 guint32 status;
11561 guint opcode;
11562 proto_item *fitem;
11563 proto_tree *ftree;
11564 proto_tree *newftree = NULL;
11565
11566 ops = tvb_get_ntohl(tvb, offset+0);
11567
11568 ftree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_nfs4_cb_request_op, NULL, "Operations (count: %u)", ops);
11569 offset += 4;
11570
11571 for (ops_counter=0; ops_counter<ops; ops_counter++)
11572 {
11573 opcode = tvb_get_ntohl(tvb, offset);
11574 col_append_fstr(pinfo->cinfo, COL_INFO, "%c%s", ops_counter == 0?' ':';',
11575 val_to_str_ext_const(opcode, &names_nfs_cb_operation_ext, "Unknown"));
11576
11577 fitem = proto_tree_add_uint(ftree, hf_nfs4_cb_op, tvb, offset, 4, opcode);
11578 offset += 4;
11579
11580 /* the opcodes are not contiguous */
11581 if ((opcode < NFS4_OP_CB_GETATTR || opcode > NFS4_OP_CB_OFFLOAD) &&
11582 (opcode != NFS4_OP_CB_ILLEGAL))
11583 break;
11584
11585 /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
11586 if (opcode == NFS4_OP_CB_ILLEGAL)
11587 newftree = proto_item_add_subtree(fitem, ett_nfs4_cb_illegal);
11588 else if (nfs4_cb_operation_ett[opcode - 3])
11589 newftree = proto_item_add_subtree(fitem, *nfs4_cb_operation_ett[opcode - 3]);
11590 else
11591 break;
11592
11593 switch (opcode)
11594 {
11595 case NFS4_OP_CB_RECALL:
11596 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
11597 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_cb_truncate, offset);
11598 offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", NULL, civ);
11599 break;
11600 case NFS4_OP_CB_GETATTR:
11601 offset = dissect_nfs4_fh(tvb, offset, pinfo, tree, "FileHandle", NULL, civ);
11602 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, tree, FATTR4_BITMAP_ONLY, civ);
11603 break;
11604 case NFS4_OP_CB_LAYOUTRECALL:
11605 offset = dissect_nfs4_cb_layoutrecall(tvb, offset, newftree, pinfo, civ);
11606 break;
11607 case NFS4_OP_CB_NOTIFY:
11608 case NFS4_OP_CB_PUSH_DELEG:
11609 case NFS4_OP_CB_RECALL_ANY:
11610 case NFS4_OP_CB_RECALLABLE_OBJ_AVAIL:
11611 case NFS4_OP_CB_RECALL_SLOT:
11612 break;
11613 case NFS4_OP_CB_SEQUENCE:
11614 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
11615 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
11616 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
11617 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
11618 offset = dissect_rpc_bool(tvb, newftree, hf_nfs4_cachethis, offset);
11619 offset = dissect_nfs4_cb_referring_calls(tvb, offset, newftree);
11620 break;
11621 case NFS4_OP_CB_WANTS_CANCELLED:
11622 break;
11623 case NFS4_OP_CB_NOTIFY_LOCK:
11624 offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", NULL, civ);
11625 offset = dissect_nfs4_lock_owner(tvb, offset, newftree);
11626 break;
11627 case NFS4_OP_CB_NOTIFY_DEVICEID:
11628 break;
11629 case NFS4_OP_CB_OFFLOAD:
11630 offset = dissect_nfs4_fh(tvb, offset, pinfo, newftree, "FileHandle", NULL, civ);
11631 offset = dissect_nfs4_stateid(tvb, offset, newftree, NULL);
11632 offset = dissect_nfs4_status(tvb, offset, newftree, &status);
11633 if (status == NFS4_OK) {
11634 offset = dissect_nfs4_write_response(tvb, offset, newftree);
11635 } else {
11636 offset = dissect_rpc_uint64(tvb, newftree, hf_nfs4_bytes_copied, offset);
11637 }
11638 break;
11639 case NFS4_OP_ILLEGAL:
11640 break;
11641 default:
11642 break;
11643 }
11644 }
11645
11646 return offset;
11647 }
11648
11649
11650 static int
dissect_nfs4_cb_compound_call(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)11651 dissect_nfs4_cb_compound_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
11652 {
11653 const char *tag = NULL;
11654 int offset = 0;
11655
11656 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_tag, &tag);
11657
11658 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
11659
11660 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_minorversion, offset);
11661 offset = dissect_rpc_uint32(tvb, tree, hf_nfs4_callback_ident, offset);
11662 offset = dissect_nfs4_cb_request(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
11663
11664 return offset;
11665 }
11666
11667
11668 static int
dissect_nfs4_cb_resp_op(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,rpc_call_info_value * civ)11669 dissect_nfs4_cb_resp_op(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, rpc_call_info_value *civ)
11670 {
11671 guint32 ops, ops_counter;
11672 guint32 opcode;
11673 proto_item *fitem;
11674 proto_tree *ftree;
11675 proto_tree *newftree = NULL;
11676 guint32 status;
11677
11678 ops = tvb_get_ntohl(tvb, offset+0);
11679 ftree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_nfs4_cb_resop, NULL, "Operations (count: %u)", ops);
11680 offset += 4;
11681
11682 for (ops_counter = 0; ops_counter < ops; ops_counter++)
11683 {
11684 opcode = tvb_get_ntohl(tvb, offset);
11685
11686 /* sanity check for bogus packets */
11687 if ((opcode < NFS4_OP_CB_GETATTR || opcode > NFS4_OP_CB_OFFLOAD) &&
11688 (opcode != NFS4_OP_ILLEGAL))
11689 break;
11690
11691 col_append_fstr(pinfo->cinfo, COL_INFO, "%c%s", ops_counter == 0 ? ' ' : ';',
11692 val_to_str_ext_const(opcode, &names_nfs_cb_operation_ext, "Unknown"));
11693
11694 fitem = proto_tree_add_uint(ftree, hf_nfs4_cb_op, tvb, offset, 4, opcode);
11695 offset += 4;
11696
11697 /* all of the V4 ops are contiguous, except for NFS4_OP_ILLEGAL */
11698 if (opcode == NFS4_OP_ILLEGAL)
11699 newftree = proto_item_add_subtree(fitem, ett_nfs4_illegal);
11700 else if (nfs4_cb_operation_ett[opcode - 3])
11701 newftree = proto_item_add_subtree(fitem, *nfs4_cb_operation_ett[opcode - 3]);
11702 else
11703 break;
11704
11705 offset = dissect_nfs4_status(tvb, offset, newftree, &status);
11706
11707 /* are there any ops that return data with a failure (?) */
11708 if (status != NFS4_OK)
11709 continue;
11710
11711 /* These parsing routines are only executed if the status is NFS4_OK */
11712 switch (opcode)
11713 {
11714 case NFS4_OP_CB_RECALL:
11715 break;
11716 case NFS4_OP_CB_GETATTR:
11717 offset = dissect_nfs4_fattrs(tvb, offset, pinfo, newftree, FATTR4_DISSECT_VALUES, civ);
11718 break;
11719 case NFS4_OP_CB_LAYOUTRECALL:
11720 break;
11721 case NFS4_OP_CB_NOTIFY:
11722 case NFS4_OP_CB_PUSH_DELEG:
11723 case NFS4_OP_CB_RECALL_ANY:
11724 case NFS4_OP_CB_RECALLABLE_OBJ_AVAIL:
11725 case NFS4_OP_CB_RECALL_SLOT:
11726 break;
11727 case NFS4_OP_CB_SEQUENCE:
11728 offset = dissect_nfs4_sessionid(tvb, offset, newftree);
11729 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_seqid, offset);
11730 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_slotid, offset);
11731 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_high_slotid, offset);
11732 offset = dissect_rpc_uint32(tvb, newftree, hf_nfs4_target_high_slotid, offset);
11733 break;
11734 case NFS4_OP_CB_WANTS_CANCELLED:
11735 case NFS4_OP_CB_NOTIFY_LOCK:
11736 case NFS4_OP_CB_NOTIFY_DEVICEID:
11737 case NFS4_OP_CB_OFFLOAD:
11738 break;
11739 case NFS4_OP_ILLEGAL:
11740 break;
11741 default:
11742 break;
11743 }
11744 }
11745
11746 return offset;
11747 }
11748
11749
11750 static int
dissect_nfs4_cb_compound_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)11751 dissect_nfs4_cb_compound_reply(tvbuff_t *tvb, packet_info *pinfo,
11752 proto_tree *tree, void *data)
11753 {
11754 guint32 status;
11755 const char *tag = NULL;
11756 int offset = 0;
11757
11758 offset = dissect_nfs4_status(tvb, offset, tree, &status);
11759 offset = dissect_nfs_utf8string(tvb, offset, tree, hf_nfs4_tag, &tag);
11760 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tag);
11761
11762 offset = dissect_nfs4_cb_resp_op(tvb, offset, pinfo, tree, (rpc_call_info_value*)data);
11763
11764 return offset;
11765 }
11766
11767
11768 static const vsff nfs_cb_proc[] = {
11769 { 0, "CB_NULL",
11770 dissect_nfs3_null_call, dissect_nfs3_null_reply },
11771 { 1, "CB_COMPOUND",
11772 dissect_nfs4_cb_compound_call, dissect_nfs4_cb_compound_reply },
11773 { 0, NULL, NULL, NULL }
11774 };
11775
11776 static const value_string nfs_cb_proc_vals[] = {
11777 { 0, "CB_NULL" },
11778 { 1, "CB_COMPOUND" },
11779 { 0, NULL }
11780 };
11781
11782 /*
11783 * The version should be 4, but some Linux kernels set this field to 1.
11784 * "Temporarily" accommodate these servers.
11785 */
11786 static const rpc_prog_vers_info nfs_cb_vers_info[] = {
11787 { 1, nfs_cb_proc, &hf_nfs4_cb_procedure },
11788 { 4, nfs_cb_proc, &hf_nfs4_cb_procedure },
11789 };
11790
11791 void
proto_register_nfs(void)11792 proto_register_nfs(void)
11793 {
11794 static hf_register_info hf[] = {
11795 { &hf_nfs2_procedure, {
11796 "V2 Procedure", "nfs.procedure_v2", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
11797 &nfs2_proc_vals_ext, 0, NULL, HFILL }},
11798 { &hf_nfs3_procedure, {
11799 "V3 Procedure", "nfs.procedure_v3", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
11800 &nfs3_proc_vals_ext, 0, NULL, HFILL }},
11801 { &hf_nfs4_procedure, {
11802 "V4 Procedure", "nfs.procedure_v4", FT_UINT32, BASE_DEC,
11803 VALS(nfs4_proc_vals), 0, NULL, HFILL }},
11804 #if 0
11805 { &hf_nfs4_impl_id_len, {
11806 "Implementation ID length", "nfs.impl_id4.length", FT_UINT32, BASE_DEC,
11807 NULL, 0, NULL, HFILL }},
11808 #endif
11809 { &hf_nfs_fh_length, {
11810 "length", "nfs.fh.length", FT_UINT32, BASE_DEC,
11811 NULL, 0, "file handle length", HFILL }},
11812 { &hf_nfs_fh_hash, {
11813 "hash (CRC-32)", "nfs.fh.hash", FT_UINT32, BASE_HEX,
11814 NULL, 0, "file handle hash", HFILL }},
11815
11816
11817 { &hf_nfs_fh_mount_fileid, {
11818 "fileid", "nfs.fh.mount.fileid", FT_UINT32, BASE_DEC,
11819 NULL, 0, "mount point fileid", HFILL }},
11820 { &hf_nfs_fh_mount_generation, {
11821 "generation", "nfs.fh.mount.generation", FT_UINT32, BASE_HEX,
11822 NULL, 0, "mount point generation", HFILL }},
11823 { &hf_nfs_fh_flags, {
11824 "Flags", "nfs.fh.flags", FT_UINT16, BASE_HEX,
11825 NULL, 0, "file handle flags", HFILL }},
11826 { &hf_nfs_fh_snapid, {
11827 "snapid", "nfs.fh.snapid", FT_UINT8, BASE_DEC,
11828 NULL, 0, "snapshot ID", HFILL }},
11829 { &hf_nfs_fh_unused, {
11830 "unused", "nfs.fh.unused", FT_UINT8, BASE_DEC,
11831 NULL, 0, NULL, HFILL }},
11832 { &hf_nfs_fh_fileid, {
11833 "fileid", "nfs.fh.fileid", FT_UINT32, BASE_DEC,
11834 NULL, 0, "file ID", HFILL }},
11835 { &hf_nfs_fh_generation, {
11836 "generation", "nfs.fh.generation", FT_UINT32, BASE_HEX,
11837 NULL, 0, "inode generation", HFILL }},
11838 { &hf_nfs_fh_fsid, {
11839 "file system ID", "nfs.fh.fsid", FT_UINT32, BASE_CUSTOM,
11840 CF_FUNC(nfs_fmt_fsid), 0, NULL, HFILL }},
11841 { &hf_nfs_fh_export_fileid, {
11842 "fileid", "nfs.fh.export.fileid", FT_UINT32, BASE_DEC,
11843 NULL, 0, "export point fileid", HFILL }},
11844 { &hf_nfs_fh_export_generation, {
11845 "generation", "nfs.fh.export.generation", FT_UINT32, BASE_HEX,
11846 NULL, 0, "export point generation", HFILL }},
11847 { &hf_nfs_fh_export_snapid, {
11848 "snapid", "nfs.fh.export.snapid", FT_UINT8, BASE_DEC,
11849 NULL, 0, "export point snapid", HFILL }},
11850 { &hf_nfs_fh_exportid, {
11851 "exportid", "nfs.fh.exportid", FT_GUID, BASE_NONE,
11852 NULL, 0, "Gluster/NFS exportid", HFILL }},
11853 { &hf_nfs_fh_handle_type, {
11854 "Handle type", "nfs.fh.handletype", FT_UINT32, BASE_DEC,
11855 VALS(handle_type_strings), 0, "v4 handle type", HFILL }},
11856 { &hf_nfs_fh_file_flag_mntpoint, {
11857 "mount point", "nfs.fh.file.flag.mntpoint", FT_BOOLEAN, 16,
11858 TFS(&tfs_set_notset), 0x0001, "file flag: mountpoint", HFILL }},
11859 { &hf_nfs_fh_file_flag_snapdir, {
11860 "snapdir", "nfs.fh.file.flag.snapdir", FT_BOOLEAN, 16,
11861 TFS(&tfs_set_notset), 0x0002, "file flag: snapdir", HFILL }},
11862 { &hf_nfs_fh_file_flag_snapdir_ent, {
11863 "snapdir_ent", "nfs.fh.file.flag.snadir_ent", FT_BOOLEAN, 16,
11864 TFS(&tfs_set_notset), 0x0004, "file flag: snapdir_ent", HFILL }},
11865 { &hf_nfs_fh_file_flag_empty, {
11866 "empty", "nfs.fh.file.flag.empty", FT_BOOLEAN, 16,
11867 TFS(&tfs_set_notset), 0x0008, "file flag: empty", HFILL }},
11868 { &hf_nfs_fh_file_flag_vbn_access, {
11869 "vbn_access", "nfs.fh.file.flag.vbn_access", FT_BOOLEAN, 16,
11870 TFS(&tfs_set_notset), 0x0010, "file flag: vbn_access", HFILL }},
11871 { &hf_nfs_fh_file_flag_multivolume, {
11872 "multivolume", "nfs.fh.file.flag.multivolume", FT_BOOLEAN, 16,
11873 TFS(&tfs_set_notset), 0x0020, "file flag: multivolume", HFILL }},
11874 { &hf_nfs_fh_file_flag_metadata, {
11875 "metadata", "nfs.fh.file.flag.metadata", FT_BOOLEAN, 16,
11876 TFS(&tfs_set_notset), 0x0040, "file flag: metadata", HFILL }},
11877 { &hf_nfs_fh_file_flag_orphan, {
11878 "orphan", "nfs.fh.file.flag.orphan", FT_BOOLEAN, 16,
11879 TFS(&tfs_set_notset), 0x0080, "file flag: orphan", HFILL }},
11880 { &hf_nfs_fh_file_flag_foster, {
11881 "foster", "nfs.fh.file.flag.foster", FT_BOOLEAN, 16,
11882 TFS(&tfs_set_notset), 0x0100, "file flag: foster", HFILL }},
11883 { &hf_nfs_fh_file_flag_named_attr, {
11884 "named_attr", "nfs.fh.file.flag.named_attr", FT_BOOLEAN, 16,
11885 TFS(&tfs_set_notset), 0x0200, "file flag: named_attr", HFILL }},
11886 { &hf_nfs_fh_file_flag_exp_snapdir, {
11887 "exp_snapdir", "nfs.fh.file.flag.exp_snapdir", FT_BOOLEAN, 16,
11888 TFS(&tfs_set_notset), 0x0400, "file flag: exp_snapdir", HFILL }},
11889 { &hf_nfs_fh_file_flag_vfiler, {
11890 "vfiler", "nfs.fh.file.flag.vfiler", FT_BOOLEAN, 16,
11891 TFS(&tfs_set_notset), 0x0800, "file flag: vfiler", HFILL }},
11892 { &hf_nfs_fh_file_flag_aggr, {
11893 "aggr", "nfs.fh.file.flag.aggr", FT_BOOLEAN, 16,
11894 TFS(&tfs_set_notset), 0x1000, "file flag: aggr", HFILL }},
11895 { &hf_nfs_fh_file_flag_striped, {
11896 "striped", "nfs.fh.file.flag.striped", FT_BOOLEAN, 16,
11897 TFS(&tfs_set_notset), 0x2000, "file flag: striped", HFILL }},
11898 { &hf_nfs_fh_file_flag_private, {
11899 "private", "nfs.fh.file.flag.private", FT_BOOLEAN, 16,
11900 TFS(&tfs_set_notset), 0x4000, "file flag: private", HFILL }},
11901 { &hf_nfs_fh_file_flag_next_gen, {
11902 "next_gen", "nfs.fh.file.flag.next_gen", FT_BOOLEAN, 16,
11903 TFS(&tfs_set_notset), 0x8000, "file flag: next_gen", HFILL }},
11904 { &hf_nfs_fh_fsid_major16_mask, {
11905 "major", "nfs.fh.fsid.major", FT_UINT16, BASE_DEC,
11906 NULL, 0xFF00, "major file system ID", HFILL }},
11907 { &hf_nfs_fh_fsid_minor16_mask, {
11908 "minor", "nfs.fh.fsid.minor", FT_UINT16, BASE_DEC,
11909 NULL, 0x00FF, "minor file system ID", HFILL }},
11910 { &hf_nfs_fh_fsid_major16, {
11911 "major", "nfs.fh.fsid.major", FT_UINT16, BASE_DEC,
11912 NULL, 0x0, "major file system ID", HFILL }},
11913 { &hf_nfs_fh_fsid_minor16, {
11914 "minor", "nfs.fh.fsid.minor", FT_UINT16, BASE_DEC,
11915 NULL, 0x0, "minor file system ID", HFILL }},
11916 { &hf_nfs_fh_fsid_major32, {
11917 "major", "nfs.fh.fsid.major", FT_UINT32, BASE_DEC,
11918 NULL, 0xfffc, "major file system ID", HFILL }},
11919 { &hf_nfs_fh_fsid_minor32, {
11920 "minor", "nfs.fh.fsid.minor", FT_UINT32, BASE_DEC,
11921 NULL, 0x03ffff, "minor file system ID", HFILL }},
11922 { &hf_nfs_fh_fsid_inode, {
11923 "inode", "nfs.fh.fsid.inode", FT_UINT32, BASE_DEC,
11924 NULL, 0, "file system inode", HFILL }},
11925 { &hf_nfs_fh_gfid, {
11926 "gfid", "nfs.fh.gfid", FT_GUID, BASE_NONE,
11927 NULL, 0, "Gluster/NFS GFID", HFILL }},
11928 { &hf_nfs_fh_xfsid_major, {
11929 "exported major", "nfs.fh.xfsid.major", FT_UINT16, BASE_DEC,
11930 NULL, 0xFF00, "exported major file system ID", HFILL }},
11931 { &hf_nfs_fh_xfsid_minor, {
11932 "exported minor", "nfs.fh.xfsid.minor", FT_UINT16, BASE_DEC,
11933 NULL, 0x00FF, "exported minor file system ID", HFILL }},
11934 { &hf_nfs_fh_fstype, {
11935 "file system type", "nfs.fh.fstype", FT_UINT32, BASE_DEC,
11936 NULL, 0, NULL, HFILL }},
11937 { &hf_nfs_fh_fn, {
11938 "file number", "nfs.fh.fn", FT_UINT32, BASE_DEC,
11939 NULL, 0, NULL, HFILL }},
11940 { &hf_nfs_fh_fn_len, {
11941 "length", "nfs.fh.fn.len", FT_UINT32, BASE_DEC,
11942 NULL, 0, "file number length", HFILL }},
11943 { &hf_nfs_fh_fn_inode, {
11944 "inode", "nfs.fh.fn.inode", FT_UINT32, BASE_DEC,
11945 NULL, 0, "file number inode", HFILL }},
11946 { &hf_nfs_fh_fn_generation, {
11947 "generation", "nfs.fh.fn.generation", FT_UINT32, BASE_DEC,
11948 NULL, 0, "file number generation", HFILL }},
11949 { &hf_nfs_fh_xfn, {
11950 "exported file number", "nfs.fh.xfn", FT_UINT32, BASE_DEC,
11951 NULL, 0, NULL, HFILL }},
11952 { &hf_nfs_fh_xfn_len, {
11953 "length", "nfs.fh.xfn.len", FT_UINT32, BASE_DEC,
11954 NULL, 0, "exported file number length", HFILL }},
11955 { &hf_nfs_fh_xfn_inode, {
11956 "exported inode", "nfs.fh.xfn.inode", FT_UINT32, BASE_DEC,
11957 NULL, 0, "exported file number inode", HFILL }},
11958 { &hf_nfs_fh_xfn_generation, {
11959 "generation", "nfs.fh.xfn.generation", FT_UINT32, BASE_DEC,
11960 NULL, 0, "exported file number generation", HFILL }},
11961 { &hf_nfs_fh_dentry, {
11962 "dentry", "nfs.fh.dentry", FT_UINT32, BASE_HEX,
11963 NULL, 0, "dentry (cookie)", HFILL }},
11964 #if 0
11965 { &hf_nfs_fh_dev, {
11966 "device", "nfs.fh.dev", FT_UINT32, BASE_DEC,
11967 NULL, 0, NULL, HFILL }},
11968 #endif
11969 #if 0
11970 { &hf_nfs_fh_xdev, {
11971 "exported device", "nfs.fh.xdev", FT_UINT32, BASE_DEC,
11972 NULL, 0, NULL, HFILL }},
11973 #endif
11974 { &hf_nfs_fh_dirinode, {
11975 "directory inode", "nfs.fh.dirinode", FT_UINT32, BASE_DEC,
11976 NULL, 0, NULL, HFILL }},
11977 { &hf_nfs_fh_pinode, {
11978 "pseudo inode", "nfs.fh.pinode", FT_UINT32, BASE_HEX,
11979 NULL, 0, NULL, HFILL }},
11980 { &hf_nfs_fh_hp_len, {
11981 "length", "nfs.fh.hp.len", FT_UINT32, BASE_DEC,
11982 NULL, 0, "hash path length", HFILL }},
11983 { &hf_nfs_fh_hp_key, {
11984 "key", "nfs.fh.hp.key", FT_BYTES, BASE_NONE,
11985 NULL, 0, NULL, HFILL }},
11986 { &hf_nfs_fh_version, {
11987 "version", "nfs.fh.version", FT_UINT8, BASE_DEC,
11988 NULL, 0, "file handle layout version", HFILL }},
11989 { &hf_nfs_fh_auth_type, {
11990 "auth_type", "nfs.fh.auth_type", FT_UINT8, BASE_DEC,
11991 VALS(auth_type_names), 0, "authentication type", HFILL }},
11992 { &hf_nfs_fh_fsid_type, {
11993 "fsid_type", "nfs.fh.fsid_type", FT_UINT8, BASE_DEC,
11994 VALS(fsid_type_names), 0, "file system ID type", HFILL }},
11995 { &hf_nfs_fh_fileid_type, {
11996 "fileid_type", "nfs.fh.fileid_type", FT_UINT8, BASE_DEC,
11997 VALS(fileid_type_names), 0, "file ID type", HFILL }},
11998 { &hf_nfs_fh_obj_id, {
11999 "Object type", "nfs.fh.obj.id", FT_UINT32, BASE_DEC,
12000 VALS(nfs_fh_obj_id), 0, "Object ID", HFILL }},
12001 { &hf_nfs_fh_ro_node, {
12002 "RO_node", "nfs.fh.ro.node", FT_BOOLEAN, BASE_NONE,
12003 TFS(&nfs4_ro_boolean), 0, "Read Only Node", HFILL }},
12004 { &hf_nfs_fh_obj, {
12005 "Object info", "nfs.fh.obj.info", FT_BYTES, BASE_NONE,
12006 NULL, 0, "File/Dir/Object Info", HFILL }},
12007 { &hf_nfs_fh_obj_fsid, {
12008 "obj_fsid", "nfs.fh.obj.fsid", FT_UINT32, BASE_DEC,
12009 NULL, 0, "File system ID of the object", HFILL }},
12010 { &hf_nfs_fh_obj_kindid, {
12011 "obj_kindid", "nfs.fh.obj.kindid", FT_UINT16, BASE_DEC,
12012 NULL, 0, "KindID of the object", HFILL }},
12013 { &hf_nfs_fh_obj_treeid, {
12014 "obj_treeid", "nfs.fh.obj.treeid", FT_UINT16, BASE_DEC,
12015 NULL, 0, "TreeID of the object", HFILL }},
12016 { &hf_nfs_fh_obj_inode, {
12017 "obj_inode", "nfs.fh.obj.inode", FT_UINT32, BASE_DEC,
12018 NULL, 0, "Inode of the object", HFILL }},
12019 { &hf_nfs_fh_obj_gen, {
12020 "obj_gen", "nfs.fh.obj.gen", FT_UINT32, BASE_DEC,
12021 NULL, 0, "Generation ID of the object", HFILL }},
12022 { &hf_nfs_fh_ex, {
12023 "Export info", "nfs.fh.ex.info", FT_BYTES, BASE_NONE,
12024 NULL, 0, "Export Info (16 bytes)", HFILL }},
12025 { &hf_nfs_fh_ex_fsid, {
12026 "ex_fsid", "nfs.fh.ex.fsid", FT_UINT32, BASE_DEC,
12027 NULL, 0, "File system ID of the object", HFILL }},
12028 { &hf_nfs_fh_ex_kindid, {
12029 "ex_kindid", "nfs.fh.ex.kindid", FT_UINT16, BASE_DEC,
12030 NULL, 0, "KindID of the object", HFILL }},
12031 { &hf_nfs_fh_ex_treeid, {
12032 "ex_treeid", "nfs.fh.ex.treeid", FT_UINT16, BASE_DEC,
12033 NULL, 0, "TreeID of the object", HFILL }},
12034 { &hf_nfs_fh_ex_inode, {
12035 "ex_inode", "nfs.fh.ex.inode", FT_UINT32, BASE_DEC,
12036 NULL, 0, "Inode of the object", HFILL }},
12037 { &hf_nfs_fh_ex_gen, {
12038 "ex_gen", "nfs.fh.ex.gen", FT_UINT32, BASE_DEC,
12039 NULL, 0, "Generation ID of the object", HFILL }},
12040 { &hf_nfs_fh_flag, {
12041 "flag", "nfs.fh.flag", FT_UINT32, BASE_HEX,
12042 NULL, 0, "file handle flag", HFILL }},
12043 { &hf_nfs_fh_endianness, {
12044 "endianness", "nfs.fh.endianness", FT_BOOLEAN, BASE_NONE,
12045 TFS(&tfs_endianness), 0x0, "server native endianness", HFILL }},
12046 { &hf_nfs_fh_dc_opaque, {
12047 "fh opaque data", "nfs.fh.dc.opaque", FT_BYTES, BASE_NONE,
12048 NULL, 0, NULL, HFILL }},
12049 { &hf_nfs_fh_dc_exportid, {
12050 "export_id", "nfs.fh.dc.exportid", FT_UINT32, BASE_HEX,
12051 NULL, 0, NULL, HFILL }},
12052 { &hf_nfs_fh_dc_handle_type, {
12053 "fh type", "nfs.fh.dc.type", FT_UINT8, BASE_DEC,
12054 VALS(dcache_handle_types), 0, NULL, HFILL }},
12055 { &hf_nfs4_fh_pd_share, {
12056 "shareid", "nfs.fh.pd.shareid", FT_UINT32, BASE_DEC,
12057 NULL, 0, NULL, HFILL }},
12058 { &hf_nfs4_fh_pd_flags, {
12059 "flags", "nfs.fh.pd.flags", FT_UINT32, BASE_HEX,
12060 NULL, 0, NULL, HFILL }},
12061 { &hf_nfs4_fh_pd_flags_reserved, {
12062 "reserved", "nfs.fh.pd.flags.reserved", FT_UINT32, BASE_HEX,
12063 NULL, PD_RESERVED_MASK, NULL, HFILL }},
12064 { &hf_nfs4_fh_pd_flags_version, {
12065 "version", "nfs.fh.pd.flags.version", FT_UINT32, BASE_DEC,
12066 NULL, PD_VERSION_MASK, NULL, HFILL }},
12067 { &hf_nfs4_fh_pd_sites, {
12068 "sites", "nfs.fh.pd.sites", FT_UINT64, BASE_HEX,
12069 NULL, 0, NULL, HFILL }},
12070 { &hf_nfs4_fh_pd_sites_inum, {
12071 "inum", "nfs.fh.pd.sites.inum", FT_UINT64, BASE_HEX,
12072 NULL, PD_INUM_MASK, NULL, HFILL }},
12073 { &hf_nfs4_fh_pd_sites_siteid, {
12074 "siteid", "nfs.fh.pd.sites.siteid", FT_UINT16, BASE_DEC,
12075 NULL, PD_SITEID_MASK, NULL, HFILL }},
12076 { &hf_nfs4_fh_pd_spaces, {
12077 "spaces", "nfs.fh.pd.spaces", FT_UINT64, BASE_HEX,
12078 NULL, 0, NULL, HFILL }},
12079 { &hf_nfs4_fh_pd_spaces_snapid, {
12080 "snapid", "nfs.fh.pd.spaces.snapid", FT_UINT16, BASE_HEX,
12081 NULL, PD_SNAPID_MASK, NULL, HFILL }},
12082 { &hf_nfs4_fh_pd_spaces_container, {
12083 "container", "nfs.fh.pd.spaces.container", FT_UINT64, BASE_DEC,
12084 NULL, PD_CONTAINER_MASK, NULL, HFILL }},
12085 { &hf_nfs4_fh_pd_container, {
12086 "container", "nfs.fh.pd.container", FT_UINT64, BASE_DEC,
12087 NULL, 0, NULL, HFILL }},
12088 { &hf_nfs4_fh_pd_inum, {
12089 "inum", "nfs.fh.pd.inum", FT_UINT64, BASE_DEC,
12090 NULL, 0, NULL, HFILL }},
12091 { &hf_nfs2_status, {
12092 "Status", "nfs.status2", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12093 &names_nfs2_stat_ext, 0, "Reply status", HFILL }},
12094 { &hf_nfs_full_name, {
12095 "Full Name", "nfs.full_name", FT_STRING, BASE_NONE,
12096 NULL, 0, NULL, HFILL }},
12097 { &hf_nfs_name, {
12098 "Name", "nfs.name", FT_STRING, BASE_NONE,
12099 NULL, 0, NULL, HFILL }},
12100 { &hf_nfs2_readlink_data, {
12101 "Data", "nfs.readlink.data", FT_STRING, BASE_NONE,
12102 NULL, 0, "Symbolic Link Data", HFILL }},
12103 { &hf_nfs2_read_offset, {
12104 "Offset", "nfs.read.offset", FT_UINT32, BASE_DEC,
12105 NULL, 0, "Read Offset", HFILL }},
12106 { &hf_nfs2_read_count, {
12107 "Count", "nfs.read.count", FT_UINT32, BASE_DEC,
12108 NULL, 0, "Read Count", HFILL }},
12109 { &hf_nfs2_read_totalcount, {
12110 "Total Count", "nfs.read.totalcount", FT_UINT32, BASE_DEC,
12111 NULL, 0, "Total Count (obsolete)", HFILL }},
12112 { &hf_nfs_data, {
12113 "Data", "nfs.data", FT_BYTES, BASE_NONE,
12114 NULL, 0, NULL, HFILL }},
12115 { &hf_nfs4_read_data_length, {
12116 "Read length", "nfs.read.data_length", FT_UINT32, BASE_DEC,
12117 NULL, 0, "Length of read response", HFILL }},
12118 { &hf_nfs4_write_data_length, {
12119 "Write length", "nfs.write.data_length", FT_UINT32, BASE_DEC,
12120 NULL, 0, "Length of write request", HFILL }},
12121 { &hf_nfs2_write_beginoffset, {
12122 "Begin Offset", "nfs.write.beginoffset", FT_UINT32, BASE_DEC,
12123 NULL, 0, "Begin offset (obsolete)", HFILL }},
12124 { &hf_nfs2_write_offset, {
12125 "Offset", "nfs.write.offset", FT_UINT32, BASE_DEC,
12126 NULL, 0, NULL, HFILL }},
12127 { &hf_nfs2_write_totalcount, {
12128 "Total Count", "nfs.write.totalcount", FT_UINT32, BASE_DEC,
12129 NULL, 0, "Total Count (obsolete)", HFILL }},
12130 { &hf_nfs_symlink_to, {
12131 "To", "nfs.symlink.to", FT_STRING, BASE_NONE,
12132 NULL, 0, "Symbolic link destination name", HFILL }},
12133 { &hf_nfs2_readdir_cookie, {
12134 "Cookie", "nfs.readdir.cookie", FT_UINT32, BASE_DEC,
12135 NULL, 0, "Directory Cookie", HFILL }},
12136 { &hf_nfs2_readdir_count, {
12137 "Count", "nfs.readdir.count", FT_UINT32, BASE_DEC,
12138 NULL, 0, "Directory Count", HFILL }},
12139
12140 { &hf_nfs_readdir_entry, {
12141 "Entry", "nfs.readdir.entry", FT_NONE, BASE_NONE,
12142 NULL, 0, "Directory Entry", HFILL }},
12143
12144 { &hf_nfs2_readdir_entry_fileid, {
12145 "File ID", "nfs.readdir.entry.fileid", FT_UINT32, BASE_DEC,
12146 NULL, 0, NULL, HFILL }},
12147
12148 { &hf_nfs2_readdir_entry_name, {
12149 "Name", "nfs.readdir.entry.name", FT_STRING, BASE_NONE,
12150 NULL, 0, NULL, HFILL }},
12151
12152 { &hf_nfs2_readdir_entry_cookie, {
12153 "Cookie", "nfs.readdir.entry.cookie", FT_UINT32, BASE_DEC,
12154 NULL, 0, "Directory Cookie", HFILL }},
12155
12156 { &hf_nfs3_readdir_entry_fileid, {
12157 "File ID", "nfs.readdir.entry3.fileid", FT_UINT64, BASE_DEC,
12158 NULL, 0, NULL, HFILL }},
12159
12160 { &hf_nfs3_readdir_entry_name, {
12161 "Name", "nfs.readdir.entry3.name", FT_STRING, BASE_NONE,
12162 NULL, 0, NULL, HFILL }},
12163
12164 { &hf_nfs3_readdir_entry_cookie, {
12165 "Cookie", "nfs.readdir.entry3.cookie", FT_UINT64, BASE_DEC,
12166 NULL, 0, "Directory Cookie", HFILL }},
12167
12168 { &hf_nfs3_readdirplus_entry_fileid, {
12169 "File ID", "nfs.readdirplus.entry.fileid", FT_UINT64, BASE_DEC,
12170 NULL, 0, NULL, HFILL }},
12171
12172 { &hf_nfs3_readdirplus_entry_name, {
12173 "Name", "nfs.readdirplus.entry.name", FT_STRING, BASE_NONE,
12174 NULL, 0, NULL, HFILL }},
12175
12176 { &hf_nfs3_readdirplus_entry_cookie, {
12177 "Cookie", "nfs.readdirplus.entry.cookie", FT_UINT64, BASE_DEC,
12178 NULL, 0, "Directory Cookie", HFILL }},
12179
12180 { &hf_nfs_readdir_eof, {
12181 "EOF", "nfs.readdir.eof", FT_UINT32, BASE_DEC,
12182 NULL, 0, NULL, HFILL }},
12183
12184 { &hf_nfs2_statfs_tsize, {
12185 "Transfer Size", "nfs.statfs.tsize", FT_UINT32, BASE_DEC,
12186 NULL, 0, NULL, HFILL }},
12187 { &hf_nfs2_statfs_bsize, {
12188 "Block Size", "nfs.statfs.bsize", FT_UINT32, BASE_DEC,
12189 NULL, 0, NULL, HFILL }},
12190 { &hf_nfs2_statfs_blocks, {
12191 "Total Blocks", "nfs.statfs.blocks", FT_UINT32, BASE_DEC,
12192 NULL, 0, NULL, HFILL }},
12193 { &hf_nfs2_statfs_bfree, {
12194 "Free Blocks", "nfs.statfs.bfree", FT_UINT32, BASE_DEC,
12195 NULL, 0, NULL, HFILL }},
12196 { &hf_nfs2_statfs_bavail, {
12197 "Available Blocks", "nfs.statfs.bavail", FT_UINT32, BASE_DEC,
12198 NULL, 0, NULL, HFILL }},
12199 { &hf_nfs3_ftype, {
12200 "Type", "nfs.type", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12201 &names_nfs_ftype3_ext, 0, "File Type", HFILL }},
12202 { &hf_nfs3_status, {
12203 "Status", "nfs.status3", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12204 &names_nfs3_status_ext, 0, "Reply status", HFILL }},
12205 { &hf_nfs3_read_eof, {
12206 "EOF", "nfs.read.eof", FT_BOOLEAN, BASE_NONE,
12207 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12208 { &hf_nfs3_write_stable, {
12209 "Stable", "nfs.write.stable", FT_UINT32, BASE_DEC,
12210 VALS(names_stable_how), 0, NULL, HFILL }},
12211 { &hf_nfs3_write_committed, {
12212 "Committed", "nfs.write.committed", FT_UINT32, BASE_DEC,
12213 VALS(names_stable_how), 0, NULL, HFILL }},
12214 { &hf_nfs3_createmode, {
12215 "Create Mode", "nfs.createmode", FT_UINT32, BASE_DEC,
12216 VALS(names_createmode3), 0, NULL, HFILL }},
12217 { &hf_nfs3_fsstat_invarsec, {
12218 "invarsec", "nfs.fsstat.invarsec", FT_UINT32, BASE_DEC,
12219 NULL, 0, "probable number of seconds of file system invariance", HFILL }},
12220 { &hf_nfs3_fsinfo_rtmax, {
12221 "rtmax", "nfs.fsinfo.rtmax", FT_UINT32, BASE_DEC,
12222 NULL, 0, "maximum READ request", HFILL }},
12223 { &hf_nfs3_fsinfo_rtpref, {
12224 "rtpref", "nfs.fsinfo.rtpref", FT_UINT32, BASE_DEC,
12225 NULL, 0, "Preferred READ request size", HFILL }},
12226 { &hf_nfs3_fsinfo_rtmult, {
12227 "rtmult", "nfs.fsinfo.rtmult", FT_UINT32, BASE_DEC,
12228 NULL, 0, "Suggested READ multiple", HFILL }},
12229 { &hf_nfs3_fsinfo_wtmax, {
12230 "wtmax", "nfs.fsinfo.wtmax", FT_UINT32, BASE_DEC,
12231 NULL, 0, "Maximum WRITE request size", HFILL }},
12232 { &hf_nfs3_fsinfo_wtpref, {
12233 "wtpref", "nfs.fsinfo.wtpref", FT_UINT32, BASE_DEC,
12234 NULL, 0, "Preferred WRITE request size", HFILL }},
12235 { &hf_nfs3_fsinfo_wtmult, {
12236 "wtmult", "nfs.fsinfo.wtmult", FT_UINT32, BASE_DEC,
12237 NULL, 0, "Suggested WRITE multiple", HFILL }},
12238 { &hf_nfs3_fsinfo_dtpref, {
12239 "dtpref", "nfs.fsinfo.dtpref", FT_UINT32, BASE_DEC,
12240 NULL, 0, "Preferred READDIR request", HFILL }},
12241 { &hf_nfs3_fsinfo_maxfilesize, {
12242 "maxfilesize", "nfs.fsinfo.maxfilesize", FT_UINT64, BASE_DEC,
12243 NULL, 0, "Maximum file size", HFILL }},
12244 { &hf_nfs3_fsinfo_properties, {
12245 "Properties", "nfs.fsinfo.properties", FT_UINT32, BASE_HEX,
12246 NULL, 0, "File System Properties", HFILL }},
12247 { &hf_nfs3_fsinfo_properties_setattr, {
12248 "SETATTR can set time on server", "nfs.fsinfo.properties.setattr", FT_BOOLEAN, 32,
12249 TFS(&tfs_yes_no), FSF3_CANSETTIME, NULL, HFILL }},
12250 { &hf_nfs3_fsinfo_properties_pathconf, {
12251 "PATHCONF", "nfs.fsinfo.properties.pathconf", FT_BOOLEAN, 32,
12252 TFS(&tfs_nfs_pathconf), FSF3_HOMOGENEOUS, NULL, HFILL }},
12253 { &hf_nfs3_fsinfo_properties_symlinks, {
12254 "File System supports symbolic links", "nfs.fsinfo.properties.symlinks", FT_BOOLEAN, 32,
12255 TFS(&tfs_yes_no), FSF3_SYMLINK, NULL, HFILL }},
12256 { &hf_nfs3_fsinfo_properties_hardlinks, {
12257 "File System supports hard links", "nfs.fsinfo.properties.hardlinks", FT_BOOLEAN, 32,
12258 TFS(&tfs_yes_no), FSF3_LINK, NULL, HFILL }},
12259 { &hf_nfs3_pathconf_linkmax, {
12260 "linkmax", "nfs.pathconf.linkmax", FT_UINT32, BASE_DEC,
12261 NULL, 0, "Maximum number of hard links", HFILL }},
12262 { &hf_nfs3_pathconf_name_max, {
12263 "name_max", "nfs.pathconf.name_max", FT_UINT32, BASE_DEC,
12264 NULL, 0, "Maximum file name length", HFILL }},
12265 { &hf_nfs3_pathconf_no_trunc, {
12266 "no_trunc", "nfs.pathconf.no_trunc", FT_BOOLEAN, BASE_NONE,
12267 TFS(&tfs_yes_no), 0x0, "No long file name truncation", HFILL }},
12268 { &hf_nfs3_pathconf_chown_restricted, {
12269 "chown_restricted", "nfs.pathconf.chown_restricted", FT_BOOLEAN, BASE_NONE,
12270 TFS(&tfs_yes_no), 0x0, "chown is restricted to root", HFILL }},
12271 { &hf_nfs3_pathconf_case_insensitive, {
12272 "case_insensitive", "nfs.pathconf.case_insensitive", FT_BOOLEAN, BASE_NONE,
12273 TFS(&tfs_yes_no), 0x0, "file names are treated case insensitive", HFILL }},
12274 { &hf_nfs3_pathconf_case_preserving, {
12275 "case_preserving", "nfs.pathconf.case_preserving", FT_BOOLEAN, BASE_NONE,
12276 TFS(&tfs_yes_no), 0x0, "file name cases are preserved", HFILL }},
12277
12278 #if 0
12279 { &hf_nfs2_fattr_type, {
12280 "type", "nfs.fattr.type", FT_UINT32, BASE_DEC,
12281 NULL, 0, NULL, HFILL }},
12282 #endif
12283
12284 { &hf_nfs2_fattr_nlink, {
12285 "nlink", "nfs.fattr.nlink", FT_UINT32, BASE_DEC,
12286 NULL, 0, NULL, HFILL }},
12287
12288 { &hf_nfs2_fattr_uid, {
12289 "uid", "nfs.fattr.uid", FT_UINT32, BASE_DEC,
12290 NULL, 0, NULL, HFILL }},
12291
12292 { &hf_nfs2_fattr_gid, {
12293 "gid", "nfs.fattr.gid", FT_UINT32, BASE_DEC,
12294 NULL, 0, NULL, HFILL }},
12295
12296 { &hf_nfs2_fattr_size, {
12297 "size", "nfs.fattr.size", FT_UINT32, BASE_DEC,
12298 NULL, 0, NULL, HFILL }},
12299
12300 { &hf_nfs2_fattr_blocksize, {
12301 "blocksize", "nfs.fattr.blocksize", FT_UINT32, BASE_DEC,
12302 NULL, 0, NULL, HFILL }},
12303
12304 { &hf_nfs2_fattr_rdev, {
12305 "rdev", "nfs.fattr.rdev", FT_UINT32, BASE_DEC,
12306 NULL, 0, NULL, HFILL }},
12307
12308 { &hf_nfs2_fattr_blocks, {
12309 "blocks", "nfs.fattr.blocks", FT_UINT32, BASE_DEC,
12310 NULL, 0, NULL, HFILL }},
12311
12312 { &hf_nfs2_fattr_fsid, {
12313 "fsid", "nfs.fattr.fsid", FT_UINT32, BASE_HEX,
12314 NULL, 0, NULL, HFILL }},
12315
12316 { &hf_nfs2_fattr_fileid, {
12317 "fileid", "nfs.fattr.fileid", FT_UINT32, BASE_DEC,
12318 NULL, 0, NULL, HFILL }},
12319
12320 { &hf_nfs3_fattr_type, {
12321 "Type", "nfs.fattr3.type", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12322 &names_nfs_ftype3_ext, 0, NULL, HFILL }},
12323
12324 { &hf_nfs3_fattr_nlink, {
12325 "nlink", "nfs.fattr3.nlink", FT_UINT32, BASE_DEC,
12326 NULL, 0, NULL, HFILL }},
12327
12328 { &hf_nfs3_fattr_uid, {
12329 "uid", "nfs.fattr3.uid", FT_UINT32, BASE_DEC,
12330 NULL, 0, NULL, HFILL }},
12331
12332 { &hf_nfs3_fattr_gid, {
12333 "gid", "nfs.fattr3.gid", FT_UINT32, BASE_DEC,
12334 NULL, 0, NULL, HFILL }},
12335
12336 { &hf_nfs3_fattr_size, {
12337 "size", "nfs.fattr3.size", FT_UINT64, BASE_DEC,
12338 NULL, 0, NULL, HFILL }},
12339
12340 { &hf_nfs3_fattr_used, {
12341 "used", "nfs.fattr3.used", FT_UINT64, BASE_DEC,
12342 NULL, 0, NULL, HFILL }},
12343
12344 #if 0
12345 { &hf_nfs3_fattr_rdev, {
12346 "rdev", "nfs.fattr3.rdev", FT_UINT32, BASE_DEC,
12347 NULL, 0, NULL, HFILL }},
12348 #endif
12349
12350 { &hf_nfs3_fattr_fsid, {
12351 "fsid", "nfs.fattr3.fsid", FT_UINT64, BASE_HEX_DEC,
12352 NULL, 0, NULL, HFILL }},
12353
12354 { &hf_nfs3_fattr_fileid, {
12355 "fileid", "nfs.fattr3.fileid", FT_UINT64, BASE_DEC,
12356 NULL, 0, NULL, HFILL }},
12357
12358 { &hf_nfs3_wcc_attr_size, {
12359 "size", "nfs.wcc_attr.size", FT_UINT64, BASE_DEC,
12360 NULL, 0, NULL, HFILL }},
12361
12362 { &hf_nfs3_set_size, {
12363 "size", "nfs.set_size", FT_UINT64, BASE_DEC,
12364 NULL, 0, NULL, HFILL }},
12365
12366 { &hf_nfs3_uid, {
12367 "uid", "nfs.uid3", FT_UINT32, BASE_DEC,
12368 NULL, 0, NULL, HFILL }},
12369
12370 { &hf_nfs3_gid, {
12371 "gid", "nfs.gid3", FT_UINT32, BASE_DEC,
12372 NULL, 0, NULL, HFILL }},
12373
12374 { &hf_nfs3_cookie, {
12375 "cookie", "nfs.cookie3", FT_UINT64, BASE_DEC,
12376 NULL, 0, NULL, HFILL }},
12377
12378 { &hf_nfs3_offset, {
12379 "offset", "nfs.offset3", FT_UINT64, BASE_DEC,
12380 NULL, 0, NULL, HFILL }},
12381
12382 { &hf_nfs3_count, {
12383 "count", "nfs.count3", FT_UINT32, BASE_DEC,
12384 NULL, 0, NULL, HFILL }},
12385
12386 { &hf_nfs3_count_maxcount, {
12387 "maxcount", "nfs.count3_maxcount", FT_UINT32, BASE_DEC,
12388 NULL, 0, NULL, HFILL }},
12389
12390 { &hf_nfs3_count_dircount, {
12391 "dircount", "nfs.count3_dircount", FT_UINT32, BASE_DEC,
12392 NULL, 0, NULL, HFILL }},
12393
12394 { &hf_nfs3_fsstat_resok_tbytes, {
12395 "Total bytes", "nfs.fsstat3_resok.tbytes", FT_UINT64, BASE_DEC,
12396 NULL, 0, NULL, HFILL }},
12397
12398 { &hf_nfs3_fsstat_resok_fbytes, {
12399 "Free bytes", "nfs.fsstat3_resok.fbytes", FT_UINT64, BASE_DEC,
12400 NULL, 0, NULL, HFILL }},
12401
12402 { &hf_nfs3_fsstat_resok_abytes, {
12403 "Available free bytes", "nfs.fsstat3_resok.abytes", FT_UINT64, BASE_DEC,
12404 NULL, 0, NULL, HFILL }},
12405
12406 { &hf_nfs3_fsstat_resok_tfiles, {
12407 "Total file slots", "nfs.fsstat3_resok.tfiles", FT_UINT64, BASE_DEC,
12408 NULL, 0, NULL, HFILL }},
12409
12410 { &hf_nfs3_fsstat_resok_ffiles, {
12411 "Free file slots", "nfs.fsstat3_resok.ffiles", FT_UINT64, BASE_DEC,
12412 NULL, 0, NULL, HFILL }},
12413
12414 { &hf_nfs3_fsstat_resok_afiles, {
12415 "Available free file slots", "nfs.fsstat3_resok.afiles", FT_UINT64, BASE_DEC,
12416 NULL, 0, NULL, HFILL }},
12417
12418 /* NFSv4 */
12419
12420 { &hf_nfs4_status, {
12421 "Status", "nfs.nfsstat4", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12422 &names_nfs4_status_ext, 0, "Reply status", HFILL }},
12423
12424 { &hf_nfs4_op, {
12425 "Opcode", "nfs.opcode", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12426 &names_nfs4_operation_ext, 0, NULL, HFILL }},
12427
12428 { &hf_nfs4_op_mask, {
12429 "op_mask", "nfs.op_mask", FT_UINT32, BASE_HEX,
12430 NULL, 0, "Operation Mask", HFILL }},
12431
12432 { &hf_nfs4_main_opcode, {
12433 "Main Opcode", "nfs.main_opcode", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
12434 &names_nfs4_operation_ext, 0, "Main Operation number", HFILL }},
12435
12436 { &hf_nfs4_linktext, {
12437 "Link Contents", "nfs.symlink.linktext", FT_STRING, BASE_NONE,
12438 NULL, 0, "Symbolic link contents", HFILL }},
12439
12440 { &hf_nfs4_dir_entry_name, {
12441 "Name", "nfs.entry_name", FT_STRING, BASE_NONE,
12442 NULL, 0, "Directory entry name", HFILL }},
12443
12444 { &hf_nfs4_pathname_components, {
12445 "pathname components", "nfs.pathname.component.count", FT_UINT32, BASE_DEC,
12446 NULL, 0, "Number of Pathname component", HFILL }},
12447
12448 { &hf_nfs4_component, {
12449 "Name", "nfs.pathname.component", FT_STRING, BASE_NONE,
12450 NULL, 0, "Pathname component", HFILL }},
12451
12452 { &hf_nfs4_tag, {
12453 "Tag", "nfs.tag", FT_STRING, BASE_NONE,
12454 NULL, 0, NULL, HFILL }},
12455
12456 { &hf_nfs4_ops_count, {
12457 "Operations", "nfs.ops.count", FT_UINT32, BASE_DEC,
12458 NULL, 0, "Number of Operations", HFILL }},
12459
12460 { &hf_nfs4_clientid, {
12461 "clientid", "nfs.clientid", FT_UINT64, BASE_HEX,
12462 NULL, 0, "Client ID", HFILL }},
12463
12464 #if 0
12465 { &hf_nfs4_ace, {
12466 "ace", "nfs.ace", FT_STRING, BASE_NONE,
12467 NULL, 0, "Access Control Entry", HFILL }},
12468 #endif
12469
12470 { &hf_nfs4_recall, {
12471 "Recall", "nfs.recall", FT_BOOLEAN, BASE_NONE,
12472 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12473
12474 { &hf_nfs4_open_claim_type, {
12475 "Claim Type", "nfs.open.claim_type", FT_UINT32, BASE_DEC,
12476 VALS(names_claim_type4), 0, NULL, HFILL }},
12477
12478 { &hf_nfs4_opentype, {
12479 "Open Type", "nfs.open.opentype", FT_UINT32, BASE_DEC,
12480 VALS(names_opentype4), 0, NULL, HFILL }},
12481
12482 { &hf_nfs4_state_protect_how, {
12483 "eia_state_protect", "nfs.exchange_id.state_protect", FT_UINT32, BASE_DEC,
12484 VALS(names_state_protect_how4), 0, "State Protect How", HFILL }},
12485
12486 { &hf_nfs4_limit_by, {
12487 "Space Limit", "nfs.open.limit_by", FT_UINT32, BASE_DEC,
12488 VALS(names_limit_by4), 0, "Limit By", HFILL }},
12489
12490 { &hf_nfs4_open_delegation_type, {
12491 "Delegation Type", "nfs.open.delegation_type", FT_UINT32, BASE_DEC,
12492 VALS(names_open_delegation_type4), 0, NULL, HFILL }},
12493
12494 { &hf_nfs4_why_no_delegation, {
12495 "why no delegation", "nfs.open.why_no_delegation", FT_UINT32, BASE_DEC,
12496 VALS(names_why_no_delegation4), 0, NULL, HFILL }},
12497
12498 { &hf_nfs4_secinfo_style, {
12499 "Secinfo Style", "nfs.secinfo.style", FT_UINT32, BASE_DEC,
12500 VALS(names_secinfo_style4), 0, NULL, HFILL }},
12501
12502 { &hf_nfs4_ftype, {
12503 "ftype4", "nfs.nfs_ftype4", FT_UINT32, BASE_DEC,
12504 VALS(names_ftype4), 0, NULL, HFILL }},
12505
12506 { &hf_nfs4_change_info_atomic, {
12507 "Atomic", "nfs.change_info.atomic", FT_BOOLEAN, BASE_NONE,
12508 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12509
12510 { &hf_nfs4_open_share_access, {
12511 "share_access", "nfs.open4.share_access", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
12512 &names_open4_share_access_ext, 0, NULL, HFILL }},
12513
12514 { &hf_nfs4_open_share_deny, {
12515 "share_deny", "nfs.open4.share_deny", FT_UINT32, BASE_DEC,
12516 VALS(names_open4_share_deny), 0, NULL, HFILL }},
12517
12518 { &hf_nfs4_want_flags, {
12519 "wants", "nfs.want", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
12520 &names_open4_share_access_ext, 0, NULL, HFILL }},
12521
12522 { &hf_nfs4_want_notify_flags, {
12523 "want notification", "nfs.want_notification", FT_UINT32, BASE_HEX,
12524 NULL, 0, NULL, HFILL }},
12525
12526 { &hf_nfs4_want_signal_deleg_when_resrc_avail, {
12527 "want_signal_deleg_when_resrc_avail",
12528 "nfs.want_notification.when_resrc_avail", FT_BOOLEAN, 32,
12529 TFS(&tfs_set_notset), OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL, NULL, HFILL }},
12530
12531 { &hf_nfs4_want_push_deleg_when_uncontended, {
12532 "want_push_deleg_when_uncontended",
12533 "nfs.want_push_deleg_when_uncontended", FT_BOOLEAN, 32,
12534 TFS(&tfs_set_notset), OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED, NULL, HFILL }},
12535
12536 { &hf_nfs4_want_deleg_timestamps, {
12537 "want_deleg_timestamps",
12538 "nfs.want_deleg_timestamps", FT_BOOLEAN, 32,
12539 TFS(&tfs_set_notset), OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS, NULL, HFILL }},
12540
12541 { &hf_nfs4_seqid, {
12542 "seqid", "nfs.seqid", FT_UINT32, BASE_HEX,
12543 NULL, 0, "Sequence ID", HFILL }},
12544
12545 { &hf_nfs4_lock_seqid, {
12546 "lock_seqid", "nfs.lock_seqid", FT_UINT32, BASE_HEX,
12547 NULL, 0, "Lock Sequence ID", HFILL }},
12548
12549 { &hf_nfs4_reqd_attr, {
12550 "reqd_attr", "nfs.attr", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
12551 &fattr4_names_ext, 0, "Required Attribute", HFILL }},
12552
12553 { &hf_nfs4_reco_attr, {
12554 "reco_attr", "nfs.attr", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
12555 &fattr4_names_ext, 0, "Recommended Attribute", HFILL }},
12556
12557 { &hf_nfs4_attr_mask, {
12558 "Attr mask", "nfs.attr_mask", FT_UINT32, BASE_HEX,
12559 NULL, 0, "Attribute mask", HFILL }},
12560
12561 { &hf_nfs4_attr_count, {
12562 "Attr count", "nfs.attr_count", FT_UINT32, BASE_DEC,
12563 NULL, 0, NULL, HFILL }},
12564
12565 { &hf_nfs4_set_it_value_follows, {
12566 "set_it", "nfs.set_it", FT_UINT32, BASE_DEC,
12567 VALS(value_follows), 0, "How To Set Time", HFILL }},
12568
12569 { &hf_nfs4_time_how, {
12570 "set_it", "nfs.set_it", FT_UINT32, BASE_DEC,
12571 VALS(time_how), 0, "How To Set Time", HFILL }},
12572
12573 { &hf_nfs4_time_how4, {
12574 "set_it", "nfs.set_it", FT_UINT32, BASE_DEC,
12575 VALS(names_time_how4), 0, "How To Set Time", HFILL }},
12576
12577 { &hf_nfs4_fattr_link_support, {
12578 "fattr4_link_support", "nfs.fattr4_link_support", FT_BOOLEAN, BASE_NONE,
12579 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12580
12581 { &hf_nfs4_fattr_symlink_support, {
12582 "fattr4_symlink_support", "nfs.fattr4_symlink_support", FT_BOOLEAN, BASE_NONE,
12583 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12584
12585 { &hf_nfs4_fattr_named_attr, {
12586 "fattr4_named_attr", "nfs.fattr4_named_attr", FT_BOOLEAN, BASE_NONE,
12587 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12588
12589 { &hf_nfs4_fattr_unique_handles, {
12590 "fattr4_unique_handles", "nfs.fattr4_unique_handles", FT_BOOLEAN, BASE_NONE,
12591 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12592
12593 { &hf_nfs4_fattr_archive, {
12594 "fattr4_archive", "nfs.fattr4_archive", FT_BOOLEAN, BASE_NONE,
12595 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12596
12597 { &hf_nfs4_fattr_cansettime, {
12598 "fattr4_cansettime", "nfs.fattr4_cansettime", FT_BOOLEAN, BASE_NONE,
12599 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12600
12601 { &hf_nfs4_fattr_case_insensitive, {
12602 "fattr4_case_insensitive", "nfs.fattr4_case_insensitive", FT_BOOLEAN, BASE_NONE,
12603 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12604
12605 { &hf_nfs4_fattr_case_preserving, {
12606 "fattr4_case_preserving", "nfs.fattr4_case_preserving", FT_BOOLEAN, BASE_NONE,
12607 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12608
12609 { &hf_nfs4_fattr_chown_restricted, {
12610 "fattr4_chown_restricted", "nfs.fattr4_chown_restricted", FT_BOOLEAN, BASE_NONE,
12611 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12612
12613 { &hf_nfs4_fattr_fh_expire_type, {
12614 "fattr4_fh_expire_type", "nfs.fattr4_fh_expire_type", FT_UINT32, BASE_HEX,
12615 VALS(nfs4_fattr4_fh_expire_type_names), 0, NULL, HFILL }},
12616
12617 { &hf_nfs4_fattr_fh_expiry_noexpire_with_open, {
12618 "noexpire_with_open", "nfs.fattr4_fh_expire_type.noexpire_with_open",
12619 FT_BOOLEAN, 32,
12620 NULL, FH4_NOEXPIRE_WITH_OPEN, NULL, HFILL }},
12621 { &hf_nfs4_fattr_fh_expiry_volatile_any, {
12622 "volatile_any", "nfs.fattr4_fh_expire_type.volatile_any",
12623 FT_BOOLEAN, 32,
12624 NULL, FH4_NOEXPIRE_WITH_OPEN, NULL, HFILL }},
12625 { &hf_nfs4_fattr_fh_expiry_vol_migration, {
12626 "vol_migration", "nfs.fattr4_fh_expire_type.vol_migration",
12627 FT_BOOLEAN, 32,
12628 NULL, FH4_NOEXPIRE_WITH_OPEN, NULL, HFILL }},
12629 { &hf_nfs4_fattr_fh_expiry_vol_rename, {
12630 "vol_rename", "nfs.fattr4_fh_expire_type.vol_rename",
12631 FT_BOOLEAN, 32,
12632 NULL, FH4_NOEXPIRE_WITH_OPEN, NULL, HFILL }},
12633
12634 { &hf_nfs4_fattr_hidden, {
12635 "fattr4_hidden", "nfs.fattr4_hidden", FT_BOOLEAN, BASE_NONE,
12636 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12637
12638 { &hf_nfs4_fattr_homogeneous, {
12639 "fattr4_homogeneous", "nfs.fattr4_homogeneous", FT_BOOLEAN, BASE_NONE,
12640 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12641
12642 { &hf_nfs4_fattr_mimetype, {
12643 "fattr4_mimetype", "nfs.fattr4_mimetype", FT_STRING, BASE_NONE,
12644 NULL, 0, NULL, HFILL }},
12645
12646 { &hf_nfs4_fattr_no_trunc, {
12647 "fattr4_no_trunc", "nfs.fattr4_no_trunc", FT_BOOLEAN, BASE_NONE,
12648 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12649
12650 { &hf_nfs4_fattr_system, {
12651 "fattr4_system", "nfs.fattr4_system", FT_BOOLEAN, BASE_NONE,
12652 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12653
12654 { &hf_nfs4_who, {
12655 "Who", "nfs.who", FT_STRING, BASE_NONE,
12656 NULL, 0, NULL, HFILL }},
12657
12658 { &hf_nfs4_server, {
12659 "server", "nfs.server", FT_STRING, BASE_NONE,
12660 NULL, 0, NULL, HFILL }},
12661
12662 { &hf_nfs4_servers, {
12663 "servers", "nfs.servers", FT_NONE, BASE_NONE,
12664 NULL, 0, NULL, HFILL }},
12665
12666 { &hf_nfs4_fslocation, {
12667 "fs_location4", "nfs.fattr4.fs_location", FT_NONE, BASE_NONE,
12668 NULL, 0, NULL, HFILL }},
12669
12670 { &hf_nfs4_fattr_owner, {
12671 "fattr4_owner", "nfs.fattr4_owner", FT_STRING, BASE_NONE,
12672 NULL, 0, NULL, HFILL }},
12673
12674 { &hf_nfs4_fattr_owner_group, {
12675 "fattr4_owner_group", "nfs.fattr4_owner_group", FT_STRING, BASE_NONE,
12676 NULL, 0, NULL, HFILL }},
12677
12678 { &hf_nfs4_stable_how, {
12679 "stable_how4", "nfs.stable_how4", FT_UINT32, BASE_DEC,
12680 VALS(names_stable_how4), 0, NULL, HFILL }},
12681
12682 { &hf_nfs4_dirlist_eof, {
12683 "EOF", "nfs.dirlist4.eof", FT_BOOLEAN, BASE_NONE,
12684 TFS(&tfs_yes_no), 0x0, "There are no more entries", HFILL }},
12685
12686 /* StateID */
12687 { &hf_nfs4_stateid,{
12688 "StateID", "nfs.stateid", FT_BYTES, BASE_NONE,
12689 NULL, 0, NULL, HFILL }},
12690 { &hf_nfs4_stateid_hash,{
12691 "StateID Hash", "nfs.stateid.hash", FT_UINT16, BASE_HEX,
12692 NULL, 0, "CRC-16 hash", HFILL }},
12693 { &hf_nfs4_seqid_stateid, {
12694 "StateID seqid", "nfs.stateid.seqid", FT_UINT32, BASE_DEC,
12695 NULL, 0, NULL, HFILL }},
12696 { &hf_nfs4_stateid_other,{
12697 "StateID Other", "nfs.stateid.other", FT_BYTES, BASE_NONE,
12698 NULL, 0, "Unique component of StateID", HFILL }},
12699 { &hf_nfs4_stateid_other_hash,{
12700 "StateID Other hash", "nfs.stateid.other_hash", FT_UINT32, BASE_HEX,
12701 NULL, 0, "CRC-32 hash", HFILL }},
12702
12703 { &hf_nfs4_offset, {
12704 "offset", "nfs.offset4", FT_UINT64, BASE_DEC,
12705 NULL, 0, NULL, HFILL }},
12706
12707 { &hf_nfs4_specdata1, {
12708 "specdata1", "nfs.specdata1", FT_UINT32, BASE_DEC,
12709 NULL, 0, NULL, HFILL }},
12710
12711 { &hf_nfs4_specdata2, {
12712 "specdata2", "nfs.specdata2", FT_UINT32, BASE_DEC,
12713 NULL, 0, NULL, HFILL }},
12714
12715 { &hf_nfs4_lock_type, {
12716 "locktype", "nfs.locktype4", FT_UINT32, BASE_DEC,
12717 VALS(names_nfs_lock_type4), 0, NULL, HFILL }},
12718
12719 { &hf_nfs4_open_rflags, {
12720 "result flags", "nfs.open_rflags", FT_UINT32, BASE_HEX,
12721 NULL, 0, NULL, HFILL }},
12722
12723 { &hf_nfs4_open_rflags_confirm, {
12724 "confirm", "nfs.open_rflags.confirm",
12725 FT_BOOLEAN, 32,
12726 NULL, OPEN4_RESULT_CONFIRM, NULL, HFILL }},
12727
12728 { &hf_nfs4_open_rflags_locktype_posix, {
12729 "locktype posix", "nfs.open_rflags.locktype_posix",
12730 FT_BOOLEAN, 32,
12731 NULL, OPEN4_RESULT_LOCKTYPE_POSIX, NULL, HFILL }},
12732
12733 { &hf_nfs4_open_rflags_preserve_unlinked, {
12734 "preserve unlinked", "nfs.open_rflags.preserve_unlinked",
12735 FT_BOOLEAN, 32,
12736 NULL, OPEN4_RESULT_PRESERVE_UNLINKED, NULL, HFILL }},
12737
12738 { &hf_nfs4_open_rflags_may_notify_lock, {
12739 "may notify lock", "nfs.open_rflags.may_notify_lock",
12740 FT_BOOLEAN, 32,
12741 NULL, OPEN4_RESULT_MAY_NOTIFY_LOCK, NULL, HFILL }},
12742
12743 { &hf_nfs4_reclaim, {
12744 "reclaim", "nfs.reclaim4", FT_BOOLEAN, BASE_NONE,
12745 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12746
12747 { &hf_nfs4_length, {
12748 "length", "nfs.length4", FT_UINT64, BASE_DEC,
12749 NULL, 0, NULL, HFILL }},
12750
12751 { &hf_nfs4_changeid, {
12752 "changeid", "nfs.changeid4", FT_UINT64, BASE_DEC,
12753 NULL, 0, NULL, HFILL }},
12754
12755 { &hf_nfs4_changeid_before, {
12756 "changeid (before)", "nfs.changeid4.before", FT_UINT64, BASE_DEC,
12757 NULL, 0, NULL, HFILL }},
12758
12759 { &hf_nfs4_changeid_after, {
12760 "changeid (after)", "nfs.changeid4.after", FT_UINT64, BASE_DEC,
12761 NULL, 0, NULL, HFILL }},
12762
12763 { &hf_nfs4_time_seconds, {
12764 "seconds", "nfs.nfstime4.seconds", FT_UINT64, BASE_DEC,
12765 NULL, 0, NULL, HFILL }},
12766
12767 { &hf_nfs4_time_nseconds, {
12768 "nseconds", "nfs.nfstime4.nseconds", FT_UINT32, BASE_DEC,
12769 NULL, 0, NULL, HFILL }},
12770
12771 { &hf_nfs4_fsid_major, {
12772 "fsid4.major", "nfs.fsid4.major", FT_UINT64, BASE_DEC,
12773 NULL, 0, NULL, HFILL }},
12774
12775 { &hf_nfs4_fsid_minor, {
12776 "fsid4.minor", "nfs.fsid4.minor", FT_UINT64, BASE_DEC,
12777 NULL, 0, NULL, HFILL }},
12778
12779 { &hf_nfs4_acetype, {
12780 "acetype", "nfs.acetype4", FT_UINT32, BASE_DEC,
12781 VALS(names_acetype4), 0, NULL, HFILL }},
12782
12783 { &hf_nfs4_aceflags, {
12784 "ACE flags", "nfs.aceflags4", FT_UINT32, BASE_HEX,
12785 NULL, 0, NULL, HFILL }},
12786
12787 { &hf_nfs4_aceflag_file_inherit, {
12788 "File_Inherit", "nfs.aceflag4.file_inherit", FT_BOOLEAN, 32,
12789 TFS(&tfs_yes_no), ACE4_FLAG_FILE_INHERIT, NULL, HFILL }},
12790
12791 { &hf_nfs4_aceflag_dir_inherit, {
12792 "Directory_Inherit", "nfs.aceflag4.dir_inherit", FT_BOOLEAN, 32,
12793 TFS(&tfs_yes_no), ACE4_FLAG_DIRECTORY_INHERIT, NULL, HFILL }},
12794
12795 { &hf_nfs4_aceflag_no_prop_inherit, {
12796 "No_Propagate_Inherit", "nfs.aceflag4.no_prop_inherit", FT_BOOLEAN, 32,
12797 TFS(&tfs_yes_no), ACE4_FLAG_NO_PROPAGATE_INHERIT, NULL, HFILL }},
12798
12799 { &hf_nfs4_aceflag_inherit_only, {
12800 "Inherit_Only", "nfs.aceflag4.inherit_only", FT_BOOLEAN, 32,
12801 TFS(&tfs_yes_no), ACE4_FLAG_INHERIT_ONLY, NULL, HFILL }},
12802
12803 { &hf_nfs4_aceflag_successful_access, {
12804 "Successful_Access", "nfs.aceflag4.successful_access", FT_BOOLEAN, 32,
12805 TFS(&tfs_yes_no), ACE4_FLAG_SUCCESSFUL_ACCESS, NULL, HFILL }},
12806
12807 { &hf_nfs4_aceflag_failed_access, {
12808 "Failed_access", "nfs.aceflag4.failed_access", FT_BOOLEAN, 32,
12809 TFS(&tfs_yes_no), ACE4_FLAG_FAILED_ACCESS, NULL, HFILL }},
12810
12811 { &hf_nfs4_aceflag_id_group, {
12812 "Identifier_Group", "nfs.aceflag4.id_group", FT_BOOLEAN, 32,
12813 TFS(&tfs_yes_no), ACE4_FLAG_IDENTIFIER_GROUP, NULL, HFILL }},
12814
12815 { &hf_nfs4_aceflag_inherited_ace, {
12816 "Inherited_ACE", "nfs.aceflag4.inherited_ace", FT_BOOLEAN, 32,
12817 TFS(&tfs_yes_no), ACE4_FLAG_INHERITED_ACE, NULL, HFILL }},
12818
12819 { &hf_nfs4_acemask, {
12820 "ACE mask", "nfs.acemask4", FT_UINT32, BASE_HEX,
12821 NULL, 0, NULL, HFILL }},
12822
12823 { &hf_nfs4_ace_permission, {
12824 "perm", "nfs.ace_perm4", FT_UINT32, BASE_HEX,
12825 NULL, 0, NULL, HFILL }},
12826
12827 { &hf_nfs4_fattr_size, {
12828 "size", "nfs.fattr4.size", FT_UINT64, BASE_DEC,
12829 NULL, 0, NULL, HFILL }},
12830
12831 { &hf_nfs4_fattr_lease_time, {
12832 "lease_time", "nfs.fattr4.lease_time", FT_UINT32, BASE_DEC,
12833 NULL, 0, "Duration of the lease at server in seconds", HFILL }},
12834
12835 { &hf_nfs4_fattr_aclsupport, {
12836 "aclsupport", "nfs.fattr4.aclsupport", FT_UINT32, BASE_DEC,
12837 NULL, 0, NULL, HFILL }},
12838
12839 { &hf_nfs4_aclsupport_allow_acl, {
12840 "ALLOW", "nfs.fattr4.aclsupport.allow_acl", FT_BOOLEAN, 32,
12841 NULL, ACL4_SUPPORT_ALLOW_ACL, NULL, HFILL }},
12842
12843 { &hf_nfs4_aclsupport_deny_acl, {
12844 "DENY", "nfs.fattr4.aclsupport.deny_acl", FT_BOOLEAN, 32,
12845 NULL, ACL4_SUPPORT_DENY_ACL, NULL, HFILL }},
12846
12847 { &hf_nfs4_aclsupport_audit_acl, {
12848 "AUDIT", "nfs.fattr4.aclsupport.audit_acl", FT_BOOLEAN, 32,
12849 NULL, ACL4_SUPPORT_AUDIT_ACL, NULL, HFILL }},
12850
12851 { &hf_nfs4_aclsupport_alarm_acl, {
12852 "ALARM", "nfs.fattr4.aclsupport.alarm_acl", FT_BOOLEAN, 32,
12853 NULL, ACL4_SUPPORT_ALARM_ACL, NULL, HFILL }},
12854
12855 { &hf_nfs4_fattr_fileid, {
12856 "fileid", "nfs.fattr4.fileid", FT_UINT64, BASE_DEC,
12857 NULL, 0, NULL, HFILL }},
12858
12859 { &hf_nfs4_fattr_files_avail, {
12860 "files_avail", "nfs.fattr4.files_avail", FT_UINT64, BASE_DEC,
12861 NULL, 0, NULL, HFILL }},
12862
12863 { &hf_nfs4_fattr_files_free, {
12864 "files_free", "nfs.fattr4.files_free", FT_UINT64, BASE_DEC,
12865 NULL, 0, NULL, HFILL }},
12866
12867 { &hf_nfs4_fattr_files_total, {
12868 "files_total", "nfs.fattr4.files_total", FT_UINT64, BASE_DEC,
12869 NULL, 0, NULL, HFILL }},
12870
12871 { &hf_nfs4_fattr_maxfilesize, {
12872 "maxfilesize", "nfs.fattr4.maxfilesize", FT_UINT64, BASE_DEC,
12873 NULL, 0, NULL, HFILL }},
12874
12875 { &hf_nfs4_fattr_maxlink, {
12876 "maxlink", "nfs.fattr4.maxlink", FT_UINT32, BASE_DEC,
12877 NULL, 0, NULL, HFILL }},
12878
12879 { &hf_nfs4_fattr_maxname, {
12880 "maxname", "nfs.fattr4.maxname", FT_UINT32, BASE_DEC,
12881 NULL, 0, NULL, HFILL }},
12882
12883 { &hf_nfs4_fattr_numlinks, {
12884 "numlinks", "nfs.fattr4.numlinks", FT_UINT32, BASE_DEC,
12885 NULL, 0, NULL, HFILL }},
12886
12887 { &hf_nfs4_delegate_type, {
12888 "delegate_type", "nfs.delegate_type", FT_UINT32, BASE_DEC,
12889 NULL, 0, NULL, HFILL }},
12890
12891 { &hf_nfs4_secinfo_flavor, {
12892 "flavor", "nfs.secinfo.flavor", FT_UINT32, BASE_DEC,
12893 VALS(rpc_auth_flavor), 0, NULL, HFILL }},
12894
12895 { &hf_nfs4_num_blocks, {
12896 "num_blocks", "nfs.num_blocks", FT_UINT32, BASE_DEC,
12897 NULL, 0, NULL, HFILL }},
12898
12899 { &hf_nfs4_bytes_per_block, {
12900 "bytes_per_block", "nfs.bytes_per_block", FT_UINT32, BASE_DEC,
12901 NULL, 0, NULL, HFILL }},
12902
12903 { &hf_nfs4_eof, {
12904 "eof", "nfs.eof", FT_UINT32, BASE_DEC,
12905 NULL, 0, NULL, HFILL }},
12906
12907 { &hf_nfs4_fattr_maxread, {
12908 "maxread", "nfs.fattr4.maxread", FT_UINT64, BASE_DEC,
12909 NULL, 0, NULL, HFILL }},
12910
12911 { &hf_nfs4_fattr_maxwrite, {
12912 "maxwrite", "nfs.fattr4.maxwrite", FT_UINT64, BASE_DEC,
12913 NULL, 0, NULL, HFILL }},
12914
12915 { &hf_nfs4_fattr_quota_hard, {
12916 "quota_hard", "nfs.fattr4.quota_hard", FT_UINT64, BASE_DEC,
12917 NULL, 0, NULL, HFILL }},
12918
12919 { &hf_nfs4_fattr_quota_soft, {
12920 "quota_soft", "nfs.fattr4.quota_soft", FT_UINT64, BASE_DEC,
12921 NULL, 0, NULL, HFILL }},
12922
12923 { &hf_nfs4_fattr_quota_used, {
12924 "quota_used", "nfs.fattr4.quota_used", FT_UINT64, BASE_DEC,
12925 NULL, 0, NULL, HFILL }},
12926
12927 { &hf_nfs4_fattr_space_avail, {
12928 "space_avail", "nfs.fattr4.space_avail", FT_UINT64, BASE_DEC,
12929 NULL, 0, NULL, HFILL }},
12930
12931 { &hf_nfs4_fattr_space_free, {
12932 "space_free", "nfs.fattr4.space_free", FT_UINT64, BASE_DEC,
12933 NULL, 0, NULL, HFILL }},
12934
12935 { &hf_nfs4_fattr_space_total, {
12936 "space_total", "nfs.fattr4.space_total", FT_UINT64, BASE_DEC,
12937 NULL, 0, NULL, HFILL }},
12938
12939 { &hf_nfs4_fattr_space_used, {
12940 "space_used", "nfs.fattr4.space_used", FT_UINT64, BASE_DEC,
12941 NULL, 0, NULL, HFILL }},
12942
12943 { &hf_nfs4_fattr_mounted_on_fileid, {
12944 "fileid", "nfs.fattr4.mounted_on_fileid", FT_UINT64, BASE_HEX,
12945 NULL, 0, NULL, HFILL }},
12946
12947 { &hf_nfs4_fattr_layout_blksize, {
12948 "blksize", "nfs.fattr4.layout_blksize", FT_UINT32, BASE_DEC,
12949 NULL, 0, NULL, HFILL }},
12950
12951 { &hf_nfs4_mdsthreshold_item, {
12952 "threshold_item4", "nfs.fattr4.threshold_item", FT_NONE, BASE_NONE,
12953 NULL, 0, NULL, HFILL }},
12954
12955 { &hf_nfs4_mdsthreshold_hint_mask, {
12956 "hint mask", "nfs.fattr4.threshold_item.hint_mask", FT_UINT32, BASE_HEX,
12957 NULL, 0, "MDS threshold hint mask", HFILL }},
12958
12959 { &hf_nfs4_mdsthreshold_hint_count, {
12960 "hint", "nfs.fattr4.threshold_item.hint_count", FT_UINT32, BASE_DEC,
12961 NULL, 0, "MDS threshold hint count", HFILL }},
12962
12963 { &hf_nfs4_mdsthreshold_mask_count, {
12964 "number of masks", "nfs.fattr4.threshold_item.mask_count", FT_UINT32, BASE_DEC,
12965 NULL, 0, "MDS threshold hint mask count", HFILL }},
12966
12967 { &hf_nfs4_mdsthreshold_hint_file, {
12968 "hint", "nfs.fattr4.threshold_item.hint", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
12969 &th4_names_ext_file, 0, "MDS threshold hint", HFILL }},
12970
12971 { &hf_nfs4_fattr_security_label_lfs, {
12972 "label_format", "nfs.fattr4.security_label.lfs", FT_UINT32, BASE_DEC,
12973 NULL, 0, NULL, HFILL }},
12974
12975 { &hf_nfs4_fattr_umask_mask, {
12976 "umask", "nfs.fattr4.umask", FT_UINT32, BASE_OCT,
12977 NULL, 0, NULL, HFILL }},
12978
12979 { &hf_nfs4_fattr_xattr_support, {
12980 "fattr4_xattr_support", "nfs.fattr4_xattr_support", FT_BOOLEAN, BASE_NONE,
12981 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12982
12983 { &hf_nfs4_fattr_offline, {
12984 "fattr4_offline", "nfs.fattr4_offline", FT_BOOLEAN, BASE_NONE,
12985 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
12986
12987 { &hf_nfs4_fattr_security_label_pi, {
12988 "policy_id", "nfs.fattr4.security_label.pi", FT_UINT32, BASE_DEC,
12989 NULL, 0, NULL, HFILL }},
12990
12991 { &hf_nfs4_fattr_security_label_context, {
12992 "context", "nfs.fattr4.security_label.context", FT_STRING, BASE_NONE,
12993 NULL, 0, NULL, HFILL }},
12994
12995 { &hf_nfs4_fattr_fs_charset_cap, {
12996 "fs_charset_cap", "nfs.fattr4.fs_charset_cap", FT_UINT32, BASE_HEX,
12997 NULL, 0, NULL, HFILL }},
12998
12999 { &hf_nfs4_fs_charset_cap_nonutf8, {
13000 "CONTAINS_NON_UTF8", "nfs.fattr4.fs_charset_cap.nonutf8", FT_BOOLEAN, 32,
13001 NULL, FSCHARSET_CAP4_CONTAINS_NON_UTF8, NULL, HFILL }},
13002
13003 { &hf_nfs4_fs_charset_cap_utf8, {
13004 "ALLOWS_ONLY_UTF8", "nfs.fattr4.fs_charset_cap.utf8", FT_BOOLEAN, 32,
13005 NULL, FSCHARSET_CAP4_ALLOWS_ONLY_UTF8, NULL, HFILL }},
13006
13007 { &hf_nfs4_verifier, {
13008 "verifier", "nfs.verifier4", FT_UINT64, BASE_HEX,
13009 NULL, 0, NULL, HFILL }},
13010
13011 { &hf_nfs4_value_follows, {
13012 "Value Follows", "nfs.value_follows", FT_BOOLEAN, BASE_NONE,
13013 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13014
13015 { &hf_nfs4_cookie, {
13016 "cookie", "nfs.cookie4", FT_UINT64, BASE_DEC,
13017 NULL, 0, NULL, HFILL }},
13018
13019 { &hf_nfs4_cookie_verf, {
13020 "cookie_verf", "nfs.cookie_verf4", FT_UINT64, BASE_DEC,
13021 NULL, 0, NULL, HFILL }},
13022
13023 #if 0
13024 { &hf_nfs4_cb_location, {
13025 "cb_location", "nfs.cb_location", FT_UINT32, BASE_DEC,
13026 NULL, 0, NULL, HFILL }},
13027 #endif
13028
13029 { &hf_nfs4_cb_program, {
13030 "cb_program", "nfs.cb_program", FT_UINT32, BASE_HEX,
13031 NULL, 0, NULL, HFILL }},
13032
13033 { &hf_nfs4_recall4, {
13034 "recall", "nfs.recall4", FT_BOOLEAN, BASE_NONE,
13035 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13036
13037 { &hf_nfs4_filesize, {
13038 "filesize", "nfs.filesize", FT_UINT64, BASE_DEC,
13039 NULL, 0, NULL, HFILL }},
13040
13041 { &hf_nfs4_count, {
13042 "count", "nfs.count4", FT_UINT32, BASE_DEC,
13043 NULL, 0, NULL, HFILL }},
13044
13045 { &hf_nfs4_count_dircount, {
13046 "dircount", "nfs.dircount", FT_UINT32, BASE_DEC,
13047 NULL, 0, NULL, HFILL }},
13048
13049 { &hf_nfs4_count_maxcount, {
13050 "maxcount", "nfs.maxcount", FT_UINT32, BASE_DEC,
13051 NULL, 0, NULL, HFILL }},
13052
13053 { &hf_nfs4_minorversion, {
13054 "minorversion", "nfs.minorversion", FT_UINT32, BASE_DEC,
13055 NULL, 0, NULL, HFILL }},
13056
13057 { &hf_nfs_atime, {
13058 "atime", "nfs.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
13059 NULL, 0, "Access Time", HFILL }},
13060
13061 { &hf_nfs_atime_sec, {
13062 "seconds", "nfs.atime.sec", FT_UINT32, BASE_DEC,
13063 NULL, 0, "Access Time, Seconds", HFILL }},
13064
13065 { &hf_nfs_atime_nsec, {
13066 "nano seconds", "nfs.atime.nsec", FT_UINT32, BASE_DEC,
13067 NULL, 0, "Access Time, Nano-seconds", HFILL }},
13068
13069 { &hf_nfs_atime_usec, {
13070 "micro seconds", "nfs.atime.usec", FT_UINT32, BASE_DEC,
13071 NULL, 0, "Access Time, Micro-seconds", HFILL }},
13072
13073 { &hf_nfs_mtime, {
13074 "mtime", "nfs.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
13075 NULL, 0, "Modify Time", HFILL }},
13076
13077 { &hf_nfs_mtime_sec, {
13078 "seconds", "nfs.mtime.sec", FT_UINT32, BASE_DEC,
13079 NULL, 0, "Modify Seconds", HFILL }},
13080
13081 { &hf_nfs_mtime_nsec, {
13082 "nano seconds", "nfs.mtime.nsec", FT_UINT32, BASE_DEC,
13083 NULL, 0, "Modify Time, Nano-seconds", HFILL }},
13084
13085 { &hf_nfs_mtime_usec, {
13086 "micro seconds", "nfs.mtime.usec", FT_UINT32, BASE_DEC,
13087 NULL, 0, "Modify Time, Micro-seconds", HFILL }},
13088
13089 { &hf_nfs_ctime, {
13090 "ctime", "nfs.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
13091 NULL, 0, "Creation Time", HFILL }},
13092
13093 { &hf_nfs_ctime_sec, {
13094 "seconds", "nfs.ctime.sec", FT_UINT32, BASE_DEC,
13095 NULL, 0, "Creation Time, Seconds", HFILL }},
13096
13097 { &hf_nfs_ctime_nsec, {
13098 "nano seconds", "nfs.ctime.nsec", FT_UINT32, BASE_DEC,
13099 NULL, 0, "Creation Time, Nano-seconds", HFILL }},
13100
13101 { &hf_nfs_ctime_usec, {
13102 "micro seconds", "nfs.ctime.usec", FT_UINT32, BASE_DEC,
13103 NULL, 0, "Creation Time, Micro-seconds", HFILL }},
13104
13105 { &hf_nfs_dtime, {
13106 "time delta", "nfs.dtime", FT_RELATIVE_TIME, BASE_NONE,
13107 NULL, 0, NULL, HFILL }},
13108
13109 { &hf_nfs_dtime_sec, {
13110 "seconds", "nfs.dtime.sec", FT_UINT32, BASE_DEC,
13111 NULL, 0, "Time Delta, Seconds", HFILL }},
13112
13113 { &hf_nfs_dtime_nsec, {
13114 "nano seconds", "nfs.dtime.nsec", FT_UINT32, BASE_DEC,
13115 NULL, 0, "Time Delta, Nano-seconds", HFILL }},
13116
13117 { &hf_nfs4_open_owner, {
13118 "owner", "nfs.open_owner4", FT_BYTES, BASE_NONE,
13119 NULL, 0, NULL, HFILL }},
13120
13121 { &hf_nfs4_lock_owner, {
13122 "owner", "nfs.lock_owner4", FT_BYTES, BASE_NONE,
13123 NULL, 0, NULL, HFILL }},
13124
13125 { &hf_nfs4_createmode, {
13126 "Create Mode", "nfs.createmode4", FT_UINT32, BASE_DEC,
13127 VALS(names_createmode4), 0, NULL, HFILL }},
13128
13129 { &hf_nfs4_secinfo_rpcsec_gss_info_service, {
13130 "service", "nfs.secinfo.rpcsec_gss_info.service", FT_UINT32, BASE_DEC,
13131 VALS(rpc_authgss_svc), 0, NULL, HFILL }},
13132
13133 { &hf_nfs4_attr_dir_create, {
13134 "attribute dir create", "nfs.openattr4.createdir", FT_BOOLEAN, BASE_NONE,
13135 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13136
13137 { &hf_nfs4_new_lock_owner, {
13138 "new lock owner?", "nfs.lock.locker.new_lock_owner", FT_BOOLEAN, BASE_NONE,
13139 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13140
13141 { &hf_nfs4_lock_reclaim, {
13142 "reclaim?", "nfs.lock.reclaim", FT_BOOLEAN, BASE_NONE,
13143 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13144
13145 { &hf_nfs4_sec_oid, {
13146 "oid", "nfs.secinfo.flavor_info.rpcsec_gss_info.oid", FT_BYTES, BASE_NONE,
13147 NULL, 0, NULL, HFILL }},
13148
13149 { &hf_nfs4_qop, {
13150 "qop", "nfs.secinfo.flavor_info.rpcsec_gss_info.qop", FT_UINT32, BASE_DEC,
13151 NULL, 0, NULL, HFILL }},
13152
13153 { &hf_nfs4_client_id, {
13154 "id", "nfs.nfs_client_id4.id", FT_BYTES, BASE_NONE,
13155 NULL, 0, NULL, HFILL }},
13156
13157 { &hf_nfs4_aclflags, {
13158 "ACL flags", "nfs.acl.flags", FT_UINT32, BASE_DEC,
13159 NULL, 0, NULL, HFILL }},
13160
13161 { &hf_nfs4_aclflag_auto_inherit, {
13162 "AUTO_INHERIT", "nfs.acl.flags.auto_inherit", FT_BOOLEAN, 32,
13163 NULL, ACL4_AUTO_INHERIT, NULL, HFILL }},
13164
13165 { &hf_nfs4_aclflag_protected, {
13166 "PROTECTED", "nfs.acl.flags.protected", FT_BOOLEAN, 32,
13167 NULL, ACL4_PROTECTED, NULL, HFILL }},
13168
13169 { &hf_nfs4_aclflag_defaulted, {
13170 "DEFAULTED", "nfs.acl.flags.defaulted", FT_BOOLEAN, 32,
13171 NULL, ACL4_DEFAULTED, NULL, HFILL }},
13172
13173 { &hf_nfs4_num_aces, {
13174 "ACE count", "nfs.num_aces", FT_UINT32, BASE_DEC,
13175 NULL, 0, "Number of ACEs", HFILL }},
13176
13177 { &hf_nfs4_callback_ident, {
13178 "callback_ident", "nfs.callback.ident", FT_UINT32, BASE_HEX,
13179 NULL, 0, "Callback Identifier", HFILL }},
13180
13181 { &hf_nfs4_gsshandle, {
13182 "gsshandle4", "nfs.gsshandle4", FT_BYTES, BASE_NONE,
13183 NULL, 0, NULL, HFILL }},
13184
13185 { &hf_nfs4_r_netid, {
13186 "r_netid", "nfs.r_netid", FT_STRING, BASE_NONE,
13187 NULL, 0, NULL, HFILL }},
13188
13189 { &hf_nfs4_r_addr, {
13190 "r_addr", "nfs.r_addr", FT_STRING, BASE_NONE,
13191 NULL, 0, NULL, HFILL }},
13192
13193 { &hf_nfs_fh_fhandle_data, {
13194 "FileHandle", "nfs.fhandle", FT_BYTES, BASE_NONE,
13195 NULL, 0, "Opaque nfs filehandle", HFILL }},
13196
13197 { &hf_nfs4_secinfo_arr, {
13198 "Flavors Info", "nfs.flavors.info", FT_NONE, BASE_NONE,
13199 NULL, 0, NULL, HFILL }},
13200
13201 { &hf_nfs3_gxfh_utlfield, {
13202 "utility", "nfs.gxfh3.utility", FT_UINT8, BASE_HEX,
13203 NULL, 0, NULL, HFILL }},
13204
13205 { &hf_nfs3_gxfh_utlfield_tree, {
13206 "tree R/W", "nfs.gxfh3.utlfield.tree", FT_BOOLEAN, 8,
13207 TFS(&tfs_read_write), NFS3GX_FH_TREE_MASK, NULL, HFILL }},
13208
13209 { &hf_nfs3_gxfh_utlfield_jun, {
13210 "broken junction", "nfs.gxfh3.utlfield.junction", FT_BOOLEAN, 8,
13211 TFS(&tfs_yes_no), NFS3GX_FH_JUN_MASK, NULL, HFILL }},
13212
13213 { &hf_nfs3_gxfh_utlfield_ver, {
13214 "file handle version", "nfs.gxfh3.utlfield.version", FT_UINT8, BASE_HEX,
13215 NULL, NFS3GX_FH_VER_MASK, NULL, HFILL }},
13216
13217 { &hf_nfs3_gxfh_volcnt, {
13218 "volume count", "nfs.gxfh3.volcnt", FT_UINT8, BASE_HEX_DEC,
13219 NULL, 0, NULL, HFILL }},
13220
13221 { &hf_nfs3_gxfh_epoch, {
13222 "epoch", "nfs.gxfh3.epoch", FT_UINT16, BASE_HEX_DEC,
13223 NULL, 0, NULL, HFILL }},
13224
13225 { &hf_nfs3_gxfh_ldsid, {
13226 "local dsid", "nfs.gxfh3.ldsid", FT_UINT32, BASE_HEX_DEC,
13227 NULL, 0, NULL, HFILL }},
13228
13229 { &hf_nfs3_gxfh_cid, {
13230 "cluster id", "nfs.gxfh3.cid", FT_UINT16, BASE_HEX_DEC,
13231 NULL, 0, NULL, HFILL }},
13232
13233 { &hf_nfs3_gxfh_resv, {
13234 "reserved", "nfs.gxfh3.reserved", FT_UINT16, BASE_HEX_DEC,
13235 NULL, 0, NULL, HFILL }},
13236
13237 { &hf_nfs3_gxfh_sfhflags, {
13238 "flags", "nfs.gxfh3.sfhflags", FT_UINT8, BASE_HEX,
13239 NULL, 0, NULL, HFILL }},
13240
13241 { &hf_nfs3_gxfh_sfhflags_resv1, {
13242 "reserved", "nfs.gxfh3.sfhflags.reserve1", FT_UINT8, BASE_HEX,
13243 NULL, SPINNP_FH_FLAG_RESV1, NULL, HFILL }},
13244
13245 { &hf_nfs3_gxfh_sfhflags_resv2, {
13246 "reserved", "nfs.gxfh3.sfhflags.reserv2", FT_UINT8, BASE_HEX,
13247 NULL, SPINNP_FH_FLAG_RESV2, NULL, HFILL }},
13248
13249 { &hf_nfs3_gxfh_sfhflags_ontap7G, {
13250 "ontap-7g", "nfs.gxfh3.sfhflags.ontap7g", FT_UINT8, BASE_HEX,
13251 NULL, SPINNP_FH_FLAG_ONTAP_MASK, NULL, HFILL }},
13252
13253 { &hf_nfs3_gxfh_sfhflags_ontapGX, {
13254 "ontap-gx", "nfs.gxfh3.sfhflags.ontapgx", FT_UINT8, BASE_HEX,
13255 NULL, SPINNP_FH_FLAG_ONTAP_MASK, NULL, HFILL }},
13256
13257 { &hf_nfs3_gxfh_sfhflags_striped, {
13258 "striped", "nfs.gxfh3.sfhflags.striped", FT_BOOLEAN, 8,
13259 TFS(&tfs_set_notset), SPINNP_FH_FLAG_STRIPED_MASK, NULL, HFILL }},
13260
13261 { &hf_nfs3_gxfh_sfhflags_empty, {
13262 "empty", "nfs.gxfh3.sfhflags.empty", FT_BOOLEAN, 8,
13263 TFS(&tfs_set_notset), SPINNP_FH_FLAG_EMPTY_MASK, NULL, HFILL }},
13264
13265 { &hf_nfs3_gxfh_sfhflags_snapdirent, {
13266 "snap dir ent", "nfs.gxfh3.sfhflags.snapdirent", FT_BOOLEAN, 8,
13267 TFS(&tfs_set_notset), SPINNP_FH_FLAG_SNAPDIR_ENT_MASK, NULL, HFILL }},
13268
13269 { &hf_nfs3_gxfh_sfhflags_snapdir, {
13270 "snap dir", "nfs.gxfh3.sfhflags.snapdir", FT_BOOLEAN, 8,
13271 TFS(&tfs_set_notset), SPINNP_FH_FLAG_SNAPDIR_MASK, NULL, HFILL }},
13272
13273 { &hf_nfs3_gxfh_sfhflags_streamdir, {
13274 "stream dir", "nfs.gxfh3.sfhflags.streamdir", FT_BOOLEAN, 8,
13275 TFS(&tfs_set_notset), SPINNP_FH_FLAG_STREAMDIR_MASK, NULL, HFILL }},
13276
13277 { &hf_nfs3_gxfh_spinfid, {
13278 "spin file id", "nfs.gxfh3.spinfid", FT_UINT32, BASE_HEX_DEC,
13279 NULL, 0, NULL, HFILL }},
13280
13281 { &hf_nfs3_gxfh_spinfuid, {
13282 "spin file unique id", "nfs.gxfh3.spinfuid", FT_UINT32, BASE_HEX_DEC,
13283 NULL, 0, NULL, HFILL }},
13284
13285 { &hf_nfs3_gxfh_exportptid, {
13286 "export point id", "nfs.gxfh3.exportptid", FT_UINT32, BASE_HEX_DEC,
13287 NULL, 0, NULL, HFILL }},
13288
13289 { &hf_nfs3_gxfh_exportptuid, {
13290 "export point unique id", "nfs.gxfh3.exportptuid", FT_UINT32, BASE_HEX_DEC,
13291 NULL, 0, NULL, HFILL }},
13292
13293 { &hf_nfs3_verifier, {
13294 "Verifier", "nfs.verifier", FT_BYTES, BASE_NONE,
13295 NULL, 0, NULL, HFILL }},
13296
13297 { &hf_nfs3_specdata1, {
13298 "specdata1", "nfs.specdata1", FT_UINT32, BASE_DEC,
13299 NULL, 0, NULL, HFILL }},
13300
13301 { &hf_nfs3_specdata2, {
13302 "specdata2", "nfs.specdata2", FT_UINT32, BASE_DEC,
13303 NULL, 0, NULL, HFILL }},
13304
13305 { &hf_nfs3_attributes_follow, {
13306 "attributes_follow", "nfs.attributes_follow", FT_UINT32, BASE_DEC,
13307 VALS(value_follows), 0, NULL, HFILL }},
13308
13309 { &hf_nfs3_handle_follow, {
13310 "handle_follow", "nfs.handle_follow", FT_UINT32, BASE_DEC,
13311 VALS(value_follows), 0, NULL, HFILL }},
13312
13313 { &hf_nfs3_sattrguard3, {
13314 "check", "nfs.sattrguard3", FT_UINT32, BASE_DEC,
13315 VALS(value_follows), 0, NULL, HFILL }},
13316
13317 { &hf_nfs4_length_minlength, {
13318 "min length", "nfs.minlength4", FT_UINT64, BASE_DEC,
13319 NULL, 0, NULL, HFILL }},
13320
13321 { &hf_nfs4_layout_type, {
13322 "layout type", "nfs.layouttype", FT_UINT32, BASE_DEC,
13323 VALS(layouttype_names), 0, NULL, HFILL }},
13324
13325 { &hf_nfs4_layout_return_type, {
13326 "return type", "nfs.returntype", FT_UINT32, BASE_DEC,
13327 VALS(layoutreturn_names), 0, NULL, HFILL }},
13328
13329 { &hf_nfs4_lrf_body_content, {
13330 "lrf_body_content", "nfs.lrf_body_content", FT_BYTES, BASE_NONE,
13331 NULL, 0, NULL, HFILL }},
13332
13333 { &hf_nfs4_iomode, {
13334 "IO mode", "nfs.iomode", FT_UINT32, BASE_DEC,
13335 VALS(iomode_names), 0, NULL, HFILL }},
13336
13337 #if 0
13338 { &hf_nfs4_stripetype, {
13339 "stripe type", "nfs.stripetype", FT_UINT32, BASE_DEC,
13340 VALS(stripetype_names), 0, NULL, HFILL }},
13341 #endif
13342
13343 { &hf_nfs4_stripeunit, {
13344 "stripe unit", "nfs.stripeunit", FT_UINT64, BASE_DEC,
13345 NULL, 0, NULL, HFILL }},
13346
13347 #if 0
13348 { &hf_nfs4_util, {
13349 "util", "nfs.util", FT_UINT32, BASE_DEC,
13350 NULL, 0, NULL, HFILL }},
13351 #endif
13352
13353 #if 0
13354 { &hf_nfs4_first_stripe_idx, {
13355 "first stripe index", "nfs.stripeindex", FT_UINT32, BASE_DEC,
13356 NULL, 0, NULL, HFILL }},
13357 #endif
13358
13359 #if 0
13360 { &hf_nfs4_pattern_offset, {
13361 "layout pattern offset", "nfs.patternoffset", FT_UINT64, BASE_DEC,
13362 NULL, 0, NULL, HFILL }},
13363 #endif
13364
13365 { &hf_nfs4_notification_mask, {
13366 "notify_mask", "nfs.notify_mask", FT_UINT32, BASE_HEX,
13367 NULL, 0, NULL, HFILL }},
13368
13369 { &hf_nfs4_notification_type, {
13370 "notify_type", "nfs.notify_type", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
13371 ¬ify_deviceid_type4_ext, 0, NULL, HFILL }},
13372
13373 { &hf_nfs4_newtime, {
13374 "new time?", "nfs.newtime", FT_BOOLEAN, BASE_NONE,
13375 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13376
13377 { &hf_nfs4_newoffset, {
13378 "new offset?", "nfs.newoffset", FT_BOOLEAN, BASE_NONE,
13379 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13380
13381 { &hf_nfs4_newsize, {
13382 "new size?", "nfs.newsize", FT_BOOLEAN, BASE_NONE,
13383 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13384
13385 { &hf_nfs4_layout_avail, {
13386 "layout available?", "nfs.layoutavail", FT_BOOLEAN, BASE_NONE,
13387 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13388
13389 #if 0
13390 { &hf_nfs4_mdscommit, {
13391 "MDS commit?", "nfs.mdscommit", FT_BOOLEAN, BASE_NONE,
13392 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13393 #endif
13394
13395 { &hf_nfs4_layoutupdate, {
13396 "layout update", "nfs.layoutupdate", FT_BYTES, BASE_NONE,
13397 NULL, 0, NULL, HFILL }},
13398
13399 { &hf_nfs4_deviceid, {
13400 "device ID", "nfs.deviceid", FT_BYTES, BASE_NONE,
13401 NULL, 0, NULL, HFILL }},
13402
13403 { &hf_nfs4_devicenum, {
13404 "num devices", "nfs.devicenum4", FT_UINT32, BASE_DEC,
13405 NULL, 0, NULL, HFILL }},
13406
13407 { &hf_nfs4_deviceidx, {
13408 "device index", "nfs.deviceidx", FT_UINT32, BASE_DEC,
13409 NULL, 0, NULL, HFILL }},
13410
13411 { &hf_nfs4_layout, {
13412 "layout", "nfs.layout", FT_BYTES, BASE_NONE,
13413 NULL, 0, NULL, HFILL }},
13414
13415 #if 0
13416 { &hf_nfs4_layout_count, {
13417 "layout", "nfs.layoutcount", FT_UINT32, BASE_DEC,
13418 NULL, 0, "layout count", HFILL }},
13419 #endif
13420
13421
13422 #if 0
13423 { &hf_nfs4_stripedevs, {
13424 "stripe devs", "nfs.stripedevs", FT_UINT32, BASE_DEC,
13425 NULL, 0, NULL, HFILL }},
13426 #endif
13427
13428 #if 0
13429 { &hf_nfs4_devaddr, {
13430 "device addr", "nfs.devaddr", FT_BYTES, BASE_NONE,
13431 NULL, 0, NULL, HFILL }},
13432 #endif
13433
13434 { &hf_nfs4_devaddr_ssv_start, {
13435 "slice start", "nfs.devaddr.ssv_start", FT_UINT32, BASE_DEC,
13436 NULL, 0, NULL, HFILL }},
13437
13438 { &hf_nfs4_devaddr_ssv_length, {
13439 "slice length", "nfs.devaddr.ssv_length", FT_UINT32, BASE_DEC,
13440 NULL, 0, NULL, HFILL }},
13441
13442 { &hf_nfs4_devaddr_scsi_vol_type, {
13443 "SCSI volume type", "nfs.devaddr.scsi_volume_type", FT_UINT32, BASE_DEC,
13444 VALS(scsi_vol_type_names), 0, NULL, HFILL }},
13445
13446 { &hf_nfs4_devaddr_scsi_vol_index, {
13447 "volume index", "nfs.devaddr.scsi_volume_index", FT_UINT32, BASE_DEC,
13448 NULL, 0, NULL, HFILL }},
13449
13450 { &hf_nfs4_devaddr_scsi_vol_ref_index, {
13451 "volume index ref", "nfs.devaddr.scsi_volume_ref_index", FT_UINT32, BASE_DEC,
13452 NULL, 0, NULL, HFILL }},
13453
13454 { &hf_nfs4_devaddr_ssv_stripe_unit, {
13455 "stripe size", "nfs.devaddr.ssv_stripe_unit", FT_UINT32, BASE_DEC,
13456 NULL, 0, NULL, HFILL }},
13457
13458 { &hf_nfs4_devaddr_scsi_vpd_code_set, {
13459 "VPD code set", "nfs.devaddr.scsi_vpd_code_set", FT_UINT32, BASE_DEC,
13460 VALS(scsi_vpd_code_set_names), 0, NULL, HFILL }},
13461
13462 { &hf_nfs4_devaddr_scsi_vpd_designator_type, {
13463 "VPD designator type", "nfs.devaddr.scsi_vpd_designator_type", FT_UINT32, BASE_DEC,
13464 VALS(scsi_vpd_designator_type_names), 0, NULL, HFILL }},
13465
13466 { &hf_nfs4_devaddr_scsi_vpd_designator, {
13467 "VPD designator", "nfs.devaddr.scsi_vpd_designator",
13468 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
13469
13470 { &hf_nfs4_devaddr_scsi_private_key, {
13471 "private key", "nfs.devaddr.scsi_private_key",
13472 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
13473
13474 { &hf_nfs4_scsil_ext_file_offset, {
13475 "file offset", "nfs.scsil_ext_file_offset", FT_UINT64, BASE_DEC,
13476 NULL, 0, NULL, HFILL }},
13477
13478 { &hf_nfs4_scsil_ext_length, {
13479 "length", "nfs.scsil_ext_length", FT_UINT64, BASE_DEC,
13480 NULL, 0, NULL, HFILL }},
13481
13482 { &hf_nfs4_scsil_ext_vol_offset, {
13483 "volume offset", "nfs.scsill_ext_vol_offset", FT_UINT64, BASE_DEC,
13484 NULL, 0, NULL, HFILL }},
13485
13486 { &hf_nfs4_scsil_ext_state, {
13487 "extent state", "nfs.scsil_ext_state", FT_UINT32, BASE_DEC,
13488 VALS(scsi_extent_state_names), 0, NULL, HFILL }},
13489
13490 { &hf_nfs4_return_on_close, {
13491 "return on close?", "nfs.retclose4", FT_BOOLEAN, BASE_NONE,
13492 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13493
13494 { &hf_nfs4_nfl_mirrors, {
13495 "Mirror", "nfs.nfl_mirrors", FT_UINT32, BASE_DEC,
13496 NULL, 0, NULL, HFILL }},
13497
13498 { &hf_nfs4_nfl_util, {
13499 "nfl_util", "nfs.nfl_util", FT_UINT32, BASE_HEX,
13500 NULL, 0, NULL, HFILL }},
13501
13502 { &hf_nfs4_nfl_util_stripe_size, {
13503 "stripe size", "nfs.nfl_util.stripe_size", FT_UINT32, BASE_DEC,
13504 NULL, 0, NULL, HFILL }},
13505
13506 { &hf_nfs4_nfl_util_commit_thru_mds, {
13507 "commit thru mds", "nfs.nfl_util.commit_thru_mds", FT_UINT32, BASE_DEC,
13508 NULL, 0, NULL, HFILL }},
13509
13510 { &hf_nfs4_nfl_util_dense, {
13511 "dense layout", "nfs.nfl_util.dense", FT_UINT32, BASE_DEC,
13512 NULL, 0, NULL, HFILL }},
13513
13514 { &hf_nfs4_nfl_fhs, {
13515 "file handles", "nfs.nfl_fhs", FT_UINT32, BASE_HEX,
13516 NULL, 0, NULL, HFILL }},
13517
13518 { &hf_nfs4_mirror_eff, {
13519 "mirror efficiency", "nfs.nff_mirror_eff", FT_UINT32, BASE_HEX,
13520 NULL, 0, NULL, HFILL }},
13521
13522 { &hf_nfs4_nfl_first_stripe_index, {
13523 "first stripe to use index", "nfs.nfl_first_stripe_index", FT_UINT32, BASE_DEC,
13524 NULL, 0, NULL, HFILL }},
13525
13526 { &hf_nfs4_slotid, {
13527 "slot id", "nfs.slotid", FT_UINT32, BASE_DEC,
13528 NULL, 0, NULL, HFILL }},
13529
13530 { &hf_nfs4_high_slotid, {
13531 "high slot id", "nfs.high_slotid", FT_UINT32, BASE_DEC,
13532 NULL, 0, NULL, HFILL }},
13533 { &hf_nfs4_target_high_slotid, {
13534 "target high slot id", "nfs.target_high_slotid", FT_UINT32, BASE_DEC,
13535 NULL, 0, NULL, HFILL }},
13536
13537 { &hf_nfs4_serverscope4, {
13538 "server scope", "nfs.scope", FT_BYTES, BASE_NONE,
13539 NULL, 0, NULL, HFILL }},
13540
13541 { &hf_nfs4_minorid, {
13542 "minor ID", "nfs.minorid4", FT_UINT64, BASE_DEC,
13543 NULL, 0, NULL, HFILL }},
13544
13545 { &hf_nfs4_majorid, {
13546 "major ID", "nfs.majorid4", FT_BYTES, BASE_NONE,
13547 NULL, 0, NULL, HFILL }},
13548
13549 { &hf_nfs4_padsize, {
13550 "hdr pad size", "nfs.padsize4", FT_UINT32, BASE_DEC,
13551 NULL, 0, NULL, HFILL }},
13552
13553 #if 0
13554 { &hf_nfs4_cbrenforce, {
13555 "binding enforce?", "nfs.cbrenforce4", FT_BOOLEAN, BASE_NONE,
13556 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13557 #endif
13558
13559 #if 0
13560 { &hf_nfs4_hashalg, {
13561 "hash alg", "nfs.hashalg4", FT_UINT32, BASE_DEC,
13562 NULL, 0, NULL, HFILL }},
13563 #endif
13564
13565 #if 0
13566 { &hf_nfs4_ssvlen, {
13567 "ssv len", "nfs.ssvlen4", FT_UINT32, BASE_DEC,
13568 NULL, 0, NULL, HFILL }},
13569 #endif
13570
13571 { &hf_nfs4_maxreqsize, {
13572 "max req size", "nfs.maxreqsize4", FT_UINT32, BASE_DEC,
13573 NULL, 0, NULL, HFILL }},
13574
13575 { &hf_nfs4_maxrespsize, {
13576 "max resp size", "nfs.maxrespsize4", FT_UINT32, BASE_DEC,
13577 NULL, 0, NULL, HFILL }},
13578
13579 { &hf_nfs4_maxrespsizecached, {
13580 "max resp size cached", "nfs.maxrespsizecached4", FT_UINT32, BASE_DEC,
13581 NULL, 0, NULL, HFILL }},
13582
13583 { &hf_nfs4_maxops, {
13584 "max ops", "nfs.maxops4", FT_UINT32, BASE_DEC,
13585 NULL, 0, NULL, HFILL }},
13586
13587 { &hf_nfs4_maxreqs, {
13588 "max reqs", "nfs.maxreqs4", FT_UINT32, BASE_DEC,
13589 NULL, 0, NULL, HFILL }},
13590
13591 { &hf_nfs4_rdmachanattrs, {
13592 "RDMA chan attrs", "nfs.rdmachanattrs4", FT_UINT32, BASE_DEC,
13593 NULL, 0, NULL, HFILL }},
13594
13595 { &hf_nfs4_machinename, {
13596 "machine name", "nfs.machinename4", FT_STRING, BASE_NONE,
13597 NULL, 0, NULL, HFILL }},
13598
13599 { &hf_nfs4_flavor, {
13600 "flavor", "nfs.flavor4", FT_UINT32, BASE_DEC,
13601 NULL, 0, NULL, HFILL }},
13602
13603 { &hf_nfs4_stamp, {
13604 "stamp", "nfs.stamp4", FT_UINT32, BASE_DEC,
13605 NULL, 0, NULL, HFILL }},
13606
13607 { &hf_nfs4_uid, {
13608 "uid", "nfs.uid4", FT_UINT32, BASE_DEC,
13609 NULL, 0, NULL, HFILL }},
13610
13611 { &hf_nfs4_gid, {
13612 "gid", "nfs.gid4", FT_UINT32, BASE_DEC,
13613 NULL, 0, NULL, HFILL }},
13614
13615 { &hf_nfs4_service, {
13616 "gid", "nfs.service4", FT_UINT32, BASE_DEC,
13617 NULL, 0, NULL, HFILL }},
13618
13619 { &hf_nfs_access_check,
13620 { "Check access", "nfs.access_check",
13621 FT_UINT8, BASE_HEX,
13622 NULL, 0x0,
13623 "Access type(s) to be checked", HFILL }
13624 },
13625 { &hf_nfs_access_supported,
13626 { "Supported types (of requested)", "nfs.access_supported",
13627 FT_UINT8, BASE_HEX,
13628 NULL, 0x0,
13629 "Access types (of those requested) that the server can reliably verify", HFILL }
13630 },
13631 { &hf_nfs_access_rights,
13632 { "Access rights (of requested)", "nfs.access_rights",
13633 FT_UINT8, BASE_HEX,
13634 NULL, 0x0,
13635 "Access rights for the types requested", HFILL }
13636 },
13637 { &hf_nfs_access_supp_read,
13638 { "0x001 READ", "nfs.access_supp_read",
13639 FT_BOOLEAN, 8,
13640 TFS(&tfs_access_supp), NFS_ACCESS_MASK_READ,
13641 NULL, HFILL }
13642 },
13643 { &hf_nfs_access_supp_lookup,
13644 { "0x002 LOOKUP", "nfs.access_supp_lookup",
13645 FT_BOOLEAN, 8,
13646 TFS(&tfs_access_supp), NFS_ACCESS_MASK_LOOKUP,
13647 NULL, HFILL }
13648 },
13649 { &hf_nfs_access_supp_modify,
13650 { "0x004 MODIFY", "nfs.access_supp_modify",
13651 FT_BOOLEAN, 8,
13652 TFS(&tfs_access_supp), NFS_ACCESS_MASK_MODIFY,
13653 NULL, HFILL }
13654 },
13655 { &hf_nfs_access_supp_extend,
13656 { "0x008 EXTEND", "nfs.access_supp_extend",
13657 FT_BOOLEAN, 8,
13658 TFS(&tfs_access_supp), NFS_ACCESS_MASK_EXTEND,
13659 NULL, HFILL }
13660 },
13661 { &hf_nfs_access_supp_delete,
13662 { "0x010 DELETE", "nfs.access_supp_delete",
13663 FT_BOOLEAN, 8,
13664 TFS(&tfs_access_supp), NFS_ACCESS_MASK_DELETE,
13665 NULL, HFILL }
13666 },
13667 { &hf_nfs_access_supp_execute,
13668 { "0x020 EXECUTE", "nfs.access_supp_execute",
13669 FT_BOOLEAN, 8,
13670 TFS(&tfs_access_supp), NFS_ACCESS_MASK_EXECUTE,
13671 NULL, HFILL }
13672 },
13673 { &hf_nfs_access_supp_xattr_read,
13674 { "0x040 XATTR READ", "nfs.access_supp_xattr_read",
13675 FT_BOOLEAN, 8,
13676 TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_READ,
13677 NULL, HFILL }
13678 },
13679 { &hf_nfs_access_supp_xattr_write,
13680 { "0x080 XATTR WRITE", "nfs.access_supp_xattr_write",
13681 FT_BOOLEAN, 8,
13682 TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_WRITE,
13683 NULL, HFILL }
13684 },
13685 { &hf_nfs_access_supp_xattr_list,
13686 { "0x100 XATTR LIST", "nfs.access_supp_xattr_list",
13687 FT_BOOLEAN, 8,
13688 TFS(&tfs_access_supp), NFS_ACCESS_MASK_XATTR_LIST,
13689 NULL, HFILL }
13690 },
13691 { &hf_nfs_access_read,
13692 { "0x001 READ", "nfs.access_read",
13693 FT_BOOLEAN, 8,
13694 TFS(&tfs_access_rights), NFS_ACCESS_MASK_READ,
13695 NULL, HFILL }
13696 },
13697 { &hf_nfs_access_lookup,
13698 { "0x002 LOOKUP", "nfs.access_lookup",
13699 FT_BOOLEAN, 8,
13700 TFS(&tfs_access_rights), NFS_ACCESS_MASK_LOOKUP,
13701 NULL, HFILL }
13702 },
13703 { &hf_nfs_access_modify,
13704 { "0x004 MODIFY", "nfs.access_modify",
13705 FT_BOOLEAN, 8,
13706 TFS(&tfs_access_rights), NFS_ACCESS_MASK_MODIFY,
13707 NULL, HFILL }
13708 },
13709 { &hf_nfs_access_extend,
13710 { "0x008 EXTEND", "nfs.access_extend",
13711 FT_BOOLEAN, 8,
13712 TFS(&tfs_access_rights), NFS_ACCESS_MASK_EXTEND,
13713 NULL, HFILL }
13714 },
13715 { &hf_nfs_access_delete,
13716 { "0x010 DELETE", "nfs.access_delete",
13717 FT_BOOLEAN, 8,
13718 TFS(&tfs_access_rights), NFS_ACCESS_MASK_DELETE,
13719 NULL, HFILL }
13720 },
13721 { &hf_nfs_access_execute,
13722 { "0x020 EXECUTE", "nfs.access_execute",
13723 FT_BOOLEAN, 8,
13724 TFS(&tfs_access_rights), NFS_ACCESS_MASK_EXECUTE,
13725 NULL, HFILL }
13726 },
13727 { &hf_nfs_access_xattr_read,
13728 { "0x040 XATTR READ", "nfs.access_xattr_read",
13729 FT_BOOLEAN, 8,
13730 TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_READ,
13731 NULL, HFILL }
13732 },
13733 { &hf_nfs_access_xattr_write,
13734 { "0x080 XATTR WRITE", "nfs.access_xattr_write",
13735 FT_BOOLEAN, 8,
13736 TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_WRITE,
13737 NULL, HFILL }
13738 },
13739 { &hf_nfs_access_xattr_list,
13740 { "0x100 XATTR LIST", "nfs.access_xattr_list",
13741 FT_BOOLEAN, 8,
13742 TFS(&tfs_access_rights), NFS_ACCESS_MASK_XATTR_LIST,
13743 NULL, HFILL }
13744 },
13745 { &hf_nfs_access_denied,
13746 { "Access Denied", "nfs.access_denied",
13747 FT_BOOLEAN, BASE_NONE,
13748 NULL, 0x0,
13749 "True if access has been denied to one or more of the requested types", HFILL }
13750 },
13751 { &hf_nfs4_sessionid, {
13752 "sessionid", "nfs.session_id4", FT_BYTES, BASE_NONE,
13753 NULL, 0, NULL, HFILL }},
13754 { &hf_nfs4_exchid_call_flags, {
13755 "flags", "nfs.exchange_id.call_flags", FT_UINT32, BASE_HEX,
13756 NULL, 0, NULL, HFILL}},
13757 { &hf_nfs4_exchid_reply_flags, {
13758 "flags", "nfs.exchange_id.reply_flags", FT_UINT32, BASE_HEX,
13759 NULL, 0, NULL, HFILL}},
13760 { &hf_nfs4_exchid_flags_moved_refer, {
13761 "EXCHGID4_FLAG_SUPP_MOVED_REFER", "nfs.exchange_id.flags.moved_refer", FT_BOOLEAN, 32,
13762 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
13763 { &hf_nfs4_exchid_flags_moved_migr, {
13764 "EXCHGID4_FLAG_SUPP_MOVED_MIGR", "nfs.exchange_id.flags.moved_migr", FT_BOOLEAN, 32,
13765 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
13766 { &hf_nfs4_exchid_flags_bind_princ, {
13767 "EXCHGID4_FLAG_BIND_PRINC_STATEID", "nfs.exchange_id.flags.bind_princ", FT_BOOLEAN, 32,
13768 TFS(&tfs_set_notset), 0x00000100, NULL, HFILL}},
13769 { &hf_nfs4_exchid_flags_non_pnfs, {
13770 "EXCHGID4_FLAG_USE_NON_PNFS", "nfs.exchange_id.flags.non_pnfs", FT_BOOLEAN, 32,
13771 TFS(&tfs_set_notset), 0x00010000, NULL, HFILL}},
13772 { &hf_nfs4_exchid_flags_pnfs_mds, {
13773 "EXCHGID4_FLAG_USE_PNFS_MDS", "nfs.exchange_id.flags.pnfs_mds", FT_BOOLEAN, 32,
13774 TFS(&tfs_set_notset), 0x00020000, NULL, HFILL}},
13775 { &hf_nfs4_exchid_flags_pnfs_ds, {
13776 "EXCHGID4_FLAG_USE_PNFS_DS", "nfs.exchange_id.flags.pnfs_ds", FT_BOOLEAN, 32,
13777 TFS(&tfs_set_notset), 0x00040000, NULL, HFILL}},
13778 { &hf_nfs4_exchid_flags_upd_conf_rec_a, {
13779 "EXCHGID4_FLAG_UPD_CONFIRMED_REC_A", "nfs.exchange_id.flags.confirmed_rec_a",
13780 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x40000000, NULL, HFILL}},
13781 { &hf_nfs4_exchid_flags_confirmed_r, {
13782 "EXCHGID4_FLAG_CONFIRMED_R", "nfs.exchange_id.flags.confirmed_r", FT_BOOLEAN, 32,
13783 TFS(&tfs_set_notset), 0x80000000, NULL, HFILL}},
13784 { &hf_nfs4_sp_parms_hash_algs, {
13785 "State Protect hash algorithms", "nfs.sp_parms4_hash_algs", FT_NONE, BASE_NONE,
13786 NULL, 0, NULL, HFILL }},
13787 { &hf_nfs4_sp_parms_encr_algs, {
13788 "State Protect encryption algorithms", "nfs.sp_parms4_encr_algs", FT_NONE, BASE_NONE,
13789 NULL, 0, NULL, HFILL }},
13790 { &hf_nfs4_prot_info_hash_alg, {
13791 "Prot Info hash algorithm", "nfs.prot_info4_hash_alg", FT_UINT32, BASE_HEX,
13792 NULL, 0, NULL, HFILL }},
13793 { &hf_nfs4_prot_info_encr_alg, {
13794 "Prot Info encryption algorithm", "nfs.prot_info4_encr_alg", FT_UINT32, BASE_HEX,
13795 NULL, 0, NULL, HFILL }},
13796 { &hf_nfs4_prot_info_svv_length, {
13797 "Prot Info svv_length", "nfs.prot_info4_svv_length", FT_UINT32, BASE_HEX,
13798 NULL, 0, NULL, HFILL }},
13799 { &hf_nfs4_prot_info_spi_window, {
13800 "Prot Info spi window", "nfs.prot_info4_spi_window", FT_UINT32, BASE_HEX,
13801 NULL, 0, NULL, HFILL }},
13802 { &hf_nfs4_state_protect_window, {
13803 "State Protect window", "nfs.state_protect_window", FT_UINT32, BASE_HEX,
13804 NULL, 0, NULL, HFILL }},
13805 { &hf_nfs4_state_protect_num_gss_handles, {
13806 "State Protect num gss handles", "nfs.state_protect_num_gss_handles", FT_UINT32, BASE_HEX,
13807 NULL, 0, NULL, HFILL }},
13808 { &hf_nfs4_nii_domain, {
13809 "Implementor DNS domain name(nii_domain)", "nfs.nii_domain4", FT_STRING, BASE_NONE,
13810 NULL, 0, NULL, HFILL }},
13811 { &hf_nfs4_nii_name, {
13812 "Implementation product name(nii_name)", "nfs.nii_name4", FT_STRING, BASE_NONE,
13813 NULL, 0, NULL, HFILL }},
13814 { &hf_nfs4_create_session_flags_csa, {
13815 "csa_flags", "nfs.create_session_flags", FT_UINT32, BASE_HEX,
13816 NULL, 0, NULL, HFILL }},
13817 { &hf_nfs4_create_session_flags_csr, {
13818 "csr_flags", "nfs.create_session_flags", FT_UINT32, BASE_HEX,
13819 NULL, 0, NULL, HFILL }},
13820 { &hf_nfs4_create_session_flags_persist, {
13821 "CREATE_SESSION4_FLAG_PERSIST", "nfs.create_session.flags.persist", FT_BOOLEAN, 32,
13822 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
13823 { &hf_nfs4_create_session_flags_conn_back_chan, {
13824 "CREATE_SESSION4_FLAG_CONN_BACK_CHAN", "nfs.create_session.flags.conn_back_chan",
13825 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
13826 { &hf_nfs4_create_session_flags_conn_rdma, {
13827 "CREATE_SESSION4_FLAG_CONN_RDMA", "nfs.create_session.flags.conn_rdma",
13828 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000004, NULL, HFILL}},
13829 { &hf_nfs4_cachethis, {
13830 "cache this?", "nfs.cachethis4", FT_BOOLEAN, BASE_NONE,
13831 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13832 { &hf_nfs4_reclaim_one_fs, {
13833 "reclaim one fs?", "nfs.reclaim_one_fs4", FT_BOOLEAN,
13834 BASE_NONE, TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13835 { &hf_nfs4_cb_procedure, {
13836 "CB Procedure", "nfs.cb_procedure", FT_UINT32, BASE_DEC,
13837 VALS(nfs_cb_proc_vals), 0, NULL, HFILL }},
13838 { &hf_nfs4_cb_op, {
13839 "Opcode", "nfs.cb.operation", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
13840 &names_nfs_cb_operation_ext, 0, NULL, HFILL }},
13841 { &hf_nfs4_lrs_present, {
13842 "StateID present?", "nfs.lrs_present", FT_BOOLEAN, BASE_NONE,
13843 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
13844 { &hf_nfs4_cb_truncate, {
13845 "Truncate?", "nfs.truncate", FT_BOOLEAN, BASE_NONE,
13846 TFS(&tfs_yes_no), 0, NULL, HFILL }},
13847 { &hf_nfs4_cb_layoutrecall_type, {
13848 "recall type", "nfs.recalltype", FT_UINT32, BASE_DEC,
13849 VALS(layoutrecall_names), 0, NULL, HFILL }},
13850 { &hf_nfs4_cb_clorachanged, {
13851 "Clora changed", "nfs.clorachanged", FT_BOOLEAN, BASE_NONE,
13852 TFS(&tfs_yes_no), 0, NULL, HFILL }},
13853
13854 { &hf_nfs4_bctsa_dir, {
13855 "bctsa_dir", "nfs.bctsa_dir", FT_UINT32, BASE_HEX,
13856 VALS(names_channel_dir_from_client), 0, NULL, HFILL }},
13857 { &hf_nfs4_bctsa_use_conn_in_rdma_mode, {
13858 "bctsa_use_conn_in_rdma_mode", "nfs.bctsa_use_conn_in_rdma_mode", FT_BOOLEAN, BASE_NONE,
13859 NULL, 0, NULL, HFILL }},
13860 { &hf_nfs4_bctsr_dir, {
13861 "bctsr_dir", "nfs.bctsr_dir", FT_UINT32, BASE_HEX,
13862 VALS(names_channel_dir_from_server), 0, NULL, HFILL }},
13863 { &hf_nfs4_bctsr_use_conn_in_rdma_mode, {
13864 "bctsr_use_conn_in_rdma_mode", "nfs.bctsr_use_conn_in_rdma_mode", FT_BOOLEAN, BASE_NONE,
13865 NULL, 0, NULL, HFILL }},
13866
13867 { &hf_nfs3_mode, {
13868 "Mode", "nfs.mode3", FT_UINT32, BASE_OCT,
13869 NULL, 0, NULL, HFILL }},
13870
13871 { &hf_nfs3_mode_suid, {
13872 "S_ISUID", "nfs.mode3.suid", FT_BOOLEAN, 32,
13873 TFS(&tfs_yes_no), 0x800, NULL, HFILL }},
13874
13875 { &hf_nfs3_mode_sgid, {
13876 "S_ISGID", "nfs.mode3.sgid", FT_BOOLEAN, 32,
13877 TFS(&tfs_yes_no), 0x400, NULL, HFILL }},
13878
13879 { &hf_nfs3_mode_sticky, {
13880 "S_ISVTX", "nfs.mode3.sticky", FT_BOOLEAN, 32,
13881 TFS(&tfs_yes_no), 0x200, NULL, HFILL }},
13882
13883 { &hf_nfs3_mode_rusr, {
13884 "S_IRUSR", "nfs.mode3.rusr", FT_BOOLEAN, 32,
13885 TFS(&tfs_yes_no), 0x100, NULL, HFILL }},
13886
13887 { &hf_nfs3_mode_wusr, {
13888 "S_IWUSR", "nfs.mode3.wusr", FT_BOOLEAN, 32,
13889 TFS(&tfs_yes_no), 0x080, NULL, HFILL }},
13890
13891 { &hf_nfs3_mode_xusr, {
13892 "S_IXUSR", "nfs.mode3.xusr", FT_BOOLEAN, 32,
13893 TFS(&tfs_yes_no), 0x040, NULL, HFILL }},
13894
13895 { &hf_nfs3_mode_rgrp, {
13896 "S_IRGRP", "nfs.mode3.rgrp", FT_BOOLEAN, 32,
13897 TFS(&tfs_yes_no), 0x020, NULL, HFILL }},
13898
13899 { &hf_nfs3_mode_wgrp, {
13900 "S_IWGRP", "nfs.mode3.wgrp", FT_BOOLEAN, 32,
13901 TFS(&tfs_yes_no), 0x010, NULL, HFILL }},
13902
13903 { &hf_nfs3_mode_xgrp, {
13904 "S_IXGRP", "nfs.mode3.xgrp", FT_BOOLEAN, 32,
13905 TFS(&tfs_yes_no), 0x008, NULL, HFILL }},
13906
13907 { &hf_nfs3_mode_roth, {
13908 "S_IROTH", "nfs.mode3.roth", FT_BOOLEAN, 32,
13909 TFS(&tfs_yes_no), 0x004, NULL, HFILL }},
13910
13911 { &hf_nfs3_mode_woth, {
13912 "S_IWOTH", "nfs.mode3.woth", FT_BOOLEAN, 32,
13913 TFS(&tfs_yes_no), 0x002, NULL, HFILL }},
13914
13915 { &hf_nfs3_mode_xoth, {
13916 "S_IXOTH", "nfs.mode3.xoth", FT_BOOLEAN, 32,
13917 TFS(&tfs_yes_no), 0x001, NULL, HFILL }},
13918
13919 { &hf_nfs2_ftype, {
13920 "type", "nfs.ftype", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
13921 &nfs2_ftype_ext, 0, NULL, HFILL }},
13922
13923 { &hf_nfs2_mode, {
13924 "mode", "nfs.mode", FT_UINT32, BASE_OCT,
13925 NULL, 0, NULL, HFILL }},
13926
13927 { &hf_nfs2_mode_name, {
13928 "Name", "nfs.mode.name", FT_UINT32, BASE_DEC,
13929 VALS(nfs2_mode_names), 0160000, NULL, HFILL }},
13930
13931 { &hf_nfs2_mode_set_user_id, {
13932 "Set user id on exec", "nfs.mode.set_user_id", FT_BOOLEAN, 32,
13933 TFS(&tfs_yes_no), 04000, NULL, HFILL }},
13934
13935 { &hf_nfs2_mode_set_group_id, {
13936 "Set group id on exec", "nfs.mode.set_group_id", FT_BOOLEAN, 32,
13937 TFS(&tfs_yes_no), 02000, NULL, HFILL }},
13938
13939 { &hf_nfs2_mode_save_swap_text, {
13940 "Save swapped text even after use", "nfs.mode.save_swap_text", FT_BOOLEAN, 32,
13941 TFS(&tfs_yes_no), 01000, NULL, HFILL }},
13942
13943 { &hf_nfs2_mode_read_owner, {
13944 "Read permission for owner", "nfs.mode.read_owner", FT_BOOLEAN, 32,
13945 TFS(&tfs_yes_no), 0400, NULL, HFILL }},
13946
13947 { &hf_nfs2_mode_write_owner, {
13948 "Write permission for owner", "nfs.mode.write_owner", FT_BOOLEAN, 32,
13949 TFS(&tfs_yes_no), 0200, NULL, HFILL }},
13950
13951 { &hf_nfs2_mode_exec_owner, {
13952 "Execute permission for owner", "nfs.mode.exec_owner", FT_BOOLEAN, 32,
13953 TFS(&tfs_yes_no), 0100, NULL, HFILL }},
13954
13955 { &hf_nfs2_mode_read_group, {
13956 "Read permission for group", "nfs.mode.read_group", FT_BOOLEAN, 32,
13957 TFS(&tfs_yes_no), 040, NULL, HFILL }},
13958
13959 { &hf_nfs2_mode_write_group, {
13960 "Write permission for group", "nfs.mode.write_group", FT_BOOLEAN, 32,
13961 TFS(&tfs_yes_no), 020, NULL, HFILL }},
13962
13963 { &hf_nfs2_mode_exec_group, {
13964 "Execute permission for group", "nfs.mode.exec_group", FT_BOOLEAN, 32,
13965 TFS(&tfs_yes_no), 010, NULL, HFILL }},
13966
13967 { &hf_nfs2_mode_read_other, {
13968 "Read permission for others", "nfs.mode.read_other", FT_BOOLEAN, 32,
13969 TFS(&tfs_yes_no), 04, NULL, HFILL }},
13970
13971 { &hf_nfs2_mode_write_other, {
13972 "Write permission for others", "nfs.mode.write_other", FT_BOOLEAN, 32,
13973 TFS(&tfs_yes_no), 02, NULL, HFILL }},
13974
13975 { &hf_nfs2_mode_exec_other, {
13976 "Execute permission for others", "nfs.mode.exec_other", FT_BOOLEAN, 32,
13977 TFS(&tfs_yes_no), 01, NULL, HFILL }},
13978
13979 { &hf_nfs4_sequence_status_flags, {
13980 "status flags", "nfs.sequence.flags", FT_UINT32, BASE_HEX,
13981 NULL, 0, NULL, HFILL }},
13982
13983 { &hf_nfs4_sequence_status_flags_cb_path_down, {
13984 "SEQ4_STATUS_CB_PATH_DOWN", "nfs.sequence.flags.cb_path_down", FT_BOOLEAN, 32,
13985 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
13986
13987 { &hf_nfs4_sequence_status_flags_cb_gss_contexts_expiring, {
13988 "SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING", "nfs.sequence.flags.cb_gss_contexts_expiring",
13989 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
13990
13991 { &hf_nfs4_sequence_status_flags_cb_gss_contexts_expired, {
13992 "SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED", "nfs.sequence.flags.cb_gss_contexts_expired",
13993 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000004, NULL, HFILL}},
13994
13995 { &hf_nfs4_sequence_status_flags_expired_all_state_revoked, {
13996 "SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED", "nfs.sequence.flags.expired_all_state_revoked",
13997 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000008, NULL, HFILL}},
13998
13999 { &hf_nfs4_sequence_status_flags_expired_some_state_revoked, {
14000 "SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED", "nfs.sequence.flags.expired_some_state_revoked",
14001 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000010, NULL, HFILL}},
14002
14003 { &hf_nfs4_sequence_status_flags_admin_state_revoked, {
14004 "SEQ4_STATUS_ADMIN_STATE_REVOKED", "nfs.sequence.flags.admin_state_revoked",
14005 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000020, NULL, HFILL}},
14006
14007 { &hf_nfs4_sequence_status_flags_recallable_state_revoked, {
14008 "SEQ4_STATUS_RECALLABLE_STATE_REVOKED", "nfs.sequence.flags.recallable_state_revoked",
14009 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000040, NULL, HFILL}},
14010
14011 { &hf_nfs4_sequence_status_flags_lease_moved, {
14012 "SEQ4_STATUS_LEASE_MOVED", "nfs.sequence.flags.lease_moved", FT_BOOLEAN, 32,
14013 TFS(&tfs_set_notset), 0x00000080, NULL, HFILL}},
14014
14015 { &hf_nfs4_sequence_status_flags_restart_reclaim_needed, {
14016 "SEQ4_STATUS_RESTART_RECLAIM_NEEDED", "nfs.sequence.flags.restart_reclaim_needed",
14017 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000100, NULL, HFILL}},
14018
14019 { &hf_nfs4_sequence_status_flags_cb_path_down_session, {
14020 "SEQ4_STATUS_CB_PATH_DOWN_SESSION", "nfs.sequence.flags.cb_path_down_session",
14021 FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000200, NULL, HFILL}},
14022
14023 { &hf_nfs4_sequence_status_flags_backchannel_fault, {
14024 "SEQ4_STATUS_BACKCHANNEL_FAULT", "nfs.sequence.flags.backchannel_fault", FT_BOOLEAN, 32,
14025 TFS(&tfs_set_notset), 0x00000400, NULL, HFILL}},
14026
14027 { &hf_nfs4_sequence_status_flags_devid_changed, {
14028 "SEQ4_STATUS_DEVID_CHANGED", "nfs.sequence.flags.devid_changed", FT_BOOLEAN, 32,
14029 TFS(&tfs_set_notset), 0x00000800, NULL, HFILL}},
14030
14031 { &hf_nfs4_sequence_status_flags_devid_deleted, {
14032 "SEQ4_STATUS_DEVID_DELETED", "nfs.sequence.flags.devid_deleted", FT_BOOLEAN, 32,
14033 TFS(&tfs_set_notset), 0x00001000, NULL, HFILL}},
14034
14035 { &hf_nfs4_test_stateid_arg, {
14036 "StateID List", "nfs.test_stateid.stateids",
14037 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
14038
14039 { &hf_nfs4_test_stateid_res, {
14040 "StateID Result List", "nfs.test_stateid.results",
14041 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
14042
14043 { &hf_nfs4_seek_data_content, {
14044 "data content", "nfs.data_content", FT_UINT32, BASE_DEC,
14045 VALS(names_data_content), 0, NULL, HFILL }},
14046
14047 { &hf_nfs4_bitmap_data, {
14048 "Undissected bitmap data", "nfs.bitmap_data", FT_BYTES, BASE_NONE,
14049 NULL, 0, NULL, HFILL }},
14050
14051 { &hf_nfs4_huge_bitmap_length, {
14052 "Huge bitmap length", "nfs.huge_bitmap_length", FT_UINT32, BASE_DEC,
14053 NULL, 0, NULL, HFILL }},
14054
14055 { &hf_nfs4_universal_address_ipv4, {
14056 "universal_address", "nfs.universal_address.ipv4", FT_IPv4, BASE_NONE,
14057 NULL, 0, NULL, HFILL }},
14058
14059 { &hf_nfs4_universal_address_ipv6, {
14060 "universal_address", "nfs.universal_address.ipv6", FT_IPv6, BASE_NONE,
14061 NULL, 0, NULL, HFILL }},
14062
14063 { &hf_nfs4_getdevinfo, {
14064 "dev info", "nfs.devinfo", FT_BYTES,
14065 BASE_NONE, NULL, 0, NULL, HFILL }},
14066
14067 { &hf_nfs4_ff_version, {
14068 "version", "nfs.ff.version", FT_UINT32, BASE_DEC,
14069 NULL, 0, NULL, HFILL }},
14070
14071 { &hf_nfs4_ff_minorversion, {
14072 "minorversion", "nfs.ff.minorversion", FT_UINT32,
14073 BASE_DEC, NULL, 0, NULL, HFILL }},
14074
14075 { &hf_nfs4_ff_rsize, {
14076 "max_rsize", "nfs.ff.rsize", FT_UINT32,
14077 BASE_DEC, NULL, 0, NULL, HFILL }},
14078
14079 { &hf_nfs4_ff_wsize, {
14080 "max_wsize", "nfs.ff.wsize", FT_UINT32,
14081 BASE_DEC, NULL, 0, NULL, HFILL }},
14082
14083 { &hf_nfs4_ff_tightly_coupled, {
14084 "tightly coupled", "nfs.ff.tightly_coupled",
14085 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
14086 NULL, HFILL }},
14087
14088 { &hf_nfs4_ff_layout_flags, {
14089 "layout flags", "nfs.ff.layout_flags", FT_UINT32, BASE_HEX,
14090 NULL, 0, NULL, HFILL }},
14091
14092 { &hf_nfs4_ff_synthetic_owner, {
14093 "synthetic owner", "nfs.ff.synthetic_owner", FT_STRING, BASE_NONE,
14094 NULL, 0, NULL, HFILL }},
14095
14096 { &hf_nfs4_ff_synthetic_owner_group, {
14097 "synthetic group", "nfs.ff.synthetic_owner_group", FT_STRING, BASE_NONE,
14098 NULL, 0, NULL, HFILL }},
14099
14100 { &hf_nfs4_ff_layout_flags_no_layoutcommit, {
14101 "FLAG_NO_LAYOUTCOMMIT", "nfs.ff.layout_flags.no_layoutcommit", FT_BOOLEAN, 32,
14102 TFS(&tfs_set_notset), 0x00000001, NULL, HFILL}},
14103
14104 { &hf_nfs4_ff_layout_flags_no_io_thru_mds, {
14105 "FLAG_NO_IO_THRU_MDS", "nfs.ff.layout_flags.no_io_thru_mds", FT_BOOLEAN, 32,
14106 TFS(&tfs_set_notset), 0x00000002, NULL, HFILL}},
14107
14108 { &hf_nfs4_ff_layout_flags_no_read_io, {
14109 "FLAG_NO_READ_IO", "nfs.ff.layout_flags.no_read_io", FT_BOOLEAN, 32,
14110 TFS(&tfs_set_notset), 0x00000004, NULL, HFILL}},
14111
14112 { &hf_nfs4_ff_stats_collect_hint, {
14113 "stats collect hint", "nfs.ff.stats_collect_hint", FT_UINT32, BASE_DEC,
14114 NULL, 0, "Layoutstats sampling period hint, Seconds", HFILL }},
14115
14116 { &hf_nfs4_fattr_clone_blocksize, {
14117 "clone block size", "nfs.fattr4.clone_block_size", FT_UINT32, BASE_DEC,
14118 NULL, 0, NULL, HFILL }},
14119
14120 { &hf_nfs4_fattr_space_freed, {
14121 "space freed", "nfs.fattr4.space_freed", FT_UINT64, BASE_DEC,
14122 NULL, 0, NULL, HFILL }},
14123
14124 { &hf_nfs4_fattr_change_attr_type, {
14125 "change attr type", "nfs.fattr4.change_attr_type", FT_UINT32, BASE_DEC,
14126 VALS(names_nfs_change_attr_types), 0, NULL, HFILL }},
14127
14128 { &hf_nfs4_callback_stateids, {
14129 "Callback StateIds", "nfs.callback_ids", FT_UINT32, BASE_DEC,
14130 NULL, 0, NULL, HFILL }},
14131
14132 { &hf_nfs4_callback_stateids_index, {
14133 "Callback Id", "nfs.ff.callback_id_index", FT_UINT32, BASE_DEC,
14134 NULL, 0, NULL, HFILL }},
14135
14136 { &hf_nfs4_num_offload_status, {
14137 "Number of offload status", "nfs.num_offload_status", FT_UINT32, BASE_DEC,
14138 NULL, 0, NULL, HFILL }},
14139
14140 { &hf_nfs4_offload_status_index, {
14141 "nfsstat4", "nfs.offload_status", FT_UINT32, BASE_DEC,
14142 NULL, 0, NULL, HFILL }},
14143
14144 { &hf_nfs4_consecutive, {
14145 "copy consecutively?", "nfs.consecutive", FT_BOOLEAN, BASE_NONE,
14146 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14147
14148 { &hf_nfs4_netloc, {
14149 "net loc", "nfs.netloc", FT_BYTES,
14150 BASE_NONE, NULL, 0, NULL, HFILL }},
14151
14152 { &hf_nfs4_netloc_type, {
14153 "netloc type", "nfs.netloctype", FT_UINT32, BASE_DEC,
14154 VALS(netloctype_names), 0, NULL, HFILL }},
14155
14156 { &hf_nfs4_nl_name, {
14157 "net loc name", "nfs.nl_name", FT_STRING, BASE_NONE,
14158 NULL, 0, NULL, HFILL }},
14159
14160 { &hf_nfs4_nl_url, {
14161 "net loc url", "nfs.nl_url", FT_STRING, BASE_NONE,
14162 NULL, 0, NULL, HFILL }},
14163
14164 { &hf_nfs4_source_servers, {
14165 "Source Server count", "nfs.source_servers", FT_UINT32, BASE_DEC,
14166 NULL, 0, NULL, HFILL }},
14167
14168 { &hf_nfs4_source_server_index, {
14169 "Source Server", "nfs.ff.source_server_index", FT_UINT32, BASE_DEC,
14170 NULL, 0, NULL, HFILL }},
14171
14172 { &hf_nfs4_synchronous, {
14173 "copy synchronous?", "nfs.synchronous", FT_BOOLEAN, BASE_NONE,
14174 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14175
14176 { &hf_nfs4_io_hints_mask, {
14177 "Hint mask", "nfs.hint.mask", FT_UINT32, BASE_HEX,
14178 NULL, 0, NULL, HFILL }},
14179
14180 { &hf_nfs4_io_hint_count, {
14181 "Hint count", "nfs.hint.count", FT_UINT32, BASE_DEC,
14182 NULL, 0, NULL, HFILL }},
14183
14184 { &hf_nfs4_io_advise_hint, {
14185 "Hint", "nfs.hint.hint", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
14186 &io_advise_names_ext, 0, NULL, HFILL }},
14187
14188 { &hf_nfs4_bytes_copied, {
14189 "bytes copied", "nfs.bytes_copied", FT_UINT64, BASE_DEC,
14190 NULL, 0, NULL, HFILL }},
14191
14192 { &hf_nfs4_read_plus_contents, {
14193 "Contents", "nfs.contents",
14194 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
14195
14196 { &hf_nfs4_read_plus_content_type, {
14197 "Content Type", "nfs.content.type", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
14198 &read_plus_content_names_ext, 0, NULL, HFILL }},
14199
14200 { &hf_nfs4_block_size, {
14201 "Content index", "nfs.content.index", FT_UINT32, BASE_DEC,
14202 NULL, 0, NULL, HFILL }},
14203
14204 { &hf_nfs4_block_count, {
14205 "Number of Blocks", "nfs.adb.block.count", FT_UINT32, BASE_DEC,
14206 NULL, 0, NULL, HFILL }},
14207
14208 { &hf_nfs4_reloff_blocknum, {
14209 "Relative Offset Block Number", "nfs.adb.block.reloff_num", FT_UINT32, BASE_DEC,
14210 NULL, 0, NULL, HFILL }},
14211
14212 { &hf_nfs4_blocknum, {
14213 "Block Number", "nfs.adb.block.num", FT_UINT32, BASE_DEC,
14214 NULL, 0, NULL, HFILL }},
14215
14216 { &hf_nfs4_reloff_pattern, {
14217 "Relative Offset Pattern", "nfs.adb.pattern.reloff", FT_UINT32, BASE_DEC,
14218 NULL, 0, NULL, HFILL }},
14219
14220 { &hf_nfs4_pattern_hash, {
14221 "hash (CRC-32)", "nfs.adb.pattern_hash", FT_UINT32, BASE_HEX,
14222 NULL, 0, "ADB pattern hash", HFILL }},
14223
14224 { &hf_nfs4_xattrkey, {
14225 "Name", "nfs.xattr.key", FT_STRING, BASE_NONE,
14226 NULL, 0, "Xattr key", HFILL }},
14227
14228 { &hf_nfs4_setxattr_options, {
14229 "setxattr options", "nfs.setxattr.options", FT_UINT32, BASE_DEC,
14230 VALS(names_setxattr_options), 0, NULL, HFILL }},
14231
14232 { &hf_nfs4_listxattr_maxcount, {
14233 "maxcount", "nfs.lisxtattr.maxcount", FT_UINT32, BASE_DEC,
14234 NULL, 0, "Lixtxattr maxcount", HFILL }},
14235
14236 { &hf_nfs4_listxattr_cookie, {
14237 "cookie", "nfs.lisxtattr.cookie", FT_UINT64, BASE_DEC,
14238 NULL, 0, "Lixtxattr cookie", HFILL }},
14239
14240 { &hf_nfs4_listxattr_names_len, {
14241 "xattr names count", "nfs.listxattr.names.count", FT_UINT32, BASE_DEC,
14242 NULL, 0, "Number of xattrkey names", HFILL }},
14243
14244 { &hf_nfs4_listxattr_eof, {
14245 "eof", "nfs.lisxtattr.eof", FT_UINT32, BASE_DEC,
14246 NULL, 0, "Lixtxattr eof", HFILL }},
14247
14248 { &hf_nfs4_ff_local, {
14249 "client used cache?", "nfs.ff.local", FT_BOOLEAN, BASE_NONE,
14250 TFS(&tfs_yes_no), 0x0, NULL, HFILL }},
14251
14252 { &hf_nfs4_io_count, {
14253 "count", "nfs.io_count", FT_UINT64, BASE_DEC,
14254 NULL, 0, NULL, HFILL }},
14255
14256 { &hf_nfs4_io_bytes, {
14257 "bytes", "nfs.io_bytes", FT_UINT64, BASE_DEC,
14258 NULL, 0, NULL, HFILL }},
14259
14260 { &hf_nfs4_ff_ops_requested, {
14261 "ops requested", "nfs.ff.ops_requested", FT_UINT64, BASE_DEC,
14262 NULL, 0, NULL, HFILL }},
14263
14264 { &hf_nfs4_ff_bytes_requested, {
14265 "bytes requested", "nfs.ff.bytes_requested", FT_UINT64, BASE_DEC,
14266 NULL, 0, NULL, HFILL }},
14267
14268 { &hf_nfs4_ff_ops_completed, {
14269 "ops completed", "nfs.ff.ops_completed", FT_UINT64, BASE_DEC,
14270 NULL, 0, NULL, HFILL }},
14271
14272 { &hf_nfs4_ff_bytes_completed, {
14273 "bytes completed", "nfs.ff.bytes_completed", FT_UINT64, BASE_DEC,
14274 NULL, 0, NULL, HFILL }},
14275
14276 { &hf_nfs4_ff_bytes_not_delivered, {
14277 "bytes not delivered", "nfs.ff.bytes_not_delivered", FT_UINT64, BASE_DEC,
14278 NULL, 0, NULL, HFILL }},
14279
14280 { &hf_nfs4_layoutstats, {
14281 "Layout Stats", "nfs.layoutstats", FT_BYTES, BASE_NONE,
14282 NULL, 0, NULL, HFILL }},
14283
14284 { &hf_nfs4_device_error_count, {
14285 "Device Error count", "nfs.device_error_count", FT_UINT32, BASE_DEC,
14286 NULL, 0, NULL, HFILL }},
14287
14288 { &hf_nfs4_device_errors_index, {
14289 "Device Error index", "nfs.device_errors_index", FT_UINT32, BASE_DEC,
14290 NULL, 0, NULL, HFILL }},
14291
14292 { &hf_nfs4_ff_ioerrs_count, {
14293 "IO Errors count", "nfs.ff.ioerrs_count", FT_UINT32, BASE_DEC,
14294 NULL, 0, NULL, HFILL }},
14295
14296 { &hf_nfs4_ff_ioerrs_index, {
14297 "IO Errors index", "nfs.ff.ioerrs_index", FT_UINT32, BASE_DEC,
14298 NULL, 0, NULL, HFILL }},
14299
14300 { &hf_nfs4_ff_ioerrs_length, {
14301 "length", "nfs.ff.ioerrs_length", FT_UINT64, BASE_DEC,
14302 NULL, 0, NULL, HFILL }},
14303
14304 { &hf_nfs4_ff_ioerrs_offset, {
14305 "offset", "nfs.ff.ioerrs_offset", FT_UINT64, BASE_DEC,
14306 NULL, 0, NULL, HFILL }},
14307
14308 { &hf_nfs4_ff_iostats_count, {
14309 "IO Stats count", "nfs.ff.iostats_count", FT_UINT32, BASE_DEC,
14310 NULL, 0, NULL, HFILL }},
14311
14312 { &hf_nfs4_ff_iostats_index, {
14313 "IO Stats index", "nfs.ff.iostats_index", FT_UINT32, BASE_DEC,
14314 NULL, 0, NULL, HFILL }},
14315
14316 { &hf_nfs4_io_error_op, {
14317 "OP", "nfs.ff_ioerrs_op", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
14318 &names_nfs4_operation_ext, 0, NULL, HFILL }},
14319
14320 /* Hidden field for v2, v3, and v4 status */
14321 { &hf_nfs_status, {
14322 "Status", "nfs.status", FT_UINT32, BASE_DEC | BASE_EXT_STRING,
14323 &names_nfs_nfsstat_ext, 0, "Reply status", HFILL }}
14324 };
14325
14326 static gint *ett[] = {
14327 &ett_nfs,
14328 &ett_nfs_fh_encoding,
14329 &ett_nfs_fh_fsid,
14330 &ett_nfs_fh_file,
14331 &ett_nfs_fh_mount,
14332 &ett_nfs_fh_export,
14333 &ett_nfs_fh_xfsid,
14334 &ett_nfs_fh_fn,
14335 &ett_nfs_fh_xfn,
14336 &ett_nfs_fh_hp,
14337 &ett_nfs_fh_auth,
14338 &ett_nfs_fhandle,
14339 &ett_nfs_timeval,
14340 &ett_nfs_fattr,
14341 &ett_nfs_fh_obj,
14342 &ett_nfs_fh_ex,
14343 &ett_nfs_readdir_entry,
14344 &ett_nfs_utf8string,
14345
14346 &ett_nfs2_mode,
14347 &ett_nfs2_sattr,
14348 &ett_nfs2_diropargs,
14349
14350 &ett_nfs3_gxfh_utlfield,
14351 &ett_nfs3_gxfh_sfhfield,
14352 &ett_nfs3_gxfh_sfhflags,
14353 &ett_nfs3_mode,
14354 &ett_nfs3_specdata,
14355 &ett_nfs3_fh,
14356 &ett_nfs3_nfstime,
14357 &ett_nfs3_fattr,
14358 &ett_nfs3_post_op_fh,
14359 &ett_nfs3_sattr,
14360 &ett_nfs3_diropargs,
14361 &ett_nfs3_sattrguard,
14362 &ett_nfs3_set_mode,
14363 &ett_nfs3_set_uid,
14364 &ett_nfs3_set_gid,
14365 &ett_nfs3_set_size,
14366 &ett_nfs3_set_atime,
14367 &ett_nfs3_set_mtime,
14368 &ett_nfs3_pre_op_attr,
14369 &ett_nfs3_post_op_attr,
14370 &ett_nfs3_wcc_attr,
14371 &ett_nfs3_wcc_data,
14372 &ett_nfs3_access,
14373 &ett_nfs3_fsinfo_properties,
14374
14375 &ett_nfs4_fh_file,
14376 &ett_nfs4_fh_file_flags,
14377 &ett_nfs4_fh_export,
14378 &ett_nfs4_compound_call,
14379 &ett_nfs4_request_op,
14380 &ett_nfs4_response_op,
14381 &ett_nfs4_access,
14382 &ett_nfs4_access_supp,
14383 &ett_nfs4_close,
14384 &ett_nfs4_commit,
14385 &ett_nfs4_create,
14386 &ett_nfs4_delegpurge,
14387 &ett_nfs4_delegreturn,
14388 &ett_nfs4_getattr,
14389 &ett_nfs4_getattr_args,
14390 &ett_nfs4_getattr_resp,
14391 &ett_nfs4_resok4,
14392 &ett_nfs4_obj_attrs,
14393 &ett_nfs4_fattr_new_attr_vals,
14394 &ett_nfs4_fattr4_attrmask,
14395 &ett_nfs4_attribute,
14396 &ett_nfs4_getfh,
14397 &ett_nfs4_link,
14398 &ett_nfs4_lock,
14399 &ett_nfs4_lockt,
14400 &ett_nfs4_locku,
14401 &ett_nfs4_lookup,
14402 &ett_nfs4_lookupp,
14403 &ett_nfs4_nverify,
14404 &ett_nfs4_open,
14405 &ett_nfs4_openattr,
14406 &ett_nfs4_open_confirm,
14407 &ett_nfs4_open_downgrade,
14408 &ett_nfs4_putfh,
14409 &ett_nfs4_putpubfh,
14410 &ett_nfs4_putrootfh,
14411 &ett_nfs4_read,
14412 &ett_nfs4_readdir,
14413 &ett_nfs4_readlink,
14414 &ett_nfs4_test_stateid,
14415 &ett_nfs4_destroy_clientid,
14416 &ett_nfs4_reclaim_complete,
14417 &ett_nfs4_remove,
14418 &ett_nfs4_rename,
14419 &ett_nfs4_renew,
14420 &ett_nfs4_restorefh,
14421 &ett_nfs4_savefh,
14422 &ett_nfs4_setattr,
14423 &ett_nfs4_setclientid,
14424 &ett_nfs4_setclientid_confirm,
14425 &ett_nfs4_verify,
14426 &ett_nfs4_write,
14427 &ett_nfs4_release_lockowner,
14428 &ett_nfs4_backchannel_ctl,
14429 &ett_nfs4_bind_conn_to_session,
14430 &ett_nfs4_exchange_id,
14431 &ett_nfs4_create_session,
14432 &ett_nfs4_destroy_session,
14433 &ett_nfs4_free_stateid,
14434 &ett_nfs4_secinfo_no_name,
14435 &ett_nfs4_sequence,
14436 &ett_nfs4_layoutget,
14437 &ett_nfs4_layoutcommit,
14438 &ett_nfs4_layoutreturn,
14439 &ett_nfs4_getdevinfo,
14440 &ett_nfs4_getdevlist,
14441 &ett_nfs4_seek,
14442 &ett_nfs4_allocate,
14443 &ett_nfs4_deallocate,
14444 &ett_nfs4_illegal,
14445 &ett_nfs4_verifier,
14446 &ett_nfs4_dirlist,
14447 &ett_nfs4_dir_entry,
14448 &ett_nfs4_pathname,
14449 &ett_nfs4_change_info,
14450 &ett_nfs4_open_delegation,
14451 &ett_nfs4_open_claim,
14452 &ett_nfs4_opentype,
14453 &ett_nfs4_lock_owner,
14454 &ett_nfs4_cb_client,
14455 &ett_nfs4_client_id,
14456 &ett_nfs4_clientowner,
14457 &ett_nfs4_exchangeid_call_flags,
14458 &ett_nfs4_exchangeid_reply_flags,
14459 &ett_nfs4_server_owner,
14460 &ett_nfs4_bitmap,
14461 &ett_nfs4_attr_request,
14462 &ett_nfs4_fattr,
14463 &ett_nfs4_fsid,
14464 &ett_nfs4_fs_locations,
14465 &ett_nfs4_fs_location,
14466 &ett_nfs4_open_result_flags,
14467 &ett_nfs4_secinfo,
14468 &ett_nfs4_secinfo_flavor_info,
14469 &ett_nfs4_stateid,
14470 &ett_nfs4_fattr_fh_expire_type,
14471 &ett_nfs4_fattr_aclsupport,
14472 &ett_nfs4_fattr_fs_charset_cap,
14473 &ett_nfs4_aclflag,
14474 &ett_nfs4_ace,
14475 &ett_nfs4_clientaddr,
14476 &ett_nfs4_aceflag,
14477 &ett_nfs4_acemask,
14478 &ett_nfs4_slotid,
14479 &ett_nfs4_sr_status,
14480 &ett_nfs4_serverscope,
14481 &ett_nfs4_minorid,
14482 &ett_nfs4_majorid,
14483 &ett_nfs4_persist,
14484 &ett_nfs4_backchan,
14485 &ett_nfs4_rdmamode,
14486 &ett_nfs4_padsize,
14487 &ett_nfs4_cbrenforce,
14488 &ett_nfs4_hashalg,
14489 &ett_nfs4_ssvlen,
14490 &ett_nfs4_maxreqsize,
14491 &ett_nfs4_maxrespsize,
14492 &ett_nfs4_maxrespsizecached,
14493 &ett_nfs4_maxops,
14494 &ett_nfs4_maxreqs,
14495 &ett_nfs4_streamchanattrs,
14496 &ett_nfs4_rdmachanattrs,
14497 &ett_nfs4_machinename,
14498 &ett_nfs4_flavor,
14499 &ett_nfs4_stamp,
14500 &ett_nfs4_uid,
14501 &ett_nfs4_gid,
14502 &ett_nfs4_service,
14503 &ett_nfs4_sessionid,
14504 &ett_nfs4_layoutseg,
14505 &ett_nfs4_layoutseg_sub,
14506 &ett_nfs4_nfl_util,
14507 &ett_nfs4_cb_request_op,
14508 &ett_nfs4_cb_resop,
14509 &ett_nfs4_cb_getattr,
14510 &ett_nfs4_cb_recall,
14511 &ett_nfs4_cb_layoutrecall,
14512 &ett_nfs4_cb_pushdeleg,
14513 &ett_nfs4_cb_recallany,
14514 &ett_nfs4_cb_recallableobjavail,
14515 &ett_nfs4_cb_recallslot,
14516 &ett_nfs4_cb_sequence,
14517 &ett_nfs4_cb_wantscancelled,
14518 &ett_nfs4_cb_notifylock,
14519 &ett_nfs4_cb_notifydeviceid,
14520 &ett_nfs4_cb_notify,
14521 &ett_nfs4_cb_reflists,
14522 &ett_nfs4_cb_refcalls,
14523 &ett_nfs4_cb_illegal,
14524 &ett_nfs4_chan_attrs,
14525 &ett_nfs4_create_session_flags,
14526 &ett_nfs4_sequence_status_flags,
14527 &ett_nfs4_want_notify_flags,
14528 &ett_nfs4_ff_layout_flags,
14529 &ett_nfs4_scsi_layout_vol,
14530 &ett_nfs4_scsi_layout_vol_indices,
14531 &ett_nfs4_layoutstats,
14532 &ett_nfs4_io_info,
14533 &ett_nfs4_io_latency,
14534 &ett_nfs4_io_time,
14535 &ett_nfs4_callback_stateids_sub,
14536 &ett_nfs4_source_servers_sub,
14537 &ett_nfs4_copy,
14538 &ett_nfs4_copy_notify,
14539 &ett_nfs4_device_errors_sub,
14540 &ett_nfs4_layouterror,
14541 &ett_nfs4_ff_ioerrs_sub,
14542 &ett_nfs4_ff_iostats_sub,
14543 &ett_nfs4_clone,
14544 &ett_nfs4_getxattr,
14545 &ett_nfs4_setxattr,
14546 &ett_nfs4_listxattr,
14547 &ett_nfs4_removexattr,
14548 &ett_nfs4_offload_cancel,
14549 &ett_nfs4_offload_status,
14550 &ett_nfs4_osr_complete_sub,
14551 &ett_nfs4_io_advise,
14552 &ett_nfs4_read_plus,
14553 &ett_nfs4_read_plus_content_sub,
14554 &ett_nfs4_write_same,
14555 &ett_nfs4_fh_pd_flags,
14556 &ett_nfs4_fh_pd_sites,
14557 &ett_nfs4_fh_pd_spaces,
14558 &ett_nfs4_listxattr_names
14559
14560 };
14561
14562 static ei_register_info ei[] = {
14563 { &ei_nfs_too_many_ops, { "nfs.too_many_ops", PI_PROTOCOL, PI_NOTE, "Too many operations", EXPFILL }},
14564 { &ei_nfs_not_vnx_file, { "nfs.not_vnx_file", PI_UNDECODED, PI_WARN, "Not a Celerra|VNX file handle", EXPFILL }},
14565 { &ei_protocol_violation, { "nfs.protocol_violation", PI_PROTOCOL, PI_WARN,
14566 "Per RFCs 3530 and 5661 an attribute mask is required but was not provided.", EXPFILL }},
14567 { &ei_nfs_too_many_bitmaps, { "nfs.too_many_bitmaps", PI_PROTOCOL, PI_NOTE, "Too many bitmap array items", EXPFILL }},
14568 { &ei_nfs_bitmap_no_dissector, { "nfs.bitmap_no_dissector", PI_PROTOCOL, PI_WARN,
14569 "Unknown dissector for bitmap attribute", EXPFILL }},
14570 { &ei_nfs_bitmap_skip_value, { "nfs.bitmap_skip_value", PI_PROTOCOL, PI_WARN,
14571 "Not dissecting value since a previous value was not dissected", EXPFILL }},
14572 { &ei_nfs_bitmap_undissected_data, { "nfs.bitmap_undissected_data", PI_PROTOCOL, PI_WARN,
14573 "There is some bitmap data left undissected", EXPFILL }},
14574 { &ei_nfs4_stateid_deprecated, { "nfs.stateid.deprecated", PI_PROTOCOL, PI_WARN, "State ID deprecated in CLOSE responses [RFC7530 16.2.5]", EXPFILL }},
14575 { &ei_nfs_file_system_cycle, { "nfs.file_system_cycle", PI_PROTOCOL, PI_WARN, "Possible file system cycle detected", EXPFILL }},
14576 };
14577
14578 module_t *nfs_module;
14579 expert_module_t* expert_nfs;
14580
14581 proto_nfs = proto_register_protocol("Network File System", "NFS", "nfs");
14582
14583 /* "protocols" registered just for Decode As */
14584 proto_nfs_unknown = proto_register_protocol_in_name_only("Unknown", "unknown", "nfs.unknown", proto_nfs, FT_PROTOCOL);
14585 proto_nfs_svr4 = proto_register_protocol_in_name_only("SVR4", "svr4", "nfs.svr4", proto_nfs, FT_PROTOCOL);
14586 proto_nfs_knfsd_le = proto_register_protocol_in_name_only("KNFSD_LE", "knfsd_le", "nfs.knfsd_le", proto_nfs, FT_PROTOCOL);
14587 proto_nfs_nfsd_le = proto_register_protocol_in_name_only("NFSD_LE", "nfsd_le", "nfs.nfsd_le", proto_nfs, FT_PROTOCOL);
14588 proto_nfs_knfsd_new = proto_register_protocol_in_name_only("KNFSD_NEW", "knfsd_new", "nfs.knfsd_new", proto_nfs, FT_PROTOCOL);
14589 proto_nfs_ontap_v3 = proto_register_protocol_in_name_only("ONTAP_V3", "ontap_v3", "nfs.ontap_v3", proto_nfs, FT_PROTOCOL);
14590 proto_nfs_ontap_v4 = proto_register_protocol_in_name_only("ONTAP_V4", "ontap_v4", "nfs.ontap_v4", proto_nfs, FT_PROTOCOL);
14591 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);
14592 proto_nfs_celerra_vnx = proto_register_protocol_in_name_only("CELERRA_VNX", "celerra_vnx", "nfs.celerra_vnx", proto_nfs, FT_PROTOCOL);
14593 proto_nfs_gluster = proto_register_protocol_in_name_only("GLUSTER", "gluster", "nfs.gluster", proto_nfs, FT_PROTOCOL);
14594 proto_nfs_dcache = proto_register_protocol_in_name_only("dCache", "dcache", "nfs.dcache", proto_nfs, FT_PROTOCOL);
14595 proto_nfs_primary_data = proto_register_protocol_in_name_only("Primary_Data", "pd", "nfs.primary_data", proto_nfs, FT_PROTOCOL);
14596
14597 /* "protocols" registered just for ONC-RPC Service Response Time */
14598 proto_nfs_cb = proto_register_protocol_in_name_only("Network File System CB", "NFS CB", "nfs.cb", proto_nfs, FT_PROTOCOL);
14599
14600 proto_register_field_array(proto_nfs, hf, array_length(hf));
14601 proto_register_subtree_array(ett, array_length(ett));
14602 expert_nfs = expert_register_protocol(proto_nfs);
14603 expert_register_field_array(expert_nfs, ei, array_length(ei));
14604
14605 nfs_module = prefs_register_protocol(proto_nfs, NULL);
14606 prefs_register_bool_preference(nfs_module, "file_name_snooping",
14607 "Snoop FH to filename mappings",
14608 "Whether the dissector should snoop the FH to"
14609 " filename mappings by looking inside certain packets",
14610 &nfs_file_name_snooping);
14611 prefs_register_bool_preference(nfs_module, "file_full_name_snooping",
14612 "Snoop full path to filenames",
14613 "Whether the dissector should snoop the full pathname"
14614 " for files for matching FH's",
14615 &nfs_file_name_full_snooping);
14616 prefs_register_bool_preference(nfs_module, "fhandle_find_both_reqrep",
14617 "Fhandle filters finds both request/response",
14618 "With this option display filters for nfs fhandles"
14619 " (nfs.fh.{name|full_name|hash}) will find both the request"
14620 " and response packets for a RPC call, even if the actual"
14621 " fhandle is only present in one of the packets",
14622 &nfs_fhandle_reqrep_matching);
14623 prefs_register_bool_preference(nfs_module, "display_nfsv4_tag",
14624 "Display NFSv4 tag in info Column",
14625 "When enabled, this option will print the NFSv4 tag"
14626 " (if one exists) in the Info column in the Summary pane",
14627 &nfs_display_v4_tag);
14628 prefs_register_bool_preference(nfs_module, "display_major_nfsv4_ops",
14629 "Display only 'significant' NFSv4 Operations in info Column",
14630 "When enabled, shows only the significant NFSv4 Operations"
14631 " in the info column. Others (like GETFH, PUTFH, etc) are not displayed",
14632 &display_major_nfs4_ops);
14633
14634 prefs_register_obsolete_preference(nfs_module, "default_fhandle_type");
14635
14636 nfs_name_snoop_known = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
14637 nfs_file_handles = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
14638 nfs_fhandle_frame_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
14639 register_init_routine(nfs_name_snoop_init);
14640 register_cleanup_routine(nfs_name_snoop_cleanup);
14641
14642 nfs_fhandle_table = register_decode_as_next_proto(proto_nfs, "nfs_fhandle.type",
14643 "NFS File Handle types", nfs_prompt);
14644 }
14645
14646
14647 void
proto_reg_handoff_nfs(void)14648 proto_reg_handoff_nfs(void)
14649 {
14650 dissector_handle_t fhandle_handle;
14651
14652 /* Register the protocol as RPC */
14653 rpc_init_prog(proto_nfs, NFS_PROGRAM, ett_nfs,
14654 G_N_ELEMENTS(nfs_vers_info), nfs_vers_info);
14655
14656 /* Register the CB protocol as RPC */
14657 rpc_init_prog(proto_nfs_cb, NFS_CB_PROGRAM, ett_nfs,
14658 G_N_ELEMENTS(nfs_cb_vers_info), nfs_cb_vers_info);
14659
14660 fhandle_handle = create_dissector_handle(dissect_fhandle_data_SVR4, proto_nfs_svr4);
14661 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14662
14663 fhandle_handle = create_dissector_handle(dissect_fhandle_data_LINUX_KNFSD_LE, proto_nfs_knfsd_le);
14664 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14665
14666 fhandle_handle = create_dissector_handle(dissect_fhandle_data_LINUX_NFSD_LE, proto_nfs_nfsd_le);
14667 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14668
14669 fhandle_handle = create_dissector_handle(dissect_fhandle_data_LINUX_KNFSD_NEW, proto_nfs_knfsd_new);
14670 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14671
14672 fhandle_handle = create_dissector_handle(dissect_fhandle_data_NETAPP, proto_nfs_ontap_v3);
14673 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14674
14675 fhandle_handle = create_dissector_handle(dissect_fhandle_data_NETAPP_V4, proto_nfs_ontap_v4);
14676 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14677
14678 fhandle_handle = create_dissector_handle(dissect_fhandle_data_NETAPP_GX_v3, proto_nfs_ontap_gx_v3);
14679 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14680
14681 fhandle_handle = create_dissector_handle(dissect_fhandle_data_CELERRA_VNX, proto_nfs_celerra_vnx);
14682 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14683
14684 fhandle_handle = create_dissector_handle(dissect_fhandle_data_GLUSTER, proto_nfs_gluster);
14685 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14686
14687 fhandle_handle = create_dissector_handle(dissect_fhandle_data_DCACHE, proto_nfs_dcache);
14688 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14689
14690 fhandle_handle = create_dissector_handle(dissect_fhandle_data_PRIMARY_DATA, proto_nfs_primary_data);
14691 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14692
14693 fhandle_handle = create_dissector_handle(dissect_fhandle_data_unknown, proto_nfs_unknown);
14694 dissector_add_for_decode_as("nfs_fhandle.type", fhandle_handle);
14695 }
14696
14697 /*
14698 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14699 *
14700 * Local variables:
14701 * c-basic-offset: 8
14702 * tab-width: 8
14703 * indent-tabs-mode: t
14704 * End:
14705 *
14706 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14707 * :indentSize=8:tabSize=8:noTabs=false:
14708 */
14709