Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-pvfs2.c
blobace82577a84638fdd1019a60889914e49ee60d43
1 /* packet-pvfs2.c
2 * Routines for pvfs2 packet dissection
3 * By Mike Frisch <mfrisch@platform.com>
4 * Joint and Several Copyright 2005, Mike Frisch and Platform Computing Inc.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Dissector for Parallel Virtual File System (PVFS) version 2.
11 * https://web.archive.org/web/20160701052501/http://www.pvfs.org/
13 * Copied from packet-smb.c and others
15 * TODO
17 * - Add filename snooping (match file handles with file names),
18 * similar to how packet-rpc.c/packet-nfs.c implements it
20 * SPDX-License-Identifier: GPL-2.0-or-later
23 #include "config.h"
26 #include <epan/packet.h>
27 #include <epan/exceptions.h>
28 #include <epan/prefs.h>
29 #include <epan/strutil.h>
30 #include <epan/expert.h>
31 #include <epan/charsets.h>
32 #include <wsutil/ws_roundup.h>
33 #include "packet-tcp.h"
35 #define TCP_PORT_PVFS2 3334 /* Not IANA registered */
37 #define PVFS2_FH_LENGTH 8
39 /* Header incl. magic number, mode, tag, size */
40 #define BMI_HEADER_SIZE 24
42 /* desegmentation of PVFS over TCP */
43 static bool pvfs_desegment = true;
45 /* Forward declaration we need below */
46 void proto_register_pvfs(void);
47 void proto_reg_handoff_pvfs(void);
49 static dissector_handle_t pvfs_handle;
51 /* Initialize the protocol and registered fields */
52 static int proto_pvfs;
53 static int hf_pvfs_magic_nr;
54 static int hf_pvfs_uid;
55 static int hf_pvfs_gid;
56 static int hf_pvfs_mode;
57 static int hf_pvfs_tag;
58 static int hf_pvfs_size;
59 static int hf_pvfs_release_number;
60 static int hf_pvfs_encoding;
61 static int hf_pvfs_server_op;
62 /* static int hf_pvfs_handle; */
63 static int hf_pvfs_fs_id;
64 static int hf_pvfs_attrmask;
65 static int hf_pvfs_attr;
66 static int hf_pvfs_ds_type;
67 static int hf_pvfs_error;
68 static int hf_pvfs_atime;
69 static int hf_pvfs_atime_sec;
70 static int hf_pvfs_atime_nsec;
71 static int hf_pvfs_mtime;
72 static int hf_pvfs_mtime_sec;
73 static int hf_pvfs_mtime_nsec;
74 static int hf_pvfs_ctime;
75 static int hf_pvfs_ctime_sec;
76 static int hf_pvfs_ctime_nsec;
77 static int hf_pvfs_parent_atime;
78 static int hf_pvfs_parent_atime_sec;
79 static int hf_pvfs_parent_atime_nsec;
80 static int hf_pvfs_parent_mtime;
81 static int hf_pvfs_parent_mtime_sec;
82 static int hf_pvfs_parent_mtime_nsec;
83 static int hf_pvfs_parent_ctime;
84 static int hf_pvfs_parent_ctime_sec;
85 static int hf_pvfs_parent_ctime_nsec;
86 static int hf_pvfs_distribution;
87 static int hf_pvfs_dfile_count;
88 static int hf_pvfs_dirent_count;
89 static int hf_pvfs_directory_version;
90 static int hf_pvfs_path;
91 static int hf_pvfs_total_completed;
92 static int hf_pvfs_io_dist;
93 static int hf_pvfs_aggregate_size;
94 static int hf_pvfs_io_type;
95 static int hf_pvfs_flowproto_type;
96 static int hf_pvfs_server_param;
97 static int hf_pvfs_prev_value;
98 /* static int hf_pvfs_ram_free_bytes; */
99 static int hf_pvfs_bytes_available;
100 static int hf_pvfs_bytes_total;
101 static int hf_pvfs_ram_bytes_total;
102 static int hf_pvfs_ram_bytes_free;
103 static int hf_pvfs_load_average_1s;
104 static int hf_pvfs_load_average_5s;
105 static int hf_pvfs_load_average_15s;
106 static int hf_pvfs_uptime_seconds;
107 static int hf_pvfs_handles_available;
108 static int hf_pvfs_handles_total;
109 static int hf_pvfs_unused;
110 static int hf_pvfs_context_id;
111 static int hf_pvfs_offset;
112 static int hf_pvfs_stride;
113 static int hf_pvfs_lb;
114 static int hf_pvfs_ub;
115 static int hf_pvfs_end_time_ms;
116 static int hf_pvfs_cur_time_ms;
117 static int hf_pvfs_start_time_ms;
118 static int hf_pvfs_bytes_written;
119 static int hf_pvfs_bytes_read;
120 static int hf_pvfs_metadata_write;
121 static int hf_pvfs_metadata_read;
122 static int hf_pvfs_b_size;
123 static int hf_pvfs_k_size;
124 static int hf_pvfs_id_gen_t;
125 static int hf_pvfs_attribute_key;
126 static int hf_pvfs_attribute_value;
127 static int hf_pvfs_strip_size;
128 static int hf_pvfs_ereg;
129 static int hf_pvfs_sreg;
130 static int hf_pvfs_num_eregs;
131 static int hf_pvfs_num_blocks;
132 static int hf_pvfs_num_contig_chunks;
133 static int hf_pvfs_server_nr;
134 static int hf_pvfs_server_count;
135 static int hf_pvfs_fh_length;
136 static int hf_pvfs_fh_hash;
137 static int hf_pvfs_permissions;
138 static int hf_pvfs_server_mode;
139 static int hf_pvfs_depth;
140 static int hf_pvfs_num_nested_req;
141 static int hf_pvfs_committed;
142 static int hf_pvfs_refcount;
143 static int hf_pvfs_numreq;
144 static int hf_pvfs_truncate_request_flags;
145 static int hf_pvfs_ds_position;
146 static int hf_pvfs_dirent_limit;
147 static int hf_pvfs_flush_request_flags;
148 static int hf_pvfs_next_id;
149 static int hf_pvfs_mgmt_perf_mon_request_count;
150 static int hf_pvfs_mgmt_perf_mon_request_event_count;
151 static int hf_pvfs_lookup_path_response_handle_count;
152 static int hf_pvfs_getconfig_response_total_bytes;
153 static int hf_pvfs_getconfig_response_lines;
154 static int hf_pvfs_getconfig_response_config_bytes;
155 static int hf_pvfs_mgmt_perf_mon_response_suggested_next_id;
156 static int hf_pvfs_mgmt_perf_stat_valid_flag;
157 static int hf_pvfs_mgmt_perf_stat_id;
158 static int hf_pvfs_mgmt_perf_mon_response_perf_array_count;
159 static int hf_pvfs_mgmt_iterate_handles_response_ds_position;
160 static int hf_pvfs_mgmt_iterate_handles_response_handle_count;
161 static int hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count;
162 static int hf_pvfs_mgmt_event_mon_response_api;
163 static int hf_pvfs_mgmt_event_mon_response_operation;
164 static int hf_pvfs_mgmt_event_mon_response_value;
165 static int hf_pvfs_mgmt_event_mon_response_flags;
166 static int hf_pvfs_mgmt_event_mon_response_tv_sec;
167 static int hf_pvfs_mgmt_event_mon_response_tv_usec;
168 static int hf_pvfs_fill_bytes;
169 static int hf_pvfs_target_path_len;
170 static int hf_pvfs_version2;
171 static int hf_pvfs_flow_data;
172 static int hf_pvfs_getconfig_response_entry;
173 static int hf_fhandle_data;
174 static int hf_pvfs_opaque_length;
176 /* Initialize the subtree pointers */
177 static int ett_pvfs;
178 static int ett_pvfs_hdr;
179 static int ett_pvfs_credentials;
180 static int ett_pvfs_server_config;
181 static int ett_pvfs_server_config_branch;
182 static int ett_pvfs_attrmask;
183 static int ett_pvfs_time;
184 static int ett_pvfs_extent_array_tree;
185 static int ett_pvfs_extent_item;
186 static int ett_pvfs_string;
187 static int ett_pvfs_attr_tree;
188 static int ett_pvfs_distribution;
189 static int ett_pvfs_mgmt_perf_stat;
190 static int ett_pvfs_mgmt_dspace_info;
191 static int ett_pvfs_attr;
192 static int ett_pvfs_fh;
194 static expert_field ei_pvfs_malformed;
196 #define BMI_MAGIC_NR 51903
198 static const value_string names_pvfs_mode[] =
200 #define TCP_MODE_IMMED 1
201 { TCP_MODE_IMMED, "TCP_MODE_IMMED" },
202 #define TCP_MODE_UNEXP 2
203 { TCP_MODE_UNEXP, "TCP_MODE_UNEXP" },
204 #define TCP_MODE_EAGER 4
205 { TCP_MODE_EAGER, "TCP_MODE_EAGER" },
206 #define TCP_MODE_REND 8
207 { TCP_MODE_REND, "TCP_MODE_REND" },
208 { 0, NULL }
211 static const value_string names_pvfs_encoding[] =
213 #define PVFS_ENCODING_DIRECT 1
214 { PVFS_ENCODING_DIRECT, "ENCODING_DIRECT" },
215 #define PVFS_ENCODING_LE_BFIELD 2
216 { PVFS_ENCODING_LE_BFIELD, "ENCODING_LE_BFIELD" },
217 #define PVFS_ENCODING_XDR 3
218 { PVFS_ENCODING_XDR, "ENCODING_XDR" },
219 { 0, NULL }
222 static const value_string names_pvfs_io_type[] =
224 #define PVFS_IO_READ 1
225 { PVFS_IO_READ, "PVFS_IO_READ" },
226 #define PVFS_IO_WRITE 2
227 { PVFS_IO_WRITE, "PVFS_IO_WRITE" },
228 { 0, NULL }
231 static const value_string names_pvfs_flowproto_type[] =
233 #define FLOWPROTO_DUMP_OFFSETS 1
234 { FLOWPROTO_DUMP_OFFSETS, "FLOWPROTO_DUMP_OFFSETS" },
235 #define FLOWPROTO_BMI_CACHE 2
236 { FLOWPROTO_BMI_CACHE, "FLOWPROTO_BMI_CACHE" },
237 #define FLOWPROTO_MULTIQUEUE 3
238 { FLOWPROTO_MULTIQUEUE, "FLOWPROTO_MULTIQUEUE" },
239 { 0, NULL }
242 static const value_string names_pvfs_server_param[] =
244 #define PVFS_SERV_PARAM_INVALID 0
245 { PVFS_SERV_PARAM_INVALID, "PVFS_SERV_PARAM_INVALID" },
246 #define PVFS_SERV_PARAM_GOSSIP_MASK 1
247 { PVFS_SERV_PARAM_GOSSIP_MASK, "PVFS_SERV_PARAM_GOSSIP_MASK" },
248 #define PVFS_SERV_PARAM_FSID_CHECK 2
249 { PVFS_SERV_PARAM_FSID_CHECK, "PVFS_SERV_PARAM_FSID_CHECK" },
250 #define PVFS_SERV_PARAM_ROOT_CHECK 3
251 { PVFS_SERV_PARAM_ROOT_CHECK, "PVFS_SERV_PARAM_ROOT_CHECK" },
252 #define PVFS_SERV_PARAM_MODE 4
253 { PVFS_SERV_PARAM_MODE, "PVFS_SERV_PARAM_MODE" },
254 #define PVFS_SERV_PARAM_EVENT_ON 5
255 { PVFS_SERV_PARAM_EVENT_ON, "PVFS_SERV_PARAM_EVENT_ON" },
256 #define PVFS_SERV_PARAM_EVENT_MASKS 6
257 { PVFS_SERV_PARAM_EVENT_MASKS, "PVFS_SERV_PARAM_EVENT_MASKS" },
258 { 0, NULL }
261 static const value_string names_pvfs_server_mode[] =
263 #define PVFS_SERVER_NORMAL_MODE 1
264 { PVFS_SERVER_NORMAL_MODE, "PVFS_SERVER_NORMAL_MODE" },
265 #define PVFS_SERVER_ADMIN_MODE 2
266 { PVFS_SERVER_ADMIN_MODE, "PVFS_SERVER_ADMIN_MODE" },
267 { 0, NULL }
270 /* Forward declaration */
271 static bool
272 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
273 bool dissect_other_as_continuation);
276 static int dissect_pvfs_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
278 dissect_pvfs_common(tvb, pinfo, tree, false);
279 return tvb_reported_length(tvb);
282 static unsigned get_pvfs_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
283 int offset, void *data _U_)
285 uint32_t plen;
288 * Get the length of the PVFS-over-TCP packet. Ignore top 32 bits
290 plen = tvb_get_letohl(tvb, offset + 16);
292 return plen+24;
295 static int
296 dissect_pvfs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
298 uint32_t magic_nr, mode;
299 uint64_t size;
301 /* verify that this is indeed PVFS and that it looks sane */
302 if(tvb_reported_length(tvb)<24){
303 /* too few bytes remaining to verify the header */
304 return 0;
307 /* validate the magic number */
308 magic_nr = tvb_get_letohl(tvb, 0);
309 if(magic_nr!=BMI_MAGIC_NR){
310 return 0;
313 /* Validate the TCP message mode (32-bit) */
314 mode = tvb_get_letohl(tvb, 4);
315 switch(mode){
316 case TCP_MODE_IMMED:
317 case TCP_MODE_UNEXP:
318 case TCP_MODE_EAGER:
319 case TCP_MODE_REND:
320 break;
321 default:
322 /* invalid mode, not a PVFS packet */
323 return 0;
326 /* validate the size : assume size must be >0 and less than 1000000 */
327 size=tvb_get_letohl(tvb, 20);
328 size<<=32;
329 size|=tvb_get_letohl(tvb, 16);
330 if((size>1000000)||(size==0)){
331 return 0;
334 tcp_dissect_pdus(tvb, pinfo, tree, pvfs_desegment, 24, get_pvfs_pdu_len,
335 dissect_pvfs_pdu, data);
337 return tvb_reported_length(tvb);
340 static bool
341 dissect_pvfs_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
343 return dissect_pvfs(tvb, pinfo, tree, data) > 0;
346 static const value_string names_pvfs_server_op[] =
348 #define PVFS_SERV_INVALID 0
349 { PVFS_SERV_INVALID, "PVFS_SERV_INVALID" },
350 #define PVFS_SERV_CREATE 1
351 { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
352 #define PVFS_SERV_REMOVE 2
353 { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
354 #define PVFS_SERV_IO 3
355 { PVFS_SERV_IO, "PVFS_SERV_IO" },
356 #define PVFS_SERV_GETATTR 4
357 { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
358 #define PVFS_SERV_SETATTR 5
359 { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
360 #define PVFS_SERV_LOOKUP_PATH 6
361 { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
362 #define PVFS_SERV_CRDIRENT 7
363 { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
364 #define PVFS_SERV_RMDIRENT 8
365 { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
366 #define PVFS_SERV_CHDIRENT 9
367 { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
368 #define PVFS_SERV_TRUNCATE 10
369 { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
370 #define PVFS_SERV_MKDIR 11
371 { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
372 #define PVFS_SERV_READDIR 12
373 { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
374 #define PVFS_SERV_GETCONFIG 13
375 { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
376 #define PVFS_SERV_WRITE_COMPLETION 14
377 { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
378 #define PVFS_SERV_FLUSH 15
379 { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
380 #define PVFS_SERV_MGMT_SETPARAM 16
381 { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
382 #define PVFS_SERV_MGMT_NOOP 17
383 { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
384 #define PVFS_SERV_STATFS 18
385 { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
386 #define PVFS_SERV_PERF_UPDATE 19 /* not a real protocol request */
387 { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
388 #define PVFS_SERV_MGMT_PERF_MON 20
389 { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
390 #define PVFS_SERV_MGMT_ITERATE_HANDLES 21
391 { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
392 #define PVFS_SERV_MGMT_DSPACE_INFO_LIST 22
393 { PVFS_SERV_MGMT_DSPACE_INFO_LIST, "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
394 #define PVFS_SERV_MGMT_EVENT_MON 23
395 { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
396 #define PVFS_SERV_MGMT_REMOVE_OBJECT 24
397 { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
398 #define PVFS_SERV_MGMT_REMOVE_DIRENT 25
399 { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
400 #define PVFS_SERV_MGMT_GET_DIRDATA_HANDLE 26
401 { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
402 #define PVFS_SERV_JOB_TIMER 27 /* not a real protocol request */
403 { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
404 #define PVFS_SERV_PROTO_ERROR 28
405 { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
406 #define PVFS_SERV_GETEATTR 29
407 { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
408 #define PVFS_SERV_SETEATTR 30
409 { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
410 #define PVFS_SERV_DELEATTR 31
411 { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
412 { 0, NULL }
415 /* special bits used to differentiate PVFS error codes from system
416 * * errno values
417 * */
418 #define PVFS_ERROR_BIT (1 << 30)
420 /* a shorthand to make the error code definitions more readable */
421 #define E(num) (num|PVFS_ERROR_BIT)
423 static const value_string names_pvfs_error[] = {
424 { 0, "Success" },
425 #define PVFS_EPERM E(1) /* Operation not permitted */
426 { PVFS_EPERM, "PVFS_EPERM" },
427 #define PVFS_ENOENT E(2) /* No such file or directory */
428 { PVFS_ENOENT, "PVFS_ENOENT" },
429 #define PVFS_EINTR E(3) /* Interrupted system call */
430 { PVFS_EINTR, "PVFS_EINTR" },
431 #define PVFS_EIO E(4) /* I/O error */
432 { PVFS_EIO, "PVFS_EIO" },
433 #define PVFS_ENXIO E(5) /* No such device or address */
434 { PVFS_ENXIO, "PVFS_ENXIO" },
435 #define PVFS_EBADF E(6) /* Bad file number */
436 { PVFS_EBADF, "PVFS_EBADF" },
437 #define PVFS_EAGAIN E(7) /* Try again */
438 { PVFS_EAGAIN, "PVFS_EAGAIN" },
439 #define PVFS_ENOMEM E(8) /* Out of memory */
440 { PVFS_ENOMEM, "PVFS_ENOMEM" },
441 #define PVFS_EFAULT E(9) /* Bad address */
442 { PVFS_EFAULT, "PVFS_EFAULT" },
443 #define PVFS_EBUSY E(10) /* Device or resource busy */
444 { PVFS_EBUSY, "PVFS_EBUSY" },
445 #define PVFS_EEXIST E(11) /* File exists */
446 { PVFS_EEXIST, "PVFS_EEXIST" },
447 #define PVFS_ENODEV E(12) /* No such device */
448 { PVFS_ENODEV, "PVFS_ENODEV" },
449 #define PVFS_ENOTDIR E(13) /* Not a directory */
450 { PVFS_ENOTDIR, "PVFS_ENOTDIR" },
451 #define PVFS_EISDIR E(14) /* Is a directory */
452 { PVFS_EISDIR, "PVFS_EISDIR" },
453 #define PVFS_EINVAL E(15) /* Invalid argument */
454 { PVFS_EINVAL, "PVFS_EINVAL" },
455 #define PVFS_EMFILE E(16) /* Too many open files */
456 { PVFS_EMFILE, "PVFS_EMFILE" },
457 #define PVFS_EFBIG E(17) /* File too large */
458 { PVFS_EFBIG, "PVFS_EFBIG" },
459 #define PVFS_ENOSPC E(18) /* No space left on device */
460 { PVFS_ENOSPC, "PVFS_ENOSPC" },
461 #define PVFS_EROFS E(19) /* Read-only file system */
462 { PVFS_EROFS, "PVFS_EROFS" },
463 #define PVFS_EMLINK E(20) /* Too many links */
464 { PVFS_EMLINK, "PVFS_EMLINK" },
465 #define PVFS_EPIPE E(21) /* Broken pipe */
466 { PVFS_EPIPE, "PVFS_EPIPE" },
467 #define PVFS_EDEADLK E(22) /* Resource deadlock would occur */
468 { PVFS_EDEADLK, "PVFS_EDEADLK" },
469 #define PVFS_ENAMETOOLONG E(23) /* File name too long */
470 { PVFS_ENAMETOOLONG, "PVFS_ENAMETOOLONG" },
471 #define PVFS_ENOLCK E(24) /* No record locks available */
472 { PVFS_ENOLCK, "PVFS_ENOLCK" },
473 #define PVFS_ENOSYS E(25) /* Function not implemented */
474 { PVFS_ENOSYS, "PVFS_ENOSYS" },
475 #define PVFS_ENOTEMPTY E(26) /* Directory not empty */
476 { PVFS_ENOTEMPTY, "PVFS_ENOTEMPTY" },
477 #define PVFS_ELOOP E(27) /* Too many symbolic links encountered */
478 { PVFS_ELOOP, "PVFS_ELOOP" },
479 #define PVFS_EWOULDBLOCK E(28) /* Operation would block */
480 { PVFS_EWOULDBLOCK, "PVFS_EWOULDBLOCK" },
481 #define PVFS_ENOMSG E(29) /* No message of desired type */
482 { PVFS_ENOMSG, "PVFS_ENOMSG" },
483 #define PVFS_EUNATCH E(30) /* Protocol driver not attached */
484 { PVFS_EUNATCH, "PVFS_EUNATCH" },
485 #define PVFS_EBADR E(31) /* Invalid request descriptor */
486 { PVFS_EBADR, "PVFS_EBADR" },
487 #define PVFS_EDEADLOCK E(32)
488 { PVFS_EDEADLOCK, "PVFS_EDEADLOCK" },
489 #define PVFS_ENODATA E(33) /* No data available */
490 { PVFS_ENODATA, "PVFS_ENODATA" },
491 #define PVFS_ETIME E(34) /* Timer expired */
492 { PVFS_ETIME, "PVFS_ETIME" },
493 #define PVFS_ENONET E(35) /* Machine is not on the network */
494 { PVFS_ENONET, "PVFS_ENONET" },
495 #define PVFS_EREMOTE E(36) /* Object is remote */
496 { PVFS_EREMOTE, "PVFS_EREMOTE" },
497 #define PVFS_ECOMM E(37) /* Communication error on send */
498 { PVFS_ECOMM, "PVFS_ECOMM" },
499 #define PVFS_EPROTO E(38) /* Protocol error */
500 { PVFS_EPROTO, "PVFS_EPROTO" },
501 #define PVFS_EBADMSG E(39) /* Not a data message */
502 { PVFS_EBADMSG, "PVFS_EBADMSG" },
503 #define PVFS_EOVERFLOW E(40) /* Value too large for defined data type */
504 { PVFS_EOVERFLOW, "PVFS_EOVERFLOW" },
505 #define PVFS_ERESTART E(41) /* Interrupted system call should be restarted */
506 { PVFS_ERESTART, "PVFS_ERESTART" },
507 #define PVFS_EMSGSIZE E(42) /* Message too long */
508 { PVFS_EMSGSIZE, "PVFS_EMSGSIZE" },
509 #define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */
510 { PVFS_EPROTOTYPE, "PVFS_EPROTOTYPE" },
511 #define PVFS_ENOPROTOOPT E(44) /* Protocol not available */
512 { PVFS_ENOPROTOOPT, "PVFS_ENOPROTOOPT" },
513 #define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */
514 { PVFS_EPROTONOSUPPORT, "PVFS_EPROTONOSUPPORT" },
515 #define PVFS_EOPNOTSUPP E(46) /* Operation not supported on transport endpoint */
516 { PVFS_EOPNOTSUPP, "PVFS_EOPNOTSUPP" },
517 #define PVFS_EADDRINUSE E(47) /* Address already in use */
518 { PVFS_EADDRINUSE, "PVFS_EADDRINUSE" },
519 #define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */
520 { PVFS_EADDRNOTAVAIL, "PVFS_EADDRNOTAVAIL" },
521 #define PVFS_ENETDOWN E(49) /* Network is down */
522 { PVFS_ENETDOWN, "PVFS_ENETDOWN" },
523 #define PVFS_ENETUNREACH E(50) /* Network is unreachable */
524 { PVFS_ENETUNREACH, "PVFS_ENETUNREACH" },
525 #define PVFS_ENETRESET E(51) /* Network dropped connection because of reset */
526 { PVFS_ENETRESET, "PVFS_ENETRESET" },
527 #define PVFS_ENOBUFS E(52) /* No buffer space available */
528 { PVFS_ENOBUFS, "PVFS_ENOBUFS" },
529 #define PVFS_ETIMEDOUT E(53) /* Connection timed out */
530 { PVFS_ETIMEDOUT, "PVFS_ETIMEDOUT" },
531 #define PVFS_ECONNREFUSED E(54) /* Connection refused */
532 { PVFS_ECONNREFUSED, "PVFS_ECONNREFUSED" },
533 #define PVFS_EHOSTDOWN E(55) /* Host is down */
534 { PVFS_EHOSTDOWN, "PVFS_EHOSTDOWN" },
535 #define PVFS_EHOSTUNREACH E(56) /* No route to host */
536 { PVFS_EHOSTUNREACH, "PVFS_EHOSTUNREACH" },
537 #define PVFS_EALREADY E(57) /* Operation already in progress */
538 { PVFS_EALREADY, "PVFS_EALREADY" },
539 #define PVFS_EACCES E(58) /* Operation already in progress */
540 { PVFS_EACCES, "PVFS_EACCES" },
541 { 0, NULL }
544 static int
545 dissect_pvfs2_error(tvbuff_t *tvb, proto_tree *tree, int offset,
546 packet_info *pinfo)
548 int32_t err;
549 const char *errmsg = NULL;
551 err = tvb_get_letohl(tvb, offset);
552 proto_tree_add_uint(tree, hf_pvfs_error, tvb, offset, 4, -err);
553 offset += 4;
555 if (err != 0)
557 errmsg = val_to_str(-err, names_pvfs_error, "Unknown error: %u");
558 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", errmsg);
561 return offset;
564 static int
565 dissect_pvfs_credentials(tvbuff_t *tvb, proto_tree *parent_tree,
566 int offset)
568 proto_tree *hcred_tree;
569 uint32_t uid, gid;
571 uid = tvb_get_letohl(tvb, offset);
572 gid = tvb_get_letohl(tvb, offset + 4);
574 hcred_tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, 8,
575 ett_pvfs_credentials, NULL, "Credentials (UID: %d, GID: %d)", uid, gid);
577 /* UID */
578 proto_tree_add_item(hcred_tree, hf_pvfs_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
579 offset += 4;
581 /* GID */
582 proto_tree_add_item(hcred_tree, hf_pvfs_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
583 offset += 4;
585 return offset;
588 static const value_string names_pvfs_attr[] =
590 #define PVFS_ATTR_COMMON_UID (1 << 0)
591 #define PVFS_ATTR_BIT_COMMON_UID 0
592 { PVFS_ATTR_BIT_COMMON_UID, "PVFS_ATTR_COMMON_UID" },
594 #define PVFS_ATTR_COMMON_GID (1 << 1)
595 #define PVFS_ATTR_BIT_COMMON_GID 1
596 { PVFS_ATTR_BIT_COMMON_GID, "PVFS_ATTR_COMMON_GID" },
598 #define PVFS_ATTR_COMMON_PERM (1 << 2)
599 #define PVFS_ATTR_BIT_COMMON_PERM 2
600 { PVFS_ATTR_BIT_COMMON_PERM, "PVFS_ATTR_COMMON_PERM" },
602 #define PVFS_ATTR_COMMON_ATIME (1 << 3)
603 #define PVFS_ATTR_BIT_COMMON_ATIME 3
604 { PVFS_ATTR_BIT_COMMON_ATIME, "PVFS_ATTR_COMMON_ATIME" },
606 #define PVFS_ATTR_COMMON_CTIME (1 << 4)
607 #define PVFS_ATTR_BIT_COMMON_CTIME 4
608 { PVFS_ATTR_BIT_COMMON_CTIME, "PVFS_ATTR_COMMON_CTIME" },
610 #define PVFS_ATTR_COMMON_MTIME (1 << 5)
611 #define PVFS_ATTR_BIT_COMMON_MTIME 5
612 { PVFS_ATTR_BIT_COMMON_MTIME, "PVFS_ATTR_COMMON_MTIME" },
614 #define PVFS_ATTR_COMMON_TYPE (1 << 6)
615 #define PVFS_ATTR_BIT_COMMON_TYPE 6
616 { PVFS_ATTR_BIT_COMMON_TYPE, "PVFS_ATTR_COMMON_TYPE" },
618 #if 0
619 #define PVFS_ATTR_COMMON_ALL \
620 (PVFS_ATTR_COMMON_UID | PVFS_ATTR_COMMON_GID | \
621 PVFS_ATTR_COMMON_PERM | PVFS_ATTR_COMMON_ATIME | \
622 PVFS_ATTR_COMMON_CTIME | PVFS_ATTR_COMMON_MTIME | \
623 PVFS_ATTR_COMMON_TYPE)
624 #endif
626 /* internal attribute masks for metadata objects */
627 #define PVFS_ATTR_META_DIST (1 << 10)
628 #define PVFS_ATTR_BIT_META_DIST 10
629 { PVFS_ATTR_BIT_META_DIST, "PVFS_ATTR_META_DIST" },
631 #define PVFS_ATTR_META_DFILES (1 << 11)
632 #define PVFS_ATTR_BIT_META_DFILES 11
633 { PVFS_ATTR_BIT_META_DFILES, "PVFS_ATTR_META_DFILES" },
635 #if 0
636 #define PVFS_ATTR_META_ALL \
637 (PVFS_ATTR_META_DIST | PVFS_ATTR_META_DFILES)
638 #endif
640 /* internal attribute masks for datafile objects */
641 #define PVFS_ATTR_DATA_SIZE (1 << 15)
642 #define PVFS_ATTR_BIT_DATA_SIZE 15
643 { PVFS_ATTR_BIT_DATA_SIZE, "PVFS_ATTR_DATA_SIZE" },
645 #if 0
646 #define PVFS_ATTR_DATA_ALL PVFS_ATTR_DATA_SIZE
647 #endif
649 /* internal attribute masks for symlink objects */
650 #define PVFS_ATTR_SYMLNK_TARGET (1 << 18)
651 #define PVFS_ATTR_BIT_SYMLINK_TARGET 18
652 { PVFS_ATTR_BIT_SYMLINK_TARGET, "PVFS_ATTR_SYMLNK_TARGET" },
654 #if 0
655 #define PVFS_ATTR_SYMLNK_ALL PVFS_ATTR_SYMLNK_TARGET
656 #endif
658 /* internal attribute masks for directory objects */
659 #define PVFS_ATTR_DIR_DIRENT_COUNT (1 << 19)
660 #define PVFS_ATTR_BIT_DIR_DIRENT_COUNT 19
661 { PVFS_ATTR_BIT_DIR_DIRENT_COUNT, "PVFS_ATTR_DIR_DIRENT_COUNT" },
663 #if 0
664 #define PVFS_ATTR_DIR_ALL PVFS_ATTR_DIR_DIRENT_COUNT
665 #endif
667 /* attribute masks used by system interface callers */
668 #define PVFS_ATTR_SYS_SIZE (1 << 20)
669 #define PVFS_ATTR_BIT_SYS_SIZE 20
670 { PVFS_ATTR_BIT_SYS_SIZE, "PVFS_ATTR_SYS_SIZE" },
672 #define PVFS_ATTR_SYS_LNK_TARGET (1 << 24)
673 #define PVFS_ATTR_BIT_SYS_LNK_TARGET 24
674 { PVFS_ATTR_BIT_SYS_LNK_TARGET, "PVFS_ATTR_SYS_LNK_TARGET" },
676 #define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25)
677 #define PVFS_ATTR_BIT_SYS_DFILE_COUNT 25
678 { PVFS_ATTR_BIT_SYS_DFILE_COUNT, "PVFS_ATTR_SYS_DFILE_COUNT" },
680 #define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26)
681 #define PVFS_ATTR_BIT_SYS_DIRENT_COUNT 26
682 { PVFS_ATTR_BIT_SYS_DIRENT_COUNT, "PVFS_ATTR_SYS_DIRENT_COUNT" },
684 #if 0
685 #define PVFS_ATTR_SYS_UID PVFS_ATTR_COMMON_UID
686 #define PVFS_ATTR_SYS_GID PVFS_ATTR_COMMON_GID
687 #define PVFS_ATTR_SYS_PERM PVFS_ATTR_COMMON_PERM
688 #define PVFS_ATTR_SYS_ATIME PVFS_ATTR_COMMON_ATIME
689 #define PVFS_ATTR_SYS_CTIME PVFS_ATTR_COMMON_CTIME
690 #define PVFS_ATTR_SYS_MTIME PVFS_ATTR_COMMON_MTIME
691 #define PVFS_ATTR_SYS_TYPE PVFS_ATTR_COMMON_TYPE
692 #endif
693 { 0, NULL }
696 #if 0
697 #define PVFS_ATTR_SYS_ALL \
698 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_SIZE | \
699 PVFS_ATTR_SYS_LNK_TARGET | PVFS_ATTR_SYS_DFILE_COUNT | \
700 PVFS_ATTR_SYS_DIRENT_COUNT)
702 #define PVFS_ATTR_SYS_ALL_NOSIZE \
703 (PVFS_ATTR_COMMON_ALL | PVFS_ATTR_SYS_LNK_TARGET | \
704 PVFS_ATTR_SYS_DFILE_COUNT | PVFS_ATTR_SYS_DIRENT_COUNT)
706 #define PVFS_ATTR_SYS_ALL_SETABLE \
707 (PVFS_ATTR_COMMON_ALL-PVFS_ATTR_COMMON_TYPE)
708 #endif
711 static int
712 dissect_pvfs2_attrmask(tvbuff_t *tvb, proto_tree *tree, int offset,
713 uint32_t *pattrmask)
715 uint32_t attrmask, i;
716 proto_item *attritem;
717 proto_tree *attrtree;
719 attrmask = tvb_get_letohl(tvb, offset);
721 attritem = proto_tree_add_uint(tree, hf_pvfs_attrmask, tvb, offset, 4, attrmask);
722 attrtree = proto_item_add_subtree(attritem, ett_pvfs_attrmask);
724 for (i = 0; i < 32; i++)
726 if (attrmask & (1u << i))
727 proto_tree_add_uint(attrtree, hf_pvfs_attr, tvb, offset, 4, i);
730 offset += 4;
732 if (pattrmask)
733 *pattrmask = attrmask;
735 return offset;
738 static const value_string names_pvfs_ds_type[] = {
739 #define PVFS_TYPE_NONE 0
740 { PVFS_TYPE_NONE, "PVFS_TYPE_NONE" },
741 #define PVFS_TYPE_METAFILE (1 << 0)
742 { PVFS_TYPE_METAFILE, "PVFS_TYPE_METAFILE" },
743 #define PVFS_TYPE_DATAFILE (1 << 1)
744 { PVFS_TYPE_DATAFILE, "PVFS_TYPE_DATAFILE" },
745 #define PVFS_TYPE_DIRECTORY (1 << 2)
746 { PVFS_TYPE_DIRECTORY, "PVFS_TYPE_DIRECTORY" },
747 #define PVFS_TYPE_SYMLINK (1 << 3)
748 { PVFS_TYPE_SYMLINK, "PVFS_TYPE_SYMLINK" },
749 #define PVFS_TYPE_DIRDATA (1 << 4)
750 { PVFS_TYPE_DIRDATA, "PVFS_TYPE_DIRDATA" },
751 { 0, NULL }
754 static int
755 dissect_pvfs2_ds_type(tvbuff_t *tvb, proto_tree *tree, int offset,
756 int *pds_type)
758 uint32_t ds_type;
760 ds_type = tvb_get_letohl(tvb, offset);
762 proto_tree_add_uint(tree, hf_pvfs_ds_type, tvb, offset, 4, ds_type);
764 offset += 4;
766 if (pds_type)
767 *pds_type = ds_type;
769 return offset;
772 static int
773 dissect_pvfs_opaque_data(tvbuff_t *tvb, int offset,
774 proto_tree *tree,
775 packet_info *pinfo,
776 int hfindex,
777 bool fixed_length, uint32_t length,
778 bool string_data, const char **string_buffer_ret)
780 int data_offset;
781 proto_item *string_item = NULL;
782 proto_tree *string_tree = NULL;
784 uint32_t string_length;
785 uint32_t string_length_full;
786 uint32_t string_length_packet;
787 uint32_t string_length_captured;
788 uint32_t string_length_copy;
790 int fill_truncated;
791 uint32_t fill_length;
792 uint32_t fill_length_packet;
793 uint32_t fill_length_captured;
794 uint32_t fill_length_copy;
796 int exception = 0;
798 char *string_buffer = NULL;
799 const char *string_buffer_print = NULL;
801 if (fixed_length) {
802 string_length = length;
803 data_offset = offset;
804 } else {
805 string_length = tvb_get_letohl(tvb,offset+0);
806 data_offset = offset + 4;
809 * Variable-length strings include NULL terminator on-the-wire but
810 * NULL terminator is not included in string length.
813 if (string_data)
814 string_length += 1;
817 string_length_captured = tvb_captured_length_remaining(tvb, data_offset);
818 string_length_packet = tvb_reported_length_remaining(tvb, data_offset);
821 * Strangeness... the protocol basically says that the length plus
822 * the string must be padded out to an 8-byte boundary.
825 if (!string_data)
826 string_length_full = WS_ROUNDUP_4(string_length);
827 else
828 string_length_full = WS_ROUNDUP_8(4 + string_length);
830 if (string_length_captured < string_length) {
831 /* truncated string */
832 string_length_copy = string_length_captured;
833 fill_truncated = 2;
834 fill_length = 0;
835 fill_length_copy = 0;
837 if (string_length_packet < string_length)
838 exception = ReportedBoundsError;
839 else
840 exception = BoundsError;
842 else {
843 /* full string data */
844 string_length_copy = string_length;
846 if (!string_data)
847 fill_length = string_length_full - string_length;
848 else
849 fill_length = string_length_full - string_length - 4;
851 fill_length_captured = tvb_captured_length_remaining(tvb,
852 data_offset + string_length);
853 fill_length_packet = tvb_reported_length_remaining(tvb,
854 data_offset + string_length);
856 if (fill_length_captured < fill_length) {
857 /* truncated fill bytes */
858 fill_length_copy = fill_length_packet;
859 fill_truncated = 1;
860 if (fill_length_packet < fill_length)
861 exception = ReportedBoundsError;
862 else
863 exception = BoundsError;
865 else {
866 /* full fill bytes */
867 fill_length_copy = fill_length;
868 fill_truncated = 0;
872 if (string_data) {
873 string_buffer = tvb_get_string_enc(pinfo->pool, tvb, data_offset, string_length_copy, ENC_ASCII);
874 } else {
875 string_buffer = (char *) tvb_memcpy(tvb,
876 wmem_alloc(pinfo->pool, string_length_copy+1), data_offset, string_length_copy);
877 string_buffer[string_length_copy] = '\0';
880 /* calculate a nice printable string */
881 if (string_length) {
882 if (string_length != strlen(string_buffer)) {
883 if (string_data) {
884 char *formatted;
885 size_t string_buffer_size = 0;
886 char *string_buffer_temp;
888 formatted = format_text(pinfo->pool, (uint8_t *)string_buffer,
889 (int)strlen(string_buffer));
891 string_buffer_size = strlen(formatted) + 12 + 1;
893 /* alloc maximum data area */
894 string_buffer_temp = (char*) wmem_alloc(pinfo->pool, string_buffer_size);
895 /* copy over the data */
896 snprintf(string_buffer_temp, string_buffer_size,
897 "%s<TRUNCATED>", formatted);
898 /* append <TRUNCATED> */
899 /* This way, we get the TRUNCATED even
900 in the case of totally wrong packets,
901 where \0 are inside the string.
902 TRUNCATED will appear at the
903 first \0 or at the end (where we
904 put the securing \0).
906 string_buffer_print = string_buffer_temp;
907 } else {
908 string_buffer_print="<DATA><TRUNCATED>";
910 } else {
911 if (string_data) {
912 string_buffer_print = format_text(pinfo->pool, (uint8_t *) string_buffer,
913 (int)strlen(string_buffer));
914 } else {
915 string_buffer_print="<DATA>";
918 } else {
919 string_buffer_print="<EMPTY>";
922 string_item = proto_tree_add_string(tree, hfindex, tvb, offset+0, -1,
923 string_buffer_print);
925 string_tree = proto_item_add_subtree(string_item,
926 ett_pvfs_string);
928 if (!fixed_length) {
929 proto_tree_add_uint_format_value(string_tree, hf_pvfs_opaque_length, tvb, offset, 4,
930 string_length - 1, "%u (excl. NULL terminator)", string_length - 1);
931 offset += 4;
934 if (string_data) {
935 proto_tree_add_string_format(string_tree,
936 hfindex, tvb, offset, string_length_copy,
937 string_buffer,
938 "contents: %s", string_buffer_print);
939 } else {
940 proto_tree_add_bytes_format(string_tree,
941 hfindex, tvb, offset, string_length_copy,
942 (uint8_t *) string_buffer,
943 "contents: %s", string_buffer_print);
946 offset += string_length_copy;
948 if (fill_length) {
949 if (string_tree) {
950 if (fill_truncated) {
951 proto_tree_add_bytes_format_value(string_tree, hf_pvfs_fill_bytes, tvb,
952 offset, fill_length_copy, NULL,
953 "opaque data <TRUNCATED>");
955 else {
956 proto_tree_add_bytes_format_value(string_tree, hf_pvfs_fill_bytes, tvb,
957 offset, fill_length_copy, NULL,
958 "opaque data");
961 offset += fill_length_copy;
964 if (string_item)
965 proto_item_set_end(string_item, tvb, offset);
967 if (string_buffer_ret != NULL)
968 *string_buffer_ret = string_buffer_print;
971 * If the data was truncated, throw the appropriate exception,
972 * so that dissection stops and the frame is properly marked.
974 if (exception != 0)
975 THROW(exception);
977 return offset;
980 static int
981 dissect_pvfs_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
982 int offset, packet_info *pinfo, const char **string_buffer_ret)
984 return dissect_pvfs_opaque_data(tvb, offset, tree, pinfo, hfindex,
985 false, 0, true, string_buffer_ret);
988 static void
989 dissect_fhandle_data_unknown(tvbuff_t *tvb, int offset, proto_tree *tree)
991 unsigned bytes_left = PVFS2_FH_LENGTH;
993 proto_tree_add_item(tree, hf_fhandle_data, tvb, offset, bytes_left, ENC_NA);
996 static void
997 dissect_fhandle_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
998 proto_tree *tree, uint32_t *hash)
1000 uint32_t fhhash;
1001 uint32_t i;
1003 /* Not all bytes there. Any attempt to deduce the type would be
1004 senseless. */
1005 if (!tvb_bytes_exist(tvb, offset, PVFS2_FH_LENGTH))
1006 goto type_ready;
1008 /* create a semiunique hash value for the filehandle */
1009 for(fhhash=0,i=0;i<(PVFS2_FH_LENGTH-3);i+=4){
1010 uint32_t val;
1011 val = tvb_get_ntohl(tvb, offset+i);
1012 fhhash ^= val;
1013 fhhash += val;
1016 proto_tree_add_uint(tree, hf_pvfs_fh_hash, tvb, offset, PVFS2_FH_LENGTH,
1017 fhhash);
1019 if (hash)
1020 *hash = fhhash;
1022 /* TODO: add file name snooping code here */
1024 type_ready:
1025 dissect_fhandle_data_unknown(tvb, offset, tree);
1028 static int
1029 dissect_pvfs_fh(tvbuff_t *tvb, int offset, packet_info *pinfo,
1030 proto_tree *tree, const char *name, uint32_t *hash)
1032 proto_tree* ftree;
1034 ftree = proto_tree_add_subtree(tree, tvb, offset, PVFS2_FH_LENGTH,
1035 ett_pvfs_fh, NULL, name);
1037 /* TODO: add fh to file name snooping code here */
1039 proto_tree_add_uint(ftree, hf_pvfs_fh_length, tvb, offset, 0,
1040 PVFS2_FH_LENGTH);
1042 dissect_fhandle_data(tvb, offset, pinfo, ftree, hash);
1044 offset += PVFS2_FH_LENGTH;
1046 return offset;
1049 static int
1050 dissect_pvfs_handle_extent(tvbuff_t *tvb, proto_tree *tree, int offset,
1051 packet_info *pinfo, uint32_t nCount)
1053 proto_tree *extent_tree;
1055 extent_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
1056 ett_pvfs_extent_item, NULL, "Item %d", nCount);
1058 /* first handle */
1059 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "first handle",
1060 NULL);
1062 /* last handle */
1063 offset = dissect_pvfs_fh(tvb, offset, pinfo, extent_tree, "last handle",
1064 NULL);
1066 return offset;
1069 static int
1070 dissect_pvfs_handle_extent_array(tvbuff_t *tvb, proto_tree *tree, int offset,
1071 packet_info *pinfo)
1073 uint32_t extent_count;
1074 uint32_t nCount;
1075 proto_tree *extent_array_tree;
1077 /* extent count */
1078 extent_count = tvb_get_letohl(tvb, offset);
1080 extent_array_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4,
1081 ett_pvfs_extent_array_tree, NULL, "Handle Extent Array (count = %d)", extent_count);
1083 offset += 4;
1085 if (extent_count > 0)
1087 /* Add extent array items */
1088 for (nCount = 0; nCount < extent_count; nCount++)
1089 offset = dissect_pvfs_handle_extent(tvb, extent_array_tree, offset,
1090 pinfo, nCount);
1093 return offset;
1096 static int
1097 dissect_pvfs_time(tvbuff_t *tvb, proto_tree *tree, int offset,
1098 int hf_time, int hf_time_sec, int hf_time_nsec)
1100 uint32_t seconds;
1101 uint32_t nseconds;
1102 nstime_t ts;
1103 proto_item *time_item;
1104 proto_tree *time_tree;
1106 ts.secs = seconds = tvb_get_letohl(tvb, offset);
1107 ts.nsecs = nseconds = tvb_get_letohl(tvb, offset + 4);
1109 time_item = proto_tree_add_time(tree, hf_time, tvb, offset, 8, &ts);
1110 time_tree = proto_item_add_subtree(time_item, ett_pvfs_time);
1112 proto_tree_add_uint(time_tree, hf_time_sec, tvb, offset, 4, seconds);
1113 proto_tree_add_uint(time_tree, hf_time_nsec, tvb, offset + 4, 4, nseconds);
1115 offset += 8;
1116 return offset;
1119 static
1120 int dissect_pvfs_uint64(tvbuff_t *tvb, proto_tree *tree, int offset,
1121 int hfindex, uint64_t *pvalue)
1123 uint64_t val;
1125 val = tvb_get_letoh64(tvb, offset);
1126 proto_tree_add_uint64(tree, hfindex, tvb, offset, 8, val);
1128 if (pvalue)
1129 *pvalue = val;
1131 return offset + 8;
1134 /* Taken from pvfs2-dist-simple-stripe.h */
1135 #define PVFS_DIST_SIMPLE_STRIPE_NAME "simple_stripe"
1136 #define PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE 14
1138 static int
1139 dissect_pvfs_distribution(tvbuff_t *tvb, proto_tree *tree, int offset,
1140 packet_info *pinfo)
1142 proto_item *dist_item;
1143 proto_tree *dist_tree;
1144 uint32_t distlen;
1145 char *tmpstr;
1146 uint8_t issimplestripe = 0;
1147 uint32_t total_len;
1149 /* Get distribution name length */
1150 distlen = tvb_get_letohl(tvb, offset);
1152 /* Get distribution name */
1153 tmpstr = (char *) tvb_get_string_enc(pinfo->pool, tvb, offset + 4, distlen, ENC_ASCII);
1155 /* 'distlen' does not include the NULL terminator */
1156 total_len = WS_ROUNDUP_8(4 + distlen + 1);
1158 if (((distlen + 1) == PVFS_DIST_SIMPLE_STRIPE_NAME_SIZE) &&
1159 (g_ascii_strncasecmp(tmpstr, PVFS_DIST_SIMPLE_STRIPE_NAME,
1160 distlen) == 0))
1162 /* Parameter for 'simple_stripe' is 8 bytes */
1163 total_len += 8;
1165 issimplestripe = 1;
1168 dist_item = proto_tree_add_string(tree, hf_pvfs_distribution,
1169 tvb, offset, total_len + 8, tmpstr);
1170 dist_tree = proto_item_add_subtree(dist_item, ett_pvfs_distribution);
1172 /* io_dist */
1173 offset = dissect_pvfs_string(tvb, dist_tree, hf_pvfs_io_dist, offset,
1174 pinfo, NULL);
1176 /* TODO: only one distribution type is currently supported */
1177 if (issimplestripe)
1178 offset = dissect_pvfs_uint64(tvb, dist_tree, offset,
1179 hf_pvfs_strip_size, NULL);
1181 offset += 8;
1183 return offset;
1186 static int
1187 dissect_pvfs_meta_attr_dfiles(tvbuff_t *tvb, proto_tree *tree, int offset,
1188 packet_info *pinfo)
1190 uint32_t dfile_count, i;
1192 /* dfile_count */
1193 dfile_count = tvb_get_letohl(tvb, offset);
1194 proto_tree_add_uint(tree, hf_pvfs_dfile_count, tvb, offset, 4, dfile_count);
1196 offset += 4;
1198 for (i = 0; i < dfile_count; i++)
1199 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1201 return offset;
1204 static int
1205 dissect_pvfs_object_attr(tvbuff_t *tvb, proto_tree *tree, int offset,
1206 packet_info *pinfo)
1208 int32_t ds_type = 0;
1209 uint32_t attrmask = 0;
1210 proto_tree *attr_tree;
1212 attr_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_pvfs_attr_tree, NULL, "Attributes");
1214 /* UID */
1215 proto_tree_add_item(attr_tree, hf_pvfs_uid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1216 offset += 4;
1218 /* GID */
1219 proto_tree_add_item(attr_tree, hf_pvfs_gid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1220 offset += 4;
1222 /* Permissions */
1223 proto_tree_add_item(attr_tree, hf_pvfs_permissions, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1224 offset += 4;
1226 offset += 4;
1228 /* atime */
1229 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_atime,
1230 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1232 /* mtime */
1233 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_mtime,
1234 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1236 /* ctime */
1237 offset = dissect_pvfs_time(tvb, attr_tree, offset, hf_pvfs_ctime,
1238 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1240 /* attrmask */
1241 offset = dissect_pvfs2_attrmask(tvb, attr_tree, offset, &attrmask);
1243 /* objtype */
1244 offset = dissect_pvfs2_ds_type(tvb, attr_tree, offset, &ds_type);
1246 if (attrmask & PVFS_ATTR_META_DIST)
1248 offset = dissect_pvfs_distribution(tvb, attr_tree, offset, pinfo);
1250 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1252 else
1254 if (attrmask & PVFS_ATTR_META_DFILES)
1256 offset = dissect_pvfs_meta_attr_dfiles(tvb, attr_tree, offset, pinfo);
1258 else
1260 if (attrmask & PVFS_ATTR_DATA_SIZE)
1262 offset = dissect_pvfs_uint64(tvb, attr_tree, offset, hf_pvfs_size,
1263 NULL);
1265 else
1267 if (attrmask & PVFS_ATTR_SYMLNK_TARGET)
1269 /* target_path_len */
1270 proto_tree_add_item(attr_tree, hf_pvfs_target_path_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1271 offset += 4;
1273 offset += 4;
1275 /* target_path */
1276 offset = dissect_pvfs_string(tvb, attr_tree, hf_pvfs_path,
1277 offset, pinfo, NULL);
1279 else
1281 if (attrmask & PVFS_ATTR_DIR_DIRENT_COUNT)
1283 offset = dissect_pvfs_uint64(tvb, attr_tree, offset,
1284 hf_pvfs_size, NULL);
1291 return offset;
1294 static int
1295 dissect_pvfs_io_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1297 proto_tree_add_item(tree, hf_pvfs_io_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1298 offset += 4;
1300 return offset;
1303 static int
1304 dissect_pvfs_flowproto_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1306 proto_tree_add_item(tree, hf_pvfs_flowproto_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1307 offset += 4;
1309 return offset;
1312 static int
1313 dissect_pvfs_server_param(tvbuff_t *tvb, proto_tree *tree, int offset,
1314 packet_info *pinfo)
1316 uint32_t server_param;
1317 proto_item* ti;
1319 /* server_param */
1320 server_param = tvb_get_letohl(tvb, offset);
1321 proto_tree_add_uint(tree, hf_pvfs_server_param, tvb, offset, 4,
1322 server_param);
1323 offset += 4;
1325 switch (server_param)
1327 case PVFS_SERV_PARAM_MODE:
1328 ti = proto_tree_add_item(tree, hf_pvfs_server_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1329 proto_item_set_len(ti, 8);
1330 break;
1332 case PVFS_SERV_PARAM_FSID_CHECK:
1333 proto_tree_add_item(tree, hf_pvfs_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1334 proto_tree_add_item(tree, hf_pvfs_unused, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1335 break;
1337 case PVFS_SERV_PARAM_ROOT_CHECK:
1338 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1339 break;
1342 offset += 8;
1344 return offset;
1347 static int
1348 dissect_pvfs_fs_id(tvbuff_t *tvb, proto_tree *tree, int offset)
1350 proto_tree_add_item(tree, hf_pvfs_fs_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1351 offset += 4;
1353 return offset;
1357 * =======================================================================
1358 * Request handlers
1359 * =======================================================================
1362 static int
1363 dissect_pvfs2_create_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1364 packet_info *pinfo)
1366 /* fs_id */
1367 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1369 /* type */
1370 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
1372 offset += 4;
1374 offset = dissect_pvfs_handle_extent_array(tvb, tree, offset, pinfo);
1376 return offset;
1379 static int
1380 dissect_pvfs2_remove_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1381 packet_info *pinfo)
1383 /* handle */
1384 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1386 /* fs_id */
1387 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1389 return offset;
1392 static int
1393 dissect_pvfs_pint_request(tvbuff_t *tvb, proto_tree *tree, int offset)
1395 /* offset */
1396 proto_tree_add_item(tree, hf_pvfs_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1397 offset += 8;
1399 /* TODO: num_eregs */
1400 proto_tree_add_item(tree, hf_pvfs_num_eregs, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1401 offset += 4;
1403 /* TODO: num_blocks */
1404 proto_tree_add_item(tree, hf_pvfs_num_blocks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1405 offset += 4;
1407 /* TODO: stride */
1408 proto_tree_add_item(tree, hf_pvfs_stride, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1409 offset += 8;
1411 /* TODO: ub */
1412 proto_tree_add_item(tree, hf_pvfs_ub, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1413 offset += 8;
1415 /* TODO: lb */
1416 proto_tree_add_item(tree, hf_pvfs_lb, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1417 offset += 8;
1419 /* TODO: aggregate size */
1420 proto_tree_add_item(tree, hf_pvfs_aggregate_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1421 offset += 8;
1423 /* num_contig_chunks */
1424 proto_tree_add_item(tree, hf_pvfs_num_contig_chunks, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1425 offset += 4;
1427 /* depth */
1428 proto_tree_add_item(tree, hf_pvfs_depth, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1429 offset += 4;
1431 /* num_nested_req */
1432 proto_tree_add_item(tree, hf_pvfs_num_nested_req, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1433 offset += 4;
1435 /* committed */
1436 proto_tree_add_item(tree, hf_pvfs_committed, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1437 offset += 4;
1439 /* refcount */
1440 proto_tree_add_item(tree, hf_pvfs_refcount, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1441 offset += 4;
1443 /* documented */
1444 offset += 4;
1446 /* ereg */
1447 proto_tree_add_item(tree, hf_pvfs_ereg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1448 offset += 4;
1450 /* sreg */
1451 proto_tree_add_item(tree, hf_pvfs_sreg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1452 offset += 4;
1454 return offset;
1457 static int
1458 dissect_pvfs2_io_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1459 packet_info *pinfo)
1461 /* handle */
1462 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1464 /* fs_id */
1465 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1467 /* skip4 as per source code */
1468 offset += 4;
1470 /* io_type */
1471 offset = dissect_pvfs_io_type(tvb, tree, offset);
1473 /* flow_type */
1474 offset = dissect_pvfs_flowproto_type(tvb, tree, offset);
1476 /* server_nr */
1477 proto_tree_add_item(tree, hf_pvfs_server_nr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1478 offset += 4;
1480 /* server_ct */
1481 proto_tree_add_item(tree, hf_pvfs_server_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1482 offset += 4;
1484 /* Distribution */
1485 offset = dissect_pvfs_distribution(tvb, tree, offset, pinfo);
1487 proto_tree_add_item(tree, hf_pvfs_numreq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1488 offset += 4;
1490 /* */
1491 offset += 4;
1493 /*offset = */dissect_pvfs_pint_request(tvb, tree, offset);
1495 /* TODO: remove this!!! */
1496 offset = tvb_reported_length(tvb) - 16;
1498 /* offset */
1499 proto_tree_add_item(tree, hf_pvfs_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1500 offset += 8;
1502 /* size */
1503 proto_tree_add_item(tree, hf_pvfs_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1504 offset += 8;
1506 return offset;
1509 static int
1510 dissect_pvfs2_getattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1511 packet_info *pinfo)
1513 /* handle */
1514 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1516 /* fs_id */
1517 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1519 /* attrmask */
1520 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1522 return offset;
1525 static int
1526 dissect_pvfs2_setattr_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1527 packet_info *pinfo)
1529 /* handle */
1530 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1532 /* parent_ref: fs_id */
1533 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1535 offset += 4;
1537 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1539 return offset;
1542 /* As per pvfs2-1.2.0/src/proto/pvfs2-req-proto.h */
1543 static int
1544 dissect_pvfs2_lookup_path_request(tvbuff_t *tvb, proto_tree *tree,
1545 int offset, packet_info *pinfo)
1547 /* Path */
1548 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1550 /* fs_id */
1551 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1553 offset += 4;
1555 /* starting_handle */
1556 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1558 /* attribute mask */
1559 offset = dissect_pvfs2_attrmask(tvb, tree, offset, NULL);
1561 return offset;
1564 static int
1565 dissect_pvfs2_crdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1566 packet_info *pinfo)
1568 /* Filename */
1569 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1571 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "file handle", NULL);
1573 /* parent_handle */
1574 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1576 /* fs_id */
1577 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1579 offset += 4;
1581 /* atime */
1582 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1583 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1585 /* mtime */
1586 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1587 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1589 /* ctime */
1590 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1591 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1593 return offset;
1596 /* TODO: incomplete */
1597 static int
1598 dissect_pvfs2_rmdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1599 packet_info *pinfo)
1601 /* path */
1602 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1604 /* handle */
1605 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1607 /* fs_id */
1608 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1610 offset += 4;
1612 /* atime */
1613 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_atime,
1614 hf_pvfs_atime_sec, hf_pvfs_atime_nsec);
1616 /* mtime */
1617 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_mtime,
1618 hf_pvfs_mtime_sec, hf_pvfs_mtime_nsec);
1620 /* ctime */
1621 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_ctime,
1622 hf_pvfs_ctime_sec, hf_pvfs_ctime_nsec);
1624 return offset;
1627 static int
1628 dissect_pvfs2_chdirent_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1629 packet_info *pinfo)
1631 /* path */
1632 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1634 /* New directory entry handle */
1635 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "new directory handle",
1636 NULL);
1638 /* Parent handle */
1639 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "parent handle", NULL);
1641 /* fs_id */
1642 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1644 /* Parent atime */
1645 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_atime,
1646 hf_pvfs_parent_atime_sec, hf_pvfs_parent_atime_nsec);
1648 /* Parent mtime */
1649 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_mtime,
1650 hf_pvfs_parent_mtime_sec, hf_pvfs_parent_mtime_nsec);
1652 /* Parent ctime */
1653 offset = dissect_pvfs_time(tvb, tree, offset, hf_pvfs_parent_ctime,
1654 hf_pvfs_parent_ctime_sec, hf_pvfs_parent_ctime_nsec);
1656 return offset;
1659 static int
1660 dissect_pvfs2_truncate_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1661 packet_info *pinfo)
1663 /* handle */
1664 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1666 /* fs_id */
1667 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1669 offset += 4;
1671 /* size */
1672 proto_tree_add_item(tree, hf_pvfs_size, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1673 offset += 8;
1675 /* TODO: flags */
1676 proto_tree_add_item(tree, hf_pvfs_truncate_request_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1677 offset += 4;
1679 return offset;
1682 static int
1683 dissect_pvfs2_mkdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1684 packet_info *pinfo)
1686 unsigned count, i;
1688 /* fs_id */
1689 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1691 offset += 4;
1693 /* attr */
1694 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
1696 /* handle_extent_array */
1697 count = tvb_get_letohl(tvb, offset);
1698 offset += 4;
1700 for (i = 0; i < count; i++)
1701 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1703 return offset;
1706 static int
1707 dissect_pvfs2_readdir_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1708 packet_info *pinfo)
1710 /* object_ref: handle */
1711 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1713 /* object_ref: fs_id */
1714 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1716 /* ds_position */
1717 proto_tree_add_item(tree, hf_pvfs_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1718 offset += 4;
1720 /* dirent_limit */
1721 proto_tree_add_item(tree, hf_pvfs_dirent_limit, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1722 offset += 4;
1724 return offset;
1727 static int
1728 dissect_pvfs2_flush_request(tvbuff_t *tvb, proto_tree *tree,
1729 int offset, packet_info *pinfo)
1731 /* handle */
1732 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1734 /* fs_id */
1735 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1737 /* flags */
1738 proto_tree_add_item(tree, hf_pvfs_flush_request_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1739 offset += 4;
1741 return offset;
1744 static int
1745 dissect_pvfs2_mgmt_setparam_request(tvbuff_t *tvb, proto_tree *tree,
1746 int offset, packet_info *pinfo)
1748 /* fs_id */
1749 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1751 /* server_param */
1752 offset = dissect_pvfs_server_param(tvb, tree, offset, pinfo);
1754 return offset;
1757 static int
1758 dissect_pvfs2_statfs_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1759 packet_info *pinfo _U_)
1761 /* fs_id */
1762 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1764 return offset;
1767 static int
1768 dissect_pvfs2_mgmt_perf_mon_request(tvbuff_t *tvb _U_, proto_tree *tree _U_,
1769 int offset, packet_info *pinfo _U_)
1771 /* TODO: next_id */
1772 proto_tree_add_item(tree, hf_pvfs_next_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1773 offset += 4;
1775 /* TODO: count */
1776 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_request_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1777 offset += 4;
1779 return offset;
1782 static int
1783 dissect_pvfs2_mgmt_iterate_handles_request(tvbuff_t *tvb, proto_tree *tree,
1784 int offset, packet_info *pinfo)
1786 /* fs_id */
1787 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1789 /* handle */
1790 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1792 return offset;
1795 static int
1796 dissect_pvfs2_mgmt_dspace_info_list_request(tvbuff_t *tvb,
1797 proto_tree *tree, int offset, packet_info *pinfo)
1799 uint32_t handle_count, i;
1801 /* fs_id */
1802 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1804 /* handle count */
1805 handle_count = tvb_get_letohl(tvb, offset);
1806 offset += 4;
1808 for (i = 0; i < handle_count; i++)
1810 /* handle */
1811 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1814 return offset;
1817 static int
1818 dissect_pvfs2_mgmt_event_mon_request(tvbuff_t *tvb, proto_tree *tree,
1819 int offset, packet_info *pinfo _U_)
1821 /* event_count */
1822 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_request_event_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1823 offset += 4;
1825 return offset;
1828 static int
1829 dissect_pvfs2_mgmt_remove_object_request(tvbuff_t *tvb, proto_tree *tree,
1830 int offset, packet_info *pinfo)
1832 /* Handle */
1833 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1835 /* fs_id */
1836 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1838 return offset;
1841 static int
1842 dissect_pvfs2_mgmt_remove_dirent_request(tvbuff_t *tvb,
1843 proto_tree *tree, int offset, packet_info *pinfo)
1845 /* Handle */
1846 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1848 /* fs_id */
1849 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1851 /* */
1852 offset += 4;
1854 /* entry */
1855 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
1857 return offset;
1860 static int
1861 dissect_pvfs2_mgmt_get_dirdata_handle_request(tvbuff_t *tvb,
1862 proto_tree *tree, int offset, packet_info *pinfo)
1864 /* Handle */
1865 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1867 /* fs_id */
1868 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1870 return offset;
1873 /* TODO: untested/incomplete */
1874 static int
1875 dissect_pvfs_ds_keyval(tvbuff_t *tvb, proto_tree *tree, int offset, packet_info *pinfo)
1877 /* attribute key */
1878 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_key, offset,
1879 pinfo, NULL);
1881 /* attribute value */
1882 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_attribute_value, offset,
1883 pinfo, NULL);
1885 return offset;
1888 /* TODO: incomplete/untested */
1889 static int
1890 dissect_ds_keyval_array(tvbuff_t *tvb, proto_tree *tree, int offset, packet_info *pinfo)
1892 uint32_t nKey, i;
1894 /* number of keys and vals */
1895 nKey = tvb_get_letohl(tvb, offset);
1896 offset += 4;
1898 for (i = 0; i < nKey; i++)
1899 offset = dissect_pvfs_ds_keyval(tvb, tree, offset, pinfo);
1901 return offset;
1904 /* TODO: incomplete/untested */
1905 static int
1906 dissect_pvfs2_geteattr_request(tvbuff_t *tvb, proto_tree *tree,
1907 int offset, packet_info *pinfo)
1909 /* handle */
1910 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1912 /* fs_id */
1913 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1915 offset += 4;
1917 offset = dissect_ds_keyval_array(tvb, tree, offset, pinfo);
1919 return offset;
1922 /* TODO: incomplete/untested */
1923 static int
1924 dissect_pvfs2_seteattr_request(tvbuff_t *tvb, proto_tree *tree,
1925 int offset, packet_info *pinfo)
1927 /* handle */
1928 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1930 /* fs_id */
1931 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1933 offset += 4;
1935 offset = dissect_ds_keyval_array(tvb, tree, offset, pinfo);
1937 return offset;
1940 /* TODO: untested */
1941 static int
1942 dissect_pvfs2_deleattr_request(tvbuff_t *tvb, proto_tree *tree,
1943 int offset, packet_info *pinfo)
1945 /* handle */
1946 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
1948 /* fs_id */
1949 offset = dissect_pvfs_fs_id(tvb, tree, offset);
1951 /* key */
1952 offset = dissect_pvfs_ds_keyval(tvb, tree, offset, pinfo);
1954 return offset;
1957 static void
1958 pvfc_fmt_release_num(char *result, uint32_t release_nr)
1960 snprintf( result, ITEM_LABEL_LENGTH, "%d (%d.%d.%d)",
1961 release_nr,
1962 release_nr / 10000,
1963 (release_nr % 10000) / 100,
1964 (release_nr % 10000) % 100);
1967 static int
1968 dissect_pvfs2_common_header(tvbuff_t *tvb, proto_tree *tree, int offset)
1970 /* PVFS release number */
1971 proto_tree_add_item(tree, hf_pvfs_release_number, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1972 offset += 4;
1974 /* wire encoding type */
1975 proto_tree_add_item(tree, hf_pvfs_encoding, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1976 offset += 4;
1978 /* server op */
1979 proto_tree_add_item(tree, hf_pvfs_server_op, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1980 offset += 4;
1982 return offset;
1985 static int
1986 dissect_pvfs2_request(tvbuff_t *tvb, proto_tree *tree, int offset,
1987 packet_info *pinfo, uint32_t server_op)
1989 /* context_id */
1990 proto_tree_add_item(tree, hf_pvfs_context_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1991 offset += 4;
1993 /* credentials */
1994 offset = dissect_pvfs_credentials(tvb, tree, offset);
1996 switch (server_op)
1998 case PVFS_SERV_CREATE:
1999 offset = dissect_pvfs2_create_request(tvb, tree, offset, pinfo);
2000 break;
2002 case PVFS_SERV_REMOVE:
2003 offset = dissect_pvfs2_remove_request(tvb, tree, offset, pinfo);
2004 break;
2006 case PVFS_SERV_IO:
2007 offset = dissect_pvfs2_io_request(tvb, tree, offset, pinfo);
2008 break;
2010 case PVFS_SERV_GETATTR:
2011 offset = dissect_pvfs2_getattr_request(tvb, tree, offset, pinfo);
2012 break;
2014 case PVFS_SERV_SETATTR:
2015 offset = dissect_pvfs2_setattr_request(tvb, tree, offset, pinfo);
2016 break;
2018 case PVFS_SERV_LOOKUP_PATH:
2019 offset = dissect_pvfs2_lookup_path_request(tvb, tree, offset, pinfo);
2020 break;
2022 case PVFS_SERV_CRDIRENT:
2023 offset = dissect_pvfs2_crdirent_request(tvb, tree, offset, pinfo);
2024 break;
2026 case PVFS_SERV_RMDIRENT:
2027 offset = dissect_pvfs2_rmdirent_request(tvb, tree, offset, pinfo);
2028 break;
2030 case PVFS_SERV_CHDIRENT:
2031 offset = dissect_pvfs2_chdirent_request(tvb, tree, offset, pinfo);
2032 break;
2034 case PVFS_SERV_TRUNCATE:
2035 offset = dissect_pvfs2_truncate_request(tvb, tree, offset, pinfo);
2036 break;
2038 case PVFS_SERV_MKDIR:
2039 offset = dissect_pvfs2_mkdir_request(tvb, tree, offset, pinfo);
2040 break;
2042 case PVFS_SERV_READDIR:
2043 offset = dissect_pvfs2_readdir_request(tvb, tree, offset, pinfo);
2044 break;
2046 #if 0
2047 case PVFS_SERV_GETCONFIG:
2048 /* No parameters in request */
2049 break;
2050 #endif
2052 #if 0
2053 case PVFS_SERV_WRITE_COMPLETION:
2054 /* No parameters in request */
2055 break;
2056 #endif
2058 case PVFS_SERV_FLUSH:
2059 offset = dissect_pvfs2_flush_request(tvb, tree, offset, pinfo);
2060 break;
2062 case PVFS_SERV_MGMT_SETPARAM:
2063 offset = dissect_pvfs2_mgmt_setparam_request(tvb, tree, offset,
2064 pinfo);
2065 break;
2067 #if 0
2068 case PVFS_SERV_MGMT_NOOP:
2069 /* No parameters in request */
2070 break;
2071 #endif
2073 case PVFS_SERV_STATFS:
2074 offset = dissect_pvfs2_statfs_request(tvb, tree, offset, pinfo);
2075 break;
2077 #if 0
2078 case PVFS_SERV_PERF_UPDATE:
2079 /* No parameters in request */
2080 break;
2081 #endif
2083 case PVFS_SERV_MGMT_PERF_MON:
2084 offset = dissect_pvfs2_mgmt_perf_mon_request(tvb, tree, offset,
2085 pinfo);
2086 break;
2088 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2089 offset = dissect_pvfs2_mgmt_iterate_handles_request(tvb, tree,
2090 offset, pinfo);
2091 break;
2093 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2094 offset = dissect_pvfs2_mgmt_dspace_info_list_request(tvb, tree,
2095 offset, pinfo);
2096 break;
2098 case PVFS_SERV_MGMT_EVENT_MON:
2099 offset = dissect_pvfs2_mgmt_event_mon_request(tvb, tree, offset,
2100 pinfo);
2101 break;
2103 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2104 offset = dissect_pvfs2_mgmt_remove_object_request(tvb, tree, offset,
2105 pinfo);
2106 break;
2108 case PVFS_SERV_MGMT_REMOVE_DIRENT:
2109 offset = dissect_pvfs2_mgmt_remove_dirent_request(tvb, tree, offset,
2110 pinfo);
2111 break;
2113 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2114 offset = dissect_pvfs2_mgmt_get_dirdata_handle_request(tvb, tree,
2115 offset, pinfo);
2116 break;
2118 #if 0
2119 case PVFS_SERV_JOB_TIMER:
2120 /* No parameters in request */
2121 break;
2122 #endif
2124 case PVFS_SERV_PROTO_ERROR:
2125 /* TODO: is this necessary? */
2126 break;
2128 case PVFS_SERV_GETEATTR:
2129 offset = dissect_pvfs2_geteattr_request(tvb, tree, offset, pinfo);
2130 break;
2132 case PVFS_SERV_SETEATTR:
2133 offset = dissect_pvfs2_seteattr_request(tvb, tree, offset, pinfo);
2134 break;
2136 case PVFS_SERV_DELEATTR:
2137 offset = dissect_pvfs2_deleattr_request(tvb, tree, offset, pinfo);
2138 break;
2140 default:
2141 /* TODO: what should we do here? */
2142 break;
2145 return offset;
2149 * =======================================================================
2150 * Response handlers
2151 * =======================================================================
2154 static int
2155 dissect_pvfs2_create_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2156 packet_info *pinfo)
2158 /* Handle */
2159 return dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2162 static int
2163 dissect_pvfs2_io_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2165 return dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_size, NULL);
2168 static int
2169 dissect_pvfs2_getattr_response(tvbuff_t *tvb, proto_tree *tree,
2170 int offset, packet_info *pinfo)
2172 offset = dissect_pvfs_object_attr(tvb, tree, offset, pinfo);
2174 return offset;
2177 static int
2178 dissect_pvfs2_lookup_path_response(tvbuff_t *tvb, proto_tree *tree,
2179 int offset, packet_info *pinfo)
2181 uint32_t nCount = 0;
2182 uint32_t handle_count = 0;
2183 uint32_t attr_count = 0;
2184 proto_tree *attr_tree;
2186 offset += 4;
2188 /* handle_count */
2189 handle_count = tvb_get_letohl(tvb, offset);
2190 proto_tree_add_item(tree, hf_pvfs_lookup_path_response_handle_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2191 offset += 4;
2193 /* TODO: add bounds checking */
2194 for (nCount = 0; nCount < handle_count; nCount++)
2195 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2197 offset += 4;
2199 /* array of attributes */
2200 attr_count = tvb_get_letohl(tvb, offset);
2202 attr_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4,
2203 ett_pvfs_attr, NULL, "Attribute array (total items: %d)", attr_count);
2205 offset += 4;
2207 /* Array of attributes */
2208 for (nCount = 0; nCount < attr_count; nCount++)
2209 offset = dissect_pvfs_object_attr(tvb, attr_tree, offset, pinfo);
2211 return offset;
2214 static int
2215 dissect_pvfs2_rmdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2216 packet_info *pinfo)
2218 /* Handle */
2219 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2221 return offset;
2224 static int
2225 dissect_pvfs2_chdirent_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2226 packet_info *pinfo)
2228 /* Handle */
2229 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2231 return offset;
2234 static int
2235 dissect_pvfs2_mkdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2236 packet_info *pinfo)
2238 /* Handle */
2239 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2241 return offset;
2244 static int
2245 dissect_pvfs2_readdir_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2246 packet_info *pinfo)
2248 uint32_t dirent_count = 0;
2249 uint32_t nCount = 0;
2251 /* ds_position */
2252 proto_tree_add_item(tree, hf_pvfs_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2253 offset += 4;
2255 offset += 4;
2257 /* directory_version */
2258 proto_tree_add_item(tree, hf_pvfs_directory_version, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2259 offset += 8;
2261 offset += 4;
2263 /* dirent_count */
2264 dirent_count = tvb_get_letohl(tvb, offset);
2265 proto_tree_add_item(tree, hf_pvfs_dirent_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2266 offset += 4;
2268 for (nCount = 0; nCount < dirent_count; nCount++)
2270 offset = dissect_pvfs_string(tvb, tree, hf_pvfs_path, offset, pinfo, NULL);
2271 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2274 return offset;
2278 * TODO: this code needs work! Not finished yet!
2280 static int
2281 dissect_pvfs2_getconfig_response(tvbuff_t *tvb, proto_tree *parent_tree,
2282 int offset, packet_info *pinfo)
2284 uint32_t i;
2285 uint32_t total_bytes = 0, total_config_bytes = 0, total_lines = 0;
2286 uint32_t bytes_processed = 0;
2287 uint32_t length_remaining = 0;
2288 const char *ptr = NULL;
2289 proto_tree *tree, *config_tree = NULL;
2290 /*uint8_t truncated = 0;*/
2292 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 12,
2293 ett_pvfs_server_config, NULL, "Server Config");
2295 /* Total number of bytes in server config (incl. entry count) */
2296 total_bytes = tvb_get_letohl(tvb, offset);
2297 proto_tree_add_item(tree, hf_pvfs_getconfig_response_total_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2298 offset += 4;
2300 /* There must be at least 4 bytes of data returned to determine the
2301 * size of the server config data
2303 if (total_bytes < 4)
2305 /* Server config not returned, bail out */
2306 return offset;
2309 /* Number of entries in server config */
2310 total_lines = tvb_get_letohl(tvb, offset);
2311 proto_tree_add_item(tree, hf_pvfs_getconfig_response_lines, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2312 offset += 4;
2314 /* Number of bytes in server config */
2315 total_config_bytes = tvb_get_letohl(tvb, offset);
2316 proto_tree_add_item(tree, hf_pvfs_getconfig_response_config_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2317 offset += 4;
2319 /* Get pointer to server config data */
2320 ptr = tvb_get_ptr(tvb, offset, total_config_bytes);
2322 if (!ptr)
2324 /* Not enough data. Bail out. */
2325 return offset;
2328 /* Check if all data is available */
2329 length_remaining = tvb_captured_length_remaining(tvb, offset);
2331 if (length_remaining < total_config_bytes)
2333 total_config_bytes = length_remaining;
2335 /*truncated = 1;*/
2338 bytes_processed = 0;
2340 for (i = 0; i < total_lines; i++)
2342 uint8_t entry[256], *pentry = entry, *tmp_entry = NULL;
2343 uint32_t entry_length = 0, tmp_entry_length = 0;
2344 uint32_t bufsiz = sizeof(entry);
2346 while ((bytes_processed < total_config_bytes) &&
2347 (entry_length < bufsiz) &&
2348 (*ptr != '\n') && (*ptr != '\0'))
2350 *pentry++ = *ptr++;
2352 bytes_processed++;
2353 entry_length++;
2356 if ((entry_length == bufsiz) &&
2357 ((entry[entry_length - 1] != '\n') &&
2358 (entry[entry_length - 1] != '\0')))
2361 * Single line of config data doesn't fit into provided buffer,
2362 * config data is malformed.
2365 break;
2368 if (bytes_processed == total_config_bytes)
2370 /* Oops... ran out of data before we could complete the entry */
2371 break;
2374 *pentry= '\0';
2376 tmp_entry = get_ascii_string(pinfo->pool, entry, entry_length);
2377 tmp_entry_length = (uint32_t)strlen(tmp_entry);
2379 /* Remove all whitespace from front of entry */
2380 while ((tmp_entry_length > 0) && (!g_ascii_isalnum(*tmp_entry)) &&
2381 (*tmp_entry != '<'))
2383 tmp_entry++;
2384 tmp_entry_length--;
2387 if (tmp_entry[0] == '<')
2389 if (tmp_entry[tmp_entry_length - 1] == '>')
2391 /* Token */
2392 if (tmp_entry[1] != '/')
2394 /* Opening token, create new tree root */
2395 config_tree = proto_tree_add_subtree(tree, tvb, offset,
2396 tmp_entry_length, ett_pvfs_server_config_branch, NULL, tmp_entry);
2398 else
2400 /* Closing token */
2401 config_tree = NULL;
2404 else
2406 /* Malformed token */
2407 break;
2410 else
2412 /* Insert items into the root config tree if there's no subtree
2413 * defined.
2415 if (config_tree == NULL)
2416 config_tree = tree;
2418 if (tmp_entry_length > 0)
2420 proto_tree_add_string_format(config_tree, hf_pvfs_getconfig_response_entry, tvb, offset, tmp_entry_length,
2421 tmp_entry, "%s", tmp_entry);
2425 offset += entry_length + 1;
2427 ptr++;
2428 bytes_processed++;
2431 if (bytes_processed < total_config_bytes)
2433 /* We ran out of server config data */
2434 proto_tree_add_expert(config_tree, pinfo, &ei_pvfs_malformed, tvb, offset, -1);
2437 return offset;
2440 static int
2441 dissect_pvfs2_write_completion_response(tvbuff_t *tvb, proto_tree *tree,
2442 int offset)
2444 /* size */
2445 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_total_completed,
2446 NULL);
2448 return offset;
2451 static int
2452 dissect_pvfs2_mgmt_setparam_response(tvbuff_t *tvb, proto_tree *tree,
2453 int offset)
2455 /* old_value */
2456 proto_tree_add_item(tree, hf_pvfs_prev_value, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2458 offset += 8;
2460 return offset;
2463 static int
2464 dissect_pvfs2_statfs_response(tvbuff_t *tvb, proto_tree *tree, int offset)
2466 offset += 4;
2468 /* fs_id */
2469 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2471 /* bytes_available */
2472 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_available,
2473 NULL);
2475 /* bytes_total */
2476 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_bytes_total,
2477 NULL);
2479 /* RAM bytes total */
2480 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_total,
2481 NULL);
2483 /* RAM bytes free */
2484 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_ram_bytes_free,
2485 NULL);
2487 /* load average (1s) */
2488 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_1s,
2489 NULL);
2491 /* load average (5s) */
2492 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_5s,
2493 NULL);
2495 /* load average (15s) */
2496 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_load_average_15s,
2497 NULL);
2499 /* uptime (seconds) */
2500 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_uptime_seconds,
2501 NULL);
2503 /* handles_available_count */
2504 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_available,
2505 NULL);
2507 /* handles_total_count */
2508 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_handles_total,
2509 NULL);
2511 return offset;
2514 static int
2515 dissect_pvfs_mgmt_perf_stat(tvbuff_t *tvb, proto_tree *tree, int offset,
2516 int nItem)
2518 proto_tree *stat_tree;
2520 stat_tree = proto_tree_add_subtree_format(tree, tvb, offset, 48,
2521 ett_pvfs_mgmt_perf_stat, NULL, "Stat Array - Element %d", nItem);
2523 /* TODO: valid_flag */
2524 proto_tree_add_item(stat_tree, hf_pvfs_mgmt_perf_stat_valid_flag, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2525 offset += 4;
2527 /* TODO: id */
2528 proto_tree_add_item(stat_tree, hf_pvfs_mgmt_perf_stat_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2529 offset += 4;
2531 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_start_time_ms,
2532 NULL);
2533 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_written,
2534 NULL);
2535 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_bytes_read,
2536 NULL);
2537 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_write,
2538 NULL);
2539 offset = dissect_pvfs_uint64(tvb, stat_tree, offset, hf_pvfs_metadata_read,
2540 NULL);
2542 return offset;
2545 static int
2546 dissect_pvfs2_mgmt_perf_mon_response(tvbuff_t *tvb, proto_tree *tree,
2547 int offset)
2549 uint32_t perf_array_count, i;
2551 /* TODO: suggested_next_id */
2552 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_response_suggested_next_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2553 offset += 4;
2555 offset += 4;
2557 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_end_time_ms, NULL);
2558 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_cur_time_ms, NULL);
2560 offset += 4;
2562 /* TODO: perf_array_count */
2563 perf_array_count = tvb_get_letohl(tvb, offset);
2564 proto_tree_add_item(tree, hf_pvfs_mgmt_perf_mon_response_perf_array_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2565 offset += 4;
2567 for (i = 0; i < perf_array_count; i++)
2568 offset = dissect_pvfs_mgmt_perf_stat(tvb, tree, offset, i);
2570 return offset;
2573 static int
2574 dissect_pvfs2_mgmt_iterate_handles_response(tvbuff_t *tvb, proto_tree *tree,
2575 int offset, packet_info *pinfo)
2577 uint32_t handle_count, i;
2579 /* ds_position */
2580 proto_tree_add_item(tree, hf_pvfs_mgmt_iterate_handles_response_ds_position, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2581 offset += 4;
2583 /* handle_count */
2584 handle_count = tvb_get_letohl(tvb, offset);
2585 proto_tree_add_item(tree, hf_pvfs_mgmt_iterate_handles_response_handle_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2586 offset += 4;
2588 /* TODO: this could be improved */
2589 for (i = 0; i < handle_count; i++)
2590 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2592 return offset;
2595 static int
2596 dissect_pvfs2_mgmt_dspace_info(tvbuff_t *tvb, proto_tree *tree, int offset,
2597 packet_info *pinfo)
2599 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2600 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2601 offset = dissect_pvfs2_ds_type(tvb, tree, offset, NULL);
2602 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_b_size,
2603 NULL);
2604 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_k_size,
2605 NULL);
2606 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2608 return offset;
2611 static int
2612 dissect_pvfs2_mgmt_dspace_info_list_response(tvbuff_t *tvb, proto_tree *tree,
2613 int offset, packet_info *pinfo)
2615 uint32_t dspace_info_count, i;
2616 proto_tree *arr_tree = NULL;
2618 offset += 4;
2620 /* dspace_info_count */
2621 dspace_info_count = tvb_get_letohl(tvb, offset);
2622 proto_tree_add_item(tree, hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2624 if ((dspace_info_count > 0) && (tree))
2626 arr_tree = proto_tree_add_subtree_format(tree, tvb, offset,
2627 dspace_info_count * 40, ett_pvfs_mgmt_dspace_info, NULL, "dspace_info Array (%d items)",
2628 dspace_info_count);
2631 for (i = 0; i < dspace_info_count; i++)
2632 offset = dissect_pvfs2_mgmt_dspace_info(tvb, arr_tree, offset, pinfo);
2634 return offset;
2637 static int
2638 dissect_pvfs2_mgmt_event_mon_response(tvbuff_t *tvb, proto_tree *tree,
2639 int offset)
2641 /* api */
2642 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_api, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2643 offset += 4;
2645 /* operation */
2646 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_operation, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2647 offset += 4;
2649 /* value */
2650 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_value, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2651 offset += 4;
2653 /* id */
2654 offset = dissect_pvfs_uint64(tvb, tree, offset, hf_pvfs_id_gen_t,
2655 NULL);
2657 /* flags */
2658 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2659 offset += 4;
2661 /* tv_sec */
2662 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_tv_sec, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2663 offset += 4;
2665 /* tv_usec */
2666 proto_tree_add_item(tree, hf_pvfs_mgmt_event_mon_response_tv_usec, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2667 offset += 4;
2669 offset += 4;
2671 return offset;
2674 static int
2675 dissect_pvfs2_mgmt_remove_object_response(tvbuff_t *tvb, proto_tree *tree,
2676 int offset, packet_info *pinfo)
2678 /* handle */
2679 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2681 /* fs_id */
2682 offset = dissect_pvfs_fs_id(tvb, tree, offset);
2684 return offset;
2687 static int
2688 dissect_pvfs2_mgmt_get_dirdata_handle_response(tvbuff_t *tvb,
2689 proto_tree *tree, int offset, packet_info *pinfo)
2691 /* handle */
2692 offset = dissect_pvfs_fh(tvb, offset, pinfo, tree, "handle", NULL);
2694 return offset;
2697 /* TODO: untested */
2698 static int
2699 dissect_pvfs2_geteattr_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2700 packet_info *pinfo _U_)
2702 offset += 4;
2704 /* Dissect nKey & ds_keyval array */
2705 offset = dissect_ds_keyval_array(tvb, tree, offset, pinfo);
2707 return offset;
2710 static int
2711 dissect_pvfs2_response(tvbuff_t *tvb, proto_tree *tree, int offset,
2712 packet_info *pinfo, uint32_t server_op)
2714 /* error code */
2715 offset = dissect_pvfs2_error(tvb, tree, offset, pinfo);
2717 switch (server_op)
2719 case PVFS_SERV_CREATE:
2720 offset = dissect_pvfs2_create_response(tvb, tree, offset, pinfo);
2721 break;
2723 #if 0
2724 case PVFS_SERV_REMOVE:
2725 /* No result data */
2726 break;
2727 #endif
2729 case PVFS_SERV_IO:
2730 offset = dissect_pvfs2_io_response(tvb, tree, offset);
2731 break;
2733 case PVFS_SERV_GETATTR:
2734 offset = dissect_pvfs2_getattr_response(tvb, tree, offset, pinfo);
2735 break;
2737 case PVFS_SERV_SETATTR:
2738 /* No result data */
2739 break;
2741 case PVFS_SERV_LOOKUP_PATH:
2742 offset = dissect_pvfs2_lookup_path_response(tvb, tree, offset, pinfo);
2743 break;
2745 #if 0
2746 case PVFS_SERV_CRDIRENT:
2747 /* No result data */
2748 break;
2749 #endif
2751 case PVFS_SERV_RMDIRENT:
2752 offset = dissect_pvfs2_rmdirent_response(tvb, tree, offset, pinfo);
2753 break;
2755 case PVFS_SERV_CHDIRENT:
2756 offset = dissect_pvfs2_chdirent_response(tvb, tree, offset, pinfo);
2757 break;
2759 #if 0
2760 case PVFS_SERV_TRUNCATE:
2761 /* No result data */
2762 break;
2763 #endif
2765 case PVFS_SERV_MKDIR:
2766 offset = dissect_pvfs2_mkdir_response(tvb, tree, offset, pinfo);
2767 break;
2769 case PVFS_SERV_READDIR:
2770 offset = dissect_pvfs2_readdir_response(tvb, tree, offset, pinfo);
2771 break;
2773 case PVFS_SERV_GETCONFIG:
2774 offset = dissect_pvfs2_getconfig_response(tvb, tree, offset, pinfo);
2775 break;
2777 case PVFS_SERV_WRITE_COMPLETION:
2778 offset = dissect_pvfs2_write_completion_response(tvb, tree, offset);
2779 break;
2781 #if 0
2782 case PVFS_SERV_FLUSH:
2783 /* No result data */
2784 break;
2785 #endif
2787 case PVFS_SERV_MGMT_SETPARAM:
2788 offset = dissect_pvfs2_mgmt_setparam_response(tvb, tree, offset);
2789 break;
2791 #if 0
2792 case PVFS_SERV_MGMT_NOOP:
2793 /* No result data */
2794 break;
2795 #endif
2797 case PVFS_SERV_STATFS:
2798 offset = dissect_pvfs2_statfs_response(tvb, tree, offset);
2799 break;
2801 #if 0
2802 case PVFS_SERV_PERF_UPDATE:
2803 /* No result data */
2804 break;
2805 #endif
2807 case PVFS_SERV_MGMT_PERF_MON:
2808 offset = dissect_pvfs2_mgmt_perf_mon_response(tvb, tree, offset);
2809 break;
2811 case PVFS_SERV_MGMT_ITERATE_HANDLES:
2812 offset = dissect_pvfs2_mgmt_iterate_handles_response(tvb, tree,
2813 offset, pinfo);
2814 break;
2816 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
2817 offset = dissect_pvfs2_mgmt_dspace_info_list_response(tvb, tree,
2818 offset, pinfo);
2819 break;
2821 case PVFS_SERV_MGMT_EVENT_MON:
2822 offset = dissect_pvfs2_mgmt_event_mon_response(tvb, tree, offset);
2823 break;
2825 case PVFS_SERV_MGMT_REMOVE_OBJECT:
2826 offset = dissect_pvfs2_mgmt_remove_object_response(tvb, tree, offset,
2827 pinfo);
2828 break;
2830 #if 0
2831 case PVFS_SERV_MGMT_REMOVE_DIRENT:
2832 /* No result data */
2833 break;
2834 #endif
2836 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
2837 offset = dissect_pvfs2_mgmt_get_dirdata_handle_response(tvb, tree,
2838 offset, pinfo);
2839 break;
2841 #if 0
2842 case PVFS_SERV_JOB_TIMER:
2843 /* No result data */
2844 break;
2845 #endif
2847 case PVFS_SERV_PROTO_ERROR:
2848 /* No result data */
2849 break;
2851 /* TODO: untested */
2852 case PVFS_SERV_GETEATTR:
2853 offset = dissect_pvfs2_geteattr_response(tvb, tree, offset, pinfo);
2854 break;
2856 #if 0
2857 case PVFS_SERV_SETEATTR:
2858 /* No result data */
2859 break;
2860 #endif
2862 #if 0
2863 case PVFS_SERV_DELEATTR:
2864 /* No result data */
2865 break;
2866 #endif
2868 default:
2869 /* TODO: what do we do here? */
2870 break;
2873 return offset;
2876 static wmem_map_t *pvfs2_io_tracking_value_table;
2878 typedef struct pvfs2_io_tracking_key
2880 uint64_t tag;
2881 } pvfs2_io_tracking_key_t;
2883 typedef struct pvfs2_io_tracking_value
2885 uint32_t request_frame_num;
2886 uint32_t response_frame_num;
2887 uint32_t flow_frame_num;
2889 } pvfs2_io_tracking_value_t;
2891 static int
2892 pvfs2_io_tracking_equal(const void *k1, const void *k2)
2894 const pvfs2_io_tracking_key_t *key1 = (const pvfs2_io_tracking_key_t *) k1;
2895 const pvfs2_io_tracking_key_t *key2 = (const pvfs2_io_tracking_key_t *) k2;
2897 return (key1->tag == key2->tag);
2900 static unsigned
2901 pvfs2_io_tracking_hash(const void *k)
2903 const pvfs2_io_tracking_key_t *key = (const pvfs2_io_tracking_key_t *) k;
2905 return (unsigned) ((key->tag >> 32) ^ ((uint32_t) key->tag));
2908 static pvfs2_io_tracking_value_t *
2909 pvfs2_io_tracking_new_with_tag(uint64_t tag, uint32_t num)
2911 pvfs2_io_tracking_value_t *value;
2912 pvfs2_io_tracking_key_t *newkey;
2914 newkey = wmem_new0(wmem_file_scope(), pvfs2_io_tracking_key_t);
2915 newkey->tag = tag;
2917 value = wmem_new0(wmem_file_scope(), pvfs2_io_tracking_value_t);
2919 wmem_map_insert(pvfs2_io_tracking_value_table, newkey, value);
2921 value->request_frame_num = num;
2923 return value;
2926 static bool
2927 dissect_pvfs_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
2928 bool dissect_other_as_continuation _U_)
2930 uint32_t mode = 0;
2931 proto_item *item;
2932 proto_tree *pvfs_tree = NULL, *pvfs_htree = NULL;
2933 int offset = 0;
2934 uint64_t tag;
2935 uint32_t server_op;
2936 pvfs2_io_tracking_value_t *val = NULL;
2938 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PVFS");
2940 col_clear(pinfo->cinfo, COL_INFO);
2942 item = proto_tree_add_item(parent_tree, proto_pvfs, tvb, 0, -1, ENC_NA);
2943 pvfs_tree = proto_item_add_subtree(item, ett_pvfs);
2945 proto_tree_add_item(pvfs_tree, hf_pvfs_version2, tvb, 0, -1, ENC_NA);
2947 /* PVFS packet header is 24 bytes */
2948 pvfs_htree = proto_tree_add_subtree(pvfs_tree, tvb, 0, BMI_HEADER_SIZE,
2949 ett_pvfs_hdr, NULL, "BMI Header");
2951 /* Magic number */
2952 proto_tree_add_item(pvfs_htree, hf_pvfs_magic_nr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2953 offset += 4;
2955 /* TCP message mode (32-bit) */
2956 mode = tvb_get_letohl(tvb, offset);
2957 proto_tree_add_uint(pvfs_htree, hf_pvfs_mode, tvb, offset, 4, mode);
2958 offset += 4;
2960 /* tag (64-bit) */
2961 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_tag, &tag);
2963 /* size (64-bit) */
2964 offset = dissect_pvfs_uint64(tvb, pvfs_htree, offset, hf_pvfs_size, NULL);
2966 /* Lookahead to get server_op (invalid if frame contains flow data) */
2967 server_op = tvb_get_letohl(tvb, offset + 8);
2969 if (mode == TCP_MODE_UNEXP)
2971 /* Add entry to tracking table for PVFS_SERV_IO request */
2972 if ((server_op == PVFS_SERV_IO) && !pinfo->fd->visited)
2973 val = pvfs2_io_tracking_new_with_tag(tag, pinfo->num);
2975 else
2977 pvfs2_io_tracking_key_t key;
2979 memset(&key, 0, sizeof(key));
2980 key.tag = tag;
2982 val = (pvfs2_io_tracking_value_t *)wmem_map_lookup(pvfs2_io_tracking_value_table, &key);
2984 /* If this frame contains a known PVFS_SERV_IO tag, track it */
2985 if (val && !pinfo->fd->visited)
2987 /* If response HAS NOT been seen, mark this frame as response */
2988 if (val->response_frame_num == 0)
2989 val->response_frame_num = pinfo->num;
2990 else
2992 /* If response HAS been seen, this frame is flow data */
2993 if (val->flow_frame_num == 0)
2994 val->flow_frame_num = pinfo->num;
2999 if (val && (val->flow_frame_num == pinfo->num))
3001 /* This frame is marked as being flow data */
3002 col_set_str(pinfo->cinfo, COL_INFO, "PVFS flow data");
3004 proto_tree_add_item(pvfs_tree, hf_pvfs_flow_data, tvb, offset, -1, ENC_NA);
3006 return true;
3009 /* Extract common part of packet found in requests and responses */
3010 offset = dissect_pvfs2_common_header(tvb, pvfs_htree, offset);
3012 /* Update column info display */
3013 col_add_str(pinfo->cinfo, COL_INFO,
3014 val_to_str(server_op, names_pvfs_server_op, "%u (unknown)"));
3016 col_append_str(pinfo->cinfo, COL_INFO,
3017 (mode == TCP_MODE_UNEXP)? " (request)": " (response)");
3019 /* TODO: handle all modes */
3020 if (mode == TCP_MODE_UNEXP)
3022 /* Request */
3023 /*offset = */dissect_pvfs2_request(tvb, pvfs_tree, offset, pinfo, server_op);
3025 else
3027 /* TODO: re-examine this! */
3028 #if 0
3029 if (mode == TCP_MODE_REND)
3032 * TODO: move this code outside so it's common for requests and
3033 * responses
3036 col_set_str(pinfo->cinfo, COL_INFO, "PVFS2 DATA (request)");
3038 else
3039 #endif
3041 /* Response */
3042 /*offset = */dissect_pvfs2_response(tvb, pvfs_tree, offset, pinfo,
3043 server_op);
3047 return true;
3050 /* Register the protocol with Wireshark */
3051 void
3052 proto_register_pvfs(void)
3054 static hf_register_info hf[] = {
3055 { &hf_pvfs_magic_nr,
3056 { "Magic Number", "pvfs.magic_nr", FT_UINT32, BASE_HEX,
3057 NULL, 0, NULL, HFILL }},
3059 { &hf_pvfs_uid,
3060 { "UID", "pvfs.uid", FT_UINT32, BASE_DEC,
3061 NULL, 0, NULL, HFILL }},
3063 { &hf_pvfs_gid,
3064 { "GID", "pvfs.gid", FT_UINT32, BASE_DEC,
3065 NULL, 0, NULL, HFILL }},
3067 { &hf_pvfs_mode,
3068 { "Mode", "pvfs.mode", FT_UINT32, BASE_DEC,
3069 VALS(names_pvfs_mode), 0, NULL, HFILL }},
3071 { &hf_pvfs_tag,
3072 { "Tag", "pvfs.tag", FT_UINT64, BASE_DEC,
3073 NULL, 0, NULL, HFILL }},
3075 { &hf_pvfs_size,
3076 { "Size", "pvfs.size", FT_UINT64, BASE_DEC,
3077 NULL, 0, NULL, HFILL }},
3079 { &hf_pvfs_release_number,
3080 { "Release Number", "pvfs.release_number", FT_UINT32, BASE_CUSTOM,
3081 CF_FUNC(pvfc_fmt_release_num), 0, NULL, HFILL }},
3083 { &hf_pvfs_encoding,
3084 { "Encoding", "pvfs.encoding", FT_UINT32, BASE_DEC,
3085 VALS(names_pvfs_encoding), 0, NULL, HFILL }},
3087 { &hf_pvfs_server_op,
3088 { "Server Operation", "pvfs.server_op", FT_UINT32, BASE_DEC,
3089 VALS(names_pvfs_server_op), 0, NULL, HFILL }},
3091 #if 0
3092 { &hf_pvfs_handle,
3093 { "Handle", "pvfs.handle", FT_BYTES, BASE_NONE,
3094 NULL, 0, NULL, HFILL }},
3095 #endif
3097 { &hf_pvfs_fs_id,
3098 { "fs_id", "pvfs.fs_id", FT_UINT32, BASE_HEX,
3099 NULL, 0, "File System ID", HFILL }},
3101 { &hf_pvfs_attrmask,
3102 { "Attribute Mask", "pvfs.attrmask", FT_UINT32, BASE_DEC,
3103 NULL, 0, NULL, HFILL }},
3105 { &hf_pvfs_attr,
3106 { "attr", "pvfs.attribute", FT_UINT32, BASE_HEX,
3107 VALS(names_pvfs_attr), 0, "Attribute", HFILL }},
3109 { &hf_pvfs_ds_type,
3110 { "ds_type", "pvfs.ds_type", FT_UINT32, BASE_HEX,
3111 VALS(names_pvfs_ds_type), 0, "Type", HFILL }},
3113 { &hf_pvfs_error,
3114 { "Result", "pvfs.error", FT_UINT32, BASE_HEX,
3115 VALS(names_pvfs_error), 0, NULL, HFILL }},
3117 { &hf_pvfs_atime,
3118 { "atime", "pvfs.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3119 NULL, 0, "Access Time", HFILL }},
3121 { &hf_pvfs_atime_sec,
3122 { "seconds", "pvfs.atime.sec", FT_UINT32, BASE_DEC,
3123 NULL, 0, "Access Time (seconds)", HFILL }},
3125 { &hf_pvfs_atime_nsec,
3126 { "microseconds", "pvfs.atime.usec", FT_UINT32, BASE_DEC,
3127 NULL, 0, "Access Time (microseconds)", HFILL }},
3129 { &hf_pvfs_mtime,
3130 { "mtime", "pvfs.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3131 NULL, 0, "Modify Time", HFILL }},
3133 { &hf_pvfs_mtime_sec,
3134 { "seconds", "pvfs.mtime.sec", FT_UINT32, BASE_DEC,
3135 NULL, 0, "Modify Time (seconds)", HFILL }},
3137 { &hf_pvfs_mtime_nsec,
3138 { "microseconds", "pvfs.mtime.usec", FT_UINT32, BASE_DEC,
3139 NULL, 0, "Modify Time (microseconds)", HFILL }},
3141 { &hf_pvfs_ctime,
3142 { "ctime", "pvfs.ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3143 NULL, 0, "Creation Time", HFILL }},
3145 { &hf_pvfs_ctime_sec,
3146 { "seconds", "pvfs.ctime.sec", FT_UINT32, BASE_DEC,
3147 NULL, 0, "Creation Time (seconds)", HFILL }},
3149 { &hf_pvfs_ctime_nsec,
3150 { "microseconds", "pvfs.ctime.usec", FT_UINT32, BASE_DEC,
3151 NULL, 0, "Creation Time (microseconds)", HFILL }},
3153 { &hf_pvfs_parent_atime,
3154 { "Parent atime", "pvfs.parent_atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3155 NULL, 0, "Access Time", HFILL }},
3157 { &hf_pvfs_parent_atime_sec,
3158 { "seconds", "pvfs.parent_atime.sec", FT_UINT32, BASE_DEC,
3159 NULL, 0, "Access Time (seconds)", HFILL }},
3161 { &hf_pvfs_parent_atime_nsec,
3162 { "microseconds", "pvfs.parent_atime.usec", FT_UINT32, BASE_DEC,
3163 NULL, 0, "Access Time (microseconds)", HFILL }},
3165 { &hf_pvfs_parent_mtime,
3166 { "Parent mtime", "pvfs.parent_mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3167 NULL, 0, "Modify Time", HFILL }},
3169 { &hf_pvfs_parent_mtime_sec,
3170 { "seconds", "pvfs.parent_mtime.sec", FT_UINT32, BASE_DEC,
3171 NULL, 0, "Modify Time (seconds)", HFILL }},
3173 { &hf_pvfs_parent_mtime_nsec,
3174 { "microseconds", "pvfs.parent_mtime.usec", FT_UINT32, BASE_DEC,
3175 NULL, 0, "Modify Time (microseconds)", HFILL }},
3177 { &hf_pvfs_parent_ctime,
3178 { "Parent ctime", "pvfs.parent_ctime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3179 NULL, 0, "Creation Time", HFILL }},
3181 { &hf_pvfs_parent_ctime_sec,
3182 { "seconds", "pvfs.parent_ctime.sec", FT_UINT32, BASE_DEC,
3183 NULL, 0, "Creation Time (seconds)", HFILL }},
3185 { &hf_pvfs_parent_ctime_nsec,
3186 { "microseconds", "pvfs.parent_ctime.usec", FT_UINT32, BASE_DEC,
3187 NULL, 0, "Creation Time (microseconds)", HFILL }},
3189 { &hf_pvfs_dfile_count,
3190 { "dfile_count", "pvfs.dfile_count", FT_UINT32, BASE_DEC,
3191 NULL, 0, NULL, HFILL }},
3193 { &hf_pvfs_distribution,
3194 { "Distribution", "pvfs.distribution", FT_STRING, BASE_NONE,
3195 NULL, 0, NULL, HFILL }},
3197 { &hf_pvfs_dirent_count,
3198 { "Dir Entry Count", "pvfs.dirent_count", FT_UINT32, BASE_DEC,
3199 NULL, 0, "Directory Entry Count", HFILL }},
3201 { &hf_pvfs_directory_version,
3202 { "Directory Version", "pvfs.directory_version", FT_UINT64, BASE_HEX,
3203 NULL, 0, NULL, HFILL }},
3205 { &hf_pvfs_path,
3206 { "Path", "pvfs.path", FT_STRING, BASE_NONE,
3207 NULL, 0, NULL, HFILL }},
3209 { &hf_pvfs_total_completed,
3210 { "Bytes Completed", "pvfs.bytes_completed", FT_UINT64, BASE_DEC,
3211 NULL, 0, NULL, HFILL }},
3213 { &hf_pvfs_io_dist,
3214 { "Name", "pvfs.distribution.name", FT_STRING, BASE_NONE,
3215 NULL, 0, "Distribution Name", HFILL }},
3217 { &hf_pvfs_aggregate_size,
3218 { "Aggregate Size", "pvfs.aggregate_size", FT_UINT64, BASE_DEC,
3219 NULL, 0, NULL, HFILL }},
3221 { &hf_pvfs_io_type,
3222 { "I/O Type", "pvfs.io_type", FT_UINT32, BASE_DEC,
3223 VALS(names_pvfs_io_type), 0, NULL, HFILL }},
3225 { &hf_pvfs_flowproto_type,
3226 { "Flow Protocol Type", "pvfs.flowproto_type", FT_UINT32, BASE_DEC,
3227 VALS(names_pvfs_flowproto_type), 0, NULL, HFILL }},
3229 { &hf_pvfs_server_param,
3230 { "Server Parameter", "pvfs.server_param", FT_UINT32, BASE_DEC,
3231 VALS(names_pvfs_server_param), 0, NULL, HFILL }},
3233 { &hf_pvfs_prev_value,
3234 { "Previous Value", "pvfs.prev_value", FT_UINT64, BASE_DEC,
3235 NULL, 0, NULL, HFILL }},
3237 #if 0
3238 { &hf_pvfs_ram_free_bytes,
3239 { "RAM Free Bytes", "pvfs.ram.free_bytes", FT_UINT64, BASE_DEC,
3240 NULL, 0, NULL, HFILL }},
3241 #endif
3243 { &hf_pvfs_bytes_available,
3244 { "Bytes Available", "pvfs.bytes_available", FT_UINT64, BASE_DEC,
3245 NULL, 0, NULL, HFILL }},
3247 { &hf_pvfs_bytes_total,
3248 { "Bytes Total", "pvfs.bytes_total", FT_UINT64, BASE_DEC,
3249 NULL, 0, NULL, HFILL }},
3251 { &hf_pvfs_ram_bytes_total,
3252 { "RAM Bytes Total", "pvfs.ram_bytes_total", FT_UINT64, BASE_DEC,
3253 NULL, 0, NULL, HFILL }},
3255 { &hf_pvfs_ram_bytes_free,
3256 { "RAM Bytes Free", "pvfs.ram_bytes_free", FT_UINT64, BASE_DEC,
3257 NULL, 0, NULL, HFILL }},
3259 { &hf_pvfs_load_average_1s,
3260 { "Load Average (1s)", "pvfs.load_average.1s", FT_UINT64, BASE_DEC,
3261 NULL, 0, NULL, HFILL }},
3263 { &hf_pvfs_load_average_5s,
3264 { "Load Average (5s)", "pvfs.load_average.5s", FT_UINT64, BASE_DEC,
3265 NULL, 0, NULL, HFILL }},
3267 { &hf_pvfs_load_average_15s,
3268 { "Load Average (15s)", "pvfs.load_average.15s", FT_UINT64, BASE_DEC,
3269 NULL, 0, NULL, HFILL }},
3271 { &hf_pvfs_uptime_seconds,
3272 { "Uptime (seconds)", "pvfs.uptime", FT_UINT64, BASE_DEC,
3273 NULL, 0, NULL, HFILL }},
3275 { &hf_pvfs_handles_available,
3276 { "Handles Available", "pvfs.handles_available", FT_UINT64, BASE_DEC,
3277 NULL, 0, NULL, HFILL }},
3279 { &hf_pvfs_handles_total,
3280 { "Total Handles", "pvfs.total_handles", FT_UINT64, BASE_DEC,
3281 NULL, 0, NULL, HFILL }},
3284 * This is used when the field returns 64-bits but we're only interested
3285 * in the lower 32-bit bits.
3287 { &hf_pvfs_unused,
3288 { "Unused", "pvfs.unused", FT_UINT32, BASE_DEC,
3289 NULL, 0, NULL, HFILL }},
3291 { &hf_pvfs_context_id,
3292 { "Context ID", "pvfs.context_id", FT_UINT32, BASE_DEC,
3293 NULL, 0, NULL, HFILL }},
3295 { &hf_pvfs_offset,
3296 { "Offset", "pvfs.offset", FT_UINT64, BASE_DEC,
3297 NULL, 0, NULL, HFILL }},
3299 { &hf_pvfs_stride,
3300 { "Stride", "pvfs.stride", FT_UINT64, BASE_DEC,
3301 NULL, 0, NULL, HFILL }},
3303 { &hf_pvfs_ub,
3304 { "ub", "pvfs.ub", FT_UINT64, BASE_DEC,
3305 NULL, 0, NULL, HFILL }},
3307 { &hf_pvfs_lb,
3308 { "lb", "pvfs.lb", FT_UINT64, BASE_DEC,
3309 NULL, 0, NULL, HFILL }},
3311 { &hf_pvfs_end_time_ms,
3312 { "end_time_ms", "pvfs.end_time_ms", FT_UINT64, BASE_DEC,
3313 NULL, 0, NULL, HFILL }},
3315 { &hf_pvfs_cur_time_ms,
3316 { "cur_time_ms", "pvfs.cur_time_ms", FT_UINT64, BASE_DEC,
3317 NULL, 0, NULL, HFILL }},
3319 { &hf_pvfs_start_time_ms,
3320 { "start_time_ms", "pvfs.start_time_ms", FT_UINT64, BASE_DEC,
3321 NULL, 0, NULL, HFILL }},
3323 { &hf_pvfs_bytes_written,
3324 { "bytes_written", "pvfs.bytes_written", FT_UINT64, BASE_DEC,
3325 NULL, 0, NULL, HFILL }},
3327 { &hf_pvfs_bytes_read,
3328 { "bytes_read", "pvfs.bytes_read", FT_UINT64, BASE_DEC,
3329 NULL, 0, NULL, HFILL }},
3331 { &hf_pvfs_metadata_write,
3332 { "metadata_write", "pvfs.metadata_write", FT_UINT64, BASE_DEC,
3333 NULL, 0, NULL, HFILL }},
3335 { &hf_pvfs_metadata_read,
3336 { "metadata_read", "pvfs.metadata_read", FT_UINT64, BASE_DEC,
3337 NULL, 0, NULL, HFILL }},
3339 { &hf_pvfs_b_size,
3340 { "Size of bstream (if applicable)", "pvfs.b_size", FT_UINT64,
3341 BASE_DEC, NULL, 0, NULL, HFILL }},
3343 { &hf_pvfs_k_size,
3344 { "Number of keyvals (if applicable)", "pvfs.k_size", FT_UINT64,
3345 BASE_DEC, NULL, 0, NULL, HFILL }},
3347 { &hf_pvfs_id_gen_t,
3348 { "id_gen_t", "pvfs.id_gen_t", FT_UINT64, BASE_DEC,
3349 NULL, 0, NULL, HFILL }},
3351 { &hf_pvfs_attribute_key,
3352 { "Attribute key", "pvfs.attribute.key", FT_STRING, BASE_NONE,
3353 NULL, 0, NULL, HFILL }},
3355 { &hf_pvfs_attribute_value,
3356 { "Attribute value", "pvfs.attribute.value", FT_STRING, BASE_NONE,
3357 NULL, 0, NULL, HFILL }},
3359 { &hf_pvfs_strip_size,
3360 { "Strip size", "pvfs.strip_size", FT_UINT64, BASE_DEC,
3361 NULL, 0, "Strip size (bytes)", HFILL }},
3363 /* TODO: need description */
3364 { &hf_pvfs_ereg,
3365 { "ereg", "pvfs.ereg", FT_INT32, BASE_DEC,
3366 NULL, 0, NULL, HFILL }},
3368 /* TODO: need description */
3369 { &hf_pvfs_sreg,
3370 { "sreg", "pvfs.sreg", FT_INT32, BASE_DEC,
3371 NULL, 0, NULL, HFILL }},
3373 { &hf_pvfs_num_eregs,
3374 { "Number of eregs", "pvfs.num_eregs", FT_UINT32, BASE_DEC,
3375 NULL, 0, NULL, HFILL }},
3377 { &hf_pvfs_num_blocks,
3378 { "Number of blocks", "pvfs.num_blocks", FT_UINT32, BASE_DEC,
3379 NULL, 0, NULL, HFILL }},
3381 { &hf_pvfs_num_contig_chunks,
3382 { "Number of contig_chunks", "pvfs.num_contig_chunks", FT_UINT32,
3383 BASE_DEC, NULL, 0, NULL, HFILL }},
3385 { &hf_pvfs_server_nr,
3386 { "Server #", "pvfs.server_nr", FT_UINT32, BASE_DEC,
3387 NULL, 0, NULL, HFILL }},
3389 { &hf_pvfs_server_count,
3390 { "Number of servers", "pvfs.server_count", FT_UINT32, BASE_DEC,
3391 NULL, 0, NULL, HFILL }},
3393 { &hf_pvfs_fh_length,
3394 { "length", "pvfs.fh.length", FT_UINT32, BASE_DEC,
3395 NULL, 0, "file handle length", HFILL }},
3397 { &hf_pvfs_fh_hash,
3398 { "hash", "pvfs.fh.hash", FT_UINT32, BASE_HEX,
3399 NULL, 0, "file handle hash", HFILL }},
3401 { &hf_pvfs_permissions,
3402 { "Permissions", "pvfs.permissions", FT_UINT32, BASE_OCT,
3403 NULL, 0, NULL, HFILL }},
3405 { &hf_pvfs_server_mode,
3406 { "Server Mode", "pvfs.server_mode", FT_UINT32, BASE_DEC,
3407 VALS(names_pvfs_server_mode), 0, NULL, HFILL }},
3409 { &hf_pvfs_depth,
3410 { "depth", "pvfs.depth", FT_UINT32, BASE_DEC,
3411 NULL, 0, NULL, HFILL }},
3413 { &hf_pvfs_num_nested_req,
3414 { "num_nested_req", "pvfs.num_nested_req", FT_UINT32, BASE_DEC,
3415 NULL, 0, NULL, HFILL }},
3417 { &hf_pvfs_committed,
3418 { "committed", "pvfs.committed", FT_UINT32, BASE_DEC,
3419 NULL, 0, NULL, HFILL }},
3421 { &hf_pvfs_refcount,
3422 { "refcount", "pvfs.refcount", FT_UINT32, BASE_DEC,
3423 NULL, 0, NULL, HFILL }},
3425 { &hf_pvfs_numreq,
3426 { "numreq", "pvfs.numreq", FT_UINT32, BASE_DEC,
3427 NULL, 0, NULL, HFILL }},
3429 { &hf_pvfs_truncate_request_flags,
3430 { "flags", "pvfs.truncate_request_flags", FT_UINT32, BASE_DEC,
3431 NULL, 0, NULL, HFILL }},
3433 { &hf_pvfs_ds_position,
3434 { "ds_position", "pvfs.ds_position", FT_UINT32, BASE_DEC,
3435 NULL, 0, NULL, HFILL }},
3437 { &hf_pvfs_dirent_limit,
3438 { "dirent_limit", "pvfs.dirent_limit", FT_UINT32, BASE_DEC,
3439 NULL, 0, NULL, HFILL }},
3441 { &hf_pvfs_flush_request_flags,
3442 { "flags", "pvfs.flush_request_flags", FT_UINT32, BASE_DEC,
3443 NULL, 0, NULL, HFILL }},
3445 { &hf_pvfs_next_id,
3446 { "next_id", "pvfs.next_id", FT_UINT32, BASE_DEC,
3447 NULL, 0, NULL, HFILL }},
3449 { &hf_pvfs_mgmt_perf_mon_request_count,
3450 { "count", "pvfs.mgmt_perf_mon_request.count", FT_UINT32, BASE_DEC,
3451 NULL, 0, NULL, HFILL }},
3453 { &hf_pvfs_mgmt_perf_mon_request_event_count,
3454 { "Event count", "pvfs.mgmt_perf_mon_request.event_count", FT_UINT32, BASE_DEC,
3455 NULL, 0, NULL, HFILL }},
3457 { &hf_pvfs_lookup_path_response_handle_count,
3458 { "Handle Count", "pvfs.lookup_path_response.handle_count", FT_UINT32, BASE_DEC,
3459 NULL, 0, NULL, HFILL }},
3461 { &hf_pvfs_getconfig_response_total_bytes,
3462 { "Total Bytes", "pvfs.getconfig_response.total_bytes", FT_UINT32, BASE_DEC,
3463 NULL, 0, NULL, HFILL }},
3465 { &hf_pvfs_getconfig_response_lines,
3466 { "Lines", "pvfs.getconfig_response.lines", FT_UINT32, BASE_DEC,
3467 NULL, 0, NULL, HFILL }},
3469 { &hf_pvfs_getconfig_response_config_bytes,
3470 { "Config Bytes", "pvfs.getconfig_response.config_bytes", FT_UINT32, BASE_DEC,
3471 NULL, 0, NULL, HFILL }},
3473 { &hf_pvfs_mgmt_perf_stat_valid_flag,
3474 { "valid_flag", "pvfs.mgmt_perf_stat.valid_flag", FT_UINT32, BASE_DEC,
3475 NULL, 0, NULL, HFILL }},
3477 { &hf_pvfs_mgmt_perf_stat_id,
3478 { "id", "pvfs.mgmt_perf_stat.id", FT_UINT32, BASE_DEC,
3479 NULL, 0, NULL, HFILL }},
3481 { &hf_pvfs_mgmt_perf_mon_response_suggested_next_id,
3482 { "suggested_next_id", "pvfs.mgmt_perf_mon_response.suggested_next_id", FT_UINT32, BASE_DEC,
3483 NULL, 0, NULL, HFILL }},
3485 { &hf_pvfs_mgmt_perf_mon_response_perf_array_count,
3486 { "perf_array_count", "pvfs.mgmt_perf_mon_response.perf_array_count", FT_UINT32, BASE_DEC,
3487 NULL, 0, NULL, HFILL }},
3489 { &hf_pvfs_mgmt_iterate_handles_response_ds_position,
3490 { "ds_position", "pvfs.mgmt_iterate_handles_response.ds_position", FT_UINT32, BASE_DEC,
3491 NULL, 0, NULL, HFILL }},
3493 { &hf_pvfs_mgmt_iterate_handles_response_handle_count,
3494 { "handle_count", "pvfs.mgmt_iterate_handles_response.handle_count", FT_UINT32, BASE_DEC,
3495 NULL, 0, NULL, HFILL }},
3497 { &hf_pvfs_mgmt_dspace_info_list_response_dspace_info_count,
3498 { "dspace_info_count", "pvfs.mgmt_dspace_info_list_response.dspace_info_count", FT_UINT32, BASE_DEC,
3499 NULL, 0, NULL, HFILL }},
3501 { &hf_pvfs_mgmt_event_mon_response_api,
3502 { "api", "pvfs.mgmt_event_mon_response.api", FT_UINT32, BASE_DEC,
3503 NULL, 0, NULL, HFILL }},
3505 { &hf_pvfs_mgmt_event_mon_response_operation,
3506 { "operation", "pvfs.mgmt_event_mon_response.operation", FT_UINT32, BASE_DEC,
3507 NULL, 0, NULL, HFILL }},
3509 { &hf_pvfs_mgmt_event_mon_response_value,
3510 { "value", "pvfs.mgmt_event_mon_response.value", FT_UINT32, BASE_DEC,
3511 NULL, 0, NULL, HFILL }},
3513 { &hf_pvfs_mgmt_event_mon_response_flags,
3514 { "flags", "pvfs.mgmt_event_mon_response.flags", FT_UINT32, BASE_DEC,
3515 NULL, 0, NULL, HFILL }},
3517 { &hf_pvfs_mgmt_event_mon_response_tv_sec,
3518 { "tv_sec", "pvfs.mgmt_event_mon_response.tv_sec", FT_UINT32, BASE_DEC,
3519 NULL, 0, NULL, HFILL }},
3521 { &hf_pvfs_mgmt_event_mon_response_tv_usec,
3522 { "tv_usec", "pvfs.mgmt_event_mon_response.tv_usec", FT_UINT32, BASE_DEC,
3523 NULL, 0, NULL, HFILL }},
3525 { &hf_pvfs_fill_bytes,
3526 { "fill_bytes", "pvfs.fill_bytes", FT_BYTES, BASE_NONE,
3527 NULL, 0, NULL, HFILL }},
3529 { &hf_pvfs_target_path_len,
3530 { "target_path_len", "pvfs.target_path_len", FT_UINT32, BASE_DEC,
3531 NULL, 0, NULL, HFILL }},
3533 { &hf_pvfs_version2,
3534 { "Version 2", "pvfs.version2", FT_NONE, BASE_NONE,
3535 NULL, 0, NULL, HFILL }},
3537 { &hf_pvfs_flow_data,
3538 { "PVFC Flow Data", "pvfs.flow_data", FT_BYTES, BASE_NONE,
3539 NULL, 0, NULL, HFILL }},
3541 { &hf_pvfs_getconfig_response_entry,
3542 { "GETCONFIG Response entry", "pvfs.getconfig_response_entry", FT_STRING, BASE_NONE,
3543 NULL, 0, NULL, HFILL }},
3545 { &hf_fhandle_data,
3546 { "data", "pvfs.fhandle_data", FT_BYTES, BASE_NONE,
3547 NULL, 0, NULL, HFILL }},
3549 { &hf_pvfs_opaque_length,
3550 { "length", "pvfs.opaque_length", FT_UINT32, BASE_DEC,
3551 NULL, 0, NULL, HFILL }},
3554 /* Setup protocol subtree array */
3555 static int *ett[] = {
3556 &ett_pvfs,
3557 &ett_pvfs_hdr,
3558 &ett_pvfs_credentials,
3559 &ett_pvfs_server_config,
3560 &ett_pvfs_server_config_branch,
3561 &ett_pvfs_attrmask,
3562 &ett_pvfs_time,
3563 &ett_pvfs_extent_array_tree,
3564 &ett_pvfs_extent_item,
3565 &ett_pvfs_string,
3566 &ett_pvfs_attr_tree,
3567 &ett_pvfs_distribution,
3568 &ett_pvfs_mgmt_perf_stat,
3569 &ett_pvfs_mgmt_dspace_info,
3570 &ett_pvfs_attr,
3571 &ett_pvfs_fh
3574 static ei_register_info ei[] = {
3575 { &ei_pvfs_malformed, { "pvfs.malformed", PI_MALFORMED, PI_ERROR, "MALFORMED OR TRUNCATED DATA", EXPFILL }},
3578 module_t *pvfs_module;
3579 expert_module_t* expert_pvfs;
3581 /* Register the protocol name and description */
3582 proto_pvfs = proto_register_protocol("Parallel Virtual File System",
3583 "PVFS", "pvfs");
3584 pvfs_handle = register_dissector("pvfs", dissect_pvfs, proto_pvfs);
3587 * Required function calls to register the header fields and
3588 * subtrees used
3591 proto_register_field_array(proto_pvfs, hf, array_length(hf));
3592 proto_register_subtree_array(ett, array_length(ett));
3593 expert_pvfs = expert_register_protocol(proto_pvfs);
3594 expert_register_field_array(expert_pvfs, ei, array_length(ei));
3596 pvfs2_io_tracking_value_table = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), pvfs2_io_tracking_hash, pvfs2_io_tracking_equal);
3598 pvfs_module = prefs_register_protocol(proto_pvfs, NULL);
3599 prefs_register_bool_preference(pvfs_module, "desegment",
3600 "Reassemble PVFS messages spanning multiple TCP segments",
3601 "Whether the PVFS dissector should reassemble messages spanning multiple TCP segments. "
3602 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3603 &pvfs_desegment);
3606 void
3607 proto_reg_handoff_pvfs(void)
3609 dissector_add_uint_with_preference("tcp.port", TCP_PORT_PVFS2, pvfs_handle);
3611 heur_dissector_add("tcp", dissect_pvfs_heur, "PVFS over TCP", "pvfs_tcp", proto_pvfs, HEURISTIC_ENABLE);
3615 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3617 * Local variables:
3618 * c-basic-offset: 8
3619 * tab-width: 8
3620 * indent-tabs-mode: t
3621 * End:
3623 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3624 * :indentSize=8:tabSize=8:noTabs=false: